Whamcloud - gitweb
LU-17038 tests: remove munlink utility
[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 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47 fi
48
49 # skip the grant tests for ARM until they are fixed
50 if [[ $(uname -m) = aarch64 ]]; then
51         always_except LU-11671 45
52 fi
53
54 # skip nfs tests on kernels >= 4.12.0 until they are fixed
55 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
56         always_except LU-12661 817
57 fi
58 # skip cgroup tests on RHEL8.1 kernels until they are fixed
59 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
60       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
61         always_except LU-13063 411
62 fi
63
64 #                                  5              12     8   12  15   (min)"
65 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
66
67 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
68         #                                               13    (min)"
69         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
70 fi
71
72 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
73         always_except LU-1941 130b 130c 130d 130e 130f 130g
74         always_except LU-9054 312
75 fi
76
77 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
78
79 # Get the SLES distro version
80 #
81 # Returns a version string that should only be used in comparing
82 # strings returned by version_code()
83 sles_version_code()
84 {
85         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
86
87         # All SuSE Linux versions have one decimal. version_code expects two
88         local sles_version=$version.0
89         version_code $sles_version
90 }
91
92 # Check if we are running on Ubuntu or SLES so we can make decisions on
93 # what tests to run
94 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
95         sles_version=$(sles_version_code)
96         [ $sles_version -lt $(version_code 11.4.0) ] &&
97                 always_except LU-4341 170
98
99         [ $sles_version -lt $(version_code 12.0.0) ] &&
100                 always_except LU-3703 234
101 elif [ -r /etc/os-release ]; then
102         if grep -qi ubuntu /etc/os-release; then
103                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
104                                                 -e 's/^VERSION=//p' \
105                                                 /etc/os-release |
106                                                 awk '{ print $1 }'))
107
108                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
109                         always_except LU-10366 410
110                 fi
111         fi
112 fi
113
114 build_test_filter
115 FAIL_ON_ERROR=false
116
117 cleanup() {
118         echo -n "cln.."
119         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
120         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
121 }
122 setup() {
123         echo -n "mnt.."
124         load_modules
125         setupall || exit 10
126         echo "done"
127 }
128
129 check_swap_layouts_support()
130 {
131         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
132                 skip "Does not support layout lock."
133 }
134
135 check_swap_layout_no_dom()
136 {
137         local FOLDER=$1
138         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
139         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
140 }
141
142 check_and_setup_lustre
143 DIR=${DIR:-$MOUNT}
144 assert_DIR
145
146 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
147
148 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
149 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
150 rm -rf $DIR/[Rdfs][0-9]*
151
152 # $RUNAS_ID may get set incorrectly somewhere else
153 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
154         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
155
156 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
157
158 if [ "${ONLY}" = "MOUNT" ] ; then
159         echo "Lustre is up, please go on"
160         exit
161 fi
162
163 echo "preparing for tests involving mounts"
164 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
165 touch $EXT2_DEV
166 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
167 echo # add a newline after mke2fs.
168
169 umask 077
170
171 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
172
173 # ensure all internal functions know we want full debug
174 export PTLDEBUG=all
175 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
176
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare client versions.  Only compare top-3 fields for compatibility
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
232         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "exp version '$exp_client_version'($exp_val) != " \
235                         "'$(lustre_build_version client)'($imp_val)"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_0e() { # LU-13417
240         (( $MDSCOUNT > 1 )) ||
241                 skip "We need at least 2 MDTs for this test"
242
243         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
244                 skip "Need server version at least 2.14.51"
245
246         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
247         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
248
249         [ $default_lmv_count -eq 1 ] ||
250                 error "$MOUNT default stripe count $default_lmv_count"
251
252         [ $default_lmv_index -eq -1 ] ||
253                 error "$MOUNT default stripe index $default_lmv_index"
254
255         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
256         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
257
258         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
259         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
260
261         [ $mdt_index1 -eq $mdt_index2 ] &&
262                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
263
264         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
265 }
266 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
267
268 test_1() {
269         test_mkdir $DIR/$tdir
270         test_mkdir $DIR/$tdir/d2
271         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
273         rmdir $DIR/$tdir/d2
274         rmdir $DIR/$tdir
275         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
276 }
277 run_test 1 "mkdir; remkdir; rmdir"
278
279 test_2() {
280         test_mkdir $DIR/$tdir
281         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
282         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
283         rm -r $DIR/$tdir
284         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
285 }
286 run_test 2 "mkdir; touch; rmdir; check file"
287
288 test_3() {
289         test_mkdir $DIR/$tdir
290         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
291         touch $DIR/$tdir/$tfile
292         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
293         rm -r $DIR/$tdir
294         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
295 }
296 run_test 3 "mkdir; touch; rmdir; check dir"
297
298 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
299 test_4() {
300         test_mkdir -i 1 $DIR/$tdir
301
302         touch $DIR/$tdir/$tfile ||
303                 error "Create file under remote directory failed"
304
305         rmdir $DIR/$tdir &&
306                 error "Expect error removing in-use dir $DIR/$tdir"
307
308         test -d $DIR/$tdir || error "Remote directory disappeared"
309
310         rm -rf $DIR/$tdir || error "remove remote dir error"
311 }
312 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
313
314 test_5() {
315         test_mkdir $DIR/$tdir
316         test_mkdir $DIR/$tdir/d2
317         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
318         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
319         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
320 }
321 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
322
323 test_6a() {
324         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
325         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile does not have perm 0666 or UID $UID"
328         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile should be 0666 and owned by UID $UID"
331 }
332 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
333
334 test_6c() {
335         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
336
337         touch $DIR/$tfile
338         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344 }
345 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
346
347 test_6e() {
348         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
349
350         touch $DIR/$tfile
351         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by GID $UID"
354         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
357 }
358 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
359
360 test_6g() {
361         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
362
363         test_mkdir $DIR/$tdir
364         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
365         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
366         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
367         test_mkdir $DIR/$tdir/d/subdir
368         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
369                 error "$tdir/d/subdir should be GID $RUNAS_GID"
370         if [[ $MDSCOUNT -gt 1 ]]; then
371                 # check remote dir sgid inherite
372                 $LFS mkdir -i 0 $DIR/$tdir.local ||
373                         error "mkdir $tdir.local failed"
374                 chmod g+s $DIR/$tdir.local ||
375                         error "chmod $tdir.local failed"
376                 chgrp $RUNAS_GID $DIR/$tdir.local ||
377                         error "chgrp $tdir.local failed"
378                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
379                         error "mkdir $tdir.remote failed"
380                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
381                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
382                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
383                         error "$tdir.remote should be mode 02755"
384         fi
385 }
386 run_test 6g "verify new dir in sgid dir inherits group"
387
388 test_6h() { # bug 7331
389         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
390
391         touch $DIR/$tfile || error "touch failed"
392         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
393         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
394                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
395         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
396                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
397 }
398 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
399
400 test_7a() {
401         test_mkdir $DIR/$tdir
402         $MCREATE $DIR/$tdir/$tfile
403         chmod 0666 $DIR/$tdir/$tfile
404         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
405                 error "$tdir/$tfile should be mode 0666"
406 }
407 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
408
409 test_7b() {
410         if [ ! -d $DIR/$tdir ]; then
411                 test_mkdir $DIR/$tdir
412         fi
413         $MCREATE $DIR/$tdir/$tfile
414         echo -n foo > $DIR/$tdir/$tfile
415         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
416         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
417 }
418 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
419
420 test_8() {
421         test_mkdir $DIR/$tdir
422         touch $DIR/$tdir/$tfile
423         chmod 0666 $DIR/$tdir/$tfile
424         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
425                 error "$tfile mode not 0666"
426 }
427 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
428
429 test_9() {
430         test_mkdir $DIR/$tdir
431         test_mkdir $DIR/$tdir/d2
432         test_mkdir $DIR/$tdir/d2/d3
433         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
434 }
435 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
436
437 test_10() {
438         test_mkdir $DIR/$tdir
439         test_mkdir $DIR/$tdir/d2
440         touch $DIR/$tdir/d2/$tfile
441         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
442                 error "$tdir/d2/$tfile not a file"
443 }
444 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
445
446 test_11() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         chmod 0666 $DIR/$tdir/d2
450         chmod 0705 $DIR/$tdir/d2
451         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
452                 error "$tdir/d2 mode not 0705"
453 }
454 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
455
456 test_12() {
457         test_mkdir $DIR/$tdir
458         touch $DIR/$tdir/$tfile
459         chmod 0666 $DIR/$tdir/$tfile
460         chmod 0654 $DIR/$tdir/$tfile
461         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
462                 error "$tdir/d2 mode not 0654"
463 }
464 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
465
466 test_13() {
467         test_mkdir $DIR/$tdir
468         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
469         >  $DIR/$tdir/$tfile
470         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
471                 error "$tdir/$tfile size not 0 after truncate"
472 }
473 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
474
475 test_14() {
476         test_mkdir $DIR/$tdir
477         touch $DIR/$tdir/$tfile
478         rm $DIR/$tdir/$tfile
479         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
480 }
481 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
482
483 test_15() {
484         test_mkdir $DIR/$tdir
485         touch $DIR/$tdir/$tfile
486         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
487         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
488                 error "$tdir/${tfile_2} not a file after rename"
489         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
490 }
491 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
492
493 test_16() {
494         test_mkdir $DIR/$tdir
495         touch $DIR/$tdir/$tfile
496         rm -rf $DIR/$tdir/$tfile
497         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
498 }
499 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
500
501 test_17a() {
502         test_mkdir $DIR/$tdir
503         touch $DIR/$tdir/$tfile
504         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
505         ls -l $DIR/$tdir
506         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
507                 error "$tdir/l-exist not a symlink"
508         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
509                 error "$tdir/l-exist not referencing a file"
510         rm -f $DIR/$tdir/l-exist
511         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
512 }
513 run_test 17a "symlinks: create, remove (real)"
514
515 test_17b() {
516         test_mkdir $DIR/$tdir
517         ln -s no-such-file $DIR/$tdir/l-dangle
518         ls -l $DIR/$tdir
519         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
520                 error "$tdir/l-dangle not referencing no-such-file"
521         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
522                 error "$tdir/l-dangle not referencing non-existent file"
523         rm -f $DIR/$tdir/l-dangle
524         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
525 }
526 run_test 17b "symlinks: create, remove (dangling)"
527
528 test_17c() { # bug 3440 - don't save failed open RPC for replay
529         test_mkdir $DIR/$tdir
530         ln -s foo $DIR/$tdir/$tfile
531         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
532 }
533 run_test 17c "symlinks: open dangling (should return error)"
534
535 test_17d() {
536         test_mkdir $DIR/$tdir
537         ln -s foo $DIR/$tdir/$tfile
538         touch $DIR/$tdir/$tfile || error "creating to new symlink"
539 }
540 run_test 17d "symlinks: create dangling"
541
542 test_17e() {
543         test_mkdir $DIR/$tdir
544         local foo=$DIR/$tdir/$tfile
545         ln -s $foo $foo || error "create symlink failed"
546         ls -l $foo || error "ls -l failed"
547         ls $foo && error "ls not failed" || true
548 }
549 run_test 17e "symlinks: create recursive symlink (should return error)"
550
551 test_17f() {
552         test_mkdir $DIR/$tdir
553         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
556         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
558         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
559         ls -l  $DIR/$tdir
560 }
561 run_test 17f "symlinks: long and very long symlink name"
562
563 # str_repeat(S, N) generate a string that is string S repeated N times
564 str_repeat() {
565         local s=$1
566         local n=$2
567         local ret=''
568         while [ $((n -= 1)) -ge 0 ]; do
569                 ret=$ret$s
570         done
571         echo $ret
572 }
573
574 # Long symlinks and LU-2241
575 test_17g() {
576         test_mkdir $DIR/$tdir
577         local TESTS="59 60 61 4094 4095"
578
579         # Fix for inode size boundary in 2.1.4
580         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
581                 TESTS="4094 4095"
582
583         # Patch not applied to 2.2 or 2.3 branches
584         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
585         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
586                 TESTS="4094 4095"
587
588         for i in $TESTS; do
589                 local SYMNAME=$(str_repeat 'x' $i)
590                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
591                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
592         done
593 }
594 run_test 17g "symlinks: really long symlink name and inode boundaries"
595
596 test_17h() { #bug 17378
597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
598         remote_mds_nodsh && skip "remote MDS with nodsh"
599
600         local mdt_idx
601
602         test_mkdir $DIR/$tdir
603         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
604         $LFS setstripe -c -1 $DIR/$tdir
605         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
606         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
607         touch $DIR/$tdir/$tfile || true
608 }
609 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
610
611 test_17i() { #bug 20018
612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
613         remote_mds_nodsh && skip "remote MDS with nodsh"
614
615         local foo=$DIR/$tdir/$tfile
616         local mdt_idx
617
618         test_mkdir -c1 $DIR/$tdir
619         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
620         ln -s $foo $foo || error "create symlink failed"
621 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
622         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
623         ls -l $foo && error "error not detected"
624         return 0
625 }
626 run_test 17i "don't panic on short symlink (should return error)"
627
628 test_17k() { #bug 22301
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         [[ -z "$(which rsync 2>/dev/null)" ]] &&
631                 skip "no rsync command"
632         rsync --help | grep -q xattr ||
633                 skip_env "$(rsync --version | head -n1) does not support xattrs"
634         test_mkdir $DIR/$tdir
635         test_mkdir $DIR/$tdir.new
636         touch $DIR/$tdir/$tfile
637         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
638         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
639                 error "rsync failed with xattrs enabled"
640 }
641 run_test 17k "symlinks: rsync with xattrs enabled"
642
643 test_17l() { # LU-279
644         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
645                 skip "no getfattr command"
646
647         test_mkdir $DIR/$tdir
648         touch $DIR/$tdir/$tfile
649         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
650         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
651                 # -h to not follow symlinks. -m '' to list all the xattrs.
652                 # grep to remove first line: '# file: $path'.
653                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
654                 do
655                         lgetxattr_size_check $path $xattr ||
656                                 error "lgetxattr_size_check $path $xattr failed"
657                 done
658         done
659 }
660 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
661
662 # LU-1540
663 test_17m() {
664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
665         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
666         remote_mds_nodsh && skip "remote MDS with nodsh"
667         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
668         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
669                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
670
671         local short_sym="0123456789"
672         local wdir=$DIR/$tdir
673         local i
674
675         test_mkdir $wdir
676         long_sym=$short_sym
677         # create a long symlink file
678         for ((i = 0; i < 4; ++i)); do
679                 long_sym=${long_sym}${long_sym}
680         done
681
682         echo "create 512 short and long symlink files under $wdir"
683         for ((i = 0; i < 256; ++i)); do
684                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
685                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
686         done
687
688         echo "erase them"
689         rm -f $wdir/*
690         sync
691         wait_delete_completed
692
693         echo "recreate the 512 symlink files with a shorter string"
694         for ((i = 0; i < 512; ++i)); do
695                 # rewrite the symlink file with a shorter string
696                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
697                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
698         done
699
700         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
701
702         echo "stop and checking mds${mds_index}:"
703         # e2fsck should not return error
704         stop mds${mds_index}
705         local devname=$(mdsdevname $mds_index)
706         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
707         rc=$?
708
709         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
710                 error "start mds${mds_index} failed"
711         df $MOUNT > /dev/null 2>&1
712         [ $rc -eq 0 ] ||
713                 error "e2fsck detected error for short/long symlink: rc=$rc"
714         rm -f $wdir/*
715 }
716 run_test 17m "run e2fsck against MDT which contains short/long symlink"
717
718 check_fs_consistency_17n() {
719         local mdt_index
720         local rc=0
721
722         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
723         # so it only check MDT1/MDT2 instead of all of MDTs.
724         for mdt_index in 1 2; do
725                 # e2fsck should not return error
726                 stop mds${mdt_index}
727                 local devname=$(mdsdevname $mdt_index)
728                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
729                         rc=$((rc + $?))
730
731                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
732                         error "mount mds$mdt_index failed"
733                 df $MOUNT > /dev/null 2>&1
734         done
735         return $rc
736 }
737
738 test_17n() {
739         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
741         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
742         remote_mds_nodsh && skip "remote MDS with nodsh"
743         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
744         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
745                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
746
747         local i
748
749         test_mkdir $DIR/$tdir
750         for ((i=0; i<10; i++)); do
751                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
752                         error "create remote dir error $i"
753                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
754                         error "create files under remote dir failed $i"
755         done
756
757         check_fs_consistency_17n ||
758                 error "e2fsck report error after create files under remote dir"
759
760         for ((i = 0; i < 10; i++)); do
761                 rm -rf $DIR/$tdir/remote_dir_${i} ||
762                         error "destroy remote dir error $i"
763         done
764
765         check_fs_consistency_17n ||
766                 error "e2fsck report error after unlink files under remote dir"
767
768         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
769                 skip "lustre < 2.4.50 does not support migrate mv"
770
771         for ((i = 0; i < 10; i++)); do
772                 mkdir -p $DIR/$tdir/remote_dir_${i}
773                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
774                         error "create files under remote dir failed $i"
775                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
776                         error "migrate remote dir error $i"
777         done
778         check_fs_consistency_17n || error "e2fsck report error after migration"
779
780         for ((i = 0; i < 10; i++)); do
781                 rm -rf $DIR/$tdir/remote_dir_${i} ||
782                         error "destroy remote dir error $i"
783         done
784
785         check_fs_consistency_17n || error "e2fsck report error after unlink"
786 }
787 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
788
789 test_17o() {
790         remote_mds_nodsh && skip "remote MDS with nodsh"
791         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
792                 skip "Need MDS version at least 2.3.64"
793
794         local wdir=$DIR/${tdir}o
795         local mdt_index
796         local rc=0
797
798         test_mkdir $wdir
799         touch $wdir/$tfile
800         mdt_index=$($LFS getstripe -m $wdir/$tfile)
801         mdt_index=$((mdt_index + 1))
802
803         cancel_lru_locks mdc
804         #fail mds will wait the failover finish then set
805         #following fail_loc to avoid interfer the recovery process.
806         fail mds${mdt_index}
807
808         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
809         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
810         ls -l $wdir/$tfile && rc=1
811         do_facet mds${mdt_index} lctl set_param fail_loc=0
812         [[ $rc -eq 0 ]] || error "stat file should fail"
813 }
814 run_test 17o "stat file with incompat LMA feature"
815
816 test_18() {
817         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
818         ls $DIR || error "Failed to ls $DIR: $?"
819 }
820 run_test 18 "touch .../f ; ls ... =============================="
821
822 test_19a() {
823         touch $DIR/$tfile
824         ls -l $DIR
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
829
830 test_19b() {
831         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
832 }
833 run_test 19b "ls -l .../f19 (should return error) =============="
834
835 test_19c() {
836         [ $RUNAS_ID -eq $UID ] &&
837                 skip_env "RUNAS_ID = UID = $UID -- skipping"
838
839         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
840 }
841 run_test 19c "$RUNAS touch .../f19 (should return error) =="
842
843 test_19d() {
844         cat $DIR/f19 && error || true
845 }
846 run_test 19d "cat .../f19 (should return error) =============="
847
848 test_20() {
849         touch $DIR/$tfile
850         rm $DIR/$tfile
851         touch $DIR/$tfile
852         rm $DIR/$tfile
853         touch $DIR/$tfile
854         rm $DIR/$tfile
855         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
856 }
857 run_test 20 "touch .../f ; ls -l ..."
858
859 test_21() {
860         test_mkdir $DIR/$tdir
861         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
862         ln -s dangle $DIR/$tdir/link
863         echo foo >> $DIR/$tdir/link
864         cat $DIR/$tdir/dangle
865         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
866         $CHECKSTAT -f -t file $DIR/$tdir/link ||
867                 error "$tdir/link not linked to a file"
868 }
869 run_test 21 "write to dangling link"
870
871 test_22() {
872         local wdir=$DIR/$tdir
873         test_mkdir $wdir
874         chown $RUNAS_ID:$RUNAS_GID $wdir
875         (cd $wdir || error "cd $wdir failed";
876                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
877                 $RUNAS tar xf -)
878         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
879         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
880         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
881                 error "checkstat -u failed"
882 }
883 run_test 22 "unpack tar archive as non-root user"
884
885 # was test_23
886 test_23a() {
887         test_mkdir $DIR/$tdir
888         local file=$DIR/$tdir/$tfile
889
890         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
891         openfile -f O_CREAT:O_EXCL $file &&
892                 error "$file recreate succeeded" || true
893 }
894 run_test 23a "O_CREAT|O_EXCL in subdir"
895
896 test_23b() { # bug 18988
897         test_mkdir $DIR/$tdir
898         local file=$DIR/$tdir/$tfile
899
900         rm -f $file
901         echo foo > $file || error "write filed"
902         echo bar >> $file || error "append filed"
903         $CHECKSTAT -s 8 $file || error "wrong size"
904         rm $file
905 }
906 run_test 23b "O_APPEND check"
907
908 # LU-9409, size with O_APPEND and tiny writes
909 test_23c() {
910         local file=$DIR/$tfile
911
912         # single dd
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
914         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
915         rm -f $file
916
917         # racing tiny writes
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
920         wait
921         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
922         rm -f $file
923
924         #racing tiny & normal writes
925         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
926         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
927         wait
928         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
929         rm -f $file
930
931         #racing tiny & normal writes 2, ugly numbers
932         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
934         wait
935         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
936         rm -f $file
937 }
938 run_test 23c "O_APPEND size checks for tiny writes"
939
940 # LU-11069 file offset is correct after appending writes
941 test_23d() {
942         local file=$DIR/$tfile
943         local offset
944
945         echo CentaurHauls > $file
946         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
947         if ((offset != 26)); then
948                 error "wrong offset, expected 26, got '$offset'"
949         fi
950 }
951 run_test 23d "file offset is correct after appending writes"
952
953 # rename sanity
954 test_24a() {
955         echo '-- same directory rename'
956         test_mkdir $DIR/$tdir
957         touch $DIR/$tdir/$tfile.1
958         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
959         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
960 }
961 run_test 24a "rename file to non-existent target"
962
963 test_24b() {
964         test_mkdir $DIR/$tdir
965         touch $DIR/$tdir/$tfile.{1,2}
966         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
967         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
968         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
969 }
970 run_test 24b "rename file to existing target"
971
972 test_24c() {
973         test_mkdir $DIR/$tdir
974         test_mkdir $DIR/$tdir/d$testnum.1
975         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
976         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
977         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
978 }
979 run_test 24c "rename directory to non-existent target"
980
981 test_24d() {
982         test_mkdir -c1 $DIR/$tdir
983         test_mkdir -c1 $DIR/$tdir/d$testnum.1
984         test_mkdir -c1 $DIR/$tdir/d$testnum.2
985         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
986         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
987         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
988 }
989 run_test 24d "rename directory to existing target"
990
991 test_24e() {
992         echo '-- cross directory renames --'
993         test_mkdir $DIR/R5a
994         test_mkdir $DIR/R5b
995         touch $DIR/R5a/f
996         mv $DIR/R5a/f $DIR/R5b/g
997         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
998         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
999 }
1000 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1001
1002 test_24f() {
1003         test_mkdir $DIR/R6a
1004         test_mkdir $DIR/R6b
1005         touch $DIR/R6a/f $DIR/R6b/g
1006         mv $DIR/R6a/f $DIR/R6b/g
1007         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1008         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1009 }
1010 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1011
1012 test_24g() {
1013         test_mkdir $DIR/R7a
1014         test_mkdir $DIR/R7b
1015         test_mkdir $DIR/R7a/d
1016         mv $DIR/R7a/d $DIR/R7b/e
1017         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1018         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1019 }
1020 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1021
1022 test_24h() {
1023         test_mkdir -c1 $DIR/R8a
1024         test_mkdir -c1 $DIR/R8b
1025         test_mkdir -c1 $DIR/R8a/d
1026         test_mkdir -c1 $DIR/R8b/e
1027         mrename $DIR/R8a/d $DIR/R8b/e
1028         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1029         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1030 }
1031 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1032
1033 test_24i() {
1034         echo "-- rename error cases"
1035         test_mkdir $DIR/R9
1036         test_mkdir $DIR/R9/a
1037         touch $DIR/R9/f
1038         mrename $DIR/R9/f $DIR/R9/a
1039         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1040         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1041         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1042 }
1043 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1044
1045 test_24j() {
1046         test_mkdir $DIR/R10
1047         mrename $DIR/R10/f $DIR/R10/g
1048         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1049         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1050         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1051 }
1052 run_test 24j "source does not exist ============================"
1053
1054 test_24k() {
1055         test_mkdir $DIR/R11a
1056         test_mkdir $DIR/R11a/d
1057         touch $DIR/R11a/f
1058         mv $DIR/R11a/f $DIR/R11a/d
1059         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1060         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1061 }
1062 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1063
1064 # bug 2429 - rename foo foo foo creates invalid file
1065 test_24l() {
1066         f="$DIR/f24l"
1067         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1068 }
1069 run_test 24l "Renaming a file to itself ========================"
1070
1071 test_24m() {
1072         f="$DIR/f24m"
1073         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1074         # on ext3 this does not remove either the source or target files
1075         # though the "expected" operation would be to remove the source
1076         $CHECKSTAT -t file ${f} || error "${f} missing"
1077         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1078 }
1079 run_test 24m "Renaming a file to a hard link to itself ========="
1080
1081 test_24n() {
1082     f="$DIR/f24n"
1083     # this stats the old file after it was renamed, so it should fail
1084     touch ${f}
1085     $CHECKSTAT ${f} || error "${f} missing"
1086     mv ${f} ${f}.rename
1087     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1088     $CHECKSTAT -a ${f} || error "${f} exists"
1089 }
1090 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1091
1092 test_24o() {
1093         test_mkdir $DIR/$tdir
1094         rename_many -s random -v -n 10 $DIR/$tdir
1095 }
1096 run_test 24o "rename of files during htree split"
1097
1098 test_24p() {
1099         test_mkdir $DIR/R12a
1100         test_mkdir $DIR/R12b
1101         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1102         mrename $DIR/R12a $DIR/R12b
1103         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1104         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1105         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1106         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1107 }
1108 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1109
1110 cleanup_multiop_pause() {
1111         trap 0
1112         kill -USR1 $MULTIPID
1113 }
1114
1115 test_24q() {
1116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1117
1118         test_mkdir $DIR/R13a
1119         test_mkdir $DIR/R13b
1120         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1121         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1122         MULTIPID=$!
1123
1124         trap cleanup_multiop_pause EXIT
1125         mrename $DIR/R13a $DIR/R13b
1126         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1127         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1128         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1129         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1130         cleanup_multiop_pause
1131         wait $MULTIPID || error "multiop close failed"
1132 }
1133 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1134
1135 test_24r() { #bug 3789
1136         test_mkdir $DIR/R14a
1137         test_mkdir $DIR/R14a/b
1138         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1139         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1140         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1141 }
1142 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1143
1144 test_24s() {
1145         test_mkdir $DIR/R15a
1146         test_mkdir $DIR/R15a/b
1147         test_mkdir $DIR/R15a/b/c
1148         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1149         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1150         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1151 }
1152 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1153
1154 test_24t() {
1155         test_mkdir $DIR/R16a
1156         test_mkdir $DIR/R16a/b
1157         test_mkdir $DIR/R16a/b/c
1158         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1159         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1160         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1161 }
1162 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1163
1164 test_24u() { # bug12192
1165         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1166         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1167 }
1168 run_test 24u "create stripe file"
1169
1170 simple_cleanup_common() {
1171         local createmany=$1
1172         local rc=0
1173
1174         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1175
1176         local start=$SECONDS
1177
1178         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1179         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1180         rc=$?
1181         wait_delete_completed
1182         echo "cleanup time $((SECONDS - start))"
1183         return $rc
1184 }
1185
1186 max_pages_per_rpc() {
1187         local mdtname="$(printf "MDT%04x" ${1:-0})"
1188         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1189 }
1190
1191 test_24v() {
1192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1193
1194         local nrfiles=${COUNT:-100000}
1195         local fname="$DIR/$tdir/$tfile"
1196
1197         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1198         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1199
1200         test_mkdir "$(dirname $fname)"
1201         # assume MDT0000 has the fewest inodes
1202         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1203         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1204         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1205
1206         stack_trap "simple_cleanup_common $nrfiles"
1207
1208         createmany -m "$fname" $nrfiles
1209
1210         cancel_lru_locks mdc
1211         lctl set_param mdc.*.stats clear
1212
1213         # was previously test_24D: LU-6101
1214         # readdir() returns correct number of entries after cursor reload
1215         local num_ls=$(ls $DIR/$tdir | wc -l)
1216         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1217         local num_all=$(ls -a $DIR/$tdir | wc -l)
1218         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1219                 [ $num_all -ne $((nrfiles + 2)) ]; then
1220                         error "Expected $nrfiles files, got $num_ls " \
1221                                 "($num_uniq unique $num_all .&..)"
1222         fi
1223         # LU-5 large readdir
1224         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1225         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1226         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1227         # take into account of overhead in lu_dirpage header and end mark in
1228         # each page, plus one in rpc_num calculation.
1229         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1230         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1231         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1232         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1233         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1234         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1235         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1236         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1237                 error "large readdir doesn't take effect: " \
1238                       "$mds_readpage should be about $rpc_max"
1239 }
1240 run_test 24v "list large directory (test hash collision, b=17560)"
1241
1242 test_24w() { # bug21506
1243         SZ1=234852
1244         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1245         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1246         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1247         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1248         [[ "$SZ1" -eq "$SZ2" ]] ||
1249                 error "Error reading at the end of the file $tfile"
1250 }
1251 run_test 24w "Reading a file larger than 4Gb"
1252
1253 test_24x() {
1254         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1256         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1257                 skip "Need MDS version at least 2.7.56"
1258
1259         local MDTIDX=1
1260         local remote_dir=$DIR/$tdir/remote_dir
1261
1262         test_mkdir $DIR/$tdir
1263         $LFS mkdir -i $MDTIDX $remote_dir ||
1264                 error "create remote directory failed"
1265
1266         test_mkdir $DIR/$tdir/src_dir
1267         touch $DIR/$tdir/src_file
1268         test_mkdir $remote_dir/tgt_dir
1269         touch $remote_dir/tgt_file
1270
1271         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1272                 error "rename dir cross MDT failed!"
1273
1274         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1275                 error "rename file cross MDT failed!"
1276
1277         touch $DIR/$tdir/ln_file
1278         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1279                 error "ln file cross MDT failed"
1280
1281         rm -rf $DIR/$tdir || error "Can not delete directories"
1282 }
1283 run_test 24x "cross MDT rename/link"
1284
1285 test_24y() {
1286         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1288
1289         local remote_dir=$DIR/$tdir/remote_dir
1290         local mdtidx=1
1291
1292         test_mkdir $DIR/$tdir
1293         $LFS mkdir -i $mdtidx $remote_dir ||
1294                 error "create remote directory failed"
1295
1296         test_mkdir $remote_dir/src_dir
1297         touch $remote_dir/src_file
1298         test_mkdir $remote_dir/tgt_dir
1299         touch $remote_dir/tgt_file
1300
1301         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1302                 error "rename subdir in the same remote dir failed!"
1303
1304         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1305                 error "rename files in the same remote dir failed!"
1306
1307         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1308                 error "link files in the same remote dir failed!"
1309
1310         rm -rf $DIR/$tdir || error "Can not delete directories"
1311 }
1312 run_test 24y "rename/link on the same dir should succeed"
1313
1314 test_24z() {
1315         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1316         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1317                 skip "Need MDS version at least 2.12.51"
1318
1319         local index
1320
1321         for index in 0 1; do
1322                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1323                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1324         done
1325
1326         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1327
1328         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1329         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1330
1331         local mdts=$(comma_list $(mdts_nodes))
1332
1333         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1334         stack_trap "do_nodes $mdts $LCTL \
1335                 set_param mdt.*.enable_remote_rename=1" EXIT
1336
1337         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1338
1339         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1340         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1341 }
1342 run_test 24z "cross-MDT rename is done as cp"
1343
1344 test_24A() { # LU-3182
1345         local NFILES=5000
1346
1347         test_mkdir $DIR/$tdir
1348         stack_trap "simple_cleanup_common $NFILES"
1349         createmany -m $DIR/$tdir/$tfile $NFILES
1350         local t=$(ls $DIR/$tdir | wc -l)
1351         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1352         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1353
1354         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1355                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1356 }
1357 run_test 24A "readdir() returns correct number of entries."
1358
1359 test_24B() { # LU-4805
1360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1361
1362         local count
1363
1364         test_mkdir $DIR/$tdir
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1366                 error "create striped dir failed"
1367
1368         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1369         [ $count -eq 2 ] || error "Expected 2, got $count"
1370
1371         touch $DIR/$tdir/striped_dir/a
1372
1373         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1374         [ $count -eq 3 ] || error "Expected 3, got $count"
1375
1376         touch $DIR/$tdir/striped_dir/.f
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 4 ] || error "Expected 4, got $count"
1380
1381         rm -rf $DIR/$tdir || error "Can not delete directories"
1382 }
1383 run_test 24B "readdir for striped dir return correct number of entries"
1384
1385 test_24C() {
1386         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1387
1388         mkdir $DIR/$tdir
1389         mkdir $DIR/$tdir/d0
1390         mkdir $DIR/$tdir/d1
1391
1392         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1393                 error "create striped dir failed"
1394
1395         cd $DIR/$tdir/d0/striped_dir
1396
1397         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1398         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1399         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1400
1401         [ "$d0_ino" = "$parent_ino" ] ||
1402                 error ".. wrong, expect $d0_ino, get $parent_ino"
1403
1404         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1405                 error "mv striped dir failed"
1406
1407         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1408
1409         [ "$d1_ino" = "$parent_ino" ] ||
1410                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1411 }
1412 run_test 24C "check .. in striped dir"
1413
1414 test_24E() {
1415         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1417
1418         mkdir -p $DIR/$tdir
1419         mkdir $DIR/$tdir/src_dir
1420         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1421                 error "create remote source failed"
1422
1423         touch $DIR/$tdir/src_dir/src_child/a
1424
1425         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1426                 error "create remote target dir failed"
1427
1428         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "create remote target child failed"
1430
1431         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1432                 error "rename dir cross MDT failed!"
1433
1434         find $DIR/$tdir
1435
1436         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1437                 error "src_child still exists after rename"
1438
1439         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1440                 error "missing file(a) after rename"
1441
1442         rm -rf $DIR/$tdir || error "Can not delete directories"
1443 }
1444 run_test 24E "cross MDT rename/link"
1445
1446 test_24F () {
1447         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1448
1449         local repeats=1000
1450         [ "$SLOW" = "no" ] && repeats=100
1451
1452         mkdir -p $DIR/$tdir
1453
1454         echo "$repeats repeats"
1455         for ((i = 0; i < repeats; i++)); do
1456                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1457                 touch $DIR/$tdir/test/a || error "touch fails"
1458                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1459                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1460         done
1461
1462         true
1463 }
1464 run_test 24F "hash order vs readdir (LU-11330)"
1465
1466 test_24G () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1468
1469         local ino1
1470         local ino2
1471
1472         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1473         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1474         touch $DIR/$tdir-0/f1 || error "touch f1"
1475         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1476         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1477         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1478         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1479         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1480 }
1481 run_test 24G "migrate symlink in rename"
1482
1483 test_24H() {
1484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1485         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1486                 skip "MDT1 should be on another node"
1487
1488         test_mkdir -i 1 -c 1 $DIR/$tdir
1489 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1490         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1491         touch $DIR/$tdir/$tfile || error "touch failed"
1492 }
1493 run_test 24H "repeat FLD_QUERY rpc"
1494
1495 test_25a() {
1496         echo '== symlink sanity ============================================='
1497
1498         test_mkdir $DIR/d25
1499         ln -s d25 $DIR/s25
1500         touch $DIR/s25/foo ||
1501                 error "File creation in symlinked directory failed"
1502 }
1503 run_test 25a "create file in symlinked directory ==============="
1504
1505 test_25b() {
1506         [ ! -d $DIR/d25 ] && test_25a
1507         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1508 }
1509 run_test 25b "lookup file in symlinked directory ==============="
1510
1511 test_26a() {
1512         test_mkdir $DIR/d26
1513         test_mkdir $DIR/d26/d26-2
1514         ln -s d26/d26-2 $DIR/s26
1515         touch $DIR/s26/foo || error "File creation failed"
1516 }
1517 run_test 26a "multiple component symlink ======================="
1518
1519 test_26b() {
1520         test_mkdir -p $DIR/$tdir/d26-2
1521         ln -s $tdir/d26-2/foo $DIR/s26-2
1522         touch $DIR/s26-2 || error "File creation failed"
1523 }
1524 run_test 26b "multiple component symlink at end of lookup ======"
1525
1526 test_26c() {
1527         test_mkdir $DIR/d26.2
1528         touch $DIR/d26.2/foo
1529         ln -s d26.2 $DIR/s26.2-1
1530         ln -s s26.2-1 $DIR/s26.2-2
1531         ln -s s26.2-2 $DIR/s26.2-3
1532         chmod 0666 $DIR/s26.2-3/foo
1533 }
1534 run_test 26c "chain of symlinks"
1535
1536 # recursive symlinks (bug 439)
1537 test_26d() {
1538         ln -s d26-3/foo $DIR/d26-3
1539 }
1540 run_test 26d "create multiple component recursive symlink"
1541
1542 test_26e() {
1543         [ ! -h $DIR/d26-3 ] && test_26d
1544         rm $DIR/d26-3
1545 }
1546 run_test 26e "unlink multiple component recursive symlink"
1547
1548 # recursive symlinks (bug 7022)
1549 test_26f() {
1550         test_mkdir $DIR/$tdir
1551         test_mkdir $DIR/$tdir/$tfile
1552         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1553         test_mkdir -p lndir/bar1
1554         test_mkdir $DIR/$tdir/$tfile/$tfile
1555         cd $tfile                || error "cd $tfile failed"
1556         ln -s .. dotdot          || error "ln dotdot failed"
1557         ln -s dotdot/lndir lndir || error "ln lndir failed"
1558         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1559         output=`ls $tfile/$tfile/lndir/bar1`
1560         [ "$output" = bar1 ] && error "unexpected output"
1561         rm -r $tfile             || error "rm $tfile failed"
1562         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1563 }
1564 run_test 26f "rm -r of a directory which has recursive symlink"
1565
1566 test_27a() {
1567         test_mkdir $DIR/$tdir
1568         $LFS getstripe $DIR/$tdir
1569         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1570         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1571         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1572 }
1573 run_test 27a "one stripe file"
1574
1575 test_27b() {
1576         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1577
1578         test_mkdir $DIR/$tdir
1579         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1580         $LFS getstripe -c $DIR/$tdir/$tfile
1581         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1582                 error "two-stripe file doesn't have two stripes"
1583
1584         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1585 }
1586 run_test 27b "create and write to two stripe file"
1587
1588 # 27c family tests specific striping, setstripe -o
1589 test_27ca() {
1590         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1591         test_mkdir -p $DIR/$tdir
1592         local osts="1"
1593
1594         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1595         $LFS getstripe -i $DIR/$tdir/$tfile
1596         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1597                 error "stripe not on specified OST"
1598
1599         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1600 }
1601 run_test 27ca "one stripe on specified OST"
1602
1603 test_27cb() {
1604         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1605         test_mkdir -p $DIR/$tdir
1606         local osts="1,0"
1607         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1608         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1609         echo "$getstripe"
1610
1611         # Strip getstripe output to a space separated list of OSTs
1612         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1613                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1614         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1615                 error "stripes not on specified OSTs"
1616
1617         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1618 }
1619 run_test 27cb "two stripes on specified OSTs"
1620
1621 test_27cc() {
1622         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1623         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1624                 skip "server does not support overstriping"
1625
1626         test_mkdir -p $DIR/$tdir
1627         local osts="0,0"
1628         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1629         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1630         echo "$getstripe"
1631
1632         # Strip getstripe output to a space separated list of OSTs
1633         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1634                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1635         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1636                 error "stripes not on specified OSTs"
1637
1638         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1639 }
1640 run_test 27cc "two stripes on the same OST"
1641
1642 test_27cd() {
1643         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1644         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1645                 skip "server does not support overstriping"
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,1,1,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cd "four stripes on two OSTs"
1661
1662 test_27ce() {
1663         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1664                 skip_env "too many osts, skipping"
1665         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1666                 skip "server does not support overstriping"
1667         # We do one more stripe than we have OSTs
1668         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1669                 skip_env "ea_inode feature disabled"
1670
1671         test_mkdir -p $DIR/$tdir
1672         local osts=""
1673         for i in $(seq 0 $OSTCOUNT);
1674         do
1675                 osts=$osts"0"
1676                 if [ $i -ne $OSTCOUNT ]; then
1677                         osts=$osts","
1678                 fi
1679         done
1680         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1681         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1682         echo "$getstripe"
1683
1684         # Strip getstripe output to a space separated list of OSTs
1685         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1686                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1687         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1688                 error "stripes not on specified OSTs"
1689
1690         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1691 }
1692 run_test 27ce "more stripes than OSTs with -o"
1693
1694 test_27cf() {
1695         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1696         local pid=0
1697
1698         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1699         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1700         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1701         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1702                 error "failed to set $osp_proc=0"
1703
1704         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1705         pid=$!
1706         sleep 1
1707         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1709                 error "failed to set $osp_proc=1"
1710         wait $pid
1711         [[ $pid -ne 0 ]] ||
1712                 error "should return error due to $osp_proc=0"
1713 }
1714 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1715
1716 test_27cg() {
1717         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1718                 skip "server does not support overstriping"
1719         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1720         large_xattr_enabled || skip_env "ea_inode feature disabled"
1721
1722         local osts="0"
1723
1724         for ((i=1;i<1000;i++)); do
1725                 osts+=",$((i % OSTCOUNT))"
1726         done
1727
1728         local mdts=$(comma_list $(mdts_nodes))
1729         local before=$(do_nodes $mdts \
1730                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1731                 awk '/many credits/{print $3}' |
1732                 calc_sum)
1733
1734         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1735         $LFS getstripe $DIR/$tfile | grep stripe
1736
1737         rm -f $DIR/$tfile || error "can't unlink"
1738
1739         after=$(do_nodes $mdts \
1740                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1741                 awk '/many credits/{print $3}' |
1742                 calc_sum)
1743
1744         (( before == after )) ||
1745                 error "too many credits happened: $after > $before"
1746 }
1747 run_test 27cg "1000 shouldn't cause too many credits"
1748
1749 test_27d() {
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1752                 error "setstripe failed"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1755 }
1756 run_test 27d "create file with default settings"
1757
1758 test_27e() {
1759         # LU-5839 adds check for existed layout before setting it
1760         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1761                 skip "Need MDS version at least 2.7.56"
1762
1763         test_mkdir $DIR/$tdir
1764         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1765         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1766         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1767 }
1768 run_test 27e "setstripe existing file (should return error)"
1769
1770 test_27f() {
1771         test_mkdir $DIR/$tdir
1772         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1773                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1774         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1775                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1776         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1777         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1778 }
1779 run_test 27f "setstripe with bad stripe size (should return error)"
1780
1781 test_27g() {
1782         test_mkdir $DIR/$tdir
1783         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1784         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1785                 error "$DIR/$tdir/$tfile has object"
1786 }
1787 run_test 27g "$LFS getstripe with no objects"
1788
1789 test_27ga() {
1790         test_mkdir $DIR/$tdir
1791         touch $DIR/$tdir/$tfile || error "touch failed"
1792         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1793         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1794         local rc=$?
1795         (( rc == 2 )) || error "getstripe did not return ENOENT"
1796 }
1797 run_test 27ga "$LFS getstripe with missing file (should return error)"
1798
1799 test_27i() {
1800         test_mkdir $DIR/$tdir
1801         touch $DIR/$tdir/$tfile || error "touch failed"
1802         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1803                 error "missing objects"
1804 }
1805 run_test 27i "$LFS getstripe with some objects"
1806
1807 test_27j() {
1808         test_mkdir $DIR/$tdir
1809         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1810                 error "setstripe failed" || true
1811 }
1812 run_test 27j "setstripe with bad stripe offset (should return error)"
1813
1814 test_27k() { # bug 2844
1815         test_mkdir $DIR/$tdir
1816         local file=$DIR/$tdir/$tfile
1817         local ll_max_blksize=$((4 * 1024 * 1024))
1818         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1819         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1820         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1821         dd if=/dev/zero of=$file bs=4k count=1
1822         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1823         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1824 }
1825 run_test 27k "limit i_blksize for broken user apps"
1826
1827 test_27l() {
1828         mcreate $DIR/$tfile || error "creating file"
1829         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1830                 error "setstripe should have failed" || true
1831 }
1832 run_test 27l "check setstripe permissions (should return error)"
1833
1834 test_27m() {
1835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1836
1837         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1838                 skip_env "multiple clients -- skipping"
1839
1840         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1841                    head -n1)
1842         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1843                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1844         fi
1845         stack_trap simple_cleanup_common
1846         test_mkdir $DIR/$tdir
1847         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1848         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1849                 error "dd should fill OST0"
1850         i=2
1851         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1852                 i=$((i + 1))
1853                 [ $i -gt 256 ] && break
1854         done
1855         i=$((i + 1))
1856         touch $DIR/$tdir/$tfile.$i
1857         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1858             awk '{print $1}'| grep -w "0") ] &&
1859                 error "OST0 was full but new created file still use it"
1860         i=$((i + 1))
1861         touch $DIR/$tdir/$tfile.$i
1862         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1863             awk '{print $1}'| grep -w "0") ] &&
1864                 error "OST0 was full but new created file still use it" || true
1865 }
1866 run_test 27m "create file while OST0 was full"
1867
1868 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1869 # if the OST isn't full anymore.
1870 reset_enospc() {
1871         local ostidx=${1:-""}
1872         local delay
1873         local ready
1874         local get_prealloc
1875
1876         local list=$(comma_list $(osts_nodes))
1877         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1878
1879         do_nodes $list lctl set_param fail_loc=0
1880         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1881         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1882                 awk '{print $1 * 2;exit;}')
1883         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1884                         grep -v \"^0$\""
1885         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1886 }
1887
1888 test_27n() {
1889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1891         remote_mds_nodsh && skip "remote MDS with nodsh"
1892         remote_ost_nodsh && skip "remote OST with nodsh"
1893
1894         reset_enospc
1895         rm -f $DIR/$tdir/$tfile
1896         exhaust_precreations 0 0x80000215
1897         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1898         touch $DIR/$tdir/$tfile || error "touch failed"
1899         $LFS getstripe $DIR/$tdir/$tfile
1900         reset_enospc
1901 }
1902 run_test 27n "create file with some full OSTs"
1903
1904 test_27o() {
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907         remote_mds_nodsh && skip "remote MDS with nodsh"
1908         remote_ost_nodsh && skip "remote OST with nodsh"
1909
1910         reset_enospc
1911         rm -f $DIR/$tdir/$tfile
1912         exhaust_all_precreations 0x215
1913
1914         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1915
1916         reset_enospc
1917         rm -rf $DIR/$tdir/*
1918 }
1919 run_test 27o "create file with all full OSTs (should error)"
1920
1921 function create_and_checktime() {
1922         local fname=$1
1923         local loops=$2
1924         local i
1925
1926         for ((i=0; i < $loops; i++)); do
1927                 local start=$SECONDS
1928                 multiop $fname-$i Oc
1929                 ((SECONDS-start < TIMEOUT)) ||
1930                         error "creation took " $((SECONDS-$start)) && return 1
1931         done
1932 }
1933
1934 test_27oo() {
1935         local mdts=$(comma_list $(mdts_nodes))
1936
1937         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1938                 skip "Need MDS version at least 2.13.57"
1939
1940         local f0=$DIR/${tfile}-0
1941         local f1=$DIR/${tfile}-1
1942
1943         wait_delete_completed
1944
1945         # refill precreated objects
1946         $LFS setstripe -i0 -c1 $f0
1947
1948         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1949         # force QoS allocation policy
1950         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1951         stack_trap "do_nodes $mdts $LCTL set_param \
1952                 lov.*.qos_threshold_rr=$saved" EXIT
1953         sleep_maxage
1954
1955         # one OST is unavailable, but still have few objects preallocated
1956         stop ost1
1957         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1958                 rm -rf $f1 $DIR/$tdir*" EXIT
1959
1960         for ((i=0; i < 7; i++)); do
1961                 mkdir $DIR/$tdir$i || error "can't create dir"
1962                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1963                         error "can't set striping"
1964         done
1965         for ((i=0; i < 7; i++)); do
1966                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1967         done
1968         wait
1969 }
1970 run_test 27oo "don't let few threads to reserve too many objects"
1971
1972 test_27p() {
1973         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1975         remote_mds_nodsh && skip "remote MDS with nodsh"
1976         remote_ost_nodsh && skip "remote OST with nodsh"
1977
1978         reset_enospc
1979         rm -f $DIR/$tdir/$tfile
1980         test_mkdir $DIR/$tdir
1981
1982         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1983         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1984         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1985
1986         exhaust_precreations 0 0x80000215
1987         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1988         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1989         $LFS getstripe $DIR/$tdir/$tfile
1990
1991         reset_enospc
1992 }
1993 run_test 27p "append to a truncated file with some full OSTs"
1994
1995 test_27q() {
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         reset_enospc
2002         rm -f $DIR/$tdir/$tfile
2003
2004         mkdir_on_mdt0 $DIR/$tdir
2005         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2006         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2007                 error "truncate $DIR/$tdir/$tfile failed"
2008         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2009
2010         exhaust_all_precreations 0x215
2011
2012         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2013         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2014
2015         reset_enospc
2016 }
2017 run_test 27q "append to truncated file with all OSTs full (should error)"
2018
2019 test_27r() {
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023         remote_ost_nodsh && skip "remote OST with nodsh"
2024
2025         reset_enospc
2026         rm -f $DIR/$tdir/$tfile
2027         exhaust_precreations 0 0x80000215
2028
2029         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2030
2031         reset_enospc
2032 }
2033 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2034
2035 test_27s() { # bug 10725
2036         test_mkdir $DIR/$tdir
2037         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2038         local stripe_count=0
2039         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2040         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2041                 error "stripe width >= 2^32 succeeded" || true
2042
2043 }
2044 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2045
2046 test_27t() { # bug 10864
2047         WDIR=$(pwd)
2048         WLFS=$(which lfs)
2049         cd $DIR
2050         touch $tfile
2051         $WLFS getstripe $tfile
2052         cd $WDIR
2053 }
2054 run_test 27t "check that utils parse path correctly"
2055
2056 test_27u() { # bug 4900
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         remote_mds_nodsh && skip "remote MDS with nodsh"
2059
2060         local index
2061         local list=$(comma_list $(mdts_nodes))
2062
2063 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2064         do_nodes $list $LCTL set_param fail_loc=0x139
2065         test_mkdir -p $DIR/$tdir
2066         stack_trap "simple_cleanup_common 1000"
2067         createmany -o $DIR/$tdir/$tfile 1000
2068         do_nodes $list $LCTL set_param fail_loc=0
2069
2070         TLOG=$TMP/$tfile.getstripe
2071         $LFS getstripe $DIR/$tdir > $TLOG
2072         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2073         [[ $OBJS -gt 0 ]] &&
2074                 error "$OBJS objects created on OST-0. See $TLOG" ||
2075                 rm -f $TLOG
2076 }
2077 run_test 27u "skip object creation on OSC w/o objects"
2078
2079 test_27v() { # bug 4900
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082         remote_mds_nodsh && skip "remote MDS with nodsh"
2083         remote_ost_nodsh && skip "remote OST with nodsh"
2084
2085         exhaust_all_precreations 0x215
2086         reset_enospc
2087
2088         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2089
2090         touch $DIR/$tdir/$tfile
2091         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2092         # all except ost1
2093         for (( i=1; i < OSTCOUNT; i++ )); do
2094                 do_facet ost$i lctl set_param fail_loc=0x705
2095         done
2096         local START=`date +%s`
2097         createmany -o $DIR/$tdir/$tfile 32
2098
2099         local FINISH=`date +%s`
2100         local TIMEOUT=`lctl get_param -n timeout`
2101         local PROCESS=$((FINISH - START))
2102         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2103                error "$FINISH - $START >= $TIMEOUT / 2"
2104         sleep $((TIMEOUT / 2 - PROCESS))
2105         reset_enospc
2106 }
2107 run_test 27v "skip object creation on slow OST"
2108
2109 test_27w() { # bug 10997
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2112         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2113                 error "stripe size $size != 65536" || true
2114         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2115                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2116 }
2117 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2118
2119 test_27wa() {
2120         [[ $OSTCOUNT -lt 2 ]] &&
2121                 skip_env "skipping multiple stripe count/offset test"
2122
2123         test_mkdir $DIR/$tdir
2124         for i in $(seq 1 $OSTCOUNT); do
2125                 offset=$((i - 1))
2126                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2127                         error "setstripe -c $i -i $offset failed"
2128                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2129                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2130                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2131                 [ $index -ne $offset ] &&
2132                         error "stripe offset $index != $offset" || true
2133         done
2134 }
2135 run_test 27wa "check $LFS setstripe -c -i options"
2136
2137 test_27x() {
2138         remote_ost_nodsh && skip "remote OST with nodsh"
2139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2141
2142         OFFSET=$(($OSTCOUNT - 1))
2143         OSTIDX=0
2144         local OST=$(ostname_from_index $OSTIDX)
2145
2146         test_mkdir $DIR/$tdir
2147         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2151         for i in $(seq 0 $OFFSET); do
2152                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2153                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2154                 error "OST0 was degraded but new created file still use it"
2155         done
2156         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2157 }
2158 run_test 27x "create files while OST0 is degraded"
2159
2160 test_27y() {
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         remote_mds_nodsh && skip "remote MDS with nodsh"
2163         remote_ost_nodsh && skip "remote OST with nodsh"
2164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2165
2166         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2167         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2168                 osp.$mdtosc.prealloc_last_id)
2169         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2170                 osp.$mdtosc.prealloc_next_id)
2171         local fcount=$((last_id - next_id))
2172         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2173         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2174
2175         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2176                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2177         local OST_DEACTIVE_IDX=-1
2178         local OSC
2179         local OSTIDX
2180         local OST
2181
2182         for OSC in $MDS_OSCS; do
2183                 OST=$(osc_to_ost $OSC)
2184                 OSTIDX=$(index_from_ostuuid $OST)
2185                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2186                         OST_DEACTIVE_IDX=$OSTIDX
2187                 fi
2188                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2189                         echo $OSC "is Deactivated:"
2190                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2191                 fi
2192         done
2193
2194         OSTIDX=$(index_from_ostuuid $OST)
2195         test_mkdir $DIR/$tdir
2196         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=1
2205                 fi
2206         done
2207
2208         sleep_maxage
2209         createmany -o $DIR/$tdir/$tfile $fcount
2210
2211         for OSC in $MDS_OSCS; do
2212                 OST=$(osc_to_ost $OSC)
2213                 OSTIDX=$(index_from_ostuuid $OST)
2214                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2215                         echo $OST "is recovered from degraded:"
2216                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2217                                                 obdfilter.$OST.degraded=0
2218                 else
2219                         do_facet $SINGLEMDS lctl --device %$OSC activate
2220                 fi
2221         done
2222
2223         # all osp devices get activated, hence -1 stripe count restored
2224         local stripe_count=0
2225
2226         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2227         # devices get activated.
2228         sleep_maxage
2229         $LFS setstripe -c -1 $DIR/$tfile
2230         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2231         rm -f $DIR/$tfile
2232         [ $stripe_count -ne $OSTCOUNT ] &&
2233                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2234         return 0
2235 }
2236 run_test 27y "create files while OST0 is degraded and the rest inactive"
2237
2238 check_seq_oid()
2239 {
2240         log "check file $1"
2241
2242         lmm_count=$($LFS getstripe -c $1)
2243         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2244         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2245
2246         local old_ifs="$IFS"
2247         IFS=$'[:]'
2248         fid=($($LFS path2fid $1))
2249         IFS="$old_ifs"
2250
2251         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2252         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2253
2254         # compare lmm_seq and lu_fid->f_seq
2255         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2256         # compare lmm_object_id and lu_fid->oid
2257         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2258
2259         # check the trusted.fid attribute of the OST objects of the file
2260         local have_obdidx=false
2261         local stripe_nr=0
2262         $LFS getstripe $1 | while read obdidx oid hex seq; do
2263                 # skip lines up to and including "obdidx"
2264                 [ -z "$obdidx" ] && break
2265                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2266                 $have_obdidx || continue
2267
2268                 local ost=$((obdidx + 1))
2269                 local dev=$(ostdevname $ost)
2270                 local oid_hex
2271
2272                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2273
2274                 seq=$(echo $seq | sed -e "s/^0x//g")
2275                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2276                         oid_hex=$(echo $oid)
2277                 else
2278                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2279                 fi
2280                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2281
2282                 local ff=""
2283                 #
2284                 # Don't unmount/remount the OSTs if we don't need to do that.
2285                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2286                 # update too, until that use mount/ll_decode_filter_fid/mount.
2287                 # Re-enable when debugfs will understand new filter_fid.
2288                 #
2289                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2290                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2291                                 $dev 2>/dev/null" | grep "parent=")
2292                 fi
2293                 if [ -z "$ff" ]; then
2294                         stop ost$ost
2295                         mount_fstype ost$ost
2296                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2297                                 $(facet_mntpt ost$ost)/$obj_file)
2298                         unmount_fstype ost$ost
2299                         start ost$ost $dev $OST_MOUNT_OPTS
2300                         clients_up
2301                 fi
2302
2303                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2304
2305                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2306
2307                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2308                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2309                 #
2310                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2311                 #       stripe_size=1048576 component_id=1 component_start=0 \
2312                 #       component_end=33554432
2313                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2314                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2315                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2316                 local ff_pstripe
2317                 if grep -q 'stripe=' <<<$ff; then
2318                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2319                 else
2320                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2321                         # into f_ver in this case.  See comment on ff_parent.
2322                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2323                 fi
2324
2325                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2326                 [ $ff_pseq = $lmm_seq ] ||
2327                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2328                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2329                 [ $ff_poid = $lmm_oid ] ||
2330                         error "FF parent OID $ff_poid != $lmm_oid"
2331                 (($ff_pstripe == $stripe_nr)) ||
2332                         error "FF stripe $ff_pstripe != $stripe_nr"
2333
2334                 stripe_nr=$((stripe_nr + 1))
2335                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2336                         continue
2337                 if grep -q 'stripe_count=' <<<$ff; then
2338                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2339                                             -e 's/ .*//' <<<$ff)
2340                         [ $lmm_count = $ff_scnt ] ||
2341                                 error "FF stripe count $lmm_count != $ff_scnt"
2342                 fi
2343         done
2344 }
2345
2346 test_27z() {
2347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2348         remote_ost_nodsh && skip "remote OST with nodsh"
2349
2350         test_mkdir $DIR/$tdir
2351         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2352                 { error "setstripe -c -1 failed"; return 1; }
2353         # We need to send a write to every object to get parent FID info set.
2354         # This _should_ also work for setattr, but does not currently.
2355         # touch $DIR/$tdir/$tfile-1 ||
2356         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2357                 { error "dd $tfile-1 failed"; return 2; }
2358         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2359                 { error "setstripe -c -1 failed"; return 3; }
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2361                 { error "dd $tfile-2 failed"; return 4; }
2362
2363         # make sure write RPCs have been sent to OSTs
2364         sync; sleep 5; sync
2365
2366         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2367         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2368 }
2369 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2370
2371 test_27A() { # b=19102
2372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2373
2374         save_layout_restore_at_exit $MOUNT
2375         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2376         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2377                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2378         local default_size=$($LFS getstripe -S $MOUNT)
2379         local default_offset=$($LFS getstripe -i $MOUNT)
2380         local dsize=$(do_facet $SINGLEMDS \
2381                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2382         [ $default_size -eq $dsize ] ||
2383                 error "stripe size $default_size != $dsize"
2384         [ $default_offset -eq -1 ] ||
2385                 error "stripe offset $default_offset != -1"
2386 }
2387 run_test 27A "check filesystem-wide default LOV EA values"
2388
2389 test_27B() { # LU-2523
2390         test_mkdir $DIR/$tdir
2391         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2392         touch $DIR/$tdir/f0
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # rename f0 onto f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2398                 $DIR/$tdir/f0
2399
2400         rm -f $DIR/$tdir/f1
2401         # open f1 with O_LOV_DELAY_CREATE
2402         # unlink f1
2403         # call setstripe ioctl on open file descriptor for f1
2404         # close
2405         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2406
2407         # Allow multiop to fail in imitation of NFS's busted semantics.
2408         true
2409 }
2410 run_test 27B "call setstripe on open unlinked file/rename victim"
2411
2412 # 27C family tests full striping and overstriping
2413 test_27Ca() { #LU-2871
2414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2415
2416         declare -a ost_idx
2417         local index
2418         local found
2419         local i
2420         local j
2421
2422         test_mkdir $DIR/$tdir
2423         cd $DIR/$tdir
2424         for i in $(seq 0 $((OSTCOUNT - 1))); do
2425                 # set stripe across all OSTs starting from OST$i
2426                 $LFS setstripe -i $i -c -1 $tfile$i
2427                 # get striping information
2428                 ost_idx=($($LFS getstripe $tfile$i |
2429                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2430                 echo "OST Index: ${ost_idx[*]}"
2431
2432                 # check the layout
2433                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2434                         error "${#ost_idx[@]} != $OSTCOUNT"
2435
2436                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2437                         found=0
2438                         for j in "${ost_idx[@]}"; do
2439                                 if [ $index -eq $j ]; then
2440                                         found=1
2441                                         break
2442                                 fi
2443                         done
2444                         [ $found = 1 ] ||
2445                                 error "Can not find $index in ${ost_idx[*]}"
2446                 done
2447         done
2448 }
2449 run_test 27Ca "check full striping across all OSTs"
2450
2451 test_27Cb() {
2452         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2453                 skip "server does not support overstriping"
2454         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2455                 skip_env "too many osts, skipping"
2456
2457         test_mkdir -p $DIR/$tdir
2458         local setcount=$(($OSTCOUNT * 2))
2459         [ $setcount -lt 160 ] || large_xattr_enabled ||
2460                 skip_env "ea_inode feature disabled"
2461
2462         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2463                 error "setstripe failed"
2464
2465         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2466         [ $count -eq $setcount ] ||
2467                 error "stripe count $count, should be $setcount"
2468
2469         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2470                 error "overstriped should be set in pattern"
2471
2472         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2473                 error "dd failed"
2474 }
2475 run_test 27Cb "more stripes than OSTs with -C"
2476
2477 test_27Cc() {
2478         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2479                 skip "server does not support overstriping"
2480         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2481
2482         test_mkdir -p $DIR/$tdir
2483         local setcount=$(($OSTCOUNT - 1))
2484
2485         [ $setcount -lt 160 ] || large_xattr_enabled ||
2486                 skip_env "ea_inode feature disabled"
2487
2488         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2489                 error "setstripe failed"
2490
2491         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2492         [ $count -eq $setcount ] ||
2493                 error "stripe count $count, should be $setcount"
2494
2495         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2496                 error "overstriped should not be set in pattern"
2497
2498         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2499                 error "dd failed"
2500 }
2501 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2502
2503 test_27Cd() {
2504         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2505                 skip "server does not support overstriping"
2506         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2507         large_xattr_enabled || skip_env "ea_inode feature disabled"
2508
2509         force_new_seq_all
2510
2511         test_mkdir -p $DIR/$tdir
2512         local setcount=$LOV_MAX_STRIPE_COUNT
2513
2514         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2515                 error "setstripe failed"
2516
2517         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2518         [ $count -eq $setcount ] ||
2519                 error "stripe count $count, should be $setcount"
2520
2521         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2522                 error "overstriped should be set in pattern"
2523
2524         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2525                 error "dd failed"
2526
2527         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2528 }
2529 run_test 27Cd "test maximum stripe count"
2530
2531 test_27Ce() {
2532         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2533                 skip "server does not support overstriping"
2534         test_mkdir -p $DIR/$tdir
2535
2536         pool_add $TESTNAME || error "Pool creation failed"
2537         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2538
2539         local setcount=8
2540
2541         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2542                 error "setstripe failed"
2543
2544         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2545         [ $count -eq $setcount ] ||
2546                 error "stripe count $count, should be $setcount"
2547
2548         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2549                 error "overstriped should be set in pattern"
2550
2551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2552                 error "dd failed"
2553
2554         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2555 }
2556 run_test 27Ce "test pool with overstriping"
2557
2558 test_27Cf() {
2559         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2560                 skip "server does not support overstriping"
2561         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2562                 skip_env "too many osts, skipping"
2563
2564         test_mkdir -p $DIR/$tdir
2565
2566         local setcount=$(($OSTCOUNT * 2))
2567         [ $setcount -lt 160 ] || large_xattr_enabled ||
2568                 skip_env "ea_inode feature disabled"
2569
2570         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2571                 error "setstripe failed"
2572
2573         echo 1 > $DIR/$tdir/$tfile
2574
2575         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2576         [ $count -eq $setcount ] ||
2577                 error "stripe count $count, should be $setcount"
2578
2579         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2580                 error "overstriped should be set in pattern"
2581
2582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2583                 error "dd failed"
2584
2585         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2586 }
2587 run_test 27Cf "test default inheritance with overstriping"
2588
2589 test_27Cg() {
2590         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2591                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2592
2593         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2594         (( $? != 0 )) || error "must be an error for not existent OST#"
2595 }
2596 run_test 27Cg "test setstripe with wrong OST idx"
2597
2598 test_27D() {
2599         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2600         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2601         remote_mds_nodsh && skip "remote MDS with nodsh"
2602
2603         local POOL=${POOL:-testpool}
2604         local first_ost=0
2605         local last_ost=$(($OSTCOUNT - 1))
2606         local ost_step=1
2607         local ost_list=$(seq $first_ost $ost_step $last_ost)
2608         local ost_range="$first_ost $last_ost $ost_step"
2609
2610         test_mkdir $DIR/$tdir
2611         pool_add $POOL || error "pool_add failed"
2612         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2613
2614         local skip27D
2615         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2616                 skip27D+="-s 29"
2617         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2618                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2619                         skip27D+=" -s 30,31"
2620         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2621           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2622                 skip27D+=" -s 32,33"
2623         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2624                 skip27D+=" -s 34"
2625         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2626                 error "llapi_layout_test failed"
2627
2628         destroy_test_pools || error "destroy test pools failed"
2629 }
2630 run_test 27D "validate llapi_layout API"
2631
2632 # Verify that default_easize is increased from its initial value after
2633 # accessing a widely striped file.
2634 test_27E() {
2635         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2636         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2637                 skip "client does not have LU-3338 fix"
2638
2639         # 72 bytes is the minimum space required to store striping
2640         # information for a file striped across one OST:
2641         # (sizeof(struct lov_user_md_v3) +
2642         #  sizeof(struct lov_user_ost_data_v1))
2643         local min_easize=72
2644         $LCTL set_param -n llite.*.default_easize $min_easize ||
2645                 error "lctl set_param failed"
2646         local easize=$($LCTL get_param -n llite.*.default_easize)
2647
2648         [ $easize -eq $min_easize ] ||
2649                 error "failed to set default_easize"
2650
2651         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2652                 error "setstripe failed"
2653         # In order to ensure stat() call actually talks to MDS we need to
2654         # do something drastic to this file to shake off all lock, e.g.
2655         # rename it (kills lookup lock forcing cache cleaning)
2656         mv $DIR/$tfile $DIR/${tfile}-1
2657         ls -l $DIR/${tfile}-1
2658         rm $DIR/${tfile}-1
2659
2660         easize=$($LCTL get_param -n llite.*.default_easize)
2661
2662         [ $easize -gt $min_easize ] ||
2663                 error "default_easize not updated"
2664 }
2665 run_test 27E "check that default extended attribute size properly increases"
2666
2667 test_27F() { # LU-5346/LU-7975
2668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2669         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2670         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2671                 skip "Need MDS version at least 2.8.51"
2672         remote_ost_nodsh && skip "remote OST with nodsh"
2673
2674         test_mkdir $DIR/$tdir
2675         rm -f $DIR/$tdir/f0
2676         $LFS setstripe -c 2 $DIR/$tdir
2677
2678         # stop all OSTs to reproduce situation for LU-7975 ticket
2679         for num in $(seq $OSTCOUNT); do
2680                 stop ost$num
2681         done
2682
2683         # open/create f0 with O_LOV_DELAY_CREATE
2684         # truncate f0 to a non-0 size
2685         # close
2686         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2687
2688         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2689         # open/write it again to force delayed layout creation
2690         cat /etc/hosts > $DIR/$tdir/f0 &
2691         catpid=$!
2692
2693         # restart OSTs
2694         for num in $(seq $OSTCOUNT); do
2695                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2696                         error "ost$num failed to start"
2697         done
2698
2699         wait $catpid || error "cat failed"
2700
2701         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2702         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2703                 error "wrong stripecount"
2704
2705 }
2706 run_test 27F "Client resend delayed layout creation with non-zero size"
2707
2708 test_27G() { #LU-10629
2709         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2710                 skip "Need MDS version at least 2.11.51"
2711         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2712         remote_mds_nodsh && skip "remote MDS with nodsh"
2713         local POOL=${POOL:-testpool}
2714         local ostrange="0 0 1"
2715
2716         test_mkdir $DIR/$tdir
2717         touch $DIR/$tdir/$tfile.nopool
2718         pool_add $POOL || error "pool_add failed"
2719         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2720         $LFS setstripe -p $POOL $DIR/$tdir
2721
2722         local pool=$($LFS getstripe -p $DIR/$tdir)
2723
2724         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2725         touch $DIR/$tdir/$tfile.default
2726         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2727         $LFS find $DIR/$tdir -type f --pool $POOL
2728         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2729         [[ "$found" == "2" ]] ||
2730                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2731
2732         $LFS setstripe -d $DIR/$tdir
2733
2734         pool=$($LFS getstripe -p -d $DIR/$tdir)
2735
2736         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2737 }
2738 run_test 27G "Clear OST pool from stripe"
2739
2740 test_27H() {
2741         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2742                 skip "Need MDS version newer than 2.11.54"
2743         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2744         test_mkdir $DIR/$tdir
2745         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2746         touch $DIR/$tdir/$tfile
2747         $LFS getstripe -c $DIR/$tdir/$tfile
2748         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2749                 error "two-stripe file doesn't have two stripes"
2750
2751         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2752         $LFS getstripe -y $DIR/$tdir/$tfile
2753         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2754              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2755                 error "expected l_ost_idx: [02]$ not matched"
2756
2757         # make sure ost list has been cleared
2758         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2759         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2760                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2761         touch $DIR/$tdir/f3
2762         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2763 }
2764 run_test 27H "Set specific OSTs stripe"
2765
2766 test_27I() {
2767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2768         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2769         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2770                 skip "Need MDS version newer than 2.12.52"
2771         local pool=$TESTNAME
2772         local ostrange="1 1 1"
2773
2774         save_layout_restore_at_exit $MOUNT
2775         $LFS setstripe -c 2 -i 0 $MOUNT
2776         pool_add $pool || error "pool_add failed"
2777         pool_add_targets $pool $ostrange ||
2778                 error "pool_add_targets failed"
2779         test_mkdir $DIR/$tdir
2780         $LFS setstripe -p $pool $DIR/$tdir
2781         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2782         $LFS getstripe $DIR/$tdir/$tfile
2783 }
2784 run_test 27I "check that root dir striping does not break parent dir one"
2785
2786 test_27J() {
2787         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2788                 skip "Need MDS version newer than 2.12.51"
2789
2790         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2791         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2792         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2793            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2794                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2795
2796         test_mkdir $DIR/$tdir
2797         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2798         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2799
2800         # create foreign file (raw way)
2801         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2802                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2803
2804         ! $LFS setstripe --foreign --flags foo \
2805                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2806                         error "creating $tfile with '--flags foo' should fail"
2807
2808         ! $LFS setstripe --foreign --flags 0xffffffff \
2809                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2810                         error "creating $tfile w/ 0xffffffff flags should fail"
2811
2812         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2813                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2814
2815         # verify foreign file (raw way)
2816         parse_foreign_file -f $DIR/$tdir/$tfile |
2817                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2818                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2819         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2820                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2821         parse_foreign_file -f $DIR/$tdir/$tfile |
2822                 grep "lov_foreign_size: 73" ||
2823                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2824         parse_foreign_file -f $DIR/$tdir/$tfile |
2825                 grep "lov_foreign_type: 1" ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_flags: 0x0000DA08" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2830         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2831                 grep "lov_foreign_value: 0x" |
2832                 sed -e 's/lov_foreign_value: 0x//')
2833         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2834         [[ $lov = ${lov2// /} ]] ||
2835                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2836
2837         # create foreign file (lfs + API)
2838         $LFS setstripe --foreign=none --flags 0xda08 \
2839                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2840                 error "$DIR/$tdir/${tfile}2: create failed"
2841
2842         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2843                 grep "lfm_magic:.*0x0BD70BD0" ||
2844                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2845         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2846         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2847                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2849                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2850         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2851                 grep "lfm_flags:.*0x0000DA08" ||
2852                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2853         $LFS getstripe $DIR/$tdir/${tfile}2 |
2854                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2856
2857         # modify striping should fail
2858         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2859                 error "$DIR/$tdir/$tfile: setstripe should fail"
2860         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2861                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2862
2863         # R/W should fail
2864         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2865         cat $DIR/$tdir/${tfile}2 &&
2866                 error "$DIR/$tdir/${tfile}2: read should fail"
2867         cat /etc/passwd > $DIR/$tdir/$tfile &&
2868                 error "$DIR/$tdir/$tfile: write should fail"
2869         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2870                 error "$DIR/$tdir/${tfile}2: write should fail"
2871
2872         # chmod should work
2873         chmod 222 $DIR/$tdir/$tfile ||
2874                 error "$DIR/$tdir/$tfile: chmod failed"
2875         chmod 222 $DIR/$tdir/${tfile}2 ||
2876                 error "$DIR/$tdir/${tfile}2: chmod failed"
2877
2878         # chown should work
2879         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2880                 error "$DIR/$tdir/$tfile: chown failed"
2881         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2882                 error "$DIR/$tdir/${tfile}2: chown failed"
2883
2884         # rename should work
2885         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2886                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2887         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2888                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2889
2890         #remove foreign file
2891         rm $DIR/$tdir/${tfile}.new ||
2892                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2893         rm $DIR/$tdir/${tfile}2.new ||
2894                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2895 }
2896 run_test 27J "basic ops on file with foreign LOV"
2897
2898 test_27K() {
2899         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2900                 skip "Need MDS version newer than 2.12.49"
2901
2902         test_mkdir $DIR/$tdir
2903         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2904         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2905
2906         # create foreign dir (raw way)
2907         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2908                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2909
2910         ! $LFS setdirstripe --foreign --flags foo \
2911                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2912                         error "creating $tdir with '--flags foo' should fail"
2913
2914         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2915                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2916                         error "creating $tdir w/ 0xffffffff flags should fail"
2917
2918         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2919                 error "create_foreign_dir FAILED"
2920
2921         # verify foreign dir (raw way)
2922         parse_foreign_dir -d $DIR/$tdir/$tdir |
2923                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2924                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2925         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2926                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2927         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2928                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2929         parse_foreign_dir -d $DIR/$tdir/$tdir |
2930                 grep "lmv_foreign_flags: 55813$" ||
2931                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2932         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2933                 grep "lmv_foreign_value: 0x" |
2934                 sed 's/lmv_foreign_value: 0x//')
2935         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2936                 sed 's/ //g')
2937         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2938
2939         # create foreign dir (lfs + API)
2940         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2941                 $DIR/$tdir/${tdir}2 ||
2942                 error "$DIR/$tdir/${tdir}2: create failed"
2943
2944         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2945
2946         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2947                 grep "lfm_magic:.*0x0CD50CD0" ||
2948                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2949         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2950         # - sizeof(lfm_type) - sizeof(lfm_flags)
2951         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2953         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2954                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2956                 grep "lfm_flags:.*0x0000DA05" ||
2957                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2958         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2959                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2960                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2961
2962         # file create in dir should fail
2963         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2964         touch $DIR/$tdir/${tdir}2/$tfile &&
2965                 error "$DIR/${tdir}2: file create should fail"
2966
2967         # chmod should work
2968         chmod 777 $DIR/$tdir/$tdir ||
2969                 error "$DIR/$tdir: chmod failed"
2970         chmod 777 $DIR/$tdir/${tdir}2 ||
2971                 error "$DIR/${tdir}2: chmod failed"
2972
2973         # chown should work
2974         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2975                 error "$DIR/$tdir: chown failed"
2976         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2977                 error "$DIR/${tdir}2: chown failed"
2978
2979         # rename should work
2980         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2981                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2982         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2983                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2984
2985         #remove foreign dir
2986         rmdir $DIR/$tdir/${tdir}.new ||
2987                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2988         rmdir $DIR/$tdir/${tdir}2.new ||
2989                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2990 }
2991 run_test 27K "basic ops on dir with foreign LMV"
2992
2993 test_27L() {
2994         remote_mds_nodsh && skip "remote MDS with nodsh"
2995
2996         local POOL=${POOL:-$TESTNAME}
2997
2998         pool_add $POOL || error "pool_add failed"
2999
3000         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3001                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3002                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3003 }
3004 run_test 27L "lfs pool_list gives correct pool name"
3005
3006 test_27M() {
3007         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3008                 skip "Need MDS version >= than 2.12.57"
3009         remote_mds_nodsh && skip "remote MDS with nodsh"
3010         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3011
3012         # Set default striping on directory
3013         local setcount=4
3014         local stripe_opt
3015         local mdts=$(comma_list $(mdts_nodes))
3016
3017         # if we run against a 2.12 server which lacks overstring support
3018         # then the connect_flag will not report overstriping, even if client
3019         # is 2.14+
3020         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3021                 stripe_opt="-C $setcount"
3022         elif (( $OSTCOUNT >= $setcount )); then
3023                 stripe_opt="-c $setcount"
3024         else
3025                 skip "server does not support overstriping"
3026         fi
3027
3028         test_mkdir $DIR/$tdir
3029
3030         # Validate existing append_* params and ensure restore
3031         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3032         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3033         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3034
3035         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3036         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3037         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3038
3039         $LFS setstripe $stripe_opt $DIR/$tdir
3040
3041         echo 1 > $DIR/$tdir/${tfile}.1
3042         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3043         (( $count == $setcount )) ||
3044                 error "(1) stripe count $count, should be $setcount"
3045
3046         local appendcount=$orig_count
3047         echo 1 >> $DIR/$tdir/${tfile}.2_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3049         (( $count == $appendcount )) ||
3050                 error "(2)stripe count $count, should be $appendcount for append"
3051
3052         # Disable O_APPEND striping, verify it works
3053         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3054
3055         # Should now get the default striping, which is 4
3056         setcount=4
3057         echo 1 >> $DIR/$tdir/${tfile}.3_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3059         (( $count == $setcount )) ||
3060                 error "(3) stripe count $count, should be $setcount"
3061
3062         # Try changing the stripe count for append files
3063         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3064
3065         # Append striping is now 2 (directory default is still 4)
3066         appendcount=2
3067         echo 1 >> $DIR/$tdir/${tfile}.4_append
3068         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3069         (( $count == $appendcount )) ||
3070                 error "(4) stripe count $count, should be $appendcount for append"
3071
3072         # Test append stripe count of -1
3073         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3074         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3075                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3076                 touch $DIR/$tdir/$tfile.specific.{1..128}
3077         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3078
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3080         appendcount=$OSTCOUNT
3081         echo 1 >> $DIR/$tdir/${tfile}.5
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3083         (( $count == $appendcount )) ||
3084                 error "(5) stripe count $count, should be $appendcount for append"
3085
3086         # Set append striping back to default of 1
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3088
3089         # Try a new default striping, PFL + DOM
3090         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3091
3092         # Create normal DOM file, DOM returns stripe count == 0
3093         setcount=0
3094         touch $DIR/$tdir/${tfile}.6
3095         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3096         (( $count == $setcount )) ||
3097                 error "(6) stripe count $count, should be $setcount"
3098
3099         # Show
3100         appendcount=1
3101         echo 1 >> $DIR/$tdir/${tfile}.7_append
3102         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3103         (( $count == $appendcount )) ||
3104                 error "(7) stripe count $count, should be $appendcount for append"
3105
3106         # Clean up DOM layout
3107         $LFS setstripe -d $DIR/$tdir
3108
3109         save_layout_restore_at_exit $MOUNT
3110         # Now test that append striping works when layout is from root
3111         $LFS setstripe -c 2 $MOUNT
3112         # Make a special directory for this
3113         mkdir $DIR/${tdir}/${tdir}.2
3114
3115         # Verify for normal file
3116         setcount=2
3117         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3118         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3119         (( $count == $setcount )) ||
3120                 error "(8) stripe count $count, should be $setcount"
3121
3122         appendcount=1
3123         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3124         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3125         (( $count == $appendcount )) ||
3126                 error "(9) stripe count $count, should be $appendcount for append"
3127
3128         # Now test O_APPEND striping with pools
3129         pool_add $TESTNAME || error "pool creation failed"
3130         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3131         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3132
3133         echo 1 >> $DIR/$tdir/${tfile}.10_append
3134
3135         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3136         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3137
3138         # Check that count is still correct
3139         appendcount=1
3140         echo 1 >> $DIR/$tdir/${tfile}.11_append
3141         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3142         (( $count == $appendcount )) ||
3143                 error "(11) stripe count $count, should be $appendcount for append"
3144
3145         # Disable O_APPEND stripe count, verify pool works separately
3146         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3147
3148         echo 1 >> $DIR/$tdir/${tfile}.12_append
3149
3150         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3151         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3152
3153         # Remove pool setting, verify it's not applied
3154         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3155
3156         echo 1 >> $DIR/$tdir/${tfile}.13_append
3157
3158         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3159         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3160 }
3161 run_test 27M "test O_APPEND striping"
3162
3163 test_27N() {
3164         combined_mgs_mds && skip "needs separate MGS/MDT"
3165
3166         pool_add $TESTNAME || error "pool_add failed"
3167         do_facet mgs "$LCTL pool_list $FSNAME" |
3168                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3169                 error "lctl pool_list on MGS failed"
3170 }
3171 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3172
3173 clean_foreign_symlink() {
3174         trap 0
3175         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3176         for i in $DIR/$tdir/* ; do
3177                 $LFS unlink_foreign $i || true
3178         done
3179 }
3180
3181 test_27O() {
3182         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3183                 skip "Need MDS version newer than 2.12.51"
3184
3185         test_mkdir $DIR/$tdir
3186         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3187         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3188
3189         trap clean_foreign_symlink EXIT
3190
3191         # enable foreign_symlink behaviour
3192         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3193
3194         # foreign symlink LOV format is a partial path by default
3195
3196         # create foreign file (lfs + API)
3197         $LFS setstripe --foreign=symlink --flags 0xda05 \
3198                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3199                 error "$DIR/$tdir/${tfile}: create failed"
3200
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_magic:.*0x0BD70BD0" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3204         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3205                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3206         $LFS getstripe -v $DIR/$tdir/${tfile} |
3207                 grep "lfm_flags:.*0x0000DA05" ||
3208                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3209         $LFS getstripe $DIR/$tdir/${tfile} |
3210                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3211                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3212
3213         # modify striping should fail
3214         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: setstripe should fail"
3216
3217         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3218         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3219         cat /etc/passwd > $DIR/$tdir/$tfile &&
3220                 error "$DIR/$tdir/$tfile: write should fail"
3221
3222         # rename should succeed
3223         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3224                 error "$DIR/$tdir/$tfile: rename has failed"
3225
3226         #remove foreign_symlink file should fail
3227         rm $DIR/$tdir/${tfile}.new &&
3228                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3229
3230         #test fake symlink
3231         mkdir /tmp/${uuid1} ||
3232                 error "/tmp/${uuid1}: mkdir has failed"
3233         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3234                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3235         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3236         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3237                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3238         #read should succeed now
3239         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3240                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3241         #write should succeed now
3242         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3243                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3244         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3245                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3246         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3247                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3248
3249         #check that getstripe still works
3250         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3251                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3252
3253         # chmod should still succeed
3254         chmod 644 $DIR/$tdir/${tfile}.new ||
3255                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3256
3257         # chown should still succeed
3258         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3259                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3260
3261         # rename should still succeed
3262         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3263                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3264
3265         #remove foreign_symlink file should still fail
3266         rm $DIR/$tdir/${tfile} &&
3267                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3268
3269         #use special ioctl() to unlink foreign_symlink file
3270         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3271                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3272
3273 }
3274 run_test 27O "basic ops on foreign file of symlink type"
3275
3276 test_27P() {
3277         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3278                 skip "Need MDS version newer than 2.12.49"
3279
3280         test_mkdir $DIR/$tdir
3281         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3282         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3283
3284         trap clean_foreign_symlink EXIT
3285
3286         # enable foreign_symlink behaviour
3287         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3288
3289         # foreign symlink LMV format is a partial path by default
3290
3291         # create foreign dir (lfs + API)
3292         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3293                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3294                 error "$DIR/$tdir/${tdir}: create failed"
3295
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3297
3298         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3299                 grep "lfm_magic:.*0x0CD50CD0" ||
3300                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3301         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3302                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3303         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3304                 grep "lfm_flags:.*0x0000DA05" ||
3305                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3306         $LFS getdirstripe $DIR/$tdir/${tdir} |
3307                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3308                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3309
3310         # file create in dir should fail
3311         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3312         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3313
3314         # rename should succeed
3315         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3316                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3317
3318         #remove foreign_symlink dir should fail
3319         rmdir $DIR/$tdir/${tdir}.new &&
3320                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3321
3322         #test fake symlink
3323         mkdir -p /tmp/${uuid1}/${uuid2} ||
3324                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3325         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3326                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3327         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3328         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3329                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3330         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3331                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3332
3333         #check that getstripe fails now that foreign_symlink enabled
3334         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3335                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3336
3337         # file create in dir should work now
3338         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3339                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3340         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3341                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3342         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3343                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3344
3345         # chmod should still succeed
3346         chmod 755 $DIR/$tdir/${tdir}.new ||
3347                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3348
3349         # chown should still succeed
3350         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3351                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3352
3353         # rename should still succeed
3354         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3355                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3356
3357         #remove foreign_symlink dir should still fail
3358         rmdir $DIR/$tdir/${tdir} &&
3359                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3360
3361         #use special ioctl() to unlink foreign_symlink file
3362         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3363                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3364
3365         #created file should still exist
3366         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3367                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3368         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3369                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3370 }
3371 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3372
3373 test_27Q() {
3374         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3375         stack_trap "rm -f $TMP/$tfile*"
3376
3377         test_mkdir $DIR/$tdir-1
3378         test_mkdir $DIR/$tdir-2
3379
3380         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3381         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3382
3383         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3384         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3385
3386         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3387         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3388
3389         # Create some bad symlinks and ensure that we don't loop
3390         # forever or something. These should return ELOOP (40) and
3391         # ENOENT (2) but I don't want to test for that because there's
3392         # always some weirdo architecture that needs to ruin
3393         # everything by defining these error numbers differently.
3394
3395         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3396         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3397
3398         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3399         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3400
3401         return 0
3402 }
3403 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3404
3405 test_27R() {
3406         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3407                 skip "need MDS 2.14.55 or later"
3408         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3409
3410         local testdir="$DIR/$tdir"
3411         test_mkdir -p $testdir
3412         stack_trap "rm -rf $testdir"
3413         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3414
3415         local f1="$testdir/f1"
3416         touch $f1 || error "failed to touch $f1"
3417         local count=$($LFS getstripe -c $f1)
3418         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3419
3420         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3421         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3422
3423         local maxcount=$(($OSTCOUNT - 1))
3424         local mdts=$(comma_list $(mdts_nodes))
3425         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3426         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3427
3428         local f2="$testdir/f2"
3429         touch $f2 || error "failed to touch $f2"
3430         local count=$($LFS getstripe -c $f2)
3431         (( $count == $maxcount )) || error "wrong stripe count"
3432 }
3433 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3434
3435 test_27T() {
3436         [ $(facet_host client) == $(facet_host ost1) ] &&
3437                 skip "need ost1 and client on different nodes"
3438
3439 #define OBD_FAIL_OSC_NO_GRANT            0x411
3440         $LCTL set_param fail_loc=0x20000411 fail_val=1
3441 #define OBD_FAIL_OST_ENOSPC              0x215
3442         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3443         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3444         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3445                 error "multiop failed"
3446 }
3447 run_test 27T "no eio on close on partial write due to enosp"
3448
3449 test_27U() {
3450         local dir=$DIR/$tdir
3451         local file=$dir/$tfile
3452         local append_pool=${TESTNAME}-append
3453         local normal_pool=${TESTNAME}-normal
3454         local pool
3455         local stripe_count
3456         local stripe_count2
3457         local mdts=$(comma_list $(mdts_nodes))
3458
3459         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3460                 skip "Need MDS version at least 2.15.51 for append pool feature"
3461
3462         # Validate existing append_* params and ensure restore
3463         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3464         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3465         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3466
3467         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3468         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3469         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3470
3471         pool_add $append_pool || error "pool creation failed"
3472         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3473
3474         pool_add $normal_pool || error "pool creation failed"
3475         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3476
3477         test_mkdir $dir
3478         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3479
3480         echo XXX >> $file.1
3481         $LFS getstripe $file.1
3482
3483         pool=$($LFS getstripe -p $file.1)
3484         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3485
3486         stripe_count2=$($LFS getstripe -c $file.1)
3487         ((stripe_count2 == stripe_count)) ||
3488                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3489
3490         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3491
3492         echo XXX >> $file.2
3493         $LFS getstripe $file.2
3494
3495         pool=$($LFS getstripe -p $file.2)
3496         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3497
3498         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3499
3500         echo XXX >> $file.3
3501         $LFS getstripe $file.3
3502
3503         stripe_count2=$($LFS getstripe -c $file.3)
3504         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3505 }
3506 run_test 27U "append pool and stripe count work with composite default layout"
3507
3508 # createtest also checks that device nodes are created and
3509 # then visible correctly (#2091)
3510 test_28() { # bug 2091
3511         test_mkdir $DIR/d28
3512         $CREATETEST $DIR/d28/ct || error "createtest failed"
3513 }
3514 run_test 28 "create/mknod/mkdir with bad file types ============"
3515
3516 test_29() {
3517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3518
3519         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3520                 disable_opencache
3521                 stack_trap "restore_opencache"
3522         }
3523
3524         sync; sleep 1; sync # flush out any dirty pages from previous tests
3525         cancel_lru_locks
3526         test_mkdir $DIR/d29
3527         touch $DIR/d29/foo
3528         log 'first d29'
3529         ls -l $DIR/d29
3530
3531         declare -i LOCKCOUNTORIG=0
3532         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3533                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3534         done
3535         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3536
3537         declare -i LOCKUNUSEDCOUNTORIG=0
3538         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3539                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3540         done
3541
3542         log 'second d29'
3543         ls -l $DIR/d29
3544         log 'done'
3545
3546         declare -i LOCKCOUNTCURRENT=0
3547         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3548                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3549         done
3550
3551         declare -i LOCKUNUSEDCOUNTCURRENT=0
3552         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3553                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3554         done
3555
3556         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3557                 $LCTL set_param -n ldlm.dump_namespaces ""
3558                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3559                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3560                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3561                 return 2
3562         fi
3563         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3564                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3565                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3566                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3567                 return 3
3568         fi
3569 }
3570 run_test 29 "IT_GETATTR regression  ============================"
3571
3572 test_30a() { # was test_30
3573         cp $(which ls) $DIR || cp /bin/ls $DIR
3574         $DIR/ls / || error "Can't execute binary from lustre"
3575         rm $DIR/ls
3576 }
3577 run_test 30a "execute binary from Lustre (execve) =============="
3578
3579 test_30b() {
3580         cp `which ls` $DIR || cp /bin/ls $DIR
3581         chmod go+rx $DIR/ls
3582         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3583         rm $DIR/ls
3584 }
3585 run_test 30b "execute binary from Lustre as non-root ==========="
3586
3587 test_30c() { # b=22376
3588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3589
3590         cp $(which ls) $DIR || cp /bin/ls $DIR
3591         chmod a-rw $DIR/ls
3592         cancel_lru_locks mdc
3593         cancel_lru_locks osc
3594         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3595         rm -f $DIR/ls
3596 }
3597 run_test 30c "execute binary from Lustre without read perms ===="
3598
3599 test_30d() {
3600         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3601
3602         for i in {1..10}; do
3603                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3604                 local PID=$!
3605                 sleep 1
3606                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3607                 wait $PID || error "executing dd from Lustre failed"
3608                 rm -f $DIR/$tfile
3609         done
3610
3611         rm -f $DIR/dd
3612 }
3613 run_test 30d "execute binary from Lustre while clear locks"
3614
3615 test_31a() {
3616         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3617         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3618 }
3619 run_test 31a "open-unlink file =================================="
3620
3621 test_31b() {
3622         touch $DIR/f31 || error "touch $DIR/f31 failed"
3623         ln $DIR/f31 $DIR/f31b || error "ln failed"
3624         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3625         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3626 }
3627 run_test 31b "unlink file with multiple links while open ======="
3628
3629 test_31c() {
3630         touch $DIR/f31 || error "touch $DIR/f31 failed"
3631         ln $DIR/f31 $DIR/f31c || error "ln failed"
3632         multiop_bg_pause $DIR/f31 O_uc ||
3633                 error "multiop_bg_pause for $DIR/f31 failed"
3634         MULTIPID=$!
3635         $MULTIOP $DIR/f31c Ouc
3636         kill -USR1 $MULTIPID
3637         wait $MULTIPID
3638 }
3639 run_test 31c "open-unlink file with multiple links ============="
3640
3641 test_31d() {
3642         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3643         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3644 }
3645 run_test 31d "remove of open directory ========================="
3646
3647 test_31e() { # bug 2904
3648         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3649 }
3650 run_test 31e "remove of open non-empty directory ==============="
3651
3652 test_31f() { # bug 4554
3653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3654
3655         set -vx
3656         test_mkdir $DIR/d31f
3657         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3658         cp /etc/hosts $DIR/d31f
3659         ls -l $DIR/d31f
3660         $LFS getstripe $DIR/d31f/hosts
3661         multiop_bg_pause $DIR/d31f D_c || return 1
3662         MULTIPID=$!
3663
3664         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3665         test_mkdir $DIR/d31f
3666         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3667         cp /etc/hosts $DIR/d31f
3668         ls -l $DIR/d31f
3669         $LFS getstripe $DIR/d31f/hosts
3670         multiop_bg_pause $DIR/d31f D_c || return 1
3671         MULTIPID2=$!
3672
3673         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3674         wait $MULTIPID || error "first opendir $MULTIPID failed"
3675
3676         sleep 6
3677
3678         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3679         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3680         set +vx
3681 }
3682 run_test 31f "remove of open directory with open-unlink file ==="
3683
3684 test_31g() {
3685         echo "-- cross directory link --"
3686         test_mkdir -c1 $DIR/${tdir}ga
3687         test_mkdir -c1 $DIR/${tdir}gb
3688         touch $DIR/${tdir}ga/f
3689         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3690         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3691         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3692         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3693         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3694 }
3695 run_test 31g "cross directory link==============="
3696
3697 test_31h() {
3698         echo "-- cross directory link --"
3699         test_mkdir -c1 $DIR/${tdir}
3700         test_mkdir -c1 $DIR/${tdir}/dir
3701         touch $DIR/${tdir}/f
3702         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3703         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3704         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3705         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3706         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3707 }
3708 run_test 31h "cross directory link under child==============="
3709
3710 test_31i() {
3711         echo "-- cross directory link --"
3712         test_mkdir -c1 $DIR/$tdir
3713         test_mkdir -c1 $DIR/$tdir/dir
3714         touch $DIR/$tdir/dir/f
3715         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3716         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3717         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3718         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3719         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3720 }
3721 run_test 31i "cross directory link under parent==============="
3722
3723 test_31j() {
3724         test_mkdir -c1 -p $DIR/$tdir
3725         test_mkdir -c1 -p $DIR/$tdir/dir1
3726         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3727         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3728         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3729         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3730         return 0
3731 }
3732 run_test 31j "link for directory==============="
3733
3734 test_31k() {
3735         test_mkdir -c1 -p $DIR/$tdir
3736         touch $DIR/$tdir/s
3737         touch $DIR/$tdir/exist
3738         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3739         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3740         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3741         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3742         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3743         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3744         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3745         return 0
3746 }
3747 run_test 31k "link to file: the same, non-existing, dir==============="
3748
3749 test_31l() {
3750         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3751
3752         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3753         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3754                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3755
3756         touch $DIR/$tfile || error "create failed"
3757         mkdir $DIR/$tdir || error "mkdir failed"
3758         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3759 }
3760 run_test 31l "link to file: target dir has trailing slash"
3761
3762 test_31m() {
3763         mkdir $DIR/d31m
3764         touch $DIR/d31m/s
3765         mkdir $DIR/d31m2
3766         touch $DIR/d31m2/exist
3767         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3768         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3769         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3770         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3771         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3772         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3773         return 0
3774 }
3775 run_test 31m "link to file: the same, non-existing, dir==============="
3776
3777 test_31n() {
3778         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3779         nlink=$(stat --format=%h $DIR/$tfile)
3780         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3781         local fd=$(free_fd)
3782         local cmd="exec $fd<$DIR/$tfile"
3783         eval $cmd
3784         cmd="exec $fd<&-"
3785         trap "eval $cmd" EXIT
3786         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3787         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3788         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3789         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3790         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3791         eval $cmd
3792 }
3793 run_test 31n "check link count of unlinked file"
3794
3795 link_one() {
3796         local tempfile=$(mktemp $1_XXXXXX)
3797         mlink $tempfile $1 2> /dev/null &&
3798                 echo "$BASHPID: link $tempfile to $1 succeeded"
3799         unlink $tempfile
3800 }
3801
3802 test_31o() { # LU-2901
3803         test_mkdir $DIR/$tdir
3804         for LOOP in $(seq 100); do
3805                 rm -f $DIR/$tdir/$tfile*
3806                 for THREAD in $(seq 8); do
3807                         link_one $DIR/$tdir/$tfile.$LOOP &
3808                 done
3809                 wait
3810                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3811                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3812                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3813                         break || true
3814         done
3815 }
3816 run_test 31o "duplicate hard links with same filename"
3817
3818 test_31p() {
3819         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3820
3821         test_mkdir $DIR/$tdir
3822         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3823         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3824
3825         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3826                 error "open unlink test1 failed"
3827         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3828                 error "open unlink test2 failed"
3829
3830         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3831                 error "test1 still exists"
3832         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3833                 error "test2 still exists"
3834 }
3835 run_test 31p "remove of open striped directory"
3836
3837 test_31q() {
3838         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3839
3840         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3841         index=$($LFS getdirstripe -i $DIR/$tdir)
3842         [ $index -eq 3 ] || error "first stripe index $index != 3"
3843         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3844         [ $index -eq 1 ] || error "second stripe index $index != 1"
3845
3846         # when "-c <stripe_count>" is set, the number of MDTs specified after
3847         # "-i" should equal to the stripe count
3848         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3849 }
3850 run_test 31q "create striped directory on specific MDTs"
3851
3852 #LU-14949
3853 test_31r() {
3854         touch $DIR/$tfile.target
3855         touch $DIR/$tfile.source
3856
3857         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3858         $LCTL set_param fail_loc=0x1419 fail_val=3
3859         cat $DIR/$tfile.target &
3860         CATPID=$!
3861
3862         # Guarantee open is waiting before we get here
3863         sleep 1
3864         mv $DIR/$tfile.source $DIR/$tfile.target
3865
3866         wait $CATPID
3867         RC=$?
3868         if [[ $RC -ne 0 ]]; then
3869                 error "open with cat failed, rc=$RC"
3870         fi
3871 }
3872 run_test 31r "open-rename(replace) race"
3873
3874 cleanup_test32_mount() {
3875         local rc=0
3876         trap 0
3877         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3878         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3879         losetup -d $loopdev || true
3880         rm -rf $DIR/$tdir
3881         return $rc
3882 }
3883
3884 test_32a() {
3885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3886
3887         echo "== more mountpoints and symlinks ================="
3888         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3889         trap cleanup_test32_mount EXIT
3890         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3891         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3892                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3893         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3894                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3895         cleanup_test32_mount
3896 }
3897 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3898
3899 test_32b() {
3900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3901
3902         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3903         trap cleanup_test32_mount EXIT
3904         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3905         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3906                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3907         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3908                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3909         cleanup_test32_mount
3910 }
3911 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3912
3913 test_32c() {
3914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3915
3916         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3917         trap cleanup_test32_mount EXIT
3918         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3919         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3920                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3921         test_mkdir -p $DIR/$tdir/d2/test_dir
3922         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3923                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3924         cleanup_test32_mount
3925 }
3926 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3927
3928 test_32d() {
3929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3930
3931         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3932         trap cleanup_test32_mount EXIT
3933         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3934         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3935                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3936         test_mkdir -p $DIR/$tdir/d2/test_dir
3937         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3938                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3939         cleanup_test32_mount
3940 }
3941 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3942
3943 test_32e() {
3944         rm -fr $DIR/$tdir
3945         test_mkdir -p $DIR/$tdir/tmp
3946         local tmp_dir=$DIR/$tdir/tmp
3947         ln -s $DIR/$tdir $tmp_dir/symlink11
3948         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3949         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3950         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3951 }
3952 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3953
3954 test_32f() {
3955         rm -fr $DIR/$tdir
3956         test_mkdir -p $DIR/$tdir/tmp
3957         local tmp_dir=$DIR/$tdir/tmp
3958         ln -s $DIR/$tdir $tmp_dir/symlink11
3959         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3960         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3961         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3962 }
3963 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3964
3965 test_32g() {
3966         local tmp_dir=$DIR/$tdir/tmp
3967         test_mkdir -p $tmp_dir
3968         test_mkdir $DIR/${tdir}2
3969         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3970         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3971         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3972         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3973         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3974         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3975 }
3976 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3977
3978 test_32h() {
3979         rm -fr $DIR/$tdir $DIR/${tdir}2
3980         tmp_dir=$DIR/$tdir/tmp
3981         test_mkdir -p $tmp_dir
3982         test_mkdir $DIR/${tdir}2
3983         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3984         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3985         ls $tmp_dir/symlink12 || error "listing symlink12"
3986         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3987 }
3988 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3989
3990 test_32i() {
3991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3992
3993         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3994         trap cleanup_test32_mount EXIT
3995         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3996         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3997                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3998         touch $DIR/$tdir/test_file
3999         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4000                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4001         cleanup_test32_mount
4002 }
4003 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4004
4005 test_32j() {
4006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4007
4008         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4009         trap cleanup_test32_mount EXIT
4010         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4011         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4012                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4013         touch $DIR/$tdir/test_file
4014         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4015                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4016         cleanup_test32_mount
4017 }
4018 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4019
4020 test_32k() {
4021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4022
4023         rm -fr $DIR/$tdir
4024         trap cleanup_test32_mount EXIT
4025         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4026         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4027                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4028         test_mkdir -p $DIR/$tdir/d2
4029         touch $DIR/$tdir/d2/test_file || error "touch failed"
4030         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4031                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4032         cleanup_test32_mount
4033 }
4034 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4035
4036 test_32l() {
4037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4038
4039         rm -fr $DIR/$tdir
4040         trap cleanup_test32_mount EXIT
4041         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4042         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4043                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4044         test_mkdir -p $DIR/$tdir/d2
4045         touch $DIR/$tdir/d2/test_file || error "touch failed"
4046         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4047                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4048         cleanup_test32_mount
4049 }
4050 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4051
4052 test_32m() {
4053         rm -fr $DIR/d32m
4054         test_mkdir -p $DIR/d32m/tmp
4055         TMP_DIR=$DIR/d32m/tmp
4056         ln -s $DIR $TMP_DIR/symlink11
4057         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4058         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4059                 error "symlink11 not a link"
4060         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4061                 error "symlink01 not a link"
4062 }
4063 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4064
4065 test_32n() {
4066         rm -fr $DIR/d32n
4067         test_mkdir -p $DIR/d32n/tmp
4068         TMP_DIR=$DIR/d32n/tmp
4069         ln -s $DIR $TMP_DIR/symlink11
4070         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4071         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4072         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4073 }
4074 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4075
4076 test_32o() {
4077         touch $DIR/$tfile
4078         test_mkdir -p $DIR/d32o/tmp
4079         TMP_DIR=$DIR/d32o/tmp
4080         ln -s $DIR/$tfile $TMP_DIR/symlink12
4081         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4082         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4083                 error "symlink12 not a link"
4084         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4085         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4086                 error "$DIR/d32o/tmp/symlink12 not file type"
4087         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4088                 error "$DIR/d32o/symlink02 not file type"
4089 }
4090 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4091
4092 test_32p() {
4093         log 32p_1
4094         rm -fr $DIR/d32p
4095         log 32p_2
4096         rm -f $DIR/$tfile
4097         log 32p_3
4098         touch $DIR/$tfile
4099         log 32p_4
4100         test_mkdir -p $DIR/d32p/tmp
4101         log 32p_5
4102         TMP_DIR=$DIR/d32p/tmp
4103         log 32p_6
4104         ln -s $DIR/$tfile $TMP_DIR/symlink12
4105         log 32p_7
4106         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4107         log 32p_8
4108         cat $DIR/d32p/tmp/symlink12 ||
4109                 error "Can't open $DIR/d32p/tmp/symlink12"
4110         log 32p_9
4111         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4112         log 32p_10
4113 }
4114 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4115
4116 test_32q() {
4117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4118
4119         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4120         trap cleanup_test32_mount EXIT
4121         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4122         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4123         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4124                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4125         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4126         cleanup_test32_mount
4127 }
4128 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4129
4130 test_32r() {
4131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4132
4133         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4134         trap cleanup_test32_mount EXIT
4135         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4136         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4137         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4138                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4139         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4140         cleanup_test32_mount
4141 }
4142 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4143
4144 test_33aa() {
4145         rm -f $DIR/$tfile
4146         touch $DIR/$tfile
4147         chmod 444 $DIR/$tfile
4148         chown $RUNAS_ID $DIR/$tfile
4149         log 33_1
4150         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4151         log 33_2
4152 }
4153 run_test 33aa "write file with mode 444 (should return error)"
4154
4155 test_33a() {
4156         rm -fr $DIR/$tdir
4157         test_mkdir $DIR/$tdir
4158         chown $RUNAS_ID $DIR/$tdir
4159         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4160                 error "$RUNAS create $tdir/$tfile failed"
4161         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4162                 error "open RDWR" || true
4163 }
4164 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4165
4166 test_33b() {
4167         rm -fr $DIR/$tdir
4168         test_mkdir $DIR/$tdir
4169         chown $RUNAS_ID $DIR/$tdir
4170         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4171 }
4172 run_test 33b "test open file with malformed flags (No panic)"
4173
4174 test_33c() {
4175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4176         remote_ost_nodsh && skip "remote OST with nodsh"
4177
4178         local ostnum
4179         local ostname
4180         local write_bytes
4181         local all_zeros
4182
4183         all_zeros=true
4184         test_mkdir $DIR/$tdir
4185         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4186
4187         sync
4188         for ostnum in $(seq $OSTCOUNT); do
4189                 # test-framework's OST numbering is one-based, while Lustre's
4190                 # is zero-based
4191                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4192                 # check if at least some write_bytes stats are counted
4193                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4194                               obdfilter.$ostname.stats |
4195                               awk '/^write_bytes/ {print $7}' )
4196                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4197                 if (( ${write_bytes:-0} > 0 )); then
4198                         all_zeros=false
4199                         break
4200                 fi
4201         done
4202
4203         $all_zeros || return 0
4204
4205         # Write four bytes
4206         echo foo > $DIR/$tdir/bar
4207         # Really write them
4208         sync
4209
4210         # Total up write_bytes after writing.  We'd better find non-zeros.
4211         for ostnum in $(seq $OSTCOUNT); do
4212                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4213                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4214                               obdfilter/$ostname/stats |
4215                               awk '/^write_bytes/ {print $7}' )
4216                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4217                 if (( ${write_bytes:-0} > 0 )); then
4218                         all_zeros=false
4219                         break
4220                 fi
4221         done
4222
4223         if $all_zeros; then
4224                 for ostnum in $(seq $OSTCOUNT); do
4225                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4226                         echo "Check write_bytes is in obdfilter.*.stats:"
4227                         do_facet ost$ostnum lctl get_param -n \
4228                                 obdfilter.$ostname.stats
4229                 done
4230                 error "OST not keeping write_bytes stats (b=22312)"
4231         fi
4232 }
4233 run_test 33c "test write_bytes stats"
4234
4235 test_33d() {
4236         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4238
4239         local MDTIDX=1
4240         local remote_dir=$DIR/$tdir/remote_dir
4241
4242         test_mkdir $DIR/$tdir
4243         $LFS mkdir -i $MDTIDX $remote_dir ||
4244                 error "create remote directory failed"
4245
4246         touch $remote_dir/$tfile
4247         chmod 444 $remote_dir/$tfile
4248         chown $RUNAS_ID $remote_dir/$tfile
4249
4250         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4251
4252         chown $RUNAS_ID $remote_dir
4253         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4254                                         error "create" || true
4255         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4256                                     error "open RDWR" || true
4257         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4258 }
4259 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4260
4261 test_33e() {
4262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4263
4264         mkdir $DIR/$tdir
4265
4266         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4267         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4268         mkdir $DIR/$tdir/local_dir
4269
4270         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4271         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4272         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4273
4274         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4275                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4276
4277         rmdir $DIR/$tdir/* || error "rmdir failed"
4278
4279         umask 777
4280         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4281         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4282         mkdir $DIR/$tdir/local_dir
4283
4284         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4285         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4286         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4287
4288         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4289                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4290
4291         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4292
4293         umask 000
4294         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4295         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4296         mkdir $DIR/$tdir/local_dir
4297
4298         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4299         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4300         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4301
4302         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4303                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4304 }
4305 run_test 33e "mkdir and striped directory should have same mode"
4306
4307 cleanup_33f() {
4308         trap 0
4309         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4310 }
4311
4312 test_33f() {
4313         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4314         remote_mds_nodsh && skip "remote MDS with nodsh"
4315
4316         mkdir $DIR/$tdir
4317         chmod go+rwx $DIR/$tdir
4318         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4319         trap cleanup_33f EXIT
4320
4321         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4322                 error "cannot create striped directory"
4323
4324         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4325                 error "cannot create files in striped directory"
4326
4327         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4328                 error "cannot remove files in striped directory"
4329
4330         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4331                 error "cannot remove striped directory"
4332
4333         cleanup_33f
4334 }
4335 run_test 33f "nonroot user can create, access, and remove a striped directory"
4336
4337 test_33g() {
4338         mkdir -p $DIR/$tdir/dir2
4339
4340         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4341         echo $err
4342         [[ $err =~ "exists" ]] || error "Not exists error"
4343 }
4344 run_test 33g "nonroot user create already existing root created file"
4345
4346 sub_33h() {
4347         local hash_type=$1
4348         local count=250
4349
4350         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4351                 error "lfs mkdir -H $hash_type $tdir failed"
4352         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4353
4354         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4355         local index2
4356         local fname
4357
4358         for fname in $DIR/$tdir/$tfile.bak \
4359                      $DIR/$tdir/$tfile.SAV \
4360                      $DIR/$tdir/$tfile.orig \
4361                      $DIR/$tdir/$tfile~; do
4362                 touch $fname || error "touch $fname failed"
4363                 index2=$($LFS getstripe -m $fname)
4364                 (( $index == $index2 )) ||
4365                         error "$fname MDT index mismatch $index != $index2"
4366         done
4367
4368         local failed=0
4369         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4370         local pattern
4371
4372         for pattern in ${patterns[*]}; do
4373                 echo "pattern $pattern"
4374                 fname=$DIR/$tdir/$pattern
4375                 for (( i = 0; i < $count; i++ )); do
4376                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4377                                 error "mktemp $DIR/$tdir/$pattern failed"
4378                         index2=$($LFS getstripe -m $fname)
4379                         (( $index == $index2 )) && continue
4380
4381                         failed=$((failed + 1))
4382                         echo "$fname MDT index mismatch $index != $index2"
4383                 done
4384         done
4385
4386         echo "$failed/$count MDT index mismatches, expect ~2-4"
4387         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4388
4389         local same=0
4390         local expect
4391
4392         # verify that "crush" is still broken with all files on same MDT,
4393         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4394         [[ "$hash_type" == "crush" ]] && expect=$count ||
4395                 expect=$((count / MDSCOUNT))
4396
4397         # crush2 doesn't put all-numeric suffixes on the same MDT,
4398         # filename like $tfile.12345678 should *not* be considered temp
4399         for pattern in ${patterns[*]}; do
4400                 local base=${pattern%%X*}
4401                 local suff=${pattern#$base}
4402
4403                 echo "pattern $pattern"
4404                 for (( i = 0; i < $count; i++ )); do
4405                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4406                         touch $fname || error "touch $fname failed"
4407                         index2=$($LFS getstripe -m $fname)
4408                         (( $index != $index2 )) && continue
4409
4410                         same=$((same + 1))
4411                 done
4412         done
4413
4414         # the number of "bad" hashes is random, as it depends on the random
4415         # filenames generated by "mktemp".  Allow some margin in the results.
4416         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4417         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4418            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4419                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4420         same=0
4421
4422         # crush2 doesn't put suffixes with special characters on the same MDT
4423         # filename like $tfile.txt.1234 should *not* be considered temp
4424         for pattern in ${patterns[*]}; do
4425                 local base=${pattern%%X*}
4426                 local suff=${pattern#$base}
4427
4428                 pattern=$base...${suff/XXX}
4429                 echo "pattern=$pattern"
4430                 for (( i = 0; i < $count; i++ )); do
4431                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4432                                 error "touch $fname failed"
4433                         index2=$($LFS getstripe -m $fname)
4434                         (( $index != $index2 )) && continue
4435
4436                         same=$((same + 1))
4437                 done
4438         done
4439
4440         # the number of "bad" hashes is random, as it depends on the random
4441         # filenames generated by "mktemp".  Allow some margin in the results.
4442         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4443         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4444            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4445                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4446 }
4447
4448 test_33h() {
4449         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4450         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4451                 skip "Need MDS version at least 2.13.50"
4452
4453         sub_33h crush
4454 }
4455 run_test 33h "temp file is located on the same MDT as target (crush)"
4456
4457 test_33hh() {
4458         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4459         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4460         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4461                 skip "Need MDS version at least 2.15.0 for crush2"
4462
4463         sub_33h crush2
4464 }
4465 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4466
4467 test_33i()
4468 {
4469         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4470
4471         local FNAME=$(str_repeat 'f' 250)
4472
4473         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4474         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4475
4476         local count
4477         local total
4478
4479         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4480
4481         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4482
4483         lctl --device %$MDC deactivate
4484         stack_trap "lctl --device %$MDC activate"
4485         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4486         total=$(\ls -l $DIR/$tdir | wc -l)
4487         # "ls -l" will list total in the first line
4488         total=$((total - 1))
4489         (( total + count == 1000 )) ||
4490                 error "ls list $total files, $count files on MDT1"
4491 }
4492 run_test 33i "striped directory can be accessed when one MDT is down"
4493
4494 test_33j() {
4495         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4496
4497         mkdir -p $DIR/$tdir/
4498
4499         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4500                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4501
4502         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4503                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4504
4505         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4506                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4507
4508         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4509                 error "-D was not specified, but still failed"
4510 }
4511 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4512
4513 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4514 test_34a() {
4515         rm -f $DIR/f34
4516         $MCREATE $DIR/f34 || error "mcreate failed"
4517         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4518                 error "getstripe failed"
4519         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4520         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4521                 error "getstripe failed"
4522         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4523                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4524 }
4525 run_test 34a "truncate file that has not been opened ==========="
4526
4527 test_34b() {
4528         [ ! -f $DIR/f34 ] && test_34a
4529         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4530                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4531         $OPENFILE -f O_RDONLY $DIR/f34
4532         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4533                 error "getstripe failed"
4534         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4535                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4536 }
4537 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4538
4539 test_34c() {
4540         [ ! -f $DIR/f34 ] && test_34a
4541         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4542                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4543         $OPENFILE -f O_RDWR $DIR/f34
4544         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4545                 error "$LFS getstripe failed"
4546         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4547                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4548 }
4549 run_test 34c "O_RDWR opening file-with-size works =============="
4550
4551 test_34d() {
4552         [ ! -f $DIR/f34 ] && test_34a
4553         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4554                 error "dd failed"
4555         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4556                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4557         rm $DIR/f34
4558 }
4559 run_test 34d "write to sparse file ============================="
4560
4561 test_34e() {
4562         rm -f $DIR/f34e
4563         $MCREATE $DIR/f34e || error "mcreate failed"
4564         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4565         $CHECKSTAT -s 1000 $DIR/f34e ||
4566                 error "Size of $DIR/f34e not equal to 1000 bytes"
4567         $OPENFILE -f O_RDWR $DIR/f34e
4568         $CHECKSTAT -s 1000 $DIR/f34e ||
4569                 error "Size of $DIR/f34e not equal to 1000 bytes"
4570 }
4571 run_test 34e "create objects, some with size and some without =="
4572
4573 test_34f() { # bug 6242, 6243
4574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4575
4576         SIZE34F=48000
4577         rm -f $DIR/f34f
4578         $MCREATE $DIR/f34f || error "mcreate failed"
4579         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4580         dd if=$DIR/f34f of=$TMP/f34f
4581         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4582         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4583         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4584         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4585         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4586 }
4587 run_test 34f "read from a file with no objects until EOF ======="
4588
4589 test_34g() {
4590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4591
4592         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4593                 error "dd failed"
4594         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4595         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4596                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4597         cancel_lru_locks osc
4598         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4599                 error "wrong size after lock cancel"
4600
4601         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4602         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4603                 error "expanding truncate failed"
4604         cancel_lru_locks osc
4605         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4606                 error "wrong expanded size after lock cancel"
4607 }
4608 run_test 34g "truncate long file ==============================="
4609
4610 test_34h() {
4611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4612
4613         local gid=10
4614         local sz=1000
4615
4616         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4617         sync # Flush the cache so that multiop below does not block on cache
4618              # flush when getting the group lock
4619         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4620         MULTIPID=$!
4621
4622         # Since just timed wait is not good enough, let's do a sync write
4623         # that way we are sure enough time for a roundtrip + processing
4624         # passed + 2 seconds of extra margin.
4625         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4626         rm $DIR/${tfile}-1
4627         sleep 2
4628
4629         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4630                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4631                 kill -9 $MULTIPID
4632         fi
4633         wait $MULTIPID
4634         local nsz=`stat -c %s $DIR/$tfile`
4635         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4636 }
4637 run_test 34h "ftruncate file under grouplock should not block"
4638
4639 test_35a() {
4640         cp /bin/sh $DIR/f35a
4641         chmod 444 $DIR/f35a
4642         chown $RUNAS_ID $DIR/f35a
4643         $RUNAS $DIR/f35a && error || true
4644         rm $DIR/f35a
4645 }
4646 run_test 35a "exec file with mode 444 (should return and not leak)"
4647
4648 test_36a() {
4649         rm -f $DIR/f36
4650         utime $DIR/f36 || error "utime failed for MDS"
4651 }
4652 run_test 36a "MDS utime check (mknod, utime)"
4653
4654 test_36b() {
4655         echo "" > $DIR/f36
4656         utime $DIR/f36 || error "utime failed for OST"
4657 }
4658 run_test 36b "OST utime check (open, utime)"
4659
4660 test_36c() {
4661         rm -f $DIR/d36/f36
4662         test_mkdir $DIR/d36
4663         chown $RUNAS_ID $DIR/d36
4664         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4665 }
4666 run_test 36c "non-root MDS utime check (mknod, utime)"
4667
4668 test_36d() {
4669         [ ! -d $DIR/d36 ] && test_36c
4670         echo "" > $DIR/d36/f36
4671         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4672 }
4673 run_test 36d "non-root OST utime check (open, utime)"
4674
4675 test_36e() {
4676         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4677
4678         test_mkdir $DIR/$tdir
4679         touch $DIR/$tdir/$tfile
4680         $RUNAS utime $DIR/$tdir/$tfile &&
4681                 error "utime worked, expected failure" || true
4682 }
4683 run_test 36e "utime on non-owned file (should return error)"
4684
4685 subr_36fh() {
4686         local fl="$1"
4687         local LANG_SAVE=$LANG
4688         local LC_LANG_SAVE=$LC_LANG
4689         export LANG=C LC_LANG=C # for date language
4690
4691         DATESTR="Dec 20  2000"
4692         test_mkdir $DIR/$tdir
4693         lctl set_param fail_loc=$fl
4694         date; date +%s
4695         cp /etc/hosts $DIR/$tdir/$tfile
4696         sync & # write RPC generated with "current" inode timestamp, but delayed
4697         sleep 1
4698         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4699         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4700         cancel_lru_locks $OSC
4701         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4702         date; date +%s
4703         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4704                 echo "BEFORE: $LS_BEFORE" && \
4705                 echo "AFTER : $LS_AFTER" && \
4706                 echo "WANT  : $DATESTR" && \
4707                 error "$DIR/$tdir/$tfile timestamps changed" || true
4708
4709         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4710 }
4711
4712 test_36f() {
4713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4714
4715         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4716         subr_36fh "0x80000214"
4717 }
4718 run_test 36f "utime on file racing with OST BRW write =========="
4719
4720 test_36g() {
4721         remote_ost_nodsh && skip "remote OST with nodsh"
4722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4723         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4724                 skip "Need MDS version at least 2.12.51"
4725
4726         local fmd_max_age
4727         local fmd
4728         local facet="ost1"
4729         local tgt="obdfilter"
4730
4731         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4732
4733         test_mkdir $DIR/$tdir
4734         fmd_max_age=$(do_facet $facet \
4735                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4736                 head -n 1")
4737
4738         echo "FMD max age: ${fmd_max_age}s"
4739         touch $DIR/$tdir/$tfile
4740         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4741                 gawk '{cnt=cnt+$1}  END{print cnt}')
4742         echo "FMD before: $fmd"
4743         [[ $fmd == 0 ]] &&
4744                 error "FMD wasn't create by touch"
4745         sleep $((fmd_max_age + 12))
4746         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4747                 gawk '{cnt=cnt+$1}  END{print cnt}')
4748         echo "FMD after: $fmd"
4749         [[ $fmd == 0 ]] ||
4750                 error "FMD wasn't expired by ping"
4751 }
4752 run_test 36g "FMD cache expiry ====================="
4753
4754 test_36h() {
4755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4756
4757         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4758         subr_36fh "0x80000227"
4759 }
4760 run_test 36h "utime on file racing with OST BRW write =========="
4761
4762 test_36i() {
4763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4764
4765         test_mkdir $DIR/$tdir
4766         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4767
4768         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4769         local new_mtime=$((mtime + 200))
4770
4771         #change Modify time of striped dir
4772         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4773                         error "change mtime failed"
4774
4775         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4776
4777         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4778 }
4779 run_test 36i "change mtime on striped directory"
4780
4781 # test_37 - duplicate with tests 32q 32r
4782
4783 test_38() {
4784         local file=$DIR/$tfile
4785         touch $file
4786         openfile -f O_DIRECTORY $file
4787         local RC=$?
4788         local ENOTDIR=20
4789         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4790         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4791 }
4792 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4793
4794 test_39a() { # was test_39
4795         touch $DIR/$tfile
4796         touch $DIR/${tfile}2
4797 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4798 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4799 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4800         sleep 2
4801         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4802         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4803                 echo "mtime"
4804                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4805                 echo "atime"
4806                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4807                 echo "ctime"
4808                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4809                 error "O_TRUNC didn't change timestamps"
4810         fi
4811 }
4812 run_test 39a "mtime changed on create"
4813
4814 test_39b() {
4815         test_mkdir -c1 $DIR/$tdir
4816         cp -p /etc/passwd $DIR/$tdir/fopen
4817         cp -p /etc/passwd $DIR/$tdir/flink
4818         cp -p /etc/passwd $DIR/$tdir/funlink
4819         cp -p /etc/passwd $DIR/$tdir/frename
4820         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4821
4822         sleep 1
4823         echo "aaaaaa" >> $DIR/$tdir/fopen
4824         echo "aaaaaa" >> $DIR/$tdir/flink
4825         echo "aaaaaa" >> $DIR/$tdir/funlink
4826         echo "aaaaaa" >> $DIR/$tdir/frename
4827
4828         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4829         local link_new=`stat -c %Y $DIR/$tdir/flink`
4830         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4831         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4832
4833         cat $DIR/$tdir/fopen > /dev/null
4834         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4835         rm -f $DIR/$tdir/funlink2
4836         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4837
4838         for (( i=0; i < 2; i++ )) ; do
4839                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4840                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4841                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4842                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4843
4844                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4845                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4846                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4847                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4848
4849                 cancel_lru_locks $OSC
4850                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4851         done
4852 }
4853 run_test 39b "mtime change on open, link, unlink, rename  ======"
4854
4855 # this should be set to past
4856 TEST_39_MTIME=`date -d "1 year ago" +%s`
4857
4858 # bug 11063
4859 test_39c() {
4860         touch $DIR1/$tfile
4861         sleep 2
4862         local mtime0=`stat -c %Y $DIR1/$tfile`
4863
4864         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4865         local mtime1=`stat -c %Y $DIR1/$tfile`
4866         [ "$mtime1" = $TEST_39_MTIME ] || \
4867                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4868
4869         local d1=`date +%s`
4870         echo hello >> $DIR1/$tfile
4871         local d2=`date +%s`
4872         local mtime2=`stat -c %Y $DIR1/$tfile`
4873         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4874                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4875
4876         mv $DIR1/$tfile $DIR1/$tfile-1
4877
4878         for (( i=0; i < 2; i++ )) ; do
4879                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4880                 [ "$mtime2" = "$mtime3" ] || \
4881                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4882
4883                 cancel_lru_locks $OSC
4884                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4885         done
4886 }
4887 run_test 39c "mtime change on rename ==========================="
4888
4889 # bug 21114
4890 test_39d() {
4891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4892
4893         touch $DIR1/$tfile
4894         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4895
4896         for (( i=0; i < 2; i++ )) ; do
4897                 local mtime=`stat -c %Y $DIR1/$tfile`
4898                 [ $mtime = $TEST_39_MTIME ] || \
4899                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4900
4901                 cancel_lru_locks $OSC
4902                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4903         done
4904 }
4905 run_test 39d "create, utime, stat =============================="
4906
4907 # bug 21114
4908 test_39e() {
4909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4910
4911         touch $DIR1/$tfile
4912         local mtime1=`stat -c %Y $DIR1/$tfile`
4913
4914         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4915
4916         for (( i=0; i < 2; i++ )) ; do
4917                 local mtime2=`stat -c %Y $DIR1/$tfile`
4918                 [ $mtime2 = $TEST_39_MTIME ] || \
4919                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4920
4921                 cancel_lru_locks $OSC
4922                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4923         done
4924 }
4925 run_test 39e "create, stat, utime, stat ========================"
4926
4927 # bug 21114
4928 test_39f() {
4929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4930
4931         touch $DIR1/$tfile
4932         mtime1=`stat -c %Y $DIR1/$tfile`
4933
4934         sleep 2
4935         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4936
4937         for (( i=0; i < 2; i++ )) ; do
4938                 local mtime2=`stat -c %Y $DIR1/$tfile`
4939                 [ $mtime2 = $TEST_39_MTIME ] || \
4940                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4941
4942                 cancel_lru_locks $OSC
4943                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4944         done
4945 }
4946 run_test 39f "create, stat, sleep, utime, stat ================="
4947
4948 # bug 11063
4949 test_39g() {
4950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4951
4952         echo hello >> $DIR1/$tfile
4953         local mtime1=`stat -c %Y $DIR1/$tfile`
4954
4955         sleep 2
4956         chmod o+r $DIR1/$tfile
4957
4958         for (( i=0; i < 2; i++ )) ; do
4959                 local mtime2=`stat -c %Y $DIR1/$tfile`
4960                 [ "$mtime1" = "$mtime2" ] || \
4961                         error "lost mtime: $mtime2, should be $mtime1"
4962
4963                 cancel_lru_locks $OSC
4964                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4965         done
4966 }
4967 run_test 39g "write, chmod, stat ==============================="
4968
4969 # bug 11063
4970 test_39h() {
4971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4972
4973         touch $DIR1/$tfile
4974         sleep 1
4975
4976         local d1=`date`
4977         echo hello >> $DIR1/$tfile
4978         local mtime1=`stat -c %Y $DIR1/$tfile`
4979
4980         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4981         local d2=`date`
4982         if [ "$d1" != "$d2" ]; then
4983                 echo "write and touch not within one second"
4984         else
4985                 for (( i=0; i < 2; i++ )) ; do
4986                         local mtime2=`stat -c %Y $DIR1/$tfile`
4987                         [ "$mtime2" = $TEST_39_MTIME ] || \
4988                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4989
4990                         cancel_lru_locks $OSC
4991                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4992                 done
4993         fi
4994 }
4995 run_test 39h "write, utime within one second, stat ============="
4996
4997 test_39i() {
4998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4999
5000         touch $DIR1/$tfile
5001         sleep 1
5002
5003         echo hello >> $DIR1/$tfile
5004         local mtime1=`stat -c %Y $DIR1/$tfile`
5005
5006         mv $DIR1/$tfile $DIR1/$tfile-1
5007
5008         for (( i=0; i < 2; i++ )) ; do
5009                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5010
5011                 [ "$mtime1" = "$mtime2" ] || \
5012                         error "lost mtime: $mtime2, should be $mtime1"
5013
5014                 cancel_lru_locks $OSC
5015                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5016         done
5017 }
5018 run_test 39i "write, rename, stat =============================="
5019
5020 test_39j() {
5021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5022
5023         start_full_debug_logging
5024         touch $DIR1/$tfile
5025         sleep 1
5026
5027         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5028         lctl set_param fail_loc=0x80000412
5029         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5030                 error "multiop failed"
5031         local multipid=$!
5032         local mtime1=`stat -c %Y $DIR1/$tfile`
5033
5034         mv $DIR1/$tfile $DIR1/$tfile-1
5035
5036         kill -USR1 $multipid
5037         wait $multipid || error "multiop close failed"
5038
5039         for (( i=0; i < 2; i++ )) ; do
5040                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5041                 [ "$mtime1" = "$mtime2" ] ||
5042                         error "mtime is lost on close: $mtime2, " \
5043                               "should be $mtime1"
5044
5045                 cancel_lru_locks
5046                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5047         done
5048         lctl set_param fail_loc=0
5049         stop_full_debug_logging
5050 }
5051 run_test 39j "write, rename, close, stat ======================="
5052
5053 test_39k() {
5054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5055
5056         touch $DIR1/$tfile
5057         sleep 1
5058
5059         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5060         local multipid=$!
5061         local mtime1=`stat -c %Y $DIR1/$tfile`
5062
5063         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5064
5065         kill -USR1 $multipid
5066         wait $multipid || error "multiop close failed"
5067
5068         for (( i=0; i < 2; i++ )) ; do
5069                 local mtime2=`stat -c %Y $DIR1/$tfile`
5070
5071                 [ "$mtime2" = $TEST_39_MTIME ] || \
5072                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5073
5074                 cancel_lru_locks
5075                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5076         done
5077 }
5078 run_test 39k "write, utime, close, stat ========================"
5079
5080 # this should be set to future
5081 TEST_39_ATIME=`date -d "1 year" +%s`
5082
5083 test_39l() {
5084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5085         remote_mds_nodsh && skip "remote MDS with nodsh"
5086
5087         local atime_diff=$(do_facet $SINGLEMDS \
5088                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5089         rm -rf $DIR/$tdir
5090         mkdir_on_mdt0 $DIR/$tdir
5091
5092         # test setting directory atime to future
5093         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5094         local atime=$(stat -c %X $DIR/$tdir)
5095         [ "$atime" = $TEST_39_ATIME ] ||
5096                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5097
5098         # test setting directory atime from future to now
5099         local now=$(date +%s)
5100         touch -a -d @$now $DIR/$tdir
5101
5102         atime=$(stat -c %X $DIR/$tdir)
5103         [ "$atime" -eq "$now"  ] ||
5104                 error "atime is not updated from future: $atime, $now"
5105
5106         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5107         sleep 3
5108
5109         # test setting directory atime when now > dir atime + atime_diff
5110         local d1=$(date +%s)
5111         ls $DIR/$tdir
5112         local d2=$(date +%s)
5113         cancel_lru_locks mdc
5114         atime=$(stat -c %X $DIR/$tdir)
5115         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5116                 error "atime is not updated  : $atime, should be $d2"
5117
5118         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5119         sleep 3
5120
5121         # test not setting directory atime when now < dir atime + atime_diff
5122         ls $DIR/$tdir
5123         cancel_lru_locks mdc
5124         atime=$(stat -c %X $DIR/$tdir)
5125         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5126                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5127
5128         do_facet $SINGLEMDS \
5129                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5130 }
5131 run_test 39l "directory atime update ==========================="
5132
5133 test_39m() {
5134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5135
5136         touch $DIR1/$tfile
5137         sleep 2
5138         local far_past_mtime=$(date -d "May 29 1953" +%s)
5139         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5140
5141         touch -m -d @$far_past_mtime $DIR1/$tfile
5142         touch -a -d @$far_past_atime $DIR1/$tfile
5143
5144         for (( i=0; i < 2; i++ )) ; do
5145                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5146                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5147                         error "atime or mtime set incorrectly"
5148
5149                 cancel_lru_locks $OSC
5150                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5151         done
5152 }
5153 run_test 39m "test atime and mtime before 1970"
5154
5155 test_39n() { # LU-3832
5156         remote_mds_nodsh && skip "remote MDS with nodsh"
5157
5158         local atime_diff=$(do_facet $SINGLEMDS \
5159                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5160         local atime0
5161         local atime1
5162         local atime2
5163
5164         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5165
5166         rm -rf $DIR/$tfile
5167         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5168         atime0=$(stat -c %X $DIR/$tfile)
5169
5170         sleep 5
5171         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5172         atime1=$(stat -c %X $DIR/$tfile)
5173
5174         sleep 5
5175         cancel_lru_locks mdc
5176         cancel_lru_locks osc
5177         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5178         atime2=$(stat -c %X $DIR/$tfile)
5179
5180         do_facet $SINGLEMDS \
5181                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5182
5183         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5184         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5185 }
5186 run_test 39n "check that O_NOATIME is honored"
5187
5188 test_39o() {
5189         TESTDIR=$DIR/$tdir/$tfile
5190         [ -e $TESTDIR ] && rm -rf $TESTDIR
5191         mkdir -p $TESTDIR
5192         cd $TESTDIR
5193         links1=2
5194         ls
5195         mkdir a b
5196         ls
5197         links2=$(stat -c %h .)
5198         [ $(($links1 + 2)) != $links2 ] &&
5199                 error "wrong links count $(($links1 + 2)) != $links2"
5200         rmdir b
5201         links3=$(stat -c %h .)
5202         [ $(($links1 + 1)) != $links3 ] &&
5203                 error "wrong links count $links1 != $links3"
5204         return 0
5205 }
5206 run_test 39o "directory cached attributes updated after create"
5207
5208 test_39p() {
5209         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5210
5211         local MDTIDX=1
5212         TESTDIR=$DIR/$tdir/$tdir
5213         [ -e $TESTDIR ] && rm -rf $TESTDIR
5214         test_mkdir -p $TESTDIR
5215         cd $TESTDIR
5216         links1=2
5217         ls
5218         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5219         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5220         ls
5221         links2=$(stat -c %h .)
5222         [ $(($links1 + 2)) != $links2 ] &&
5223                 error "wrong links count $(($links1 + 2)) != $links2"
5224         rmdir remote_dir2
5225         links3=$(stat -c %h .)
5226         [ $(($links1 + 1)) != $links3 ] &&
5227                 error "wrong links count $links1 != $links3"
5228         return 0
5229 }
5230 run_test 39p "remote directory cached attributes updated after create ========"
5231
5232 test_39r() {
5233         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5234                 skip "no atime update on old OST"
5235         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5236                 skip_env "ldiskfs only test"
5237         fi
5238
5239         local saved_adiff
5240         saved_adiff=$(do_facet ost1 \
5241                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5242         stack_trap "do_facet ost1 \
5243                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5244
5245         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5246
5247         $LFS setstripe -i 0 $DIR/$tfile
5248         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5249                 error "can't write initial file"
5250         cancel_lru_locks osc
5251
5252         # exceed atime_diff and access file
5253         sleep 10
5254         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5255                 error "can't udpate atime"
5256
5257         local atime_cli=$(stat -c %X $DIR/$tfile)
5258         echo "client atime: $atime_cli"
5259         # allow atime update to be written to device
5260         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5261         sleep 5
5262
5263         local ostdev=$(ostdevname 1)
5264         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5265         local seq=${fid[3]#0x}
5266         local oid=${fid[1]}
5267         local oid_hex
5268
5269         if [ $seq == 0 ]; then
5270                 oid_hex=${fid[1]}
5271         else
5272                 oid_hex=${fid[2]#0x}
5273         fi
5274         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5275         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5276
5277         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5278         local atime_ost=$(do_facet ost1 "$cmd" |&
5279                           awk -F'[: ]' '/atime:/ { print $4 }')
5280         (( atime_cli == atime_ost )) ||
5281                 error "atime on client $atime_cli != ost $atime_ost"
5282 }
5283 run_test 39r "lazy atime update on OST"
5284
5285 test_39q() { # LU-8041
5286         local testdir=$DIR/$tdir
5287         mkdir -p $testdir
5288         multiop_bg_pause $testdir D_c || error "multiop failed"
5289         local multipid=$!
5290         cancel_lru_locks mdc
5291         kill -USR1 $multipid
5292         local atime=$(stat -c %X $testdir)
5293         [ "$atime" -ne 0 ] || error "atime is zero"
5294 }
5295 run_test 39q "close won't zero out atime"
5296
5297 test_39s() {
5298         local atime0
5299         local atime1
5300         local atime2
5301         local atime3
5302         local atime4
5303
5304         umount_client $MOUNT
5305         mount_client $MOUNT relatime
5306
5307         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5308         atime0=$(stat -c %X $DIR/$tfile)
5309
5310         # First read updates atime
5311         sleep 1
5312         cat $DIR/$tfile >/dev/null
5313         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5314
5315         # Next reads do not update atime
5316         sleep 1
5317         cat $DIR/$tfile >/dev/null
5318         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5319
5320         # If mtime is greater than atime, atime is updated
5321         sleep 1
5322         touch -m $DIR/$tfile # (mtime = now)
5323         sleep 1
5324         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5325         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5326
5327         # Next reads do not update atime
5328         sleep 1
5329         cat $DIR/$tfile >/dev/null
5330         atime4=$(stat -c %X $DIR/$tfile)
5331
5332         # Remount the client to clear 'relatime' option
5333         remount_client $MOUNT
5334
5335         (( atime0 < atime1 )) ||
5336                 error "atime $atime0 should be smaller than $atime1"
5337         (( atime1 == atime2 )) ||
5338                 error "atime $atime1 was updated to $atime2"
5339         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5340         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5341 }
5342 run_test 39s "relatime is supported"
5343
5344 test_40() {
5345         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5346         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5347                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5348         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5349                 error "$tfile is not 4096 bytes in size"
5350 }
5351 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5352
5353 test_41() {
5354         # bug 1553
5355         small_write $DIR/f41 18
5356 }
5357 run_test 41 "test small file write + fstat ====================="
5358
5359 count_ost_writes() {
5360         lctl get_param -n ${OSC}.*.stats |
5361                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5362                         END { printf("%0.0f", writes) }'
5363 }
5364
5365 # decent default
5366 WRITEBACK_SAVE=500
5367 DIRTY_RATIO_SAVE=40
5368 MAX_DIRTY_RATIO=50
5369 BG_DIRTY_RATIO_SAVE=10
5370 MAX_BG_DIRTY_RATIO=25
5371
5372 start_writeback() {
5373         trap 0
5374         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5375         # dirty_ratio, dirty_background_ratio
5376         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5377                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5378                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5379                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5380         else
5381                 # if file not here, we are a 2.4 kernel
5382                 kill -CONT `pidof kupdated`
5383         fi
5384 }
5385
5386 stop_writeback() {
5387         # setup the trap first, so someone cannot exit the test at the
5388         # exact wrong time and mess up a machine
5389         trap start_writeback EXIT
5390         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5391         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5392                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5393                 sysctl -w vm.dirty_writeback_centisecs=0
5394                 sysctl -w vm.dirty_writeback_centisecs=0
5395                 # save and increase /proc/sys/vm/dirty_ratio
5396                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5397                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5398                 # save and increase /proc/sys/vm/dirty_background_ratio
5399                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5400                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5401         else
5402                 # if file not here, we are a 2.4 kernel
5403                 kill -STOP `pidof kupdated`
5404         fi
5405 }
5406
5407 # ensure that all stripes have some grant before we test client-side cache
5408 setup_test42() {
5409         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5410                 dd if=/dev/zero of=$i bs=4k count=1
5411                 rm $i
5412         done
5413 }
5414
5415 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5416 # file truncation, and file removal.
5417 test_42a() {
5418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5419
5420         setup_test42
5421         cancel_lru_locks $OSC
5422         stop_writeback
5423         sync; sleep 1; sync # just to be safe
5424         BEFOREWRITES=`count_ost_writes`
5425         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5426         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5427         AFTERWRITES=`count_ost_writes`
5428         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5429                 error "$BEFOREWRITES < $AFTERWRITES"
5430         start_writeback
5431 }
5432 run_test 42a "ensure that we don't flush on close"
5433
5434 test_42b() {
5435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5436
5437         setup_test42
5438         cancel_lru_locks $OSC
5439         stop_writeback
5440         sync
5441         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5442         BEFOREWRITES=$(count_ost_writes)
5443         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5444         AFTERWRITES=$(count_ost_writes)
5445         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5446                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5447         fi
5448         BEFOREWRITES=$(count_ost_writes)
5449         sync || error "sync: $?"
5450         AFTERWRITES=$(count_ost_writes)
5451         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5452                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5453         fi
5454         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5455         start_writeback
5456         return 0
5457 }
5458 run_test 42b "test destroy of file with cached dirty data ======"
5459
5460 # if these tests just want to test the effect of truncation,
5461 # they have to be very careful.  consider:
5462 # - the first open gets a {0,EOF}PR lock
5463 # - the first write conflicts and gets a {0, count-1}PW
5464 # - the rest of the writes are under {count,EOF}PW
5465 # - the open for truncate tries to match a {0,EOF}PR
5466 #   for the filesize and cancels the PWs.
5467 # any number of fixes (don't get {0,EOF} on open, match
5468 # composite locks, do smarter file size management) fix
5469 # this, but for now we want these tests to verify that
5470 # the cancellation with truncate intent works, so we
5471 # start the file with a full-file pw lock to match against
5472 # until the truncate.
5473 trunc_test() {
5474         test=$1
5475         file=$DIR/$test
5476         offset=$2
5477         cancel_lru_locks $OSC
5478         stop_writeback
5479         # prime the file with 0,EOF PW to match
5480         touch $file
5481         $TRUNCATE $file 0
5482         sync; sync
5483         # now the real test..
5484         dd if=/dev/zero of=$file bs=1024 count=100
5485         BEFOREWRITES=`count_ost_writes`
5486         $TRUNCATE $file $offset
5487         cancel_lru_locks $OSC
5488         AFTERWRITES=`count_ost_writes`
5489         start_writeback
5490 }
5491
5492 test_42c() {
5493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5494
5495         trunc_test 42c 1024
5496         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5497                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5498         rm $file
5499 }
5500 run_test 42c "test partial truncate of file with cached dirty data"
5501
5502 test_42d() {
5503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5504
5505         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5506         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5507         $LCTL set_param debug=+cache
5508
5509         trunc_test 42d 0
5510         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5511                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5512         rm $file
5513 }
5514 run_test 42d "test complete truncate of file with cached dirty data"
5515
5516 test_42e() { # bug22074
5517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5518
5519         local TDIR=$DIR/${tdir}e
5520         local pages=16 # hardcoded 16 pages, don't change it.
5521         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5522         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5523         local max_dirty_mb
5524         local warmup_files
5525
5526         test_mkdir $DIR/${tdir}e
5527         $LFS setstripe -c 1 $TDIR
5528         createmany -o $TDIR/f $files
5529
5530         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5531
5532         # we assume that with $OSTCOUNT files, at least one of them will
5533         # be allocated on OST0.
5534         warmup_files=$((OSTCOUNT * max_dirty_mb))
5535         createmany -o $TDIR/w $warmup_files
5536
5537         # write a large amount of data into one file and sync, to get good
5538         # avail_grant number from OST.
5539         for ((i=0; i<$warmup_files; i++)); do
5540                 idx=$($LFS getstripe -i $TDIR/w$i)
5541                 [ $idx -ne 0 ] && continue
5542                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5543                 break
5544         done
5545         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5546         sync
5547         $LCTL get_param $proc_osc0/cur_dirty_bytes
5548         $LCTL get_param $proc_osc0/cur_grant_bytes
5549
5550         # create as much dirty pages as we can while not to trigger the actual
5551         # RPCs directly. but depends on the env, VFS may trigger flush during this
5552         # period, hopefully we are good.
5553         for ((i=0; i<$warmup_files; i++)); do
5554                 idx=$($LFS getstripe -i $TDIR/w$i)
5555                 [ $idx -ne 0 ] && continue
5556                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5557         done
5558         $LCTL get_param $proc_osc0/cur_dirty_bytes
5559         $LCTL get_param $proc_osc0/cur_grant_bytes
5560
5561         # perform the real test
5562         $LCTL set_param $proc_osc0/rpc_stats 0
5563         for ((;i<$files; i++)); do
5564                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5565                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5566         done
5567         sync
5568         $LCTL get_param $proc_osc0/rpc_stats
5569
5570         local percent=0
5571         local have_ppr=false
5572         $LCTL get_param $proc_osc0/rpc_stats |
5573                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5574                         # skip lines until we are at the RPC histogram data
5575                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5576                         $have_ppr || continue
5577
5578                         # we only want the percent stat for < 16 pages
5579                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5580
5581                         percent=$((percent + WPCT))
5582                         if [[ $percent -gt 15 ]]; then
5583                                 error "less than 16-pages write RPCs" \
5584                                       "$percent% > 15%"
5585                                 break
5586                         fi
5587                 done
5588         rm -rf $TDIR
5589 }
5590 run_test 42e "verify sub-RPC writes are not done synchronously"
5591
5592 test_43A() { # was test_43
5593         test_mkdir $DIR/$tdir
5594         cp -p /bin/ls $DIR/$tdir/$tfile
5595         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5596         pid=$!
5597         # give multiop a chance to open
5598         sleep 1
5599
5600         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5601         kill -USR1 $pid
5602         # Wait for multiop to exit
5603         wait $pid
5604 }
5605 run_test 43A "execution of file opened for write should return -ETXTBSY"
5606
5607 test_43a() {
5608         test_mkdir $DIR/$tdir
5609         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5610         $DIR/$tdir/sleep 60 &
5611         SLEEP_PID=$!
5612         # Make sure exec of $tdir/sleep wins race with truncate
5613         sleep 1
5614         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5615         kill $SLEEP_PID
5616 }
5617 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5618
5619 test_43b() {
5620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5621
5622         test_mkdir $DIR/$tdir
5623         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5624         $DIR/$tdir/sleep 60 &
5625         SLEEP_PID=$!
5626         # Make sure exec of $tdir/sleep wins race with truncate
5627         sleep 1
5628         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5629         kill $SLEEP_PID
5630 }
5631 run_test 43b "truncate of file being executed should return -ETXTBSY"
5632
5633 test_43c() {
5634         local testdir="$DIR/$tdir"
5635         test_mkdir $testdir
5636         cp $SHELL $testdir/
5637         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5638                 ( cd $testdir && md5sum -c )
5639 }
5640 run_test 43c "md5sum of copy into lustre"
5641
5642 test_44A() { # was test_44
5643         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5644
5645         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5646         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5647 }
5648 run_test 44A "zero length read from a sparse stripe"
5649
5650 test_44a() {
5651         local nstripe=$($LFS getstripe -c -d $DIR)
5652         [ -z "$nstripe" ] && skip "can't get stripe info"
5653         [[ $nstripe -gt $OSTCOUNT ]] &&
5654                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5655
5656         local stride=$($LFS getstripe -S -d $DIR)
5657         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5658                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5659         fi
5660
5661         OFFSETS="0 $((stride/2)) $((stride-1))"
5662         for offset in $OFFSETS; do
5663                 for i in $(seq 0 $((nstripe-1))); do
5664                         local GLOBALOFFSETS=""
5665                         # size in Bytes
5666                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5667                         local myfn=$DIR/d44a-$size
5668                         echo "--------writing $myfn at $size"
5669                         ll_sparseness_write $myfn $size ||
5670                                 error "ll_sparseness_write"
5671                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5672                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5673                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5674
5675                         for j in $(seq 0 $((nstripe-1))); do
5676                                 # size in Bytes
5677                                 size=$((((j + $nstripe )*$stride + $offset)))
5678                                 ll_sparseness_write $myfn $size ||
5679                                         error "ll_sparseness_write"
5680                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5681                         done
5682                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5683                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5684                         rm -f $myfn
5685                 done
5686         done
5687 }
5688 run_test 44a "test sparse pwrite ==============================="
5689
5690 dirty_osc_total() {
5691         tot=0
5692         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5693                 tot=$(($tot + $d))
5694         done
5695         echo $tot
5696 }
5697 do_dirty_record() {
5698         before=`dirty_osc_total`
5699         echo executing "\"$*\""
5700         eval $*
5701         after=`dirty_osc_total`
5702         echo before $before, after $after
5703 }
5704 test_45() {
5705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5706
5707         f="$DIR/f45"
5708         # Obtain grants from OST if it supports it
5709         echo blah > ${f}_grant
5710         stop_writeback
5711         sync
5712         do_dirty_record "echo blah > $f"
5713         [[ $before -eq $after ]] && error "write wasn't cached"
5714         do_dirty_record "> $f"
5715         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5716         do_dirty_record "echo blah > $f"
5717         [[ $before -eq $after ]] && error "write wasn't cached"
5718         do_dirty_record "sync"
5719         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5720         do_dirty_record "echo blah > $f"
5721         [[ $before -eq $after ]] && error "write wasn't cached"
5722         do_dirty_record "cancel_lru_locks osc"
5723         [[ $before -gt $after ]] ||
5724                 error "lock cancellation didn't lower dirty count"
5725         start_writeback
5726 }
5727 run_test 45 "osc io page accounting ============================"
5728
5729 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5730 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5731 # objects offset and an assert hit when an rpc was built with 1023's mapped
5732 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5733 test_46() {
5734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5735
5736         f="$DIR/f46"
5737         stop_writeback
5738         sync
5739         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5740         sync
5741         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5742         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5743         sync
5744         start_writeback
5745 }
5746 run_test 46 "dirtying a previously written page ================"
5747
5748 # test_47 is removed "Device nodes check" is moved to test_28
5749
5750 test_48a() { # bug 2399
5751         [ "$mds1_FSTYPE" = "zfs" ] &&
5752         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5753                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5754
5755         test_mkdir $DIR/$tdir
5756         cd $DIR/$tdir
5757         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5758         test_mkdir $DIR/$tdir
5759         touch foo || error "'touch foo' failed after recreating cwd"
5760         test_mkdir bar
5761         touch .foo || error "'touch .foo' failed after recreating cwd"
5762         test_mkdir .bar
5763         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5764         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5765         cd . || error "'cd .' failed after recreating cwd"
5766         mkdir . && error "'mkdir .' worked after recreating cwd"
5767         rmdir . && error "'rmdir .' worked after recreating cwd"
5768         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5769         cd .. || error "'cd ..' failed after recreating cwd"
5770 }
5771 run_test 48a "Access renamed working dir (should return errors)="
5772
5773 test_48b() { # bug 2399
5774         rm -rf $DIR/$tdir
5775         test_mkdir $DIR/$tdir
5776         cd $DIR/$tdir
5777         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5778         touch foo && error "'touch foo' worked after removing cwd"
5779         mkdir foo && error "'mkdir foo' worked after removing cwd"
5780         touch .foo && error "'touch .foo' worked after removing cwd"
5781         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5782         ls . > /dev/null && error "'ls .' worked after removing cwd"
5783         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5784         mkdir . && error "'mkdir .' worked after removing cwd"
5785         rmdir . && error "'rmdir .' worked after removing cwd"
5786         ln -s . foo && error "'ln -s .' worked after removing cwd"
5787         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5788 }
5789 run_test 48b "Access removed working dir (should return errors)="
5790
5791 test_48c() { # bug 2350
5792         #lctl set_param debug=-1
5793         #set -vx
5794         rm -rf $DIR/$tdir
5795         test_mkdir -p $DIR/$tdir/dir
5796         cd $DIR/$tdir/dir
5797         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5798         $TRACE touch foo && error "touch foo worked after removing cwd"
5799         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5800         touch .foo && error "touch .foo worked after removing cwd"
5801         mkdir .foo && error "mkdir .foo worked after removing cwd"
5802         $TRACE ls . && error "'ls .' worked after removing cwd"
5803         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5804         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5805         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5806         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5807         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5808 }
5809 run_test 48c "Access removed working subdir (should return errors)"
5810
5811 test_48d() { # bug 2350
5812         #lctl set_param debug=-1
5813         #set -vx
5814         rm -rf $DIR/$tdir
5815         test_mkdir -p $DIR/$tdir/dir
5816         cd $DIR/$tdir/dir
5817         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5818         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5819         $TRACE touch foo && error "'touch foo' worked after removing parent"
5820         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5821         touch .foo && error "'touch .foo' worked after removing parent"
5822         mkdir .foo && error "mkdir .foo worked after removing parent"
5823         $TRACE ls . && error "'ls .' worked after removing parent"
5824         $TRACE ls .. && error "'ls ..' worked after removing parent"
5825         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5826         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5827         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5828         true
5829 }
5830 run_test 48d "Access removed parent subdir (should return errors)"
5831
5832 test_48e() { # bug 4134
5833         #lctl set_param debug=-1
5834         #set -vx
5835         rm -rf $DIR/$tdir
5836         test_mkdir -p $DIR/$tdir/dir
5837         cd $DIR/$tdir/dir
5838         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5839         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5840         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5841         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5842         # On a buggy kernel addition of "touch foo" after cd .. will
5843         # produce kernel oops in lookup_hash_it
5844         touch ../foo && error "'cd ..' worked after recreate parent"
5845         cd $DIR
5846         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5847 }
5848 run_test 48e "Access to recreated parent subdir (should return errors)"
5849
5850 test_48f() {
5851         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5852                 skip "need MDS >= 2.13.55"
5853         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5854         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5855                 skip "needs different host for mdt1 mdt2"
5856         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5857
5858         $LFS mkdir -i0 $DIR/$tdir
5859         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5860
5861         for d in sub1 sub2 sub3; do
5862                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5863                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5864                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5865         done
5866
5867         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5868 }
5869 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5870
5871 test_49() { # LU-1030
5872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5873         remote_ost_nodsh && skip "remote OST with nodsh"
5874
5875         # get ost1 size - $FSNAME-OST0000
5876         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5877                 awk '{ print $4 }')
5878         # write 800M at maximum
5879         [[ $ost1_size -lt 2 ]] && ost1_size=2
5880         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5881
5882         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5883         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5884         local dd_pid=$!
5885
5886         # change max_pages_per_rpc while writing the file
5887         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5888         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5889         # loop until dd process exits
5890         while ps ax -opid | grep -wq $dd_pid; do
5891                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5892                 sleep $((RANDOM % 5 + 1))
5893         done
5894         # restore original max_pages_per_rpc
5895         $LCTL set_param $osc1_mppc=$orig_mppc
5896         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5897 }
5898 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5899
5900 test_50() {
5901         # bug 1485
5902         test_mkdir $DIR/$tdir
5903         cd $DIR/$tdir
5904         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5905 }
5906 run_test 50 "special situations: /proc symlinks  ==============="
5907
5908 test_51a() {    # was test_51
5909         # bug 1516 - create an empty entry right after ".." then split dir
5910         test_mkdir -c1 $DIR/$tdir
5911         touch $DIR/$tdir/foo
5912         $MCREATE $DIR/$tdir/bar
5913         rm $DIR/$tdir/foo
5914         createmany -m $DIR/$tdir/longfile 201
5915         FNUM=202
5916         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5917                 $MCREATE $DIR/$tdir/longfile$FNUM
5918                 FNUM=$(($FNUM + 1))
5919                 echo -n "+"
5920         done
5921         echo
5922         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5923 }
5924 run_test 51a "special situations: split htree with empty entry =="
5925
5926 cleanup_print_lfs_df () {
5927         trap 0
5928         $LFS df
5929         $LFS df -i
5930 }
5931
5932 test_51b() {
5933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5934
5935         local dir=$DIR/$tdir
5936         local nrdirs=$((65536 + 100))
5937
5938         # cleanup the directory
5939         rm -fr $dir
5940
5941         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5942
5943         $LFS df
5944         $LFS df -i
5945         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5946         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5947         [[ $numfree -lt $nrdirs ]] &&
5948                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5949
5950         # need to check free space for the directories as well
5951         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5952         numfree=$(( blkfree / $(fs_inode_ksize) ))
5953         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5954
5955         trap cleanup_print_lfs_df EXIT
5956
5957         # create files
5958         createmany -d $dir/d $nrdirs || {
5959                 unlinkmany $dir/d $nrdirs
5960                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5961         }
5962
5963         # really created :
5964         nrdirs=$(ls -U $dir | wc -l)
5965
5966         # unlink all but 100 subdirectories, then check it still works
5967         local left=100
5968         local delete=$((nrdirs - left))
5969
5970         $LFS df
5971         $LFS df -i
5972
5973         # for ldiskfs the nlink count should be 1, but this is OSD specific
5974         # and so this is listed for informational purposes only
5975         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5976         unlinkmany -d $dir/d $delete ||
5977                 error "unlink of first $delete subdirs failed"
5978
5979         echo "nlink between: $(stat -c %h $dir)"
5980         local found=$(ls -U $dir | wc -l)
5981         [ $found -ne $left ] &&
5982                 error "can't find subdirs: found only $found, expected $left"
5983
5984         unlinkmany -d $dir/d $delete $left ||
5985                 error "unlink of second $left subdirs failed"
5986         # regardless of whether the backing filesystem tracks nlink accurately
5987         # or not, the nlink count shouldn't be more than "." and ".." here
5988         local after=$(stat -c %h $dir)
5989         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5990                 echo "nlink after: $after"
5991
5992         cleanup_print_lfs_df
5993 }
5994 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5995
5996 test_51d_sub() {
5997         local stripecount=$1
5998         local nfiles=$2
5999
6000         log "create files with stripecount=$stripecount"
6001         $LFS setstripe -C $stripecount $DIR/$tdir
6002         createmany -o $DIR/$tdir/t- $nfiles
6003         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6004         for ((n = 0; n < $OSTCOUNT; n++)); do
6005                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6006                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6007                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6008                             '($1 == '$n') { objs += 1 } \
6009                             END { printf("%0.0f", objs) }')
6010                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6011         done
6012         unlinkmany $DIR/$tdir/t- $nfiles
6013         rm  -f $TMP/$tfile
6014
6015         local nlast
6016         local min=4
6017         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6018
6019         # For some combinations of stripecount and OSTCOUNT current code
6020         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6021         # than others. Rather than skipping this test entirely, check that
6022         # and keep testing to ensure imbalance does not get worse. LU-15282
6023         (( (OSTCOUNT == 6 && stripecount == 4) ||
6024            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6025            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6026         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6027                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6028                         { $LFS df && $LFS df -i &&
6029                         error "stripecount=$stripecount: " \
6030                               "OST $n has fewer objects vs. OST $nlast " \
6031                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6032                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6033                         { $LFS df && $LFS df -i &&
6034                         error "stripecount=$stripecount: " \
6035                               "OST $n has more objects vs. OST $nlast " \
6036                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6037
6038                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6039                         { $LFS df && $LFS df -i &&
6040                         error "stripecount=$stripecount: " \
6041                               "OST $n has fewer #0 objects vs. OST $nlast " \
6042                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6043                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6044                         { $LFS df && $LFS df -i &&
6045                         error "stripecount=$stripecount: " \
6046                               "OST $n has more #0 objects vs. OST $nlast " \
6047                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6048         done
6049 }
6050
6051 test_51d() {
6052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6053         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6054
6055         local stripecount
6056         local per_ost=100
6057         local nfiles=$((per_ost * OSTCOUNT))
6058         local mdts=$(comma_list $(mdts_nodes))
6059         local param="osp.*.create_count"
6060         local qos_old=$(do_facet mds1 \
6061                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6062
6063         do_nodes $mdts \
6064                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6065         stack_trap "do_nodes $mdts \
6066                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6067
6068         test_mkdir $DIR/$tdir
6069         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6070         (( dirstripes > 0 )) || dirstripes=1
6071
6072         # Ensure enough OST objects precreated for tests to pass without
6073         # running out of objects.  This is an LOV r-r OST algorithm test,
6074         # not an OST object precreation test.
6075         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6076         (( old >= nfiles )) ||
6077         {
6078                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6079
6080                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6081                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6082
6083                 # trigger precreation from all MDTs for all OSTs
6084                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6085                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6086                 done
6087         }
6088
6089         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6090                 sleep 8  # allow object precreation to catch up
6091                 test_51d_sub $stripecount $nfiles
6092         done
6093 }
6094 run_test 51d "check LOV round-robin OST object distribution"
6095
6096 test_51e() {
6097         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6098                 skip_env "ldiskfs only test"
6099         fi
6100
6101         test_mkdir -c1 $DIR/$tdir
6102         test_mkdir -c1 $DIR/$tdir/d0
6103
6104         touch $DIR/$tdir/d0/foo
6105         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6106                 error "file exceed 65000 nlink limit!"
6107         unlinkmany $DIR/$tdir/d0/f- 65001
6108         return 0
6109 }
6110 run_test 51e "check file nlink limit"
6111
6112 test_51f() {
6113         test_mkdir $DIR/$tdir
6114
6115         local max=100000
6116         local ulimit_old=$(ulimit -n)
6117         local spare=20 # number of spare fd's for scripts/libraries, etc.
6118         local mdt=$($LFS getstripe -m $DIR/$tdir)
6119         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6120
6121         echo "MDT$mdt numfree=$numfree, max=$max"
6122         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6123         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6124                 while ! ulimit -n $((numfree + spare)); do
6125                         numfree=$((numfree * 3 / 4))
6126                 done
6127                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6128         else
6129                 echo "left ulimit at $ulimit_old"
6130         fi
6131
6132         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6133                 unlinkmany $DIR/$tdir/f $numfree
6134                 error "create+open $numfree files in $DIR/$tdir failed"
6135         }
6136         ulimit -n $ulimit_old
6137
6138         # if createmany exits at 120s there will be fewer than $numfree files
6139         unlinkmany $DIR/$tdir/f $numfree || true
6140 }
6141 run_test 51f "check many open files limit"
6142
6143 test_52a() {
6144         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6145         test_mkdir $DIR/$tdir
6146         touch $DIR/$tdir/foo
6147         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6148         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6149         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6150         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6151         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6152                                         error "link worked"
6153         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6154         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6155         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6156                                                      error "lsattr"
6157         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6158         cp -r $DIR/$tdir $TMP/
6159         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6160 }
6161 run_test 52a "append-only flag test (should return errors)"
6162
6163 test_52b() {
6164         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6165         test_mkdir $DIR/$tdir
6166         touch $DIR/$tdir/foo
6167         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6168         cat test > $DIR/$tdir/foo && error "cat test worked"
6169         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6170         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6171         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6172                                         error "link worked"
6173         echo foo >> $DIR/$tdir/foo && error "echo worked"
6174         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6175         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6176         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6177         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6178                                                         error "lsattr"
6179         chattr -i $DIR/$tdir/foo || error "chattr failed"
6180
6181         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6182 }
6183 run_test 52b "immutable flag test (should return errors) ======="
6184
6185 test_53() {
6186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6187         remote_mds_nodsh && skip "remote MDS with nodsh"
6188         remote_ost_nodsh && skip "remote OST with nodsh"
6189
6190         local param
6191         local param_seq
6192         local ostname
6193         local mds_last
6194         local mds_last_seq
6195         local ost_last
6196         local ost_last_seq
6197         local ost_last_id
6198         local ostnum
6199         local node
6200         local found=false
6201         local support_last_seq=true
6202
6203         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6204                 support_last_seq=false
6205
6206         # only test MDT0000
6207         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6208         local value
6209         for value in $(do_facet $SINGLEMDS \
6210                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6211                 param=$(echo ${value[0]} | cut -d "=" -f1)
6212                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6213
6214                 if $support_last_seq; then
6215                         param_seq=$(echo $param |
6216                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6217                         mds_last_seq=$(do_facet $SINGLEMDS \
6218                                        $LCTL get_param -n $param_seq)
6219                 fi
6220                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6221
6222                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6223                 node=$(facet_active_host ost$((ostnum+1)))
6224                 param="obdfilter.$ostname.last_id"
6225                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6226                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6227                         ost_last_id=$ost_last
6228
6229                         if $support_last_seq; then
6230                                 ost_last_id=$(echo $ost_last |
6231                                               awk -F':' '{print $2}' |
6232                                               sed -e "s/^0x//g")
6233                                 ost_last_seq=$(echo $ost_last |
6234                                                awk -F':' '{print $1}')
6235                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6236                         fi
6237
6238                         if [[ $ost_last_id != $mds_last ]]; then
6239                                 error "$ost_last_id != $mds_last"
6240                         else
6241                                 found=true
6242                                 break
6243                         fi
6244                 done
6245         done
6246         $found || error "can not match last_seq/last_id for $mdtosc"
6247         return 0
6248 }
6249 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6250
6251 test_54a() {
6252         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6253
6254         LANG=C $SOCKETSERVER $DIR/socket ||
6255                 error "$SOCKETSERVER $DIR/socket failed: $?"
6256         LANG=C $SOCKETCLIENT $DIR/socket ||
6257                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6258         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6259 }
6260 run_test 54a "unix domain socket test =========================="
6261
6262 test_54b() {
6263         f="$DIR/f54b"
6264         mknod $f c 1 3
6265         chmod 0666 $f
6266         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6267 }
6268 run_test 54b "char device works in lustre ======================"
6269
6270 find_loop_dev() {
6271         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6272         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6273         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6274
6275         for i in $(seq 3 7); do
6276                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6277                 LOOPDEV=$LOOPBASE$i
6278                 LOOPNUM=$i
6279                 break
6280         done
6281 }
6282
6283 cleanup_54c() {
6284         local rc=0
6285         loopdev="$DIR/loop54c"
6286
6287         trap 0
6288         $UMOUNT $DIR/$tdir || rc=$?
6289         losetup -d $loopdev || true
6290         losetup -d $LOOPDEV || true
6291         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6292         return $rc
6293 }
6294
6295 test_54c() {
6296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6297
6298         loopdev="$DIR/loop54c"
6299
6300         find_loop_dev
6301         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6302         trap cleanup_54c EXIT
6303         mknod $loopdev b 7 $LOOPNUM
6304         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6305         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6306         losetup $loopdev $DIR/$tfile ||
6307                 error "can't set up $loopdev for $DIR/$tfile"
6308         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6309         test_mkdir $DIR/$tdir
6310         mount -t ext2 $loopdev $DIR/$tdir ||
6311                 error "error mounting $loopdev on $DIR/$tdir"
6312         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6313                 error "dd write"
6314         df $DIR/$tdir
6315         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6316                 error "dd read"
6317         cleanup_54c
6318 }
6319 run_test 54c "block device works in lustre ====================="
6320
6321 test_54d() {
6322         local pipe="$DIR/$tfile.pipe"
6323         local string="aaaaaa"
6324
6325         mknod $pipe p
6326         echo -n "$string" > $pipe &
6327         local result=$(cat $pipe)
6328         [[ "$result" == "$string" ]] || error "$result != $string"
6329 }
6330 run_test 54d "fifo device works in lustre ======================"
6331
6332 test_54e() {
6333         f="$DIR/f54e"
6334         string="aaaaaa"
6335         cp -aL /dev/console $f
6336         echo $string > $f || error "echo $string to $f failed"
6337 }
6338 run_test 54e "console/tty device works in lustre ======================"
6339
6340 test_56a() {
6341         local numfiles=3
6342         local numdirs=2
6343         local dir=$DIR/$tdir
6344
6345         rm -rf $dir
6346         test_mkdir -p $dir/dir
6347         for i in $(seq $numfiles); do
6348                 touch $dir/file$i
6349                 touch $dir/dir/file$i
6350         done
6351
6352         local numcomp=$($LFS getstripe --component-count $dir)
6353
6354         [[ $numcomp == 0 ]] && numcomp=1
6355
6356         # test lfs getstripe with --recursive
6357         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6358
6359         [[ $filenum -eq $((numfiles * 2)) ]] ||
6360                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6361         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6362         [[ $filenum -eq $numfiles ]] ||
6363                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6364         echo "$LFS getstripe showed obdidx or l_ost_idx"
6365
6366         # test lfs getstripe with file instead of dir
6367         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6368         [[ $filenum -eq 1 ]] ||
6369                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6370         echo "$LFS getstripe file1 passed"
6371
6372         #test lfs getstripe with --verbose
6373         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6374         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6375                 error "$LFS getstripe --verbose $dir: "\
6376                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6377         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6378                 error "$LFS getstripe $dir: showed lmm_magic"
6379
6380         #test lfs getstripe with -v prints lmm_fid
6381         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6382         local countfids=$((numdirs + numfiles * numcomp))
6383         [[ $filenum -eq $countfids ]] ||
6384                 error "$LFS getstripe -v $dir: "\
6385                       "got $filenum want $countfids lmm_fid"
6386         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6387                 error "$LFS getstripe $dir: showed lmm_fid by default"
6388         echo "$LFS getstripe --verbose passed"
6389
6390         #check for FID information
6391         local fid1=$($LFS getstripe --fid $dir/file1)
6392         local fid2=$($LFS getstripe --verbose $dir/file1 |
6393                      awk '/lmm_fid: / { print $2; exit; }')
6394         local fid3=$($LFS path2fid $dir/file1)
6395
6396         [ "$fid1" != "$fid2" ] &&
6397                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6398         [ "$fid1" != "$fid3" ] &&
6399                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6400         echo "$LFS getstripe --fid passed"
6401
6402         #test lfs getstripe with --obd
6403         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6404                 error "$LFS getstripe --obd wrong_uuid: should return error"
6405
6406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6407
6408         local ostidx=1
6409         local obduuid=$(ostuuid_from_index $ostidx)
6410         local found=$($LFS getstripe -r --obd $obduuid $dir |
6411                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6412
6413         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6414         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6415                 ((filenum--))
6416         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6417                 ((filenum--))
6418
6419         [[ $found -eq $filenum ]] ||
6420                 error "$LFS getstripe --obd: found $found expect $filenum"
6421         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6422                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6423                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6424                 error "$LFS getstripe --obd: should not show file on other obd"
6425         echo "$LFS getstripe --obd passed"
6426 }
6427 run_test 56a "check $LFS getstripe"
6428
6429 test_56b() {
6430         local dir=$DIR/$tdir
6431         local numdirs=3
6432
6433         test_mkdir $dir
6434         for i in $(seq $numdirs); do
6435                 test_mkdir $dir/dir$i
6436         done
6437
6438         # test lfs getdirstripe default mode is non-recursion, which is
6439         # different from lfs getstripe
6440         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6441
6442         [[ $dircnt -eq 1 ]] ||
6443                 error "$LFS getdirstripe: found $dircnt, not 1"
6444         dircnt=$($LFS getdirstripe --recursive $dir |
6445                 grep -c lmv_stripe_count)
6446         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6447                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6448 }
6449 run_test 56b "check $LFS getdirstripe"
6450
6451 test_56bb() {
6452         verify_yaml_available || skip_env "YAML verification not installed"
6453         local output_file=$DIR/$tfile.out
6454
6455         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6456
6457         cat $output_file
6458         cat $output_file | verify_yaml || error "layout is not valid YAML"
6459 }
6460 run_test 56bb "check $LFS getdirstripe layout is YAML"
6461
6462 test_56c() {
6463         remote_ost_nodsh && skip "remote OST with nodsh"
6464
6465         local ost_idx=0
6466         local ost_name=$(ostname_from_index $ost_idx)
6467         local old_status=$(ost_dev_status $ost_idx)
6468         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6469
6470         [[ -z "$old_status" ]] ||
6471                 skip_env "OST $ost_name is in $old_status status"
6472
6473         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6474         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6475                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6476         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6477                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6478                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6479         fi
6480
6481         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6482                 error "$LFS df -v showing inactive devices"
6483         sleep_maxage
6484
6485         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6486
6487         [[ "$new_status" =~ "D" ]] ||
6488                 error "$ost_name status is '$new_status', missing 'D'"
6489         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6490                 [[ "$new_status" =~ "N" ]] ||
6491                         error "$ost_name status is '$new_status', missing 'N'"
6492         fi
6493         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6494                 [[ "$new_status" =~ "f" ]] ||
6495                         error "$ost_name status is '$new_status', missing 'f'"
6496         fi
6497
6498         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6499         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6500                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6501         [[ -z "$p" ]] && restore_lustre_params < $p || true
6502         sleep_maxage
6503
6504         new_status=$(ost_dev_status $ost_idx)
6505         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6506                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6507         # can't check 'f' as devices may actually be on flash
6508 }
6509 run_test 56c "check 'lfs df' showing device status"
6510
6511 test_56d() {
6512         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6513         local osts=$($LFS df -v $MOUNT | grep -c OST)
6514
6515         $LFS df $MOUNT
6516
6517         (( mdts == MDSCOUNT )) ||
6518                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6519         (( osts == OSTCOUNT )) ||
6520                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6521 }
6522 run_test 56d "'lfs df -v' prints only configured devices"
6523
6524 test_56e() {
6525         err_enoent=2 # No such file or directory
6526         err_eopnotsupp=95 # Operation not supported
6527
6528         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6529         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6530
6531         # Check for handling of path not exists
6532         output=$($LFS df $enoent_mnt 2>&1)
6533         ret=$?
6534
6535         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6536         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6537                 error "expect failure $err_enoent, not $ret"
6538
6539         # Check for handling of non-Lustre FS
6540         output=$($LFS df $notsup_mnt)
6541         ret=$?
6542
6543         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6544         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6545                 error "expect success $err_eopnotsupp, not $ret"
6546
6547         # Check for multiple LustreFS argument
6548         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6549         ret=$?
6550
6551         [[ $output -eq 3 && $ret -eq 0 ]] ||
6552                 error "expect success 3, not $output, rc = $ret"
6553
6554         # Check for correct non-Lustre FS handling among multiple
6555         # LustreFS argument
6556         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6557                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6558         ret=$?
6559
6560         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6561                 error "expect success 2, not $output, rc = $ret"
6562 }
6563 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6564
6565 NUMFILES=3
6566 NUMDIRS=3
6567 setup_56() {
6568         local local_tdir="$1"
6569         local local_numfiles="$2"
6570         local local_numdirs="$3"
6571         local dir_params="$4"
6572         local dir_stripe_params="$5"
6573
6574         if [ ! -d "$local_tdir" ] ; then
6575                 test_mkdir -p $dir_stripe_params $local_tdir
6576                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6577                 for i in $(seq $local_numfiles) ; do
6578                         touch $local_tdir/file$i
6579                 done
6580                 for i in $(seq $local_numdirs) ; do
6581                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6582                         for j in $(seq $local_numfiles) ; do
6583                                 touch $local_tdir/dir$i/file$j
6584                         done
6585                 done
6586         fi
6587 }
6588
6589 setup_56_special() {
6590         local local_tdir=$1
6591         local local_numfiles=$2
6592         local local_numdirs=$3
6593
6594         setup_56 $local_tdir $local_numfiles $local_numdirs
6595
6596         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6597                 for i in $(seq $local_numfiles) ; do
6598                         mknod $local_tdir/loop${i}b b 7 $i
6599                         mknod $local_tdir/null${i}c c 1 3
6600                         ln -s $local_tdir/file1 $local_tdir/link${i}
6601                 done
6602                 for i in $(seq $local_numdirs) ; do
6603                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6604                         mknod $local_tdir/dir$i/null${i}c c 1 3
6605                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6606                 done
6607         fi
6608 }
6609
6610 test_56g() {
6611         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6612         local expected=$(($NUMDIRS + 2))
6613
6614         setup_56 $dir $NUMFILES $NUMDIRS
6615
6616         # test lfs find with -name
6617         for i in $(seq $NUMFILES) ; do
6618                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6619
6620                 [ $nums -eq $expected ] ||
6621                         error "lfs find -name '*$i' $dir wrong: "\
6622                               "found $nums, expected $expected"
6623         done
6624 }
6625 run_test 56g "check lfs find -name"
6626
6627 test_56h() {
6628         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6629         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6630
6631         setup_56 $dir $NUMFILES $NUMDIRS
6632
6633         # test lfs find with ! -name
6634         for i in $(seq $NUMFILES) ; do
6635                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6636
6637                 [ $nums -eq $expected ] ||
6638                         error "lfs find ! -name '*$i' $dir wrong: "\
6639                               "found $nums, expected $expected"
6640         done
6641 }
6642 run_test 56h "check lfs find ! -name"
6643
6644 test_56i() {
6645         local dir=$DIR/$tdir
6646
6647         test_mkdir $dir
6648
6649         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6650         local out=$($cmd)
6651
6652         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6653 }
6654 run_test 56i "check 'lfs find -ost UUID' skips directories"
6655
6656 test_56j() {
6657         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6658
6659         setup_56_special $dir $NUMFILES $NUMDIRS
6660
6661         local expected=$((NUMDIRS + 1))
6662         local cmd="$LFS find -type d $dir"
6663         local nums=$($cmd | wc -l)
6664
6665         [ $nums -eq $expected ] ||
6666                 error "'$cmd' wrong: found $nums, expected $expected"
6667 }
6668 run_test 56j "check lfs find -type d"
6669
6670 test_56k() {
6671         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6672
6673         setup_56_special $dir $NUMFILES $NUMDIRS
6674
6675         local expected=$(((NUMDIRS + 1) * NUMFILES))
6676         local cmd="$LFS find -type f $dir"
6677         local nums=$($cmd | wc -l)
6678
6679         [ $nums -eq $expected ] ||
6680                 error "'$cmd' wrong: found $nums, expected $expected"
6681 }
6682 run_test 56k "check lfs find -type f"
6683
6684 test_56l() {
6685         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6686
6687         setup_56_special $dir $NUMFILES $NUMDIRS
6688
6689         local expected=$((NUMDIRS + NUMFILES))
6690         local cmd="$LFS find -type b $dir"
6691         local nums=$($cmd | wc -l)
6692
6693         [ $nums -eq $expected ] ||
6694                 error "'$cmd' wrong: found $nums, expected $expected"
6695 }
6696 run_test 56l "check lfs find -type b"
6697
6698 test_56m() {
6699         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6700
6701         setup_56_special $dir $NUMFILES $NUMDIRS
6702
6703         local expected=$((NUMDIRS + NUMFILES))
6704         local cmd="$LFS find -type c $dir"
6705         local nums=$($cmd | wc -l)
6706         [ $nums -eq $expected ] ||
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708 }
6709 run_test 56m "check lfs find -type c"
6710
6711 test_56n() {
6712         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6713         setup_56_special $dir $NUMFILES $NUMDIRS
6714
6715         local expected=$((NUMDIRS + NUMFILES))
6716         local cmd="$LFS find -type l $dir"
6717         local nums=$($cmd | wc -l)
6718
6719         [ $nums -eq $expected ] ||
6720                 error "'$cmd' wrong: found $nums, expected $expected"
6721 }
6722 run_test 56n "check lfs find -type l"
6723
6724 test_56o() {
6725         local dir=$DIR/$tdir
6726
6727         setup_56 $dir $NUMFILES $NUMDIRS
6728         utime $dir/file1 > /dev/null || error "utime (1)"
6729         utime $dir/file2 > /dev/null || error "utime (2)"
6730         utime $dir/dir1 > /dev/null || error "utime (3)"
6731         utime $dir/dir2 > /dev/null || error "utime (4)"
6732         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6733         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6734
6735         local expected=4
6736         local nums=$($LFS find -mtime +0 $dir | wc -l)
6737
6738         [ $nums -eq $expected ] ||
6739                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6740
6741         expected=12
6742         cmd="$LFS find -mtime 0 $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746 }
6747 run_test 56o "check lfs find -mtime for old files"
6748
6749 test_56ob() {
6750         local dir=$DIR/$tdir
6751         local expected=1
6752         local count=0
6753
6754         # just to make sure there is something that won't be found
6755         test_mkdir $dir
6756         touch $dir/$tfile.now
6757
6758         for age in year week day hour min; do
6759                 count=$((count + 1))
6760
6761                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6762                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6763                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6764
6765                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6766                 local nums=$($cmd | wc -l)
6767                 [ $nums -eq $expected ] ||
6768                         error "'$cmd' wrong: found $nums, expected $expected"
6769
6770                 cmd="$LFS find $dir -atime $count${age:0:1}"
6771                 nums=$($cmd | wc -l)
6772                 [ $nums -eq $expected ] ||
6773                         error "'$cmd' wrong: found $nums, expected $expected"
6774         done
6775
6776         sleep 2
6777         cmd="$LFS find $dir -ctime +1s -type f"
6778         nums=$($cmd | wc -l)
6779         (( $nums == $count * 2 + 1)) ||
6780                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6781 }
6782 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6783
6784 test_newerXY_base() {
6785         local x=$1
6786         local y=$2
6787         local dir=$DIR/$tdir
6788         local ref
6789         local negref
6790
6791         if [ $y == "t" ]; then
6792                 if [ $x == "b" ]; then
6793                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6794                 else
6795                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6796                 fi
6797         else
6798                 ref=$DIR/$tfile.newer.$x$y
6799                 touch $ref || error "touch $ref failed"
6800         fi
6801
6802         echo "before = $ref"
6803         sleep 2
6804         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6805         sleep 2
6806         if [ $y == "t" ]; then
6807                 if [ $x == "b" ]; then
6808                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6809                 else
6810                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6811                 fi
6812         else
6813                 negref=$DIR/$tfile.negnewer.$x$y
6814                 touch $negref || error "touch $negref failed"
6815         fi
6816
6817         echo "after = $negref"
6818         local cmd="$LFS find $dir -newer$x$y $ref"
6819         local nums=$(eval $cmd | wc -l)
6820         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6821
6822         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6823                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6824
6825         cmd="$LFS find $dir ! -newer$x$y $negref"
6826         nums=$(eval $cmd | wc -l)
6827         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6828                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6829
6830         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6831         nums=$(eval $cmd | wc -l)
6832         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6833                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6834
6835         rm -rf $DIR/*
6836 }
6837
6838 test_56oc() {
6839         test_newerXY_base "a" "a"
6840         test_newerXY_base "a" "m"
6841         test_newerXY_base "a" "c"
6842         test_newerXY_base "m" "a"
6843         test_newerXY_base "m" "m"
6844         test_newerXY_base "m" "c"
6845         test_newerXY_base "c" "a"
6846         test_newerXY_base "c" "m"
6847         test_newerXY_base "c" "c"
6848
6849         test_newerXY_base "a" "t"
6850         test_newerXY_base "m" "t"
6851         test_newerXY_base "c" "t"
6852
6853         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6854            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6855                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6856
6857         test_newerXY_base "b" "b"
6858         test_newerXY_base "b" "t"
6859 }
6860 run_test 56oc "check lfs find -newerXY work"
6861
6862 test_56od() {
6863         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6864                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6865
6866         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6867                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6868
6869         local dir=$DIR/$tdir
6870         local ref=$DIR/$tfile.ref
6871         local negref=$DIR/$tfile.negref
6872
6873         mkdir $dir || error "mkdir $dir failed"
6874         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6875         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6876         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6877         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6878         touch $ref || error "touch $ref failed"
6879         # sleep 3 seconds at least
6880         sleep 3
6881
6882         local before=$(do_facet mds1 date +%s)
6883         local skew=$(($(date +%s) - before + 1))
6884
6885         if (( skew < 0 && skew > -5 )); then
6886                 sleep $((0 - skew + 1))
6887                 skew=0
6888         fi
6889
6890         # Set the dir stripe params to limit files all on MDT0,
6891         # otherwise we need to calc the max clock skew between
6892         # the client and MDTs.
6893         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6894         sleep 2
6895         touch $negref || error "touch $negref failed"
6896
6897         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6898         local nums=$($cmd | wc -l)
6899         local expected=$(((NUMFILES + 1) * NUMDIRS))
6900
6901         [ $nums -eq $expected ] ||
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903
6904         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6905         nums=$($cmd | wc -l)
6906         expected=$((NUMFILES + 1))
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         [ $skew -lt 0 ] && return
6911
6912         local after=$(do_facet mds1 date +%s)
6913         local age=$((after - before + 1 + skew))
6914
6915         cmd="$LFS find $dir -btime -${age}s -type f"
6916         nums=$($cmd | wc -l)
6917         expected=$(((NUMFILES + 1) * NUMDIRS))
6918
6919         echo "Clock skew between client and server: $skew, age:$age"
6920         [ $nums -eq $expected ] ||
6921                 error "'$cmd' wrong: found $nums, expected $expected"
6922
6923         expected=$(($NUMDIRS + 1))
6924         cmd="$LFS find $dir -btime -${age}s -type d"
6925         nums=$($cmd | wc -l)
6926         [ $nums -eq $expected ] ||
6927                 error "'$cmd' wrong: found $nums, expected $expected"
6928         rm -f $ref $negref || error "Failed to remove $ref $negref"
6929 }
6930 run_test 56od "check lfs find -btime with units"
6931
6932 test_56p() {
6933         [ $RUNAS_ID -eq $UID ] &&
6934                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6935
6936         local dir=$DIR/$tdir
6937
6938         setup_56 $dir $NUMFILES $NUMDIRS
6939         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6940
6941         local expected=$NUMFILES
6942         local cmd="$LFS find -uid $RUNAS_ID $dir"
6943         local nums=$($cmd | wc -l)
6944
6945         [ $nums -eq $expected ] ||
6946                 error "'$cmd' wrong: found $nums, expected $expected"
6947
6948         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6949         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6950         nums=$($cmd | wc -l)
6951         [ $nums -eq $expected ] ||
6952                 error "'$cmd' wrong: found $nums, expected $expected"
6953 }
6954 run_test 56p "check lfs find -uid and ! -uid"
6955
6956 test_56q() {
6957         [ $RUNAS_ID -eq $UID ] &&
6958                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6959
6960         local dir=$DIR/$tdir
6961
6962         setup_56 $dir $NUMFILES $NUMDIRS
6963         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6964
6965         local expected=$NUMFILES
6966         local cmd="$LFS find -gid $RUNAS_GID $dir"
6967         local nums=$($cmd | wc -l)
6968
6969         [ $nums -eq $expected ] ||
6970                 error "'$cmd' wrong: found $nums, expected $expected"
6971
6972         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6973         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6974         nums=$($cmd | wc -l)
6975         [ $nums -eq $expected ] ||
6976                 error "'$cmd' wrong: found $nums, expected $expected"
6977 }
6978 run_test 56q "check lfs find -gid and ! -gid"
6979
6980 test_56r() {
6981         local dir=$DIR/$tdir
6982
6983         setup_56 $dir $NUMFILES $NUMDIRS
6984
6985         local expected=12
6986         local cmd="$LFS find -size 0 -type f -lazy $dir"
6987         local nums=$($cmd | wc -l)
6988
6989         [ $nums -eq $expected ] ||
6990                 error "'$cmd' wrong: found $nums, expected $expected"
6991         cmd="$LFS find -size 0 -type f $dir"
6992         nums=$($cmd | wc -l)
6993         [ $nums -eq $expected ] ||
6994                 error "'$cmd' wrong: found $nums, expected $expected"
6995
6996         expected=0
6997         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6998         nums=$($cmd | wc -l)
6999         [ $nums -eq $expected ] ||
7000                 error "'$cmd' wrong: found $nums, expected $expected"
7001         cmd="$LFS find ! -size 0 -type f $dir"
7002         nums=$($cmd | wc -l)
7003         [ $nums -eq $expected ] ||
7004                 error "'$cmd' wrong: found $nums, expected $expected"
7005
7006         echo "test" > $dir/$tfile
7007         echo "test2" > $dir/$tfile.2 && sync
7008         expected=1
7009         cmd="$LFS find -size 5 -type f -lazy $dir"
7010         nums=$($cmd | wc -l)
7011         [ $nums -eq $expected ] ||
7012                 error "'$cmd' wrong: found $nums, expected $expected"
7013         cmd="$LFS find -size 5 -type f $dir"
7014         nums=$($cmd | wc -l)
7015         [ $nums -eq $expected ] ||
7016                 error "'$cmd' wrong: found $nums, expected $expected"
7017
7018         expected=1
7019         cmd="$LFS find -size +5 -type f -lazy $dir"
7020         nums=$($cmd | wc -l)
7021         [ $nums -eq $expected ] ||
7022                 error "'$cmd' wrong: found $nums, expected $expected"
7023         cmd="$LFS find -size +5 -type f $dir"
7024         nums=$($cmd | wc -l)
7025         [ $nums -eq $expected ] ||
7026                 error "'$cmd' wrong: found $nums, expected $expected"
7027
7028         expected=2
7029         cmd="$LFS find -size +0 -type f -lazy $dir"
7030         nums=$($cmd | wc -l)
7031         [ $nums -eq $expected ] ||
7032                 error "'$cmd' wrong: found $nums, expected $expected"
7033         cmd="$LFS find -size +0 -type f $dir"
7034         nums=$($cmd | wc -l)
7035         [ $nums -eq $expected ] ||
7036                 error "'$cmd' wrong: found $nums, expected $expected"
7037
7038         expected=2
7039         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7040         nums=$($cmd | wc -l)
7041         [ $nums -eq $expected ] ||
7042                 error "'$cmd' wrong: found $nums, expected $expected"
7043         cmd="$LFS find ! -size -5 -type f $dir"
7044         nums=$($cmd | wc -l)
7045         [ $nums -eq $expected ] ||
7046                 error "'$cmd' wrong: found $nums, expected $expected"
7047
7048         expected=12
7049         cmd="$LFS find -size -5 -type f -lazy $dir"
7050         nums=$($cmd | wc -l)
7051         [ $nums -eq $expected ] ||
7052                 error "'$cmd' wrong: found $nums, expected $expected"
7053         cmd="$LFS find -size -5 -type f $dir"
7054         nums=$($cmd | wc -l)
7055         [ $nums -eq $expected ] ||
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057 }
7058 run_test 56r "check lfs find -size works"
7059
7060 test_56ra_sub() {
7061         local expected=$1
7062         local glimpses=$2
7063         local cmd="$3"
7064
7065         cancel_lru_locks $OSC
7066
7067         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7068         local nums=$($cmd | wc -l)
7069
7070         [ $nums -eq $expected ] ||
7071                 error "'$cmd' wrong: found $nums, expected $expected"
7072
7073         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7074
7075         if (( rpcs_before + glimpses != rpcs_after )); then
7076                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7077                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7078
7079                 if [[ $glimpses == 0 ]]; then
7080                         error "'$cmd' should not send glimpse RPCs to OST"
7081                 else
7082                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7083                 fi
7084         fi
7085 }
7086
7087 test_56ra() {
7088         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7089                 skip "MDS < 2.12.58 doesn't return LSOM data"
7090         local dir=$DIR/$tdir
7091         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7092
7093         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7094
7095         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7096         $LCTL set_param -n llite.*.statahead_agl=0
7097         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7098
7099         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7100         # open and close all files to ensure LSOM is updated
7101         cancel_lru_locks $OSC
7102         find $dir -type f | xargs cat > /dev/null
7103
7104         #   expect_found  glimpse_rpcs  command_to_run
7105         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7106         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7107         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7108         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7109
7110         echo "test" > $dir/$tfile
7111         echo "test2" > $dir/$tfile.2 && sync
7112         cancel_lru_locks $OSC
7113         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7114
7115         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7116         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7117         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7118         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7119
7120         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7121         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7122         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7123         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7124         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7125         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7126 }
7127 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7128
7129 test_56rb() {
7130         local dir=$DIR/$tdir
7131         local tmp=$TMP/$tfile.log
7132         local mdt_idx;
7133
7134         test_mkdir -p $dir || error "failed to mkdir $dir"
7135         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7136                 error "failed to setstripe $dir/$tfile"
7137         mdt_idx=$($LFS getdirstripe -i $dir)
7138         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7139
7140         stack_trap "rm -f $tmp" EXIT
7141         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7142         ! grep -q obd_uuid $tmp ||
7143                 error "failed to find --size +100K --ost 0 $dir"
7144         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7145         ! grep -q obd_uuid $tmp ||
7146                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7147 }
7148 run_test 56rb "check lfs find --size --ost/--mdt works"
7149
7150 test_56rc() {
7151         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7152         local dir=$DIR/$tdir
7153         local found
7154
7155         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7156         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7157         (( $MDSCOUNT > 2 )) &&
7158                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7159         mkdir $dir/$tdir-{1..10}
7160         touch $dir/$tfile-{1..10}
7161
7162         found=$($LFS find $dir --mdt-count 2 | wc -l)
7163         expect=11
7164         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7165
7166         found=$($LFS find $dir -T +1 | wc -l)
7167         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7168         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7169
7170         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7171         expect=11
7172         (( $found == $expect )) || error "found $found all_char, expect $expect"
7173
7174         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7175         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7176         (( $found == $expect )) || error "found $found all_char, expect $expect"
7177 }
7178 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7179
7180 test_56rd() {
7181         local dir=$DIR/$tdir
7182
7183         test_mkdir $dir
7184         rm -f $dir/*
7185
7186         mkfifo $dir/fifo || error "failed to create fifo file"
7187         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7188                 error "should not fail even cannot get projid from pipe file"
7189         found=$($LFS find $dir -t p --printf "%y")
7190         [[ "p" == $found ]] || error "found $found, expect p"
7191
7192         mknod $dir/chardev c 1 5 ||
7193                 error "failed to create character device file"
7194         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7195                 error "should not fail even cannot get projid from chardev file"
7196         found=$($LFS find $dir -t c --printf "%y")
7197         [[ "c" == $found ]] || error "found $found, expect c"
7198
7199         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7200         (( found == 2 )) || error "unable to list all files"
7201 }
7202 run_test 56rd "check lfs find --printf special files"
7203
7204 test_56s() { # LU-611 #LU-9369
7205         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7206
7207         local dir=$DIR/$tdir
7208         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7209
7210         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7211         for i in $(seq $NUMDIRS); do
7212                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7213         done
7214
7215         local expected=$NUMDIRS
7216         local cmd="$LFS find -c $OSTCOUNT $dir"
7217         local nums=$($cmd | wc -l)
7218
7219         [ $nums -eq $expected ] || {
7220                 $LFS getstripe -R $dir
7221                 error "'$cmd' wrong: found $nums, expected $expected"
7222         }
7223
7224         expected=$((NUMDIRS + onestripe))
7225         cmd="$LFS find -stripe-count +0 -type f $dir"
7226         nums=$($cmd | wc -l)
7227         [ $nums -eq $expected ] || {
7228                 $LFS getstripe -R $dir
7229                 error "'$cmd' wrong: found $nums, expected $expected"
7230         }
7231
7232         expected=$onestripe
7233         cmd="$LFS find -stripe-count 1 -type f $dir"
7234         nums=$($cmd | wc -l)
7235         [ $nums -eq $expected ] || {
7236                 $LFS getstripe -R $dir
7237                 error "'$cmd' wrong: found $nums, expected $expected"
7238         }
7239
7240         cmd="$LFS find -stripe-count -2 -type f $dir"
7241         nums=$($cmd | wc -l)
7242         [ $nums -eq $expected ] || {
7243                 $LFS getstripe -R $dir
7244                 error "'$cmd' wrong: found $nums, expected $expected"
7245         }
7246
7247         expected=0
7248         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7249         nums=$($cmd | wc -l)
7250         [ $nums -eq $expected ] || {
7251                 $LFS getstripe -R $dir
7252                 error "'$cmd' wrong: found $nums, expected $expected"
7253         }
7254 }
7255 run_test 56s "check lfs find -stripe-count works"
7256
7257 test_56t() { # LU-611 #LU-9369
7258         local dir=$DIR/$tdir
7259
7260         setup_56 $dir 0 $NUMDIRS
7261         for i in $(seq $NUMDIRS); do
7262                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7263         done
7264
7265         local expected=$NUMDIRS
7266         local cmd="$LFS find -S 8M $dir"
7267         local nums=$($cmd | wc -l)
7268
7269         [ $nums -eq $expected ] || {
7270                 $LFS getstripe -R $dir
7271                 error "'$cmd' wrong: found $nums, expected $expected"
7272         }
7273         rm -rf $dir
7274
7275         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7276
7277         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7278
7279         expected=$(((NUMDIRS + 1) * NUMFILES))
7280         cmd="$LFS find -stripe-size 512k -type f $dir"
7281         nums=$($cmd | wc -l)
7282         [ $nums -eq $expected ] ||
7283                 error "'$cmd' wrong: found $nums, expected $expected"
7284
7285         cmd="$LFS find -stripe-size +320k -type f $dir"
7286         nums=$($cmd | wc -l)
7287         [ $nums -eq $expected ] ||
7288                 error "'$cmd' wrong: found $nums, expected $expected"
7289
7290         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7291         cmd="$LFS find -stripe-size +200k -type f $dir"
7292         nums=$($cmd | wc -l)
7293         [ $nums -eq $expected ] ||
7294                 error "'$cmd' wrong: found $nums, expected $expected"
7295
7296         cmd="$LFS find -stripe-size -640k -type f $dir"
7297         nums=$($cmd | wc -l)
7298         [ $nums -eq $expected ] ||
7299                 error "'$cmd' wrong: found $nums, expected $expected"
7300
7301         expected=4
7302         cmd="$LFS find -stripe-size 256k -type f $dir"
7303         nums=$($cmd | wc -l)
7304         [ $nums -eq $expected ] ||
7305                 error "'$cmd' wrong: found $nums, expected $expected"
7306
7307         cmd="$LFS find -stripe-size -320k -type f $dir"
7308         nums=$($cmd | wc -l)
7309         [ $nums -eq $expected ] ||
7310                 error "'$cmd' wrong: found $nums, expected $expected"
7311
7312         expected=0
7313         cmd="$LFS find -stripe-size 1024k -type f $dir"
7314         nums=$($cmd | wc -l)
7315         [ $nums -eq $expected ] ||
7316                 error "'$cmd' wrong: found $nums, expected $expected"
7317 }
7318 run_test 56t "check lfs find -stripe-size works"
7319
7320 test_56u() { # LU-611
7321         local dir=$DIR/$tdir
7322
7323         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7324
7325         if [[ $OSTCOUNT -gt 1 ]]; then
7326                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7327                 onestripe=4
7328         else
7329                 onestripe=0
7330         fi
7331
7332         local expected=$(((NUMDIRS + 1) * NUMFILES))
7333         local cmd="$LFS find -stripe-index 0 -type f $dir"
7334         local nums=$($cmd | wc -l)
7335
7336         [ $nums -eq $expected ] ||
7337                 error "'$cmd' wrong: found $nums, expected $expected"
7338
7339         expected=$onestripe
7340         cmd="$LFS find -stripe-index 1 -type f $dir"
7341         nums=$($cmd | wc -l)
7342         [ $nums -eq $expected ] ||
7343                 error "'$cmd' wrong: found $nums, expected $expected"
7344
7345         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7346         nums=$($cmd | wc -l)
7347         [ $nums -eq $expected ] ||
7348                 error "'$cmd' wrong: found $nums, expected $expected"
7349
7350         expected=0
7351         # This should produce an error and not return any files
7352         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7353         nums=$($cmd 2>/dev/null | wc -l)
7354         [ $nums -eq $expected ] ||
7355                 error "'$cmd' wrong: found $nums, expected $expected"
7356
7357         if [[ $OSTCOUNT -gt 1 ]]; then
7358                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7359                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7360                 nums=$($cmd | wc -l)
7361                 [ $nums -eq $expected ] ||
7362                         error "'$cmd' wrong: found $nums, expected $expected"
7363         fi
7364 }
7365 run_test 56u "check lfs find -stripe-index works"
7366
7367 test_56v() {
7368         local mdt_idx=0
7369         local dir=$DIR/$tdir
7370
7371         setup_56 $dir $NUMFILES $NUMDIRS
7372
7373         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7374         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7375
7376         for file in $($LFS find -m $UUID $dir); do
7377                 file_midx=$($LFS getstripe -m $file)
7378                 [ $file_midx -eq $mdt_idx ] ||
7379                         error "lfs find -m $UUID != getstripe -m $file_midx"
7380         done
7381 }
7382 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7383
7384 test_56wa() {
7385         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7387
7388         local dir=$DIR/$tdir
7389
7390         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7391         stack_trap "rm -rf $dir"
7392
7393         local stripe_size=$($LFS getstripe -S -d $dir) ||
7394                 error "$LFS getstripe -S -d $dir failed"
7395         stripe_size=${stripe_size%% *}
7396
7397         local file_size=$((stripe_size * OSTCOUNT))
7398         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7399         local required_space=$((file_num * file_size))
7400         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7401                            head -n1)
7402         (( free_space >= required_space / 1024 )) ||
7403                 skip_env "need $required_space, have $free_space kbytes"
7404
7405         local dd_bs=65536
7406         local dd_count=$((file_size / dd_bs))
7407
7408         # write data into the files
7409         local i
7410         local j
7411         local file
7412
7413         for ((i = 1; i <= NUMFILES; i++ )); do
7414                 file=$dir/file$i
7415                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7416                         error "write data into $file failed"
7417         done
7418         for ((i = 1; i <= NUMDIRS; i++ )); do
7419                 for ((j = 1; j <= NUMFILES; j++ )); do
7420                         file=$dir/dir$i/file$j
7421                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7422                                 error "write data into $file failed"
7423                 done
7424         done
7425
7426         # $LFS_MIGRATE will fail if hard link migration is unsupported
7427         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7428                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7429                         error "creating links to $dir/dir1/file1 failed"
7430         fi
7431
7432         local expected=-1
7433
7434         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7435
7436         # lfs_migrate file
7437         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7438
7439         echo "$cmd"
7440         eval $cmd || error "$cmd failed"
7441
7442         check_stripe_count $dir/file1 $expected
7443
7444         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7445                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7446                 # OST 1 if it is on OST 0. This file is small enough to
7447                 # be on only one stripe.
7448                 file=$dir/migr_1_ost
7449                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7450                         error "write data into $file failed"
7451                 local obdidx=$($LFS getstripe -i $file)
7452                 local oldmd5=$(md5sum $file)
7453                 local newobdidx=0
7454
7455                 (( obdidx != 0 )) || newobdidx=1
7456                 cmd="$LFS migrate -i $newobdidx $file"
7457                 echo $cmd
7458                 eval $cmd || error "$cmd failed"
7459
7460                 local realobdix=$($LFS getstripe -i $file)
7461                 local newmd5=$(md5sum $file)
7462
7463                 (( $newobdidx == $realobdix )) ||
7464                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7465                 [[ "$oldmd5" == "$newmd5" ]] ||
7466                         error "md5sum differ: $oldmd5, $newmd5"
7467         fi
7468
7469         # lfs_migrate dir
7470         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7471         echo "$cmd"
7472         eval $cmd || error "$cmd failed"
7473
7474         for (( j = 1; j <= NUMFILES; j++ )); do
7475                 check_stripe_count $dir/dir1/file$j $expected
7476         done
7477
7478         # lfs_migrate works with lfs find
7479         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7480              $LFS_MIGRATE -y -c $expected"
7481         echo "$cmd"
7482         eval $cmd || error "$cmd failed"
7483
7484         for (( i = 2; i <= NUMFILES; i++ )); do
7485                 check_stripe_count $dir/file$i $expected
7486         done
7487         for (( i = 2; i <= NUMDIRS; i++ )); do
7488                 for (( j = 1; j <= NUMFILES; j++ )); do
7489                         check_stripe_count $dir/dir$i/file$j $expected
7490                 done
7491         done
7492 }
7493 run_test 56wa "check lfs_migrate -c stripe_count works"
7494
7495 test_56wb() {
7496         local file1=$DIR/$tdir/file1
7497         local create_pool=false
7498         local initial_pool=$($LFS getstripe -p $DIR)
7499         local pool_list=()
7500         local pool=""
7501
7502         echo -n "Creating test dir..."
7503         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7504         echo "done."
7505
7506         echo -n "Creating test file..."
7507         touch $file1 || error "cannot create file"
7508         echo "done."
7509
7510         echo -n "Detecting existing pools..."
7511         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7512
7513         if [ ${#pool_list[@]} -gt 0 ]; then
7514                 echo "${pool_list[@]}"
7515                 for thispool in "${pool_list[@]}"; do
7516                         if [[ -z "$initial_pool" ||
7517                               "$initial_pool" != "$thispool" ]]; then
7518                                 pool="$thispool"
7519                                 echo "Using existing pool '$pool'"
7520                                 break
7521                         fi
7522                 done
7523         else
7524                 echo "none detected."
7525         fi
7526         if [ -z "$pool" ]; then
7527                 pool=${POOL:-testpool}
7528                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7529                 echo -n "Creating pool '$pool'..."
7530                 create_pool=true
7531                 pool_add $pool &> /dev/null ||
7532                         error "pool_add failed"
7533                 echo "done."
7534
7535                 echo -n "Adding target to pool..."
7536                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7537                         error "pool_add_targets failed"
7538                 echo "done."
7539         fi
7540
7541         echo -n "Setting pool using -p option..."
7542         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7543                 error "migrate failed rc = $?"
7544         echo "done."
7545
7546         echo -n "Verifying test file is in pool after migrating..."
7547         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7548                 error "file was not migrated to pool $pool"
7549         echo "done."
7550
7551         echo -n "Removing test file from pool '$pool'..."
7552         # "lfs migrate $file" won't remove the file from the pool
7553         # until some striping information is changed.
7554         $LFS migrate -c 1 $file1 &> /dev/null ||
7555                 error "cannot remove from pool"
7556         [ "$($LFS getstripe -p $file1)" ] &&
7557                 error "pool still set"
7558         echo "done."
7559
7560         echo -n "Setting pool using --pool option..."
7561         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7562                 error "migrate failed rc = $?"
7563         echo "done."
7564
7565         # Clean up
7566         rm -f $file1
7567         if $create_pool; then
7568                 destroy_test_pools 2> /dev/null ||
7569                         error "destroy test pools failed"
7570         fi
7571 }
7572 run_test 56wb "check lfs_migrate pool support"
7573
7574 test_56wc() {
7575         local file1="$DIR/$tdir/$tfile"
7576         local md5
7577         local parent_ssize
7578         local parent_scount
7579         local cur_ssize
7580         local cur_scount
7581         local orig_ssize
7582         local new_scount
7583         local cur_comp
7584
7585         echo -n "Creating test dir..."
7586         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7587         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7588                 error "cannot set stripe by '-S 1M -c 1'"
7589         echo "done"
7590
7591         echo -n "Setting initial stripe for test file..."
7592         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7593                 error "cannot set stripe"
7594         cur_ssize=$($LFS getstripe -S "$file1")
7595         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7596         echo "done."
7597
7598         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7599         stack_trap "rm -f $file1"
7600         md5="$(md5sum $file1)"
7601
7602         # File currently set to -S 512K -c 1
7603
7604         # Ensure -c and -S options are rejected when -R is set
7605         echo -n "Verifying incompatible options are detected..."
7606         $LFS_MIGRATE -R -c 1 "$file1" &&
7607                 error "incompatible -R and -c options not detected"
7608         $LFS_MIGRATE -R -S 1M "$file1" &&
7609                 error "incompatible -R and -S options not detected"
7610         $LFS_MIGRATE -R -p pool "$file1" &&
7611                 error "incompatible -R and -p options not detected"
7612         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7613                 error "incompatible -R and -E options not detected"
7614         $LFS_MIGRATE -R -A "$file1" &&
7615                 error "incompatible -R and -A options not detected"
7616         $LFS_MIGRATE -A -c 1 "$file1" &&
7617                 error "incompatible -A and -c options not detected"
7618         $LFS_MIGRATE -A -S 1M "$file1" &&
7619                 error "incompatible -A and -S options not detected"
7620         $LFS_MIGRATE -A -p pool "$file1" &&
7621                 error "incompatible -A and -p options not detected"
7622         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7623                 error "incompatible -A and -E options not detected"
7624         echo "done."
7625
7626         # Ensure unrecognized options are passed through to 'lfs migrate'
7627         echo -n "Verifying -S option is passed through to lfs migrate..."
7628         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7629         cur_ssize=$($LFS getstripe -S "$file1")
7630         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7631         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7632         echo "done."
7633
7634         # File currently set to -S 1M -c 1
7635
7636         # Ensure long options are supported
7637         echo -n "Verifying long options supported..."
7638         $LFS_MIGRATE --non-block "$file1" ||
7639                 error "long option without argument not supported"
7640         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7641                 error "long option with argument not supported"
7642         cur_ssize=$($LFS getstripe -S "$file1")
7643         (( cur_ssize == 524288 )) ||
7644                 error "migrate --stripe-size $cur_ssize != 524288"
7645         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7646         echo "done."
7647
7648         # File currently set to -S 512K -c 1
7649
7650         if (( OSTCOUNT > 1 )); then
7651                 echo -n "Verifying explicit stripe count can be set..."
7652                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7653                 cur_scount=$($LFS getstripe -c "$file1")
7654                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7655                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7656                         error "file data has changed (3)"
7657                 echo "done."
7658         fi
7659
7660         # File currently set to -S 512K -c 1 or -S 512K -c 2
7661
7662         # Ensure parent striping is used if -R is set, and no stripe
7663         # count or size is specified
7664         echo -n "Setting stripe for parent directory..."
7665         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7666                 error "cannot set stripe '-S 2M -c 1'"
7667         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7668         echo "done."
7669
7670         echo -n "Verifying restripe option uses parent stripe settings..."
7671         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7672         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7673         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7674         cur_ssize=$($LFS getstripe -S "$file1")
7675         (( cur_ssize == parent_ssize )) ||
7676                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7677         cur_scount=$($LFS getstripe -c "$file1")
7678         (( cur_scount == parent_scount )) ||
7679                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7680         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7681         echo "done."
7682
7683         # File currently set to -S 1M -c 1
7684
7685         # Ensure striping is preserved if -R is not set, and no stripe
7686         # count or size is specified
7687         echo -n "Verifying striping size preserved when not specified..."
7688         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7689         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7690                 error "cannot set stripe on parent directory"
7691         $LFS_MIGRATE "$file1" || error "migrate failed"
7692         cur_ssize=$($LFS getstripe -S "$file1")
7693         (( cur_ssize == orig_ssize )) ||
7694                 error "migrate by default $cur_ssize != $orig_ssize"
7695         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7696         echo "done."
7697
7698         # Ensure file name properly detected when final option has no argument
7699         echo -n "Verifying file name properly detected..."
7700         $LFS_MIGRATE "$file1" ||
7701                 error "file name interpreted as option argument"
7702         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7703         echo "done."
7704
7705         # Ensure PFL arguments are passed through properly
7706         echo -n "Verifying PFL options passed through..."
7707         new_scount=$(((OSTCOUNT + 1) / 2))
7708         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7709                 error "migrate PFL arguments failed"
7710         cur_comp=$($LFS getstripe --comp-count $file1)
7711         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7712         cur_scount=$($LFS getstripe --stripe-count $file1)
7713         (( cur_scount == new_scount)) ||
7714                 error "PFL stripe count $cur_scount != $new_scount"
7715         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7716         echo "done."
7717 }
7718 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7719
7720 test_56wd() {
7721         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7722
7723         local file1=$DIR/$tdir/$tfile
7724
7725         echo -n "Creating test dir..."
7726         test_mkdir $DIR/$tdir || error "cannot create dir"
7727         echo "done."
7728
7729         echo -n "Creating test file..."
7730         echo "$tfile" > $file1
7731         echo "done."
7732
7733         # Ensure 'lfs migrate' will fail by using a non-existent option,
7734         # and make sure rsync is not called to recover
7735         echo -n "Make sure --no-rsync option works..."
7736         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7737                 grep -q 'refusing to fall back to rsync' ||
7738                 error "rsync was called with --no-rsync set"
7739         echo "done."
7740
7741         # Ensure rsync is called without trying 'lfs migrate' first
7742         echo -n "Make sure --rsync option works..."
7743         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7744                 grep -q 'falling back to rsync' &&
7745                 error "lfs migrate was called with --rsync set"
7746         echo "done."
7747 }
7748 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7749
7750 test_56we() {
7751         local td=$DIR/$tdir
7752         local tf=$td/$tfile
7753
7754         test_mkdir $td || error "cannot create $td"
7755         touch $tf || error "cannot touch $tf"
7756
7757         echo -n "Make sure --non-direct|-D works..."
7758         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7759                 grep -q "lfs migrate --non-direct" ||
7760                 error "--non-direct option cannot work correctly"
7761         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7762                 grep -q "lfs migrate -D" ||
7763                 error "-D option cannot work correctly"
7764         echo "done."
7765 }
7766 run_test 56we "check lfs_migrate --non-direct|-D support"
7767
7768 test_56x() {
7769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7770         check_swap_layouts_support
7771
7772         local dir=$DIR/$tdir
7773         local ref1=/etc/passwd
7774         local file1=$dir/file1
7775
7776         test_mkdir $dir || error "creating dir $dir"
7777         $LFS setstripe -c 2 $file1
7778         cp $ref1 $file1
7779         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7780         stripe=$($LFS getstripe -c $file1)
7781         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7782         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7783
7784         # clean up
7785         rm -f $file1
7786 }
7787 run_test 56x "lfs migration support"
7788
7789 test_56xa() {
7790         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7791         check_swap_layouts_support
7792
7793         local dir=$DIR/$tdir/$testnum
7794
7795         test_mkdir -p $dir
7796
7797         local ref1=/etc/passwd
7798         local file1=$dir/file1
7799
7800         $LFS setstripe -c 2 $file1
7801         cp $ref1 $file1
7802         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7803
7804         local stripe=$($LFS getstripe -c $file1)
7805
7806         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7807         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7808
7809         # clean up
7810         rm -f $file1
7811 }
7812 run_test 56xa "lfs migration --block support"
7813
7814 check_migrate_links() {
7815         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7816         local dir="$1"
7817         local file1="$dir/file1"
7818         local begin="$2"
7819         local count="$3"
7820         local runas="$4"
7821         local total_count=$(($begin + $count - 1))
7822         local symlink_count=10
7823         local uniq_count=10
7824
7825         if [ ! -f "$file1" ]; then
7826                 echo -n "creating initial file..."
7827                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7828                         error "cannot setstripe initial file"
7829                 echo "done"
7830
7831                 echo -n "creating symlinks..."
7832                 for s in $(seq 1 $symlink_count); do
7833                         ln -s "$file1" "$dir/slink$s" ||
7834                                 error "cannot create symlinks"
7835                 done
7836                 echo "done"
7837
7838                 echo -n "creating nonlinked files..."
7839                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7840                         error "cannot create nonlinked files"
7841                 echo "done"
7842         fi
7843
7844         # create hard links
7845         if [ ! -f "$dir/file$total_count" ]; then
7846                 echo -n "creating hard links $begin:$total_count..."
7847                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7848                         /dev/null || error "cannot create hard links"
7849                 echo "done"
7850         fi
7851
7852         echo -n "checking number of hard links listed in xattrs..."
7853         local fid=$($LFS getstripe -F "$file1")
7854         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7855
7856         echo "${#paths[*]}"
7857         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7858                         skip "hard link list has unexpected size, skipping test"
7859         fi
7860         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7861                         error "link names should exceed xattrs size"
7862         fi
7863
7864         echo -n "migrating files..."
7865         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7866         local rc=$?
7867         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7868         echo "done"
7869
7870         # make sure all links have been properly migrated
7871         echo -n "verifying files..."
7872         fid=$($LFS getstripe -F "$file1") ||
7873                 error "cannot get fid for file $file1"
7874         for i in $(seq 2 $total_count); do
7875                 local fid2=$($LFS getstripe -F $dir/file$i)
7876
7877                 [ "$fid2" == "$fid" ] ||
7878                         error "migrated hard link has mismatched FID"
7879         done
7880
7881         # make sure hard links were properly detected, and migration was
7882         # performed only once for the entire link set; nonlinked files should
7883         # also be migrated
7884         local actual=$(grep -c 'done' <<< "$migrate_out")
7885         local expected=$(($uniq_count + 1))
7886
7887         [ "$actual" -eq  "$expected" ] ||
7888                 error "hard links individually migrated ($actual != $expected)"
7889
7890         # make sure the correct number of hard links are present
7891         local hardlinks=$(stat -c '%h' "$file1")
7892
7893         [ $hardlinks -eq $total_count ] ||
7894                 error "num hard links $hardlinks != $total_count"
7895         echo "done"
7896
7897         return 0
7898 }
7899
7900 test_56xb() {
7901         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7902                 skip "Need MDS version at least 2.10.55"
7903
7904         local dir="$DIR/$tdir"
7905
7906         test_mkdir "$dir" || error "cannot create dir $dir"
7907
7908         echo "testing lfs migrate mode when all links fit within xattrs"
7909         check_migrate_links "$dir" 2 99
7910
7911         echo "testing rsync mode when all links fit within xattrs"
7912         check_migrate_links --rsync "$dir" 2 99
7913
7914         echo "testing lfs migrate mode when all links do not fit within xattrs"
7915         check_migrate_links "$dir" 101 100
7916
7917         echo "testing rsync mode when all links do not fit within xattrs"
7918         check_migrate_links --rsync "$dir" 101 100
7919
7920         chown -R $RUNAS_ID $dir
7921         echo "testing non-root lfs migrate mode when not all links are in xattr"
7922         check_migrate_links "$dir" 101 100 "$RUNAS"
7923
7924         # clean up
7925         rm -rf $dir
7926 }
7927 run_test 56xb "lfs migration hard link support"
7928
7929 test_56xc() {
7930         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7931
7932         local dir="$DIR/$tdir"
7933
7934         test_mkdir "$dir" || error "cannot create dir $dir"
7935
7936         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7937         echo -n "Setting initial stripe for 20MB test file..."
7938         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7939                 error "cannot setstripe 20MB file"
7940         echo "done"
7941         echo -n "Sizing 20MB test file..."
7942         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7943         echo "done"
7944         echo -n "Verifying small file autostripe count is 1..."
7945         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7946                 error "cannot migrate 20MB file"
7947         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7948                 error "cannot get stripe for $dir/20mb"
7949         [ $stripe_count -eq 1 ] ||
7950                 error "unexpected stripe count $stripe_count for 20MB file"
7951         rm -f "$dir/20mb"
7952         echo "done"
7953
7954         # Test 2: File is small enough to fit within the available space on
7955         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7956         # have at least an additional 1KB for each desired stripe for test 3
7957         echo -n "Setting stripe for 1GB test file..."
7958         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7959         echo "done"
7960         echo -n "Sizing 1GB test file..."
7961         # File size is 1GB + 3KB
7962         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7963         echo "done"
7964
7965         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7966         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7967         if (( avail > 524288 * OSTCOUNT )); then
7968                 echo -n "Migrating 1GB file..."
7969                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7970                         error "cannot migrate 1GB file"
7971                 echo "done"
7972                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7973                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7974                         error "cannot getstripe for 1GB file"
7975                 [ $stripe_count -eq 2 ] ||
7976                         error "unexpected stripe count $stripe_count != 2"
7977                 echo "done"
7978         fi
7979
7980         # Test 3: File is too large to fit within the available space on
7981         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7982         if [ $OSTCOUNT -ge 3 ]; then
7983                 # The required available space is calculated as
7984                 # file size (1GB + 3KB) / OST count (3).
7985                 local kb_per_ost=349526
7986
7987                 echo -n "Migrating 1GB file with limit..."
7988                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7989                         error "cannot migrate 1GB file with limit"
7990                 echo "done"
7991
7992                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7993                 echo -n "Verifying 1GB autostripe count with limited space..."
7994                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7995                         error "unexpected stripe count $stripe_count (min 3)"
7996                 echo "done"
7997         fi
7998
7999         # clean up
8000         rm -rf $dir
8001 }
8002 run_test 56xc "lfs migration autostripe"
8003
8004 test_56xd() {
8005         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8006
8007         local dir=$DIR/$tdir
8008         local f_mgrt=$dir/$tfile.mgrt
8009         local f_yaml=$dir/$tfile.yaml
8010         local f_copy=$dir/$tfile.copy
8011         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8012         local layout_copy="-c 2 -S 2M -i 1"
8013         local yamlfile=$dir/yamlfile
8014         local layout_before;
8015         local layout_after;
8016
8017         test_mkdir "$dir" || error "cannot create dir $dir"
8018         stack_trap "rm -rf $dir"
8019         $LFS setstripe $layout_yaml $f_yaml ||
8020                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8021         $LFS getstripe --yaml $f_yaml > $yamlfile
8022         $LFS setstripe $layout_copy $f_copy ||
8023                 error "cannot setstripe $f_copy with layout $layout_copy"
8024         touch $f_mgrt
8025         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8026
8027         # 1. test option --yaml
8028         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8029                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8030         layout_before=$(get_layout_param $f_yaml)
8031         layout_after=$(get_layout_param $f_mgrt)
8032         [ "$layout_after" == "$layout_before" ] ||
8033                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8034
8035         # 2. test option --copy
8036         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8037                 error "cannot migrate $f_mgrt with --copy $f_copy"
8038         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8039         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8040         [ "$layout_after" == "$layout_before" ] ||
8041                 error "lfs_migrate --copy: $layout_after != $layout_before"
8042 }
8043 run_test 56xd "check lfs_migrate --yaml and --copy support"
8044
8045 test_56xe() {
8046         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8047
8048         local dir=$DIR/$tdir
8049         local f_comp=$dir/$tfile
8050         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8051         local layout_before=""
8052         local layout_after=""
8053
8054         test_mkdir "$dir" || error "cannot create dir $dir"
8055         stack_trap "rm -rf $dir"
8056         $LFS setstripe $layout $f_comp ||
8057                 error "cannot setstripe $f_comp with layout $layout"
8058         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8059         dd if=/dev/zero of=$f_comp bs=1M count=4
8060
8061         # 1. migrate a comp layout file by lfs_migrate
8062         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8063         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8064         [ "$layout_before" == "$layout_after" ] ||
8065                 error "lfs_migrate: $layout_before != $layout_after"
8066
8067         # 2. migrate a comp layout file by lfs migrate
8068         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8069         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8070         [ "$layout_before" == "$layout_after" ] ||
8071                 error "lfs migrate: $layout_before != $layout_after"
8072 }
8073 run_test 56xe "migrate a composite layout file"
8074
8075 test_56xf() {
8076         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8077
8078         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8079                 skip "Need server version at least 2.13.53"
8080
8081         local dir=$DIR/$tdir
8082         local f_comp=$dir/$tfile
8083         local layout="-E 1M -c1 -E -1 -c2"
8084         local fid_before=""
8085         local fid_after=""
8086
8087         test_mkdir "$dir" || error "cannot create dir $dir"
8088         stack_trap "rm -rf $dir"
8089         $LFS setstripe $layout $f_comp ||
8090                 error "cannot setstripe $f_comp with layout $layout"
8091         fid_before=$($LFS getstripe --fid $f_comp)
8092         dd if=/dev/zero of=$f_comp bs=1M count=4
8093
8094         # 1. migrate a comp layout file to a comp layout
8095         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8096         fid_after=$($LFS getstripe --fid $f_comp)
8097         [ "$fid_before" == "$fid_after" ] ||
8098                 error "comp-to-comp migrate: $fid_before != $fid_after"
8099
8100         # 2. migrate a comp layout file to a plain layout
8101         $LFS migrate -c2 $f_comp ||
8102                 error "cannot migrate $f_comp by lfs migrate"
8103         fid_after=$($LFS getstripe --fid $f_comp)
8104         [ "$fid_before" == "$fid_after" ] ||
8105                 error "comp-to-plain migrate: $fid_before != $fid_after"
8106
8107         # 3. migrate a plain layout file to a comp layout
8108         $LFS migrate $layout $f_comp ||
8109                 error "cannot migrate $f_comp by lfs migrate"
8110         fid_after=$($LFS getstripe --fid $f_comp)
8111         [ "$fid_before" == "$fid_after" ] ||
8112                 error "plain-to-comp migrate: $fid_before != $fid_after"
8113 }
8114 run_test 56xf "FID is not lost during migration of a composite layout file"
8115
8116 check_file_ost_range() {
8117         local file="$1"
8118         shift
8119         local range="$*"
8120         local -a file_range
8121         local idx
8122
8123         file_range=($($LFS getstripe -y "$file" |
8124                 awk '/l_ost_idx:/ { print $NF }'))
8125
8126         if [[ "${#file_range[@]}" = 0 ]]; then
8127                 echo "No osts found for $file"
8128                 return 1
8129         fi
8130
8131         for idx in "${file_range[@]}"; do
8132                 [[ " $range " =~ " $idx " ]] ||
8133                         return 1
8134         done
8135
8136         return 0
8137 }
8138
8139 sub_test_56xg() {
8140         local stripe_opt="$1"
8141         local pool="$2"
8142         shift 2
8143         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8144
8145         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8146                 error "Fail to migrate $tfile on $pool"
8147         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8148                 error "$tfile is not in pool $pool"
8149         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8150                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8151 }
8152
8153 test_56xg() {
8154         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8155         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8156         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8157                 skip "Need MDS version newer than 2.14.52"
8158
8159         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8160         local -a pool_ranges=("0 0" "1 1" "0 1")
8161
8162         # init pools
8163         for i in "${!pool_names[@]}"; do
8164                 pool_add ${pool_names[$i]} ||
8165                         error "pool_add failed (pool: ${pool_names[$i]})"
8166                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8167                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8168         done
8169
8170         # init the file to migrate
8171         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8172                 error "Unable to create $tfile on OST1"
8173         stack_trap "rm -f $DIR/$tfile"
8174         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8175                 error "Unable to write on $tfile"
8176
8177         echo "1. migrate $tfile on pool ${pool_names[0]}"
8178         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8179
8180         echo "2. migrate $tfile on pool ${pool_names[2]}"
8181         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8182
8183         echo "3. migrate $tfile on pool ${pool_names[1]}"
8184         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8185
8186         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8187         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8188         echo
8189
8190         # Clean pools
8191         destroy_test_pools ||
8192                 error "pool_destroy failed"
8193 }
8194 run_test 56xg "lfs migrate pool support"
8195
8196 test_56xh() {
8197         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8198
8199         local size_mb=25
8200         local file1=$DIR/$tfile
8201         local tmp1=$TMP/$tfile.tmp
8202
8203         $LFS setstripe -c 2 $file1
8204
8205         stack_trap "rm -f $file1 $tmp1"
8206         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8207                         error "error creating $tmp1"
8208         ls -lsh $tmp1
8209         cp $tmp1 $file1
8210
8211         local start=$SECONDS
8212
8213         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8214                 error "migrate failed rc = $?"
8215
8216         local elapsed=$((SECONDS - start))
8217
8218         # with 1MB/s, elapsed should equal size_mb
8219         (( elapsed >= size_mb * 95 / 100 )) ||
8220                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8221
8222         (( elapsed <= size_mb * 120 / 100 )) ||
8223                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8224
8225         (( elapsed <= size_mb * 350 / 100 )) ||
8226                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8227
8228         stripe=$($LFS getstripe -c $file1)
8229         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8230         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8231
8232         # Clean up file (since it is multiple MB)
8233         rm -f $file1 $tmp1
8234 }
8235 run_test 56xh "lfs migrate bandwidth limitation support"
8236
8237 test_56xi() {
8238         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8239         verify_yaml_available || skip_env "YAML verification not installed"
8240
8241         local size_mb=5
8242         local file1=$DIR/$tfile.1
8243         local file2=$DIR/$tfile.2
8244         local file3=$DIR/$tfile.3
8245         local output_file=$DIR/$tfile.out
8246         local tmp1=$TMP/$tfile.tmp
8247
8248         $LFS setstripe -c 2 $file1
8249         $LFS setstripe -c 2 $file2
8250         $LFS setstripe -c 2 $file3
8251
8252         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8253         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8254                         error "error creating $tmp1"
8255         ls -lsh $tmp1
8256         cp $tmp1 $file1
8257         cp $tmp1 $file2
8258         cp $tmp1 $file3
8259
8260         $LFS migrate --stats --stats-interval=1 \
8261                 -c 1 $file1 $file2 $file3 1> $output_file ||
8262                 error "migrate failed rc = $?"
8263
8264         cat $output_file
8265         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8266
8267         # Clean up file (since it is multiple MB)
8268         rm -f $file1 $file2 $file3 $tmp1 $output_file
8269 }
8270 run_test 56xi "lfs migrate stats support"
8271
8272 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8273         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8274
8275         local file=$DIR/$tfile
8276         local linkdir=$DIR/$tdir
8277
8278         test_mkdir $linkdir || error "fail to create $linkdir"
8279         $LFS setstripe -i 0 -c 1 -S1M $file
8280         stack_trap "rm -rf $file $linkdir"
8281         dd if=/dev/urandom of=$file bs=1M count=10 ||
8282                 error "fail to create $file"
8283
8284         # Create file links
8285         local cpts
8286         local threads_max
8287         local nlinks
8288
8289         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8290         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8291         (( nlinks = thread_max * 3 / 2 / cpts))
8292
8293         echo "create $nlinks hard links of $file"
8294         createmany -l $file $linkdir/link $nlinks
8295
8296         # Parallel migrates (should not block)
8297         local i
8298         for ((i = 0; i < nlinks; i++)); do
8299                 echo $linkdir/link$i
8300         done | xargs -n1 -P $nlinks $LFS migrate -c2
8301
8302         local stripe_count
8303         stripe_count=$($LFS getstripe -c $file) ||
8304                 error "fail to get stripe count on $file"
8305
8306         ((stripe_count == 2)) ||
8307                 error "fail to migrate $file (stripe_count = $stripe_count)"
8308 }
8309 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8310
8311 test_56xk() {
8312         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8313
8314         local size_mb=5
8315         local file1=$DIR/$tfile
8316
8317         stack_trap "rm -f $file1"
8318         $LFS setstripe -c 1 $file1
8319         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8320                 error "error creating $file1"
8321         $LFS mirror extend -N $file1 || error "can't mirror"
8322         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8323                 error "can't dd"
8324         $LFS getstripe $file1 | grep stale ||
8325                 error "one component must be stale"
8326
8327         local start=$SECONDS
8328         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8329                 error "migrate failed rc = $?"
8330         local elapsed=$((SECONDS - start))
8331         $LFS getstripe $file1 | grep stale &&
8332                 error "all components must be sync"
8333
8334         # with 1MB/s, elapsed should equal size_mb
8335         (( elapsed >= size_mb * 95 / 100 )) ||
8336                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8337
8338         (( elapsed <= size_mb * 120 / 100 )) ||
8339                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8340
8341         (( elapsed <= size_mb * 350 / 100 )) ||
8342                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8343 }
8344 run_test 56xk "lfs mirror resync bandwidth limitation support"
8345
8346 test_56xl() {
8347         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8348         verify_yaml_available || skip_env "YAML verification not installed"
8349
8350         local size_mb=5
8351         local file1=$DIR/$tfile.1
8352         local output_file=$DIR/$tfile.out
8353
8354         stack_trap "rm -f $file1"
8355         $LFS setstripe -c 1 $file1
8356         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8357                 error "error creating $file1"
8358         $LFS mirror extend -N $file1 || error "can't mirror"
8359         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8360                 error "can't dd"
8361         $LFS getstripe $file1 | grep stale ||
8362                 error "one component must be stale"
8363         $LFS getstripe $file1
8364
8365         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8366                 error "resync failed rc = $?"
8367         $LFS getstripe $file1 | grep stale &&
8368                 error "all components must be sync"
8369
8370         cat $output_file
8371         cat $output_file | verify_yaml || error "stats is not valid YAML"
8372 }
8373 run_test 56xl "lfs mirror resync stats support"
8374
8375 test_56y() {
8376         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8377                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8378
8379         local res=""
8380         local dir=$DIR/$tdir
8381         local f1=$dir/file1
8382         local f2=$dir/file2
8383
8384         test_mkdir -p $dir || error "creating dir $dir"
8385         touch $f1 || error "creating std file $f1"
8386         $MULTIOP $f2 H2c || error "creating released file $f2"
8387
8388         # a directory can be raid0, so ask only for files
8389         res=$($LFS find $dir -L raid0 -type f | wc -l)
8390         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8391
8392         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8393         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8394
8395         # only files can be released, so no need to force file search
8396         res=$($LFS find $dir -L released)
8397         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8398
8399         res=$($LFS find $dir -type f \! -L released)
8400         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8401 }
8402 run_test 56y "lfs find -L raid0|released"
8403
8404 test_56z() { # LU-4824
8405         # This checks to make sure 'lfs find' continues after errors
8406         # There are two classes of errors that should be caught:
8407         # - If multiple paths are provided, all should be searched even if one
8408         #   errors out
8409         # - If errors are encountered during the search, it should not terminate
8410         #   early
8411         local dir=$DIR/$tdir
8412         local i
8413
8414         test_mkdir $dir
8415         for i in d{0..9}; do
8416                 test_mkdir $dir/$i
8417                 touch $dir/$i/$tfile
8418         done
8419         $LFS find $DIR/non_existent_dir $dir &&
8420                 error "$LFS find did not return an error"
8421         # Make a directory unsearchable. This should NOT be the last entry in
8422         # directory order.  Arbitrarily pick the 6th entry
8423         chmod 700 $($LFS find $dir -type d | sed '6!d')
8424
8425         $RUNAS $LFS find $DIR/non_existent $dir
8426         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8427
8428         # The user should be able to see 10 directories and 9 files
8429         (( count == 19 )) ||
8430                 error "$LFS find found $count != 19 entries after error"
8431 }
8432 run_test 56z "lfs find should continue after an error"
8433
8434 test_56aa() { # LU-5937
8435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8436
8437         local dir=$DIR/$tdir
8438
8439         mkdir $dir
8440         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8441
8442         createmany -o $dir/striped_dir/${tfile}- 1024
8443         local dirs=$($LFS find --size +8k $dir/)
8444
8445         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8446 }
8447 run_test 56aa "lfs find --size under striped dir"
8448
8449 test_56ab() { # LU-10705
8450         test_mkdir $DIR/$tdir
8451         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8452         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8453         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8454         # Flush writes to ensure valid blocks.  Need to be more thorough for
8455         # ZFS, since blocks are not allocated/returned to client immediately.
8456         sync_all_data
8457         wait_zfs_commit ost1 2
8458         cancel_lru_locks osc
8459         ls -ls $DIR/$tdir
8460
8461         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8462
8463         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8464
8465         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8466         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8467
8468         rm -f $DIR/$tdir/$tfile.[123]
8469 }
8470 run_test 56ab "lfs find --blocks"
8471
8472 # LU-11188
8473 test_56aca() {
8474         local dir="$DIR/$tdir"
8475         local perms=(001 002 003 004 005 006 007
8476                      010 020 030 040 050 060 070
8477                      100 200 300 400 500 600 700
8478                      111 222 333 444 555 666 777)
8479         local perm_minus=(8 8 4 8 4 4 2
8480                           8 8 4 8 4 4 2
8481                           8 8 4 8 4 4 2
8482                           4 4 2 4 2 2 1)
8483         local perm_slash=(8  8 12  8 12 12 14
8484                           8  8 12  8 12 12 14
8485                           8  8 12  8 12 12 14
8486                          16 16 24 16 24 24 28)
8487
8488         test_mkdir "$dir"
8489         for perm in ${perms[*]}; do
8490                 touch "$dir/$tfile.$perm"
8491                 chmod $perm "$dir/$tfile.$perm"
8492         done
8493
8494         for ((i = 0; i < ${#perms[*]}; i++)); do
8495                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8496                 (( $num == 1 )) ||
8497                         error "lfs find -perm ${perms[i]}:"\
8498                               "$num != 1"
8499
8500                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8501                 (( $num == ${perm_minus[i]} )) ||
8502                         error "lfs find -perm -${perms[i]}:"\
8503                               "$num != ${perm_minus[i]}"
8504
8505                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8506                 (( $num == ${perm_slash[i]} )) ||
8507                         error "lfs find -perm /${perms[i]}:"\
8508                               "$num != ${perm_slash[i]}"
8509         done
8510 }
8511 run_test 56aca "check lfs find -perm with octal representation"
8512
8513 test_56acb() {
8514         local dir=$DIR/$tdir
8515         # p is the permission of write and execute for user, group and other
8516         # without the umask. It is used to test +wx.
8517         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8518         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8519         local symbolic=(+t  a+t u+t g+t o+t
8520                         g+s u+s o+s +s o+sr
8521                         o=r,ug+o,u+w
8522                         u+ g+ o+ a+ ugo+
8523                         u- g- o- a- ugo-
8524                         u= g= o= a= ugo=
8525                         o=r,ug+o,u+w u=r,a+u,u+w
8526                         g=r,ugo=g,u+w u+x,+X +X
8527                         u+x,u+X u+X u+x,g+X o+r,+X
8528                         u+x,go+X +wx +rwx)
8529
8530         test_mkdir $dir
8531         for perm in ${perms[*]}; do
8532                 touch "$dir/$tfile.$perm"
8533                 chmod $perm "$dir/$tfile.$perm"
8534         done
8535
8536         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8537                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8538
8539                 (( $num == 1 )) ||
8540                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8541         done
8542 }
8543 run_test 56acb "check lfs find -perm with symbolic representation"
8544
8545 test_56acc() {
8546         local dir=$DIR/$tdir
8547         local tests="17777 787 789 abcd
8548                 ug=uu ug=a ug=gu uo=ou urw
8549                 u+xg+x a=r,u+x,"
8550
8551         test_mkdir $dir
8552         for err in $tests; do
8553                 if $LFS find $dir -perm $err 2>/dev/null; then
8554                         error "lfs find -perm $err: parsing should have failed"
8555                 fi
8556         done
8557 }
8558 run_test 56acc "check parsing error for lfs find -perm"
8559
8560 test_56ba() {
8561         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8562                 skip "Need MDS version at least 2.10.50"
8563
8564         # Create composite files with one component
8565         local dir=$DIR/$tdir
8566
8567         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8568         # Create composite files with three components
8569         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8570         # LU-16904 Create plain layout files
8571         lfs setstripe -c 1 $dir/$tfile-{1..10}
8572
8573         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8574
8575         [[ $nfiles == 10 ]] ||
8576                 error "lfs find -E 1M found $nfiles != 10 files"
8577
8578         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8579         [[ $nfiles == 25 ]] ||
8580                 error "lfs find ! -E 1M found $nfiles != 25 files"
8581
8582         # All files have a component that starts at 0
8583         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8584         [[ $nfiles == 35 ]] ||
8585                 error "lfs find --component-start 0 - $nfiles != 35 files"
8586
8587         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8588         [[ $nfiles == 15 ]] ||
8589                 error "lfs find --component-start 2M - $nfiles != 15 files"
8590
8591         # All files created here have a componenet that does not starts at 2M
8592         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8593         [[ $nfiles == 35 ]] ||
8594                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8595
8596         # Find files with a specified number of components
8597         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8598         [[ $nfiles == 15 ]] ||
8599                 error "lfs find --component-count 3 - $nfiles != 15 files"
8600
8601         # Remember non-composite files have a component count of zero
8602         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8603         [[ $nfiles == 10 ]] ||
8604                 error "lfs find --component-count 0 - $nfiles != 10 files"
8605
8606         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8607         [[ $nfiles == 20 ]] ||
8608                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8609
8610         # All files have a flag called "init"
8611         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8612         [[ $nfiles == 35 ]] ||
8613                 error "lfs find --component-flags init - $nfiles != 35 files"
8614
8615         # Multi-component files will have a component not initialized
8616         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8617         [[ $nfiles == 15 ]] ||
8618                 error "lfs find !--component-flags init - $nfiles != 15 files"
8619
8620         rm -rf $dir
8621
8622 }
8623 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8624
8625 test_56ca() {
8626         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8627                 skip "Need MDS version at least 2.10.57"
8628
8629         local td=$DIR/$tdir
8630         local tf=$td/$tfile
8631         local dir
8632         local nfiles
8633         local cmd
8634         local i
8635         local j
8636
8637         # create mirrored directories and mirrored files
8638         mkdir $td || error "mkdir $td failed"
8639         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8640         createmany -o $tf- 10 || error "create $tf- failed"
8641
8642         for i in $(seq 2); do
8643                 dir=$td/dir$i
8644                 mkdir $dir || error "mkdir $dir failed"
8645                 $LFS mirror create -N$((3 + i)) $dir ||
8646                         error "create mirrored dir $dir failed"
8647                 createmany -o $dir/$tfile- 10 ||
8648                         error "create $dir/$tfile- failed"
8649         done
8650
8651         # change the states of some mirrored files
8652         echo foo > $tf-6
8653         for i in $(seq 2); do
8654                 dir=$td/dir$i
8655                 for j in $(seq 4 9); do
8656                         echo foo > $dir/$tfile-$j
8657                 done
8658         done
8659
8660         # find mirrored files with specific mirror count
8661         cmd="$LFS find --mirror-count 3 --type f $td"
8662         nfiles=$($cmd | wc -l)
8663         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8664
8665         cmd="$LFS find ! --mirror-count 3 --type f $td"
8666         nfiles=$($cmd | wc -l)
8667         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8668
8669         cmd="$LFS find --mirror-count +2 --type f $td"
8670         nfiles=$($cmd | wc -l)
8671         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8672
8673         cmd="$LFS find --mirror-count -6 --type f $td"
8674         nfiles=$($cmd | wc -l)
8675         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8676
8677         # find mirrored files with specific file state
8678         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8679         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8680
8681         cmd="$LFS find --mirror-state=ro --type f $td"
8682         nfiles=$($cmd | wc -l)
8683         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8684
8685         cmd="$LFS find ! --mirror-state=ro --type f $td"
8686         nfiles=$($cmd | wc -l)
8687         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8688
8689         cmd="$LFS find --mirror-state=wp --type f $td"
8690         nfiles=$($cmd | wc -l)
8691         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8692
8693         cmd="$LFS find ! --mirror-state=sp --type f $td"
8694         nfiles=$($cmd | wc -l)
8695         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8696 }
8697 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8698
8699 test_56da() { # LU-14179
8700         local path=$DIR/$tdir
8701
8702         test_mkdir $path
8703         cd $path
8704
8705         local longdir=$(str_repeat 'a' 255)
8706
8707         for i in {1..15}; do
8708                 path=$path/$longdir
8709                 test_mkdir $longdir
8710                 cd $longdir
8711         done
8712
8713         local len=${#path}
8714         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8715
8716         test_mkdir $lastdir
8717         cd $lastdir
8718         # PATH_MAX-1
8719         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8720
8721         # NAME_MAX
8722         touch $(str_repeat 'f' 255)
8723
8724         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8725                 error "lfs find reported an error"
8726
8727         rm -rf $DIR/$tdir
8728 }
8729 run_test 56da "test lfs find with long paths"
8730
8731 test_56ea() { #LU-10378
8732         local path=$DIR/$tdir
8733         local pool=$TESTNAME
8734
8735         # Create ost pool
8736         pool_add $pool || error "pool_add $pool failed"
8737         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8738                 error "adding targets to $pool failed"
8739
8740         # Set default pool on directory before creating file
8741         mkdir $path || error "mkdir $path failed"
8742         $LFS setstripe -p $pool $path ||
8743                 error "set OST pool on $pool failed"
8744         touch $path/$tfile || error "touch $path/$tfile failed"
8745
8746         # Compare basic file attributes from -printf and stat
8747         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8748         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8749
8750         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8751                 error "Attrs from lfs find and stat don't match"
8752
8753         # Compare Lustre attributes from lfs find and lfs getstripe
8754         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8755         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8756         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8757         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8758         local fpool=$($LFS getstripe --pool $path/$tfile)
8759         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8760
8761         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8762                 error "Attrs from lfs find and lfs getstripe don't match"
8763
8764         # Verify behavior for unknown escape/format sequences
8765         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8766
8767         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8768                 error "Escape/format codes don't match"
8769 }
8770 run_test 56ea "test lfs find -printf option"
8771
8772 test_56eb() {
8773         local dir=$DIR/$tdir
8774         local subdir_1=$dir/subdir_1
8775
8776         test_mkdir -p $subdir_1
8777         ln -s subdir_1 $dir/link_1
8778
8779         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8780                 error "symlink is not followed"
8781
8782         $LFS getstripe --no-follow $dir |
8783                 grep "^$dir/link_1 has no stripe info$" ||
8784                 error "symlink should not have stripe info"
8785
8786         touch $dir/testfile
8787         ln -s testfile $dir/file_link_2
8788
8789         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8790                 error "symlink is not followed"
8791
8792         $LFS getstripe --no-follow $dir |
8793                 grep "^$dir/file_link_2 has no stripe info$" ||
8794                 error "symlink should not have stripe info"
8795 }
8796 run_test 56eb "check lfs getstripe on symlink"
8797
8798 test_56ec() {
8799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8800         local dir=$DIR/$tdir
8801         local srcfile=$dir/srcfile
8802         local srcyaml=$dir/srcyaml
8803         local destfile=$dir/destfile
8804
8805         test_mkdir -p $dir
8806
8807         $LFS setstripe -i 1 $srcfile
8808         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8809         # if the setstripe yaml parsing fails for any reason, the command can
8810         # randomly assign the correct OST index, leading to an erroneous
8811         # success. but the chance of false success is low enough that a
8812         # regression should still be quickly caught.
8813         $LFS setstripe --yaml=$srcyaml $destfile
8814
8815         local srcindex=$($LFS getstripe -i $srcfile)
8816         local destindex=$($LFS getstripe -i $destfile)
8817
8818         if [[ ! $srcindex -eq $destindex ]]; then
8819                 error "setstripe did not set OST index correctly"
8820         fi
8821 }
8822 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8823
8824 test_56eda() {
8825         local dir=$DIR/$tdir
8826         local subdir=$dir/subdir
8827         local file1=$dir/$tfile
8828         local file2=$dir/$tfile\2
8829         local link=$dir/$tfile-link
8830         local nfiles
8831
8832         test_mkdir -p $dir
8833         $LFS setdirstripe -c1 $subdir
8834         touch $file1
8835         touch $file2
8836         ln $file2 $link
8837
8838         nfiles=$($LFS find --links 1 $dir | wc -l)
8839         (( $nfiles == 1 )) ||
8840                 error "lfs find --links expected 1 file, got $nfiles"
8841
8842         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8843         (( $nfiles == 2 )) ||
8844                 error "lfs find --links expected 2 files, got $nfiles"
8845
8846         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8847         (( $nfiles == 1 )) ||
8848                 error "lfs find --links expected 1 directory, got $nfiles"
8849 }
8850 run_test 56eda "check lfs find --links"
8851
8852 test_56edb() {
8853         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8854
8855         local dir=$DIR/$tdir
8856         local stripedir=$dir/stripedir
8857         local nfiles
8858
8859         test_mkdir -p $dir
8860
8861         $LFS setdirstripe -c2 $stripedir
8862
8863         $LFS getdirstripe $stripedir
8864
8865         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8866         (( $nfiles == 1 )) ||
8867                 error "lfs find --links expected 1 directory, got $nfiles"
8868 }
8869 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8870
8871 test_56ef() {
8872         local dir=$DIR/$tdir
8873         local dir1=$dir/d1
8874         local dir2=$dir/d2
8875         local nfiles
8876
8877         test_mkdir -p $dir
8878
8879         mkdir $dir1
8880         mkdir $dir2
8881
8882         touch $dir1/f
8883         touch $dir2/f
8884
8885         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8886         (( $nfiles == 2 )) ||
8887                 error "(1) lfs find expected 2 files, got $nfiles"
8888
8889         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8890         (( $nfiles == 2 )) ||
8891                 error "(2) lfs find expected 2 files, got $nfiles"
8892
8893         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8894         (( $nfiles == 2 )) ||
8895                 error "(3) lfs find expected 2 files, got $nfiles"
8896 }
8897 run_test 56ef "lfs find with multiple paths"
8898
8899 test_57a() {
8900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8901         # note test will not do anything if MDS is not local
8902         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8903                 skip_env "ldiskfs only test"
8904         fi
8905         remote_mds_nodsh && skip "remote MDS with nodsh"
8906
8907         local MNTDEV="osd*.*MDT*.mntdev"
8908         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8909         [ -z "$DEV" ] && error "can't access $MNTDEV"
8910         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8911                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8912                         error "can't access $DEV"
8913                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8914                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8915                 rm $TMP/t57a.dump
8916         done
8917 }
8918 run_test 57a "verify MDS filesystem created with large inodes =="
8919
8920 test_57b() {
8921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8922         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8923                 skip_env "ldiskfs only test"
8924         fi
8925         remote_mds_nodsh && skip "remote MDS with nodsh"
8926
8927         local dir=$DIR/$tdir
8928         local filecount=100
8929         local file1=$dir/f1
8930         local fileN=$dir/f$filecount
8931
8932         rm -rf $dir || error "removing $dir"
8933         test_mkdir -c1 $dir
8934         local mdtidx=$($LFS getstripe -m $dir)
8935         local mdtname=MDT$(printf %04x $mdtidx)
8936         local facet=mds$((mdtidx + 1))
8937
8938         echo "mcreating $filecount files"
8939         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8940
8941         # verify that files do not have EAs yet
8942         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8943                 error "$file1 has an EA"
8944         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8945                 error "$fileN has an EA"
8946
8947         sync
8948         sleep 1
8949         df $dir  #make sure we get new statfs data
8950         local mdsfree=$(do_facet $facet \
8951                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8952         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8953         local file
8954
8955         echo "opening files to create objects/EAs"
8956         for file in $(seq -f $dir/f%g 1 $filecount); do
8957                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8958                         error "opening $file"
8959         done
8960
8961         # verify that files have EAs now
8962         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
8963                 error "$file1 missing EA"
8964         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
8965                 error "$fileN missing EA"
8966
8967         sleep 1  #make sure we get new statfs data
8968         df $dir
8969         local mdsfree2=$(do_facet $facet \
8970                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8971         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8972
8973         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8974                 if [ "$mdsfree" != "$mdsfree2" ]; then
8975                         error "MDC before $mdcfree != after $mdcfree2"
8976                 else
8977                         echo "MDC before $mdcfree != after $mdcfree2"
8978                         echo "unable to confirm if MDS has large inodes"
8979                 fi
8980         fi
8981         rm -rf $dir
8982 }
8983 run_test 57b "default LOV EAs are stored inside large inodes ==="
8984
8985 test_58() {
8986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8987         [ -z "$(which wiretest 2>/dev/null)" ] &&
8988                         skip_env "could not find wiretest"
8989
8990         wiretest
8991 }
8992 run_test 58 "verify cross-platform wire constants =============="
8993
8994 test_59() {
8995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8996
8997         echo "touch 130 files"
8998         createmany -o $DIR/f59- 130
8999         echo "rm 130 files"
9000         unlinkmany $DIR/f59- 130
9001         sync
9002         # wait for commitment of removal
9003         wait_delete_completed
9004 }
9005 run_test 59 "verify cancellation of llog records async ========="
9006
9007 TEST60_HEAD="test_60 run $RANDOM"
9008 test_60a() {
9009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9010         remote_mgs_nodsh && skip "remote MGS with nodsh"
9011         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9012                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9013                         skip_env "missing subtest run-llog.sh"
9014
9015         log "$TEST60_HEAD - from kernel mode"
9016         do_facet mgs "$LCTL dk > /dev/null"
9017         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9018         do_facet mgs $LCTL dk > $TMP/$tfile
9019
9020         # LU-6388: test llog_reader
9021         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9022         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9023         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9024                         skip_env "missing llog_reader"
9025         local fstype=$(facet_fstype mgs)
9026         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9027                 skip_env "Only for ldiskfs or zfs type mgs"
9028
9029         local mntpt=$(facet_mntpt mgs)
9030         local mgsdev=$(mgsdevname 1)
9031         local fid_list
9032         local fid
9033         local rec_list
9034         local rec
9035         local rec_type
9036         local obj_file
9037         local path
9038         local seq
9039         local oid
9040         local pass=true
9041
9042         #get fid and record list
9043         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9044                 tail -n 4))
9045         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9046                 tail -n 4))
9047         #remount mgs as ldiskfs or zfs type
9048         stop mgs || error "stop mgs failed"
9049         mount_fstype mgs || error "remount mgs failed"
9050         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9051                 fid=${fid_list[i]}
9052                 rec=${rec_list[i]}
9053                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9054                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9055                 oid=$((16#$oid))
9056
9057                 case $fstype in
9058                         ldiskfs )
9059                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9060                         zfs )
9061                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9062                 esac
9063                 echo "obj_file is $obj_file"
9064                 do_facet mgs $llog_reader $obj_file
9065
9066                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9067                         awk '{ print $3 }' | sed -e "s/^type=//g")
9068                 if [ $rec_type != $rec ]; then
9069                         echo "FAILED test_60a wrong record type $rec_type," \
9070                               "should be $rec"
9071                         pass=false
9072                         break
9073                 fi
9074
9075                 #check obj path if record type is LLOG_LOGID_MAGIC
9076                 if [ "$rec" == "1064553b" ]; then
9077                         path=$(do_facet mgs $llog_reader $obj_file |
9078                                 grep "path=" | awk '{ print $NF }' |
9079                                 sed -e "s/^path=//g")
9080                         if [ $obj_file != $mntpt/$path ]; then
9081                                 echo "FAILED test_60a wrong obj path" \
9082                                       "$montpt/$path, should be $obj_file"
9083                                 pass=false
9084                                 break
9085                         fi
9086                 fi
9087         done
9088         rm -f $TMP/$tfile
9089         #restart mgs before "error", otherwise it will block the next test
9090         stop mgs || error "stop mgs failed"
9091         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9092         $pass || error "test failed, see FAILED test_60a messages for specifics"
9093 }
9094 run_test 60a "llog_test run from kernel module and test llog_reader"
9095
9096 test_60b() { # bug 6411
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098
9099         dmesg > $DIR/$tfile
9100         LLOG_COUNT=$(do_facet mgs dmesg |
9101                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9102                           /llog_[a-z]*.c:[0-9]/ {
9103                                 if (marker)
9104                                         from_marker++
9105                                 from_begin++
9106                           }
9107                           END {
9108                                 if (marker)
9109                                         print from_marker
9110                                 else
9111                                         print from_begin
9112                           }")
9113
9114         [[ $LLOG_COUNT -gt 120 ]] &&
9115                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9116 }
9117 run_test 60b "limit repeated messages from CERROR/CWARN"
9118
9119 test_60c() {
9120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9121
9122         echo "create 5000 files"
9123         createmany -o $DIR/f60c- 5000
9124 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9125         lctl set_param fail_loc=0x80000137
9126         unlinkmany $DIR/f60c- 5000
9127         lctl set_param fail_loc=0
9128 }
9129 run_test 60c "unlink file when mds full"
9130
9131 test_60d() {
9132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9133
9134         SAVEPRINTK=$(lctl get_param -n printk)
9135         # verify "lctl mark" is even working"
9136         MESSAGE="test message ID $RANDOM $$"
9137         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9138         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9139
9140         lctl set_param printk=0 || error "set lnet.printk failed"
9141         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9142         MESSAGE="new test message ID $RANDOM $$"
9143         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9144         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9145         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9146
9147         lctl set_param -n printk="$SAVEPRINTK"
9148 }
9149 run_test 60d "test printk console message masking"
9150
9151 test_60e() {
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153         remote_mds_nodsh && skip "remote MDS with nodsh"
9154
9155         touch $DIR/$tfile
9156 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9157         do_facet mds1 lctl set_param fail_loc=0x15b
9158         rm $DIR/$tfile
9159 }
9160 run_test 60e "no space while new llog is being created"
9161
9162 test_60f() {
9163         local old_path=$($LCTL get_param -n debug_path)
9164
9165         stack_trap "$LCTL set_param debug_path=$old_path"
9166         stack_trap "rm -f $TMP/$tfile*"
9167         rm -f $TMP/$tfile* 2> /dev/null
9168         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9169         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9170         test_mkdir $DIR/$tdir
9171         # retry in case the open is cached and not released
9172         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9173                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9174                 sleep 0.1
9175         done
9176         ls $TMP/$tfile*
9177         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9178 }
9179 run_test 60f "change debug_path works"
9180
9181 test_60g() {
9182         local pid
9183         local i
9184
9185         test_mkdir -c $MDSCOUNT $DIR/$tdir
9186
9187         (
9188                 local index=0
9189                 while true; do
9190                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9191                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9192                                 2>/dev/null
9193                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9194                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9195                         index=$((index + 1))
9196                 done
9197         ) &
9198
9199         pid=$!
9200
9201         for i in {0..100}; do
9202                 # define OBD_FAIL_OSD_TXN_START    0x19a
9203                 local index=$((i % MDSCOUNT + 1))
9204
9205                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9206                         > /dev/null
9207                 sleep 0.01
9208         done
9209
9210         kill -9 $pid
9211
9212         for i in $(seq $MDSCOUNT); do
9213                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9214         done
9215
9216         mkdir $DIR/$tdir/new || error "mkdir failed"
9217         rmdir $DIR/$tdir/new || error "rmdir failed"
9218
9219         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9220                 -t namespace
9221         for i in $(seq $MDSCOUNT); do
9222                 wait_update_facet mds$i "$LCTL get_param -n \
9223                         mdd.$(facet_svc mds$i).lfsck_namespace |
9224                         awk '/^status/ { print \\\$2 }'" "completed"
9225         done
9226
9227         ls -R $DIR/$tdir
9228         rm -rf $DIR/$tdir || error "rmdir failed"
9229 }
9230 run_test 60g "transaction abort won't cause MDT hung"
9231
9232 test_60h() {
9233         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9234                 skip "Need MDS version at least 2.12.52"
9235         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9236
9237         local f
9238
9239         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9240         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9241         for fail_loc in 0x80000188 0x80000189; do
9242                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9243                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9244                         error "mkdir $dir-$fail_loc failed"
9245                 for i in {0..10}; do
9246                         # create may fail on missing stripe
9247                         echo $i > $DIR/$tdir-$fail_loc/$i
9248                 done
9249                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9250                         error "getdirstripe $tdir-$fail_loc failed"
9251                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9252                         error "migrate $tdir-$fail_loc failed"
9253                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9254                         error "getdirstripe $tdir-$fail_loc failed"
9255                 pushd $DIR/$tdir-$fail_loc
9256                 for f in *; do
9257                         echo $f | cmp $f - || error "$f data mismatch"
9258                 done
9259                 popd
9260                 rm -rf $DIR/$tdir-$fail_loc
9261         done
9262 }
9263 run_test 60h "striped directory with missing stripes can be accessed"
9264
9265 function t60i_load() {
9266         mkdir $DIR/$tdir
9267         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9268         $LCTL set_param fail_loc=0x131c fail_val=1
9269         for ((i=0; i<5000; i++)); do
9270                 touch $DIR/$tdir/f$i
9271         done
9272 }
9273
9274 test_60i() {
9275         changelog_register || error "changelog_register failed"
9276         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9277         changelog_users $SINGLEMDS | grep -q $cl_user ||
9278                 error "User $cl_user not found in changelog_users"
9279         changelog_chmask "ALL"
9280         t60i_load &
9281         local PID=$!
9282         for((i=0; i<100; i++)); do
9283                 changelog_dump >/dev/null ||
9284                         error "can't read changelog"
9285         done
9286         kill $PID
9287         wait $PID
9288         changelog_deregister || error "changelog_deregister failed"
9289         $LCTL set_param fail_loc=0
9290 }
9291 run_test 60i "llog: new record vs reader race"
9292
9293 test_60j() {
9294         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9295                 skip "need MDS version at least 2.15.50"
9296         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9297         remote_mds_nodsh && skip "remote MDS with nodsh"
9298         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9299
9300         changelog_users $SINGLEMDS | grep "^cl" &&
9301                 skip "active changelog user"
9302
9303         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9304
9305         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9306                 skip_env "missing llog_reader"
9307
9308         mkdir_on_mdt0 $DIR/$tdir
9309
9310         local f=$DIR/$tdir/$tfile
9311         local mdt_dev
9312         local tmpfile
9313         local plain
9314
9315         changelog_register || error "cannot register changelog user"
9316
9317         # set changelog_mask to ALL
9318         changelog_chmask "ALL"
9319         changelog_clear
9320
9321         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9322         unlinkmany ${f}- 100 || error "unlinkmany failed"
9323
9324         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9325         mdt_dev=$(facet_device $SINGLEMDS)
9326
9327         do_facet $SINGLEMDS sync
9328         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9329                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9330                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9331
9332         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9333
9334         # if $tmpfile is not on EXT3 filesystem for some reason
9335         [[ ${plain:0:1} == 'O' ]] ||
9336                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9337
9338         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9339                 $mdt_dev; stat -c %s $tmpfile")
9340         echo "Truncate llog from $size to $((size - size % 8192))"
9341         size=$((size - size % 8192))
9342         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9343         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9344                 grep -c 'in bitmap only')
9345         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9346
9347         size=$((size - 9000))
9348         echo "Corrupt llog in the middle at $size"
9349         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9350                 count=333 conv=notrunc
9351         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9352                 grep -c 'next chunk')
9353         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9354 }
9355 run_test 60j "llog_reader reports corruptions"
9356
9357 test_61a() {
9358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9359
9360         f="$DIR/f61"
9361         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9362         cancel_lru_locks osc
9363         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9364         sync
9365 }
9366 run_test 61a "mmap() writes don't make sync hang ================"
9367
9368 test_61b() {
9369         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9370 }
9371 run_test 61b "mmap() of unstriped file is successful"
9372
9373 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9374 # Though this test is irrelevant anymore, it helped to reveal some
9375 # other grant bugs (LU-4482), let's keep it.
9376 test_63a() {   # was test_63
9377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9378
9379         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9380
9381         for i in `seq 10` ; do
9382                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9383                 sleep 5
9384                 kill $!
9385                 sleep 1
9386         done
9387
9388         rm -f $DIR/f63 || true
9389 }
9390 run_test 63a "Verify oig_wait interruption does not crash ======="
9391
9392 # bug 2248 - async write errors didn't return to application on sync
9393 # bug 3677 - async write errors left page locked
9394 test_63b() {
9395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9396
9397         debugsave
9398         lctl set_param debug=-1
9399
9400         # ensure we have a grant to do async writes
9401         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9402         rm $DIR/$tfile
9403
9404         sync    # sync lest earlier test intercept the fail_loc
9405
9406         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9407         lctl set_param fail_loc=0x80000406
9408         $MULTIOP $DIR/$tfile Owy && \
9409                 error "sync didn't return ENOMEM"
9410         sync; sleep 2; sync     # do a real sync this time to flush page
9411         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9412                 error "locked page left in cache after async error" || true
9413         debugrestore
9414 }
9415 run_test 63b "async write errors should be returned to fsync ==="
9416
9417 test_64a () {
9418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9419
9420         lfs df $DIR
9421         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9422 }
9423 run_test 64a "verify filter grant calculations (in kernel) ====="
9424
9425 test_64b () {
9426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9427
9428         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9429 }
9430 run_test 64b "check out-of-space detection on client"
9431
9432 test_64c() {
9433         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9434 }
9435 run_test 64c "verify grant shrink"
9436
9437 import_param() {
9438         local tgt=$1
9439         local param=$2
9440
9441         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9442 }
9443
9444 # this does exactly what osc_request.c:osc_announce_cached() does in
9445 # order to calculate max amount of grants to ask from server
9446 want_grant() {
9447         local tgt=$1
9448
9449         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9450         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9451
9452         ((rpc_in_flight++));
9453         nrpages=$((nrpages * rpc_in_flight))
9454
9455         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9456
9457         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9458
9459         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9460         local undirty=$((nrpages * PAGE_SIZE))
9461
9462         local max_extent_pages
9463         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9464         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9465         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9466         local grant_extent_tax
9467         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9468
9469         undirty=$((undirty + nrextents * grant_extent_tax))
9470
9471         echo $undirty
9472 }
9473
9474 # this is size of unit for grant allocation. It should be equal to
9475 # what tgt_grant.c:tgt_grant_chunk() calculates
9476 grant_chunk() {
9477         local tgt=$1
9478         local max_brw_size
9479         local grant_extent_tax
9480
9481         max_brw_size=$(import_param $tgt max_brw_size)
9482
9483         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9484
9485         echo $(((max_brw_size + grant_extent_tax) * 2))
9486 }
9487
9488 test_64d() {
9489         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9490                 skip "OST < 2.10.55 doesn't limit grants enough"
9491
9492         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9493
9494         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9495                 skip "no grant_param connect flag"
9496
9497         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9498
9499         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9500         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9501
9502
9503         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9504         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9505
9506         $LFS setstripe $DIR/$tfile -i 0 -c 1
9507         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9508         ddpid=$!
9509
9510         while kill -0 $ddpid; do
9511                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9512
9513                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9514                         kill $ddpid
9515                         error "cur_grant $cur_grant > $max_cur_granted"
9516                 fi
9517
9518                 sleep 1
9519         done
9520 }
9521 run_test 64d "check grant limit exceed"
9522
9523 check_grants() {
9524         local tgt=$1
9525         local expected=$2
9526         local msg=$3
9527         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9528
9529         ((cur_grants == expected)) ||
9530                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9531 }
9532
9533 round_up_p2() {
9534         echo $((($1 + $2 - 1) & ~($2 - 1)))
9535 }
9536
9537 test_64e() {
9538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9539         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9540                 skip "Need OSS version at least 2.11.56"
9541
9542         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9543         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9544         $LCTL set_param debug=+cache
9545
9546         # Remount client to reset grant
9547         remount_client $MOUNT || error "failed to remount client"
9548         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9549
9550         local init_grants=$(import_param $osc_tgt initial_grant)
9551
9552         check_grants $osc_tgt $init_grants "init grants"
9553
9554         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9555         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9556         local gbs=$(import_param $osc_tgt grant_block_size)
9557
9558         # write random number of bytes from max_brw_size / 4 to max_brw_size
9559         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9560         # align for direct io
9561         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9562         # round to grant consumption unit
9563         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9564
9565         local grants=$((wb_round_up + extent_tax))
9566
9567         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9568         stack_trap "rm -f $DIR/$tfile"
9569
9570         # define OBD_FAIL_TGT_NO_GRANT 0x725
9571         # make the server not grant more back
9572         do_facet ost1 $LCTL set_param fail_loc=0x725
9573         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9574
9575         do_facet ost1 $LCTL set_param fail_loc=0
9576
9577         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9578
9579         rm -f $DIR/$tfile || error "rm failed"
9580
9581         # Remount client to reset grant
9582         remount_client $MOUNT || error "failed to remount client"
9583         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9584
9585         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9586
9587         # define OBD_FAIL_TGT_NO_GRANT 0x725
9588         # make the server not grant more back
9589         do_facet ost1 $LCTL set_param fail_loc=0x725
9590         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9591         do_facet ost1 $LCTL set_param fail_loc=0
9592
9593         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9594 }
9595 run_test 64e "check grant consumption (no grant allocation)"
9596
9597 test_64f() {
9598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9599
9600         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9601         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9602         $LCTL set_param debug=+cache
9603
9604         # Remount client to reset grant
9605         remount_client $MOUNT || error "failed to remount client"
9606         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9607
9608         local init_grants=$(import_param $osc_tgt initial_grant)
9609         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9610         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9611         local gbs=$(import_param $osc_tgt grant_block_size)
9612         local chunk=$(grant_chunk $osc_tgt)
9613
9614         # write random number of bytes from max_brw_size / 4 to max_brw_size
9615         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9616         # align for direct io
9617         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9618         # round to grant consumption unit
9619         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9620
9621         local grants=$((wb_round_up + extent_tax))
9622
9623         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9624         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9625                 error "error writing to $DIR/$tfile"
9626
9627         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9628                 "direct io with grant allocation"
9629
9630         rm -f $DIR/$tfile || error "rm failed"
9631
9632         # Remount client to reset grant
9633         remount_client $MOUNT || error "failed to remount client"
9634         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9635
9636         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9637
9638         # Testing that buffered IO consumes grant on the client
9639
9640         # Delay the RPC on the server so it's guaranteed to not complete even
9641         # if the RPC is sent from the client
9642         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9643         $LCTL set_param fail_loc=0x50a fail_val=3
9644         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9645                 error "error writing to $DIR/$tfile with buffered IO"
9646
9647         check_grants $osc_tgt $((init_grants - grants)) \
9648                 "buffered io, not write rpc"
9649
9650         # Clear the fail loc and do a sync on the client
9651         $LCTL set_param fail_loc=0 fail_val=0
9652         sync
9653
9654         # RPC is now known to have sent
9655         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9656                 "buffered io, one RPC"
9657 }
9658 run_test 64f "check grant consumption (with grant allocation)"
9659
9660 test_64g() {
9661         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9662                 skip "Need MDS version at least 2.14.56"
9663
9664         local mdts=$(comma_list $(mdts_nodes))
9665
9666         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9667                         tr '\n' ' ')
9668         stack_trap "$LCTL set_param $old"
9669
9670         # generate dirty pages and increase dirty granted on MDT
9671         stack_trap "rm -f $DIR/$tfile-*"
9672         for (( i = 0; i < 10; i++)); do
9673                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9674                         error "can't set stripe"
9675                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9676                         error "can't dd"
9677                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9678                         $LFS getstripe $DIR/$tfile-$i
9679                         error "not DoM file"
9680                 }
9681         done
9682
9683         # flush dirty pages
9684         sync
9685
9686         # wait until grant shrink reset grant dirty on MDTs
9687         for ((i = 0; i < 120; i++)); do
9688                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9689                         awk '{sum=sum+$1} END {print sum}')
9690                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9691                 echo "$grant_dirty grants, $vm_dirty pages"
9692                 (( grant_dirty + vm_dirty == 0 )) && break
9693                 (( i == 3 )) && sync &&
9694                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9695                 sleep 1
9696         done
9697
9698         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9699                 awk '{sum=sum+$1} END {print sum}')
9700         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9701 }
9702 run_test 64g "grant shrink on MDT"
9703
9704 test_64h() {
9705         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9706                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9707
9708         local instance=$($LFS getname -i $DIR)
9709         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9710         local num_exps=$(do_facet ost1 \
9711             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9712         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9713         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9714         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9715
9716         # 10MiB is for file to be written, max_brw_size * 16 *
9717         # num_exps is space reserve so that tgt_grant_shrink() decided
9718         # to not shrink
9719         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9720         (( avail * 1024 < expect )) &&
9721                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9722
9723         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9724         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9725         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9726         $LCTL set_param osc.*OST0000*.grant_shrink=1
9727         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9728
9729         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9730         stack_trap "rm -f $DIR/$tfile"
9731         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9732
9733         # drop cache so that coming read would do rpc
9734         cancel_lru_locks osc
9735
9736         # shrink interval is set to 10, pause for 7 seconds so that
9737         # grant thread did not wake up yet but coming read entered
9738         # shrink mode for rpc (osc_should_shrink_grant())
9739         sleep 7
9740
9741         declare -a cur_grant_bytes
9742         declare -a tot_granted
9743         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9744         tot_granted[0]=$(do_facet ost1 \
9745             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9746
9747         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9748
9749         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9750         tot_granted[1]=$(do_facet ost1 \
9751             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9752
9753         # grant change should be equal on both sides
9754         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9755                 tot_granted[0] - tot_granted[1])) ||
9756                 error "grant change mismatch, "                                \
9757                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9758                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9759 }
9760 run_test 64h "grant shrink on read"
9761
9762 test_64i() {
9763         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9764                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9765
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767         remote_ost_nodsh && skip "remote OSTs with nodsh"
9768
9769         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9770         stack_trap "rm -f $DIR/$tfile"
9771
9772         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9773
9774         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9775         local instance=$($LFS getname -i $DIR)
9776
9777         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9778         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9779
9780         # shrink grants and simulate rpc loss
9781         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9782         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9783         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9784
9785         fail ost1
9786
9787         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9788
9789         local testid=$(echo $TESTNAME | tr '_' ' ')
9790
9791         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9792                 grep "GRANT, real grant" &&
9793                 error "client has more grants then it owns" || true
9794 }
9795 run_test 64i "shrink on reconnect"
9796
9797 # bug 1414 - set/get directories' stripe info
9798 test_65a() {
9799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9800
9801         test_mkdir $DIR/$tdir
9802         touch $DIR/$tdir/f1
9803         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9804 }
9805 run_test 65a "directory with no stripe info"
9806
9807 test_65b() {
9808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9809
9810         test_mkdir $DIR/$tdir
9811         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9812
9813         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9814                                                 error "setstripe"
9815         touch $DIR/$tdir/f2
9816         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9817 }
9818 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9819
9820 test_65c() {
9821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9822         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9823
9824         test_mkdir $DIR/$tdir
9825         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9826
9827         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9828                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9829         touch $DIR/$tdir/f3
9830         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9831 }
9832 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9833
9834 test_65d() {
9835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9836
9837         test_mkdir $DIR/$tdir
9838         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9839         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9840
9841         if [[ $STRIPECOUNT -le 0 ]]; then
9842                 sc=1
9843         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9844                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9845                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9846         else
9847                 sc=$(($STRIPECOUNT - 1))
9848         fi
9849         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9850         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9851         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9852                 error "lverify failed"
9853 }
9854 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9855
9856 test_65e() {
9857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9858
9859         # LU-16904 delete layout when root is set as PFL layout
9860         save_layout_restore_at_exit $MOUNT
9861         $LFS setstripe -d $MOUNT || error "setstripe failed"
9862
9863         test_mkdir $DIR/$tdir
9864
9865         $LFS setstripe $DIR/$tdir || error "setstripe"
9866         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9867                                         error "no stripe info failed"
9868         touch $DIR/$tdir/f6
9869         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9870 }
9871 run_test 65e "directory setstripe defaults"
9872
9873 test_65f() {
9874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9875
9876         test_mkdir $DIR/${tdir}f
9877         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9878                 error "setstripe succeeded" || true
9879 }
9880 run_test 65f "dir setstripe permission (should return error) ==="
9881
9882 test_65g() {
9883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9884
9885         # LU-16904 delete layout when root is set as PFL layout
9886         save_layout_restore_at_exit $MOUNT
9887         $LFS setstripe -d $MOUNT || error "setstripe failed"
9888
9889         test_mkdir $DIR/$tdir
9890         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9891
9892         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9893                 error "setstripe -S failed"
9894         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9895         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9896                 error "delete default stripe failed"
9897 }
9898 run_test 65g "directory setstripe -d"
9899
9900 test_65h() {
9901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9902
9903         test_mkdir $DIR/$tdir
9904         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9905
9906         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9907                 error "setstripe -S failed"
9908         test_mkdir $DIR/$tdir/dd1
9909         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9910                 error "stripe info inherit failed"
9911 }
9912 run_test 65h "directory stripe info inherit ===================="
9913
9914 test_65i() {
9915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9916
9917         save_layout_restore_at_exit $MOUNT
9918
9919         # bug6367: set non-default striping on root directory
9920         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9921
9922         # bug12836: getstripe on -1 default directory striping
9923         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9924
9925         # bug12836: getstripe -v on -1 default directory striping
9926         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9927
9928         # bug12836: new find on -1 default directory striping
9929         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9930 }
9931 run_test 65i "various tests to set root directory striping"
9932
9933 test_65j() { # bug6367
9934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9935
9936         sync; sleep 1
9937
9938         # if we aren't already remounting for each test, do so for this test
9939         if [ "$I_MOUNTED" = "yes" ]; then
9940                 cleanup || error "failed to unmount"
9941                 setup
9942         fi
9943
9944         save_layout_restore_at_exit $MOUNT
9945
9946         $LFS setstripe -d $MOUNT || error "setstripe failed"
9947 }
9948 run_test 65j "set default striping on root directory (bug 6367)="
9949
9950 cleanup_65k() {
9951         rm -rf $DIR/$tdir
9952         wait_delete_completed
9953         do_facet $SINGLEMDS "lctl set_param -n \
9954                 osp.$ost*MDT0000.max_create_count=$max_count"
9955         do_facet $SINGLEMDS "lctl set_param -n \
9956                 osp.$ost*MDT0000.create_count=$count"
9957         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9958         echo $INACTIVE_OSC "is Activate"
9959
9960         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9961 }
9962
9963 test_65k() { # bug11679
9964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9966         remote_mds_nodsh && skip "remote MDS with nodsh"
9967
9968         local disable_precreate=true
9969         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9970                 disable_precreate=false
9971
9972         echo "Check OST status: "
9973         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9974                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9975
9976         for OSC in $MDS_OSCS; do
9977                 echo $OSC "is active"
9978                 do_facet $SINGLEMDS lctl --device %$OSC activate
9979         done
9980
9981         for INACTIVE_OSC in $MDS_OSCS; do
9982                 local ost=$(osc_to_ost $INACTIVE_OSC)
9983                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9984                                lov.*md*.target_obd |
9985                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9986
9987                 mkdir -p $DIR/$tdir
9988                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9989                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9990
9991                 echo "Deactivate: " $INACTIVE_OSC
9992                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9993
9994                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9995                               osp.$ost*MDT0000.create_count")
9996                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9997                                   osp.$ost*MDT0000.max_create_count")
9998                 $disable_precreate &&
9999                         do_facet $SINGLEMDS "lctl set_param -n \
10000                                 osp.$ost*MDT0000.max_create_count=0"
10001
10002                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10003                         [ -f $DIR/$tdir/$idx ] && continue
10004                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10005                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10006                                 { cleanup_65k;
10007                                   error "setstripe $idx should succeed"; }
10008                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10009                 done
10010                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10011                 rmdir $DIR/$tdir
10012
10013                 do_facet $SINGLEMDS "lctl set_param -n \
10014                         osp.$ost*MDT0000.max_create_count=$max_count"
10015                 do_facet $SINGLEMDS "lctl set_param -n \
10016                         osp.$ost*MDT0000.create_count=$count"
10017                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10018                 echo $INACTIVE_OSC "is Activate"
10019
10020                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10021         done
10022 }
10023 run_test 65k "validate manual striping works properly with deactivated OSCs"
10024
10025 test_65l() { # bug 12836
10026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10027
10028         test_mkdir -p $DIR/$tdir/test_dir
10029         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10030         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10031 }
10032 run_test 65l "lfs find on -1 stripe dir ========================"
10033
10034 test_65m() {
10035         local layout=$(save_layout $MOUNT)
10036         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10037                 restore_layout $MOUNT $layout
10038                 error "setstripe should fail by non-root users"
10039         }
10040         true
10041 }
10042 run_test 65m "normal user can't set filesystem default stripe"
10043
10044 test_65n() {
10045         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10046         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10047                 skip "Need MDS version at least 2.12.50"
10048         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10049
10050         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10051         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10052         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10053
10054         save_layout_restore_at_exit $MOUNT
10055
10056         # new subdirectory under root directory should not inherit
10057         # the default layout from root
10058         # LU-16904 check if the root is set as PFL layout
10059         local numcomp=$($LFS getstripe --component-count $MOUNT)
10060
10061         if [[ $numcomp -eq 0 ]]; then
10062                 local dir1=$MOUNT/$tdir-1
10063                 mkdir $dir1 || error "mkdir $dir1 failed"
10064                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10065                         error "$dir1 shouldn't have LOV EA"
10066         fi
10067
10068         # delete the default layout on root directory
10069         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10070
10071         local dir2=$MOUNT/$tdir-2
10072         mkdir $dir2 || error "mkdir $dir2 failed"
10073         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10074                 error "$dir2 shouldn't have LOV EA"
10075
10076         # set a new striping pattern on root directory
10077         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10078         local new_def_stripe_size=$((def_stripe_size * 2))
10079         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10080                 error "set stripe size on $MOUNT failed"
10081
10082         # new file created in $dir2 should inherit the new stripe size from
10083         # the filesystem default
10084         local file2=$dir2/$tfile-2
10085         touch $file2 || error "touch $file2 failed"
10086
10087         local file2_stripe_size=$($LFS getstripe -S $file2)
10088         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10089         {
10090                 echo "file2_stripe_size: '$file2_stripe_size'"
10091                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10092                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10093         }
10094
10095         local dir3=$MOUNT/$tdir-3
10096         mkdir $dir3 || error "mkdir $dir3 failed"
10097         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10098         # the root layout, which is the actual default layout that will be used
10099         # when new files are created in $dir3.
10100         local dir3_layout=$(get_layout_param $dir3)
10101         local root_dir_layout=$(get_layout_param $MOUNT)
10102         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10103         {
10104                 echo "dir3_layout: '$dir3_layout'"
10105                 echo "root_dir_layout: '$root_dir_layout'"
10106                 error "$dir3 should show the default layout from $MOUNT"
10107         }
10108
10109         # set OST pool on root directory
10110         local pool=$TESTNAME
10111         pool_add $pool || error "add $pool failed"
10112         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10113                 error "add targets to $pool failed"
10114
10115         $LFS setstripe -p $pool $MOUNT ||
10116                 error "set OST pool on $MOUNT failed"
10117
10118         # new file created in $dir3 should inherit the pool from
10119         # the filesystem default
10120         local file3=$dir3/$tfile-3
10121         touch $file3 || error "touch $file3 failed"
10122
10123         local file3_pool=$($LFS getstripe -p $file3)
10124         [[ "$file3_pool" = "$pool" ]] ||
10125                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10126
10127         local dir4=$MOUNT/$tdir-4
10128         mkdir $dir4 || error "mkdir $dir4 failed"
10129         local dir4_layout=$(get_layout_param $dir4)
10130         root_dir_layout=$(get_layout_param $MOUNT)
10131         echo "$LFS getstripe -d $dir4"
10132         $LFS getstripe -d $dir4
10133         echo "$LFS getstripe -d $MOUNT"
10134         $LFS getstripe -d $MOUNT
10135         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10136         {
10137                 echo "dir4_layout: '$dir4_layout'"
10138                 echo "root_dir_layout: '$root_dir_layout'"
10139                 error "$dir4 should show the default layout from $MOUNT"
10140         }
10141
10142         # new file created in $dir4 should inherit the pool from
10143         # the filesystem default
10144         local file4=$dir4/$tfile-4
10145         touch $file4 || error "touch $file4 failed"
10146
10147         local file4_pool=$($LFS getstripe -p $file4)
10148         [[ "$file4_pool" = "$pool" ]] ||
10149                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10150
10151         # new subdirectory under non-root directory should inherit
10152         # the default layout from its parent directory
10153         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10154                 error "set directory layout on $dir4 failed"
10155
10156         local dir5=$dir4/$tdir-5
10157         mkdir $dir5 || error "mkdir $dir5 failed"
10158
10159         dir4_layout=$(get_layout_param $dir4)
10160         local dir5_layout=$(get_layout_param $dir5)
10161         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10162         {
10163                 echo "dir4_layout: '$dir4_layout'"
10164                 echo "dir5_layout: '$dir5_layout'"
10165                 error "$dir5 should inherit the default layout from $dir4"
10166         }
10167
10168         # though subdir under ROOT doesn't inherit default layout, but
10169         # its sub dir/file should be created with default layout.
10170         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10171         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10172                 skip "Need MDS version at least 2.12.59"
10173
10174         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10175         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10176         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10177
10178         if [ $default_lmv_hash == "none" ]; then
10179                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10180         else
10181                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10182                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10183         fi
10184
10185         $LFS setdirstripe -D -c 2 $MOUNT ||
10186                 error "setdirstripe -D -c 2 failed"
10187         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10188         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10189         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10190
10191         # $dir4 layout includes pool
10192         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10193         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10194                 error "pool lost on setstripe"
10195         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10196         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10197                 error "pool lost on compound layout setstripe"
10198 }
10199 run_test 65n "don't inherit default layout from root for new subdirectories"
10200
10201 test_65o() {
10202         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10203                 skip "need MDS version at least 2.14.57"
10204
10205         # set OST pool on root directory
10206         local pool=$TESTNAME
10207
10208         pool_add $pool || error "add $pool failed"
10209         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10210                 error "add targets to $pool failed"
10211
10212         local dir1=$MOUNT/$tdir
10213
10214         mkdir $dir1 || error "mkdir $dir1 failed"
10215
10216         # set a new striping pattern on root directory
10217         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10218
10219         $LFS setstripe -p $pool $dir1 ||
10220                 error "set directory layout on $dir1 failed"
10221
10222         # $dir1 layout includes pool
10223         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10224         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10225                 error "pool lost on setstripe"
10226         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10227         $LFS getstripe $dir1
10228         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10229                 error "pool lost on compound layout setstripe"
10230
10231         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10232                 error "setdirstripe failed on sub-dir with inherited pool"
10233         $LFS getstripe $dir1/dir2
10234         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10235                 error "pool lost on compound layout setdirstripe"
10236
10237         $LFS setstripe -E -1 -c 1 $dir1
10238         $LFS getstripe -d $dir1
10239         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10240                 error "pool lost on setstripe"
10241 }
10242 run_test 65o "pool inheritance for mdt component"
10243
10244 test_65p () { # LU-16152
10245         local src_dir=$DIR/$tdir/src_dir
10246         local dst_dir=$DIR/$tdir/dst_dir
10247         local yaml_file=$DIR/$tdir/layout.yaml
10248         local border
10249
10250         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10251                 skip "Need at least version 2.15.51"
10252
10253         test_mkdir -p $src_dir
10254         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10255                 error "failed to setstripe"
10256         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10257                 error "failed to getstripe"
10258
10259         test_mkdir -p $dst_dir
10260         $LFS setstripe --yaml $yaml_file $dst_dir ||
10261                 error "failed to setstripe with yaml file"
10262         border=$($LFS getstripe -d $dst_dir |
10263                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10264                 error "failed to getstripe"
10265
10266         # 2048M is 0x80000000, or 2147483648
10267         (( $border == 2147483648 )) ||
10268                 error "failed to handle huge number in yaml layout"
10269 }
10270 run_test 65p "setstripe with yaml file and huge number"
10271
10272 # bug 2543 - update blocks count on client
10273 test_66() {
10274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10275
10276         local COUNT=${COUNT:-8}
10277         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10278         sync; sync_all_data; sync; sync_all_data
10279         cancel_lru_locks osc
10280         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10281         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10282 }
10283 run_test 66 "update inode blocks count on client ==============="
10284
10285 meminfo() {
10286         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10287 }
10288
10289 swap_used() {
10290         swapon -s | awk '($1 == "'$1'") { print $4 }'
10291 }
10292
10293 # bug5265, obdfilter oa2dentry return -ENOENT
10294 # #define OBD_FAIL_SRV_ENOENT 0x217
10295 test_69() {
10296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10297         remote_ost_nodsh && skip "remote OST with nodsh"
10298
10299         f="$DIR/$tfile"
10300         $LFS setstripe -c 1 -i 0 $f
10301         stack_trap "rm -f $f ${f}.2"
10302
10303         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10304
10305         do_facet ost1 lctl set_param fail_loc=0x217
10306         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10307         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10308
10309         do_facet ost1 lctl set_param fail_loc=0
10310         $DIRECTIO write $f 0 2 || error "write error"
10311
10312         cancel_lru_locks osc
10313         $DIRECTIO read $f 0 1 || error "read error"
10314
10315         do_facet ost1 lctl set_param fail_loc=0x217
10316         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10317
10318         do_facet ost1 lctl set_param fail_loc=0
10319 }
10320 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10321
10322 test_71() {
10323         test_mkdir $DIR/$tdir
10324         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10325         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10326 }
10327 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10328
10329 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10331         [ "$RUNAS_ID" = "$UID" ] &&
10332                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10333         # Check that testing environment is properly set up. Skip if not
10334         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10335                 skip_env "User $RUNAS_ID does not exist - skipping"
10336
10337         touch $DIR/$tfile
10338         chmod 777 $DIR/$tfile
10339         chmod ug+s $DIR/$tfile
10340         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10341                 error "$RUNAS dd $DIR/$tfile failed"
10342         # See if we are still setuid/sgid
10343         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10344                 error "S/gid is not dropped on write"
10345         # Now test that MDS is updated too
10346         cancel_lru_locks mdc
10347         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10348                 error "S/gid is not dropped on MDS"
10349         rm -f $DIR/$tfile
10350 }
10351 run_test 72a "Test that remove suid works properly (bug5695) ===="
10352
10353 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10354         local perm
10355
10356         [ "$RUNAS_ID" = "$UID" ] &&
10357                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10358         [ "$RUNAS_ID" -eq 0 ] &&
10359                 skip_env "RUNAS_ID = 0 -- skipping"
10360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10361         # Check that testing environment is properly set up. Skip if not
10362         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10363                 skip_env "User $RUNAS_ID does not exist - skipping"
10364
10365         touch $DIR/${tfile}-f{g,u}
10366         test_mkdir $DIR/${tfile}-dg
10367         test_mkdir $DIR/${tfile}-du
10368         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10369         chmod g+s $DIR/${tfile}-{f,d}g
10370         chmod u+s $DIR/${tfile}-{f,d}u
10371         for perm in 777 2777 4777; do
10372                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10373                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10374                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10375                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10376         done
10377         true
10378 }
10379 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10380
10381 # bug 3462 - multiple simultaneous MDC requests
10382 test_73() {
10383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10384
10385         test_mkdir $DIR/d73-1
10386         test_mkdir $DIR/d73-2
10387         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10388         pid1=$!
10389
10390         lctl set_param fail_loc=0x80000129
10391         $MULTIOP $DIR/d73-1/f73-2 Oc &
10392         sleep 1
10393         lctl set_param fail_loc=0
10394
10395         $MULTIOP $DIR/d73-2/f73-3 Oc &
10396         pid3=$!
10397
10398         kill -USR1 $pid1
10399         wait $pid1 || return 1
10400
10401         sleep 25
10402
10403         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10404         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10405         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10406
10407         rm -rf $DIR/d73-*
10408 }
10409 run_test 73 "multiple MDC requests (should not deadlock)"
10410
10411 test_74a() { # bug 6149, 6184
10412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10413
10414         touch $DIR/f74a
10415         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10416         #
10417         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10418         # will spin in a tight reconnection loop
10419         $LCTL set_param fail_loc=0x8000030e
10420         # get any lock that won't be difficult - lookup works.
10421         ls $DIR/f74a
10422         $LCTL set_param fail_loc=0
10423         rm -f $DIR/f74a
10424         true
10425 }
10426 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10427
10428 test_74b() { # bug 13310
10429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10430
10431         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10432         #
10433         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10434         # will spin in a tight reconnection loop
10435         $LCTL set_param fail_loc=0x8000030e
10436         # get a "difficult" lock
10437         touch $DIR/f74b
10438         $LCTL set_param fail_loc=0
10439         rm -f $DIR/f74b
10440         true
10441 }
10442 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10443
10444 test_74c() {
10445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10446
10447         #define OBD_FAIL_LDLM_NEW_LOCK
10448         $LCTL set_param fail_loc=0x319
10449         touch $DIR/$tfile && error "touch successful"
10450         $LCTL set_param fail_loc=0
10451         true
10452 }
10453 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10454
10455 slab_lic=/sys/kernel/slab/lustre_inode_cache
10456 num_objects() {
10457         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10458         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10459                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10460 }
10461
10462 test_76a() { # Now for b=20433, added originally in b=1443
10463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10464
10465         cancel_lru_locks osc
10466         # there may be some slab objects cached per core
10467         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10468         local before=$(num_objects)
10469         local count=$((512 * cpus))
10470         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10471         local margin=$((count / 10))
10472         if [[ -f $slab_lic/aliases ]]; then
10473                 local aliases=$(cat $slab_lic/aliases)
10474                 (( aliases > 0 )) && margin=$((margin * aliases))
10475         fi
10476
10477         echo "before slab objects: $before"
10478         for i in $(seq $count); do
10479                 touch $DIR/$tfile
10480                 rm -f $DIR/$tfile
10481         done
10482         cancel_lru_locks osc
10483         local after=$(num_objects)
10484         echo "created: $count, after slab objects: $after"
10485         # shared slab counts are not very accurate, allow significant margin
10486         # the main goal is that the cache growth is not permanently > $count
10487         while (( after > before + margin )); do
10488                 sleep 1
10489                 after=$(num_objects)
10490                 wait=$((wait + 1))
10491                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10492                 if (( wait > 60 )); then
10493                         error "inode slab grew from $before+$margin to $after"
10494                 fi
10495         done
10496 }
10497 run_test 76a "confirm clients recycle inodes properly ===="
10498
10499 test_76b() {
10500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10501         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10502
10503         local count=512
10504         local before=$(num_objects)
10505
10506         for i in $(seq $count); do
10507                 mkdir $DIR/$tdir
10508                 rmdir $DIR/$tdir
10509         done
10510
10511         local after=$(num_objects)
10512         local wait=0
10513
10514         while (( after > before )); do
10515                 sleep 1
10516                 after=$(num_objects)
10517                 wait=$((wait + 1))
10518                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10519                 if (( wait > 60 )); then
10520                         error "inode slab grew from $before to $after"
10521                 fi
10522         done
10523
10524         echo "slab objects before: $before, after: $after"
10525 }
10526 run_test 76b "confirm clients recycle directory inodes properly ===="
10527
10528 export ORIG_CSUM=""
10529 set_checksums()
10530 {
10531         # Note: in sptlrpc modes which enable its own bulk checksum, the
10532         # original crc32_le bulk checksum will be automatically disabled,
10533         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10534         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10535         # In this case set_checksums() will not be no-op, because sptlrpc
10536         # bulk checksum will be enabled all through the test.
10537
10538         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10539         lctl set_param -n osc.*.checksums $1
10540         return 0
10541 }
10542
10543 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10544                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10545 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10546                              tr -d [] | head -n1)}
10547 set_checksum_type()
10548 {
10549         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10550         rc=$?
10551         log "set checksum type to $1, rc = $rc"
10552         return $rc
10553 }
10554
10555 get_osc_checksum_type()
10556 {
10557         # arugment 1: OST name, like OST0000
10558         ost=$1
10559         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10560                         sed 's/.*\[\(.*\)\].*/\1/g')
10561         rc=$?
10562         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10563         echo $checksum_type
10564 }
10565
10566 F77_TMP=$TMP/f77-temp
10567 F77SZ=8
10568 setup_f77() {
10569         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10570                 error "error writing to $F77_TMP"
10571 }
10572
10573 test_77a() { # bug 10889
10574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10575         $GSS && skip_env "could not run with gss"
10576
10577         [ ! -f $F77_TMP ] && setup_f77
10578         set_checksums 1
10579         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10580         set_checksums 0
10581         rm -f $DIR/$tfile
10582 }
10583 run_test 77a "normal checksum read/write operation"
10584
10585 test_77b() { # bug 10889
10586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10587         $GSS && skip_env "could not run with gss"
10588
10589         [ ! -f $F77_TMP ] && setup_f77
10590         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10591         $LCTL set_param fail_loc=0x80000409
10592         set_checksums 1
10593
10594         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10595                 error "dd error: $?"
10596         $LCTL set_param fail_loc=0
10597
10598         for algo in $CKSUM_TYPES; do
10599                 cancel_lru_locks osc
10600                 set_checksum_type $algo
10601                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10602                 $LCTL set_param fail_loc=0x80000408
10603                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10604                 $LCTL set_param fail_loc=0
10605         done
10606         set_checksums 0
10607         set_checksum_type $ORIG_CSUM_TYPE
10608         rm -f $DIR/$tfile
10609 }
10610 run_test 77b "checksum error on client write, read"
10611
10612 cleanup_77c() {
10613         trap 0
10614         set_checksums 0
10615         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10616         $check_ost &&
10617                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10618         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10619         $check_ost && [ -n "$ost_file_prefix" ] &&
10620                 do_facet ost1 rm -f ${ost_file_prefix}\*
10621 }
10622
10623 test_77c() {
10624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10625         $GSS && skip_env "could not run with gss"
10626         remote_ost_nodsh && skip "remote OST with nodsh"
10627
10628         local bad1
10629         local osc_file_prefix
10630         local osc_file
10631         local check_ost=false
10632         local ost_file_prefix
10633         local ost_file
10634         local orig_cksum
10635         local dump_cksum
10636         local fid
10637
10638         # ensure corruption will occur on first OSS/OST
10639         $LFS setstripe -i 0 $DIR/$tfile
10640
10641         [ ! -f $F77_TMP ] && setup_f77
10642         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10643                 error "dd write error: $?"
10644         fid=$($LFS path2fid $DIR/$tfile)
10645
10646         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10647         then
10648                 check_ost=true
10649                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10650                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10651         else
10652                 echo "OSS do not support bulk pages dump upon error"
10653         fi
10654
10655         osc_file_prefix=$($LCTL get_param -n debug_path)
10656         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10657
10658         trap cleanup_77c EXIT
10659
10660         set_checksums 1
10661         # enable bulk pages dump upon error on Client
10662         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10663         # enable bulk pages dump upon error on OSS
10664         $check_ost &&
10665                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10666
10667         # flush Client cache to allow next read to reach OSS
10668         cancel_lru_locks osc
10669
10670         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10671         $LCTL set_param fail_loc=0x80000408
10672         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10673         $LCTL set_param fail_loc=0
10674
10675         rm -f $DIR/$tfile
10676
10677         # check cksum dump on Client
10678         osc_file=$(ls ${osc_file_prefix}*)
10679         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10680         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10681         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10682         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10683         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10684                      cksum)
10685         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10686         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10687                 error "dump content does not match on Client"
10688
10689         $check_ost || skip "No need to check cksum dump on OSS"
10690
10691         # check cksum dump on OSS
10692         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10693         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10694         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10695         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10696         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10697                 error "dump content does not match on OSS"
10698
10699         cleanup_77c
10700 }
10701 run_test 77c "checksum error on client read with debug"
10702
10703 test_77d() { # bug 10889
10704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10705         $GSS && skip_env "could not run with gss"
10706
10707         stack_trap "rm -f $DIR/$tfile"
10708         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10709         $LCTL set_param fail_loc=0x80000409
10710         set_checksums 1
10711         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10712                 error "direct write: rc=$?"
10713         $LCTL set_param fail_loc=0
10714         set_checksums 0
10715
10716         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10717         $LCTL set_param fail_loc=0x80000408
10718         set_checksums 1
10719         cancel_lru_locks osc
10720         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10721                 error "direct read: rc=$?"
10722         $LCTL set_param fail_loc=0
10723         set_checksums 0
10724 }
10725 run_test 77d "checksum error on OST direct write, read"
10726
10727 test_77f() { # bug 10889
10728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10729         $GSS && skip_env "could not run with gss"
10730
10731         set_checksums 1
10732         stack_trap "rm -f $DIR/$tfile"
10733         for algo in $CKSUM_TYPES; do
10734                 cancel_lru_locks osc
10735                 set_checksum_type $algo
10736                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10737                 $LCTL set_param fail_loc=0x409
10738                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10739                         error "direct write succeeded"
10740                 $LCTL set_param fail_loc=0
10741         done
10742         set_checksum_type $ORIG_CSUM_TYPE
10743         set_checksums 0
10744 }
10745 run_test 77f "repeat checksum error on write (expect error)"
10746
10747 test_77g() { # bug 10889
10748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10749         $GSS && skip_env "could not run with gss"
10750         remote_ost_nodsh && skip "remote OST with nodsh"
10751
10752         [ ! -f $F77_TMP ] && setup_f77
10753
10754         local file=$DIR/$tfile
10755         stack_trap "rm -f $file" EXIT
10756
10757         $LFS setstripe -c 1 -i 0 $file
10758         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10759         do_facet ost1 lctl set_param fail_loc=0x8000021a
10760         set_checksums 1
10761         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10762                 error "write error: rc=$?"
10763         do_facet ost1 lctl set_param fail_loc=0
10764         set_checksums 0
10765
10766         cancel_lru_locks osc
10767         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10768         do_facet ost1 lctl set_param fail_loc=0x8000021b
10769         set_checksums 1
10770         cmp $F77_TMP $file || error "file compare failed"
10771         do_facet ost1 lctl set_param fail_loc=0
10772         set_checksums 0
10773 }
10774 run_test 77g "checksum error on OST write, read"
10775
10776 test_77k() { # LU-10906
10777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10778         $GSS && skip_env "could not run with gss"
10779
10780         local cksum_param="osc.$FSNAME*.checksums"
10781         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10782         local checksum
10783         local i
10784
10785         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10786         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10787         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10788
10789         for i in 0 1; do
10790                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10791                         error "failed to set checksum=$i on MGS"
10792                 wait_update $HOSTNAME "$get_checksum" $i
10793                 #remount
10794                 echo "remount client, checksum should be $i"
10795                 remount_client $MOUNT || error "failed to remount client"
10796                 checksum=$(eval $get_checksum)
10797                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10798         done
10799         # remove persistent param to avoid races with checksum mountopt below
10800         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10801                 error "failed to delete checksum on MGS"
10802
10803         for opt in "checksum" "nochecksum"; do
10804                 #remount with mount option
10805                 echo "remount client with option $opt, checksum should be $i"
10806                 umount_client $MOUNT || error "failed to umount client"
10807                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10808                         error "failed to mount client with option '$opt'"
10809                 checksum=$(eval $get_checksum)
10810                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10811                 i=$((i - 1))
10812         done
10813
10814         remount_client $MOUNT || error "failed to remount client"
10815 }
10816 run_test 77k "enable/disable checksum correctly"
10817
10818 test_77l() {
10819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10820         $GSS && skip_env "could not run with gss"
10821
10822         set_checksums 1
10823         stack_trap "set_checksums $ORIG_CSUM" EXIT
10824         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10825
10826         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10827
10828         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10829         for algo in $CKSUM_TYPES; do
10830                 set_checksum_type $algo || error "fail to set checksum type $algo"
10831                 osc_algo=$(get_osc_checksum_type OST0000)
10832                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10833
10834                 # no locks, no reqs to let the connection idle
10835                 cancel_lru_locks osc
10836                 lru_resize_disable osc
10837                 wait_osc_import_state client ost1 IDLE
10838
10839                 # ensure ost1 is connected
10840                 stat $DIR/$tfile >/dev/null || error "can't stat"
10841                 wait_osc_import_state client ost1 FULL
10842
10843                 osc_algo=$(get_osc_checksum_type OST0000)
10844                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10845         done
10846         return 0
10847 }
10848 run_test 77l "preferred checksum type is remembered after reconnected"
10849
10850 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10851 rm -f $F77_TMP
10852 unset F77_TMP
10853
10854 test_77m() {
10855         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10856                 skip "Need at least version 2.14.52"
10857         local param=checksum_speed
10858
10859         $LCTL get_param $param || error "reading $param failed"
10860
10861         csum_speeds=$($LCTL get_param -n $param)
10862
10863         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10864                 error "known checksum types are missing"
10865 }
10866 run_test 77m "Verify checksum_speed is correctly read"
10867
10868 check_filefrag_77n() {
10869         local nr_ext=0
10870         local starts=()
10871         local ends=()
10872
10873         while read extidx a b start end rest; do
10874                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10875                         nr_ext=$(( $nr_ext + 1 ))
10876                         starts+=( ${start%..} )
10877                         ends+=( ${end%:} )
10878                 fi
10879         done < <( filefrag -sv $1 )
10880
10881         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10882         return 1
10883 }
10884
10885 test_77n() {
10886         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10887
10888         touch $DIR/$tfile
10889         $TRUNCATE $DIR/$tfile 0
10890         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10891         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10892         check_filefrag_77n $DIR/$tfile ||
10893                 skip "$tfile blocks not contiguous around hole"
10894
10895         set_checksums 1
10896         stack_trap "set_checksums $ORIG_CSUM" EXIT
10897         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10898         stack_trap "rm -f $DIR/$tfile"
10899
10900         for algo in $CKSUM_TYPES; do
10901                 if [[ "$algo" =~ ^t10 ]]; then
10902                         set_checksum_type $algo ||
10903                                 error "fail to set checksum type $algo"
10904                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10905                                 error "fail to read $tfile with $algo"
10906                 fi
10907         done
10908         rm -f $DIR/$tfile
10909         return 0
10910 }
10911 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10912
10913 test_77o() {
10914         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10915                 skip "Need MDS version at least 2.14.55"
10916         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10917                 skip "Need OST version at least 2.14.55"
10918         local ofd=obdfilter
10919         local mdt=mdt
10920
10921         # print OST checksum_type
10922         echo "$ofd.$FSNAME-*.checksum_type:"
10923         do_nodes $(comma_list $(osts_nodes)) \
10924                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10925
10926         # print MDT checksum_type
10927         echo "$mdt.$FSNAME-*.checksum_type:"
10928         do_nodes $(comma_list $(mdts_nodes)) \
10929                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10930
10931         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10932                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10933
10934         (( $o_count == $OSTCOUNT )) ||
10935                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10936
10937         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10938                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10939
10940         (( $m_count == $MDSCOUNT )) ||
10941                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10942 }
10943 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10944
10945 cleanup_test_78() {
10946         trap 0
10947         rm -f $DIR/$tfile
10948 }
10949
10950 test_78() { # bug 10901
10951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10952         remote_ost || skip_env "local OST"
10953
10954         NSEQ=5
10955         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10956         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10957         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10958         echo "MemTotal: $MEMTOTAL"
10959
10960         # reserve 256MB of memory for the kernel and other running processes,
10961         # and then take 1/2 of the remaining memory for the read/write buffers.
10962         if [ $MEMTOTAL -gt 512 ] ;then
10963                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10964         else
10965                 # for those poor memory-starved high-end clusters...
10966                 MEMTOTAL=$((MEMTOTAL / 2))
10967         fi
10968         echo "Mem to use for directio: $MEMTOTAL"
10969
10970         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10971         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10972         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10973         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10974                 head -n1)
10975         echo "Smallest OST: $SMALLESTOST"
10976         [[ $SMALLESTOST -lt 10240 ]] &&
10977                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10978
10979         trap cleanup_test_78 EXIT
10980
10981         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10982                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10983
10984         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10985         echo "File size: $F78SIZE"
10986         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10987         for i in $(seq 1 $NSEQ); do
10988                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10989                 echo directIO rdwr round $i of $NSEQ
10990                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10991         done
10992
10993         cleanup_test_78
10994 }
10995 run_test 78 "handle large O_DIRECT writes correctly ============"
10996
10997 test_79() { # bug 12743
10998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10999
11000         wait_delete_completed
11001
11002         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11003         BKFREE=$(calc_osc_kbytes kbytesfree)
11004         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11005
11006         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11007         DFTOTAL=`echo $STRING | cut -d, -f1`
11008         DFUSED=`echo $STRING  | cut -d, -f2`
11009         DFAVAIL=`echo $STRING | cut -d, -f3`
11010         DFFREE=$(($DFTOTAL - $DFUSED))
11011
11012         ALLOWANCE=$((64 * $OSTCOUNT))
11013
11014         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11015            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11016                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11017         fi
11018         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11019            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11020                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11021         fi
11022         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11023            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11024                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11025         fi
11026 }
11027 run_test 79 "df report consistency check ======================="
11028
11029 test_80() { # bug 10718
11030         remote_ost_nodsh && skip "remote OST with nodsh"
11031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11032
11033         # relax strong synchronous semantics for slow backends like ZFS
11034         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11035                 local soc="obdfilter.*.sync_lock_cancel"
11036                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11037
11038                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11039                 if [ -z "$save" ]; then
11040                         soc="obdfilter.*.sync_on_lock_cancel"
11041                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11042                 fi
11043
11044                 if [ "$save" != "never" ]; then
11045                         local hosts=$(comma_list $(osts_nodes))
11046
11047                         do_nodes $hosts $LCTL set_param $soc=never
11048                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11049                 fi
11050         fi
11051
11052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11053         sync; sleep 1; sync
11054         local before=$(date +%s)
11055         cancel_lru_locks osc
11056         local after=$(date +%s)
11057         local diff=$((after - before))
11058         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11059
11060         rm -f $DIR/$tfile
11061 }
11062 run_test 80 "Page eviction is equally fast at high offsets too"
11063
11064 test_81a() { # LU-456
11065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11066         remote_ost_nodsh && skip "remote OST with nodsh"
11067
11068         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11069         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11070         do_facet ost1 lctl set_param fail_loc=0x80000228
11071
11072         # write should trigger a retry and success
11073         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11074         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11075         RC=$?
11076         if [ $RC -ne 0 ] ; then
11077                 error "write should success, but failed for $RC"
11078         fi
11079 }
11080 run_test 81a "OST should retry write when get -ENOSPC ==============="
11081
11082 test_81b() { # LU-456
11083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11084         remote_ost_nodsh && skip "remote OST with nodsh"
11085
11086         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11087         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11088         do_facet ost1 lctl set_param fail_loc=0x228
11089
11090         # write should retry several times and return -ENOSPC finally
11091         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11092         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11093         RC=$?
11094         ENOSPC=28
11095         if [ $RC -ne $ENOSPC ] ; then
11096                 error "dd should fail for -ENOSPC, but succeed."
11097         fi
11098 }
11099 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11100
11101 test_99() {
11102         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11103
11104         test_mkdir $DIR/$tdir.cvsroot
11105         chown $RUNAS_ID $DIR/$tdir.cvsroot
11106
11107         cd $TMP
11108         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11109
11110         cd /etc/init.d
11111         # some versions of cvs import exit(1) when asked to import links or
11112         # files they can't read.  ignore those files.
11113         local toignore=$(find . -type l -printf '-I %f\n' -o \
11114                          ! -perm /4 -printf '-I %f\n')
11115         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11116                 $tdir.reposname vtag rtag
11117
11118         cd $DIR
11119         test_mkdir $DIR/$tdir.reposname
11120         chown $RUNAS_ID $DIR/$tdir.reposname
11121         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11122
11123         cd $DIR/$tdir.reposname
11124         $RUNAS touch foo99
11125         $RUNAS cvs add -m 'addmsg' foo99
11126         $RUNAS cvs update
11127         $RUNAS cvs commit -m 'nomsg' foo99
11128         rm -fr $DIR/$tdir.cvsroot
11129 }
11130 run_test 99 "cvs strange file/directory operations"
11131
11132 test_100() {
11133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11134         [[ "$NETTYPE" =~ tcp ]] ||
11135                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11136         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11137         remote_ost_nodsh && skip "remote OST with nodsh"
11138         remote_mds_nodsh && skip "remote MDS with nodsh"
11139         remote_servers || skip "useless for local single node setup"
11140
11141         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11142                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11143
11144                 rc=0
11145                 if (( ${LOCAL/*:/} >= 1024 )); then
11146                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11147                         ss -tna
11148                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11149                 fi
11150         done
11151         (( $rc == 0 )) || error "privileged port not found" )
11152 }
11153 run_test 100 "check local port using privileged port"
11154
11155 function get_named_value()
11156 {
11157     local tag=$1
11158
11159     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11160 }
11161
11162 test_101a() {
11163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11164
11165         local s
11166         local discard
11167         local nreads=10000
11168         local cache_limit=32
11169
11170         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11171         $LCTL set_param -n llite.*.read_ahead_stats=0
11172         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11173                               awk '/^max_cached_mb/ { print $2 }')
11174         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11175         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11176
11177         #
11178         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11179         #
11180         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11181         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11182
11183         discard=0
11184         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11185                    get_named_value 'read.but.discarded'); do
11186                         discard=$(($discard + $s))
11187         done
11188
11189         $LCTL get_param osc.*-osc*.rpc_stats
11190         $LCTL get_param llite.*.read_ahead_stats
11191
11192         # Discard is generally zero, but sometimes a few random reads line up
11193         # and trigger larger readahead, which is wasted & leads to discards.
11194         if [[ $(($discard)) -gt $nreads ]]; then
11195                 error "too many ($discard) discarded pages"
11196         fi
11197         rm -f $DIR/$tfile || true
11198 }
11199 run_test 101a "check read-ahead for random reads"
11200
11201 setup_test101bc() {
11202         test_mkdir $DIR/$tdir
11203         local ssize=$1
11204         local FILE_LENGTH=$2
11205         STRIPE_OFFSET=0
11206
11207         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11208
11209         local list=$(comma_list $(osts_nodes))
11210         set_osd_param $list '' read_cache_enable 0
11211         set_osd_param $list '' writethrough_cache_enable 0
11212
11213         trap cleanup_test101bc EXIT
11214         # prepare the read-ahead file
11215         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11216
11217         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11218                                 count=$FILE_SIZE_MB 2> /dev/null
11219
11220 }
11221
11222 cleanup_test101bc() {
11223         trap 0
11224         rm -rf $DIR/$tdir
11225         rm -f $DIR/$tfile
11226
11227         local list=$(comma_list $(osts_nodes))
11228         set_osd_param $list '' read_cache_enable 1
11229         set_osd_param $list '' writethrough_cache_enable 1
11230 }
11231
11232 calc_total() {
11233         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11234 }
11235
11236 ra_check_101() {
11237         local read_size=$1
11238         local stripe_size=$2
11239         local stride_length=$((stripe_size / read_size))
11240         local stride_width=$((stride_length * OSTCOUNT))
11241         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11242                                 (stride_width - stride_length) ))
11243         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11244                   get_named_value 'read.but.discarded' | calc_total)
11245
11246         if [[ $discard -gt $discard_limit ]]; then
11247                 $LCTL get_param llite.*.read_ahead_stats
11248                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11249         else
11250                 echo "Read-ahead success for size ${read_size}"
11251         fi
11252 }
11253
11254 test_101b() {
11255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11256         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11257
11258         local STRIPE_SIZE=1048576
11259         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11260
11261         if [ $SLOW == "yes" ]; then
11262                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11263         else
11264                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11265         fi
11266
11267         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11268
11269         # prepare the read-ahead file
11270         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11271         cancel_lru_locks osc
11272         for BIDX in 2 4 8 16 32 64 128 256
11273         do
11274                 local BSIZE=$((BIDX*4096))
11275                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11276                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11277                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11278                 $LCTL set_param -n llite.*.read_ahead_stats=0
11279                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11280                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11281                 cancel_lru_locks osc
11282                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11283         done
11284         cleanup_test101bc
11285         true
11286 }
11287 run_test 101b "check stride-io mode read-ahead ================="
11288
11289 test_101c() {
11290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11291
11292         local STRIPE_SIZE=1048576
11293         local FILE_LENGTH=$((STRIPE_SIZE*100))
11294         local nreads=10000
11295         local rsize=65536
11296         local osc_rpc_stats
11297
11298         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11299
11300         cancel_lru_locks osc
11301         $LCTL set_param osc.*.rpc_stats=0
11302         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11303         $LCTL get_param osc.*.rpc_stats
11304         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11305                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11306                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11307                 local size
11308
11309                 if [ $lines -le 20 ]; then
11310                         echo "continue debug"
11311                         continue
11312                 fi
11313                 for size in 1 2 4 8; do
11314                         local rpc=$(echo "$stats" |
11315                                     awk '($1 == "'$size':") {print $2; exit; }')
11316                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11317                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11318                 done
11319                 echo "$osc_rpc_stats check passed!"
11320         done
11321         cleanup_test101bc
11322         true
11323 }
11324 run_test 101c "check stripe_size aligned read-ahead"
11325
11326 test_101d() {
11327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11328
11329         local file=$DIR/$tfile
11330         local sz_MB=${FILESIZE_101d:-80}
11331         local ra_MB=${READAHEAD_MB:-40}
11332
11333         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11334         [ $free_MB -lt $sz_MB ] &&
11335                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11336
11337         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11338         $LFS setstripe -c -1 $file || error "setstripe failed"
11339
11340         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11341         echo Cancel LRU locks on lustre client to flush the client cache
11342         cancel_lru_locks osc
11343
11344         echo Disable read-ahead
11345         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11346         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11347         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11348         $LCTL get_param -n llite.*.max_read_ahead_mb
11349
11350         echo "Reading the test file $file with read-ahead disabled"
11351         local sz_KB=$((sz_MB * 1024 / 4))
11352         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11353         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11354         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11355                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11356
11357         echo "Cancel LRU locks on lustre client to flush the client cache"
11358         cancel_lru_locks osc
11359         echo Enable read-ahead with ${ra_MB}MB
11360         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11361
11362         echo "Reading the test file $file with read-ahead enabled"
11363         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11364                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11365
11366         echo "read-ahead disabled time read $raOFF"
11367         echo "read-ahead enabled time read $raON"
11368
11369         rm -f $file
11370         wait_delete_completed
11371
11372         # use awk for this check instead of bash because it handles decimals
11373         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11374                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11375 }
11376 run_test 101d "file read with and without read-ahead enabled"
11377
11378 test_101e() {
11379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11380
11381         local file=$DIR/$tfile
11382         local size_KB=500  #KB
11383         local count=100
11384         local bsize=1024
11385
11386         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11387         local need_KB=$((count * size_KB))
11388         [[ $free_KB -le $need_KB ]] &&
11389                 skip_env "Need free space $need_KB, have $free_KB"
11390
11391         echo "Creating $count ${size_KB}K test files"
11392         for ((i = 0; i < $count; i++)); do
11393                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11394         done
11395
11396         echo "Cancel LRU locks on lustre client to flush the client cache"
11397         cancel_lru_locks $OSC
11398
11399         echo "Reset readahead stats"
11400         $LCTL set_param -n llite.*.read_ahead_stats=0
11401
11402         for ((i = 0; i < $count; i++)); do
11403                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11404         done
11405
11406         $LCTL get_param llite.*.max_cached_mb
11407         $LCTL get_param llite.*.read_ahead_stats
11408         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11409                      get_named_value 'misses' | calc_total)
11410
11411         for ((i = 0; i < $count; i++)); do
11412                 rm -rf $file.$i 2>/dev/null
11413         done
11414
11415         #10000 means 20% reads are missing in readahead
11416         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11417 }
11418 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11419
11420 test_101f() {
11421         which iozone || skip_env "no iozone installed"
11422
11423         local old_debug=$($LCTL get_param debug)
11424         old_debug=${old_debug#*=}
11425         $LCTL set_param debug="reada mmap"
11426
11427         # create a test file
11428         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11429
11430         echo Cancel LRU locks on lustre client to flush the client cache
11431         cancel_lru_locks osc
11432
11433         echo Reset readahead stats
11434         $LCTL set_param -n llite.*.read_ahead_stats=0
11435
11436         echo mmap read the file with small block size
11437         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11438                 > /dev/null 2>&1
11439
11440         echo checking missing pages
11441         $LCTL get_param llite.*.read_ahead_stats
11442         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11443                         get_named_value 'misses' | calc_total)
11444
11445         $LCTL set_param debug="$old_debug"
11446         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11447         rm -f $DIR/$tfile
11448 }
11449 run_test 101f "check mmap read performance"
11450
11451 test_101g_brw_size_test() {
11452         local mb=$1
11453         local pages=$((mb * 1048576 / PAGE_SIZE))
11454         local file=$DIR/$tfile
11455
11456         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11457                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11458         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11459                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11460                         return 2
11461         done
11462
11463         stack_trap "rm -f $file" EXIT
11464         $LCTL set_param -n osc.*.rpc_stats=0
11465
11466         # 10 RPCs should be enough for the test
11467         local count=10
11468         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11469                 { error "dd write ${mb} MB blocks failed"; return 3; }
11470         cancel_lru_locks osc
11471         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11472                 { error "dd write ${mb} MB blocks failed"; return 4; }
11473
11474         # calculate number of full-sized read and write RPCs
11475         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11476                 sed -n '/pages per rpc/,/^$/p' |
11477                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11478                 END { print reads,writes }'))
11479         # allow one extra full-sized read RPC for async readahead
11480         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11481                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11482         [[ ${rpcs[1]} == $count ]] ||
11483                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11484 }
11485
11486 test_101g() {
11487         remote_ost_nodsh && skip "remote OST with nodsh"
11488
11489         local rpcs
11490         local osts=$(get_facets OST)
11491         local list=$(comma_list $(osts_nodes))
11492         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11493         local brw_size="obdfilter.*.brw_size"
11494
11495         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11496
11497         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11498
11499         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11500                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11501                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11502            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11503                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11504                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11505
11506                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11507                         suffix="M"
11508
11509                 if [[ $orig_mb -lt 16 ]]; then
11510                         save_lustre_params $osts "$brw_size" > $p
11511                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11512                                 error "set 16MB RPC size failed"
11513
11514                         echo "remount client to enable new RPC size"
11515                         remount_client $MOUNT || error "remount_client failed"
11516                 fi
11517
11518                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11519                 # should be able to set brw_size=12, but no rpc_stats for that
11520                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11521         fi
11522
11523         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11524
11525         if [[ $orig_mb -lt 16 ]]; then
11526                 restore_lustre_params < $p
11527                 remount_client $MOUNT || error "remount_client restore failed"
11528         fi
11529
11530         rm -f $p $DIR/$tfile
11531 }
11532 run_test 101g "Big bulk(4/16 MiB) readahead"
11533
11534 test_101h() {
11535         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11536
11537         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11538                 error "dd 70M file failed"
11539         echo Cancel LRU locks on lustre client to flush the client cache
11540         cancel_lru_locks osc
11541
11542         echo "Reset readahead stats"
11543         $LCTL set_param -n llite.*.read_ahead_stats 0
11544
11545         echo "Read 10M of data but cross 64M bundary"
11546         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11547         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11548                      get_named_value 'misses' | calc_total)
11549         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11550         rm -f $p $DIR/$tfile
11551 }
11552 run_test 101h "Readahead should cover current read window"
11553
11554 test_101i() {
11555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11556                 error "dd 10M file failed"
11557
11558         local max_per_file_mb=$($LCTL get_param -n \
11559                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11560         cancel_lru_locks osc
11561         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11562         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11563                 error "set max_read_ahead_per_file_mb to 1 failed"
11564
11565         echo "Reset readahead stats"
11566         $LCTL set_param llite.*.read_ahead_stats=0
11567
11568         dd if=$DIR/$tfile of=/dev/null bs=2M
11569
11570         $LCTL get_param llite.*.read_ahead_stats
11571         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11572                      awk '/misses/ { print $2 }')
11573         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11574         rm -f $DIR/$tfile
11575 }
11576 run_test 101i "allow current readahead to exceed reservation"
11577
11578 test_101j() {
11579         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11580                 error "setstripe $DIR/$tfile failed"
11581         local file_size=$((1048576 * 16))
11582         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11583         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11584
11585         echo Disable read-ahead
11586         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11587
11588         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11589         for blk in $PAGE_SIZE 1048576 $file_size; do
11590                 cancel_lru_locks osc
11591                 echo "Reset readahead stats"
11592                 $LCTL set_param -n llite.*.read_ahead_stats=0
11593                 local count=$(($file_size / $blk))
11594                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11595                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11596                              get_named_value 'failed.to.fast.read' | calc_total)
11597                 $LCTL get_param -n llite.*.read_ahead_stats
11598                 [ $miss -eq $count ] || error "expected $count got $miss"
11599         done
11600
11601         rm -f $p $DIR/$tfile
11602 }
11603 run_test 101j "A complete read block should be submitted when no RA"
11604
11605 test_readahead_base() {
11606         local file=$DIR/$tfile
11607         local size=$1
11608         local iosz
11609         local ramax
11610         local ranum
11611
11612         $LCTL set_param -n llite.*.read_ahead_stats=0
11613         # The first page is not accounted into readahead
11614         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11615         iosz=$(((size + 1048575) / 1048576 * 1048576))
11616         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11617
11618         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11619         fallocate -l $size $file || error "failed to fallocate $file"
11620         cancel_lru_locks osc
11621         $MULTIOP $file or${iosz}c || error "failed to read $file"
11622         $LCTL get_param -n llite.*.read_ahead_stats
11623         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11624                 awk '/readahead.pages/ { print $7 }' | calc_total)
11625         (( $ranum <= $ramax )) ||
11626                 error "read-ahead pages is $ranum more than $ramax"
11627         rm -rf $file || error "failed to remove $file"
11628 }
11629
11630 test_101m()
11631 {
11632         local file=$DIR/$tfile
11633         local ramax
11634         local ranum
11635         local size
11636         local iosz
11637
11638         check_set_fallocate_or_skip
11639         stack_trap "rm -f $file" EXIT
11640
11641         test_readahead_base 4096
11642
11643         # file size: 16K = 16384
11644         test_readahead_base 16384
11645         test_readahead_base 16385
11646         test_readahead_base 16383
11647
11648         # file size: 1M + 1 = 1048576 + 1
11649         test_readahead_base 1048577
11650         # file size: 1M + 16K
11651         test_readahead_base $((1048576 + 16384))
11652
11653         # file size: stripe_size * (stripe_count - 1) + 16K
11654         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11655         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11656         # file size: stripe_size * stripe_count + 16K
11657         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11658         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11659         # file size: 2 * stripe_size * stripe_count + 16K
11660         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11661         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11662 }
11663 run_test 101m "read ahead for small file and last stripe of the file"
11664
11665 setup_test102() {
11666         test_mkdir $DIR/$tdir
11667         chown $RUNAS_ID $DIR/$tdir
11668         STRIPE_SIZE=65536
11669         STRIPE_OFFSET=1
11670         STRIPE_COUNT=$OSTCOUNT
11671         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11672
11673         trap cleanup_test102 EXIT
11674         cd $DIR
11675         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11676         cd $DIR/$tdir
11677         for num in 1 2 3 4; do
11678                 for count in $(seq 1 $STRIPE_COUNT); do
11679                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11680                                 local size=`expr $STRIPE_SIZE \* $num`
11681                                 local file=file"$num-$idx-$count"
11682                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11683                         done
11684                 done
11685         done
11686
11687         cd $DIR
11688         $1 tar cf $TMP/f102.tar $tdir --xattrs
11689 }
11690
11691 cleanup_test102() {
11692         trap 0
11693         rm -f $TMP/f102.tar
11694         rm -rf $DIR/d0.sanity/d102
11695 }
11696
11697 test_102a() {
11698         [ "$UID" != 0 ] && skip "must run as root"
11699         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11700                 skip_env "must have user_xattr"
11701
11702         [ -z "$(which setfattr 2>/dev/null)" ] &&
11703                 skip_env "could not find setfattr"
11704
11705         local testfile=$DIR/$tfile
11706
11707         touch $testfile
11708         echo "set/get xattr..."
11709         setfattr -n trusted.name1 -v value1 $testfile ||
11710                 error "setfattr -n trusted.name1=value1 $testfile failed"
11711         getfattr -n trusted.name1 $testfile 2> /dev/null |
11712           grep "trusted.name1=.value1" ||
11713                 error "$testfile missing trusted.name1=value1"
11714
11715         setfattr -n user.author1 -v author1 $testfile ||
11716                 error "setfattr -n user.author1=author1 $testfile failed"
11717         getfattr -n user.author1 $testfile 2> /dev/null |
11718           grep "user.author1=.author1" ||
11719                 error "$testfile missing trusted.author1=author1"
11720
11721         echo "listxattr..."
11722         setfattr -n trusted.name2 -v value2 $testfile ||
11723                 error "$testfile unable to set trusted.name2"
11724         setfattr -n trusted.name3 -v value3 $testfile ||
11725                 error "$testfile unable to set trusted.name3"
11726         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11727             grep "trusted.name" | wc -l) -eq 3 ] ||
11728                 error "$testfile missing 3 trusted.name xattrs"
11729
11730         setfattr -n user.author2 -v author2 $testfile ||
11731                 error "$testfile unable to set user.author2"
11732         setfattr -n user.author3 -v author3 $testfile ||
11733                 error "$testfile unable to set user.author3"
11734         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11735             grep "user.author" | wc -l) -eq 3 ] ||
11736                 error "$testfile missing 3 user.author xattrs"
11737
11738         echo "remove xattr..."
11739         setfattr -x trusted.name1 $testfile ||
11740                 error "$testfile error deleting trusted.name1"
11741         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11742                 error "$testfile did not delete trusted.name1 xattr"
11743
11744         setfattr -x user.author1 $testfile ||
11745                 error "$testfile error deleting user.author1"
11746         echo "set lustre special xattr ..."
11747         $LFS setstripe -c1 $testfile
11748         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11749                 awk -F "=" '/trusted.lov/ { print $2 }' )
11750         setfattr -n "trusted.lov" -v $lovea $testfile ||
11751                 error "$testfile doesn't ignore setting trusted.lov again"
11752         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11753                 error "$testfile allow setting invalid trusted.lov"
11754         rm -f $testfile
11755 }
11756 run_test 102a "user xattr test =================================="
11757
11758 check_102b_layout() {
11759         local layout="$*"
11760         local testfile=$DIR/$tfile
11761
11762         echo "test layout '$layout'"
11763         $LFS setstripe $layout $testfile || error "setstripe failed"
11764         $LFS getstripe -y $testfile
11765
11766         echo "get/set/list trusted.lov xattr ..." # b=10930
11767         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11768         [[ "$value" =~ "trusted.lov" ]] ||
11769                 error "can't get trusted.lov from $testfile"
11770         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11771                 error "getstripe failed"
11772
11773         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11774
11775         value=$(cut -d= -f2 <<<$value)
11776         # LU-13168: truncated xattr should fail if short lov_user_md header
11777         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11778                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11779         for len in $lens; do
11780                 echo "setfattr $len $testfile.2"
11781                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11782                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11783         done
11784         local stripe_size=$($LFS getstripe -S $testfile.2)
11785         local stripe_count=$($LFS getstripe -c $testfile.2)
11786         [[ $stripe_size -eq 65536 ]] ||
11787                 error "stripe size $stripe_size != 65536"
11788         [[ $stripe_count -eq $stripe_count_orig ]] ||
11789                 error "stripe count $stripe_count != $stripe_count_orig"
11790         rm $testfile $testfile.2
11791 }
11792
11793 test_102b() {
11794         [ -z "$(which setfattr 2>/dev/null)" ] &&
11795                 skip_env "could not find setfattr"
11796         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11797
11798         # check plain layout
11799         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11800
11801         # and also check composite layout
11802         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11803
11804 }
11805 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11806
11807 test_102c() {
11808         [ -z "$(which setfattr 2>/dev/null)" ] &&
11809                 skip_env "could not find setfattr"
11810         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11811
11812         # b10930: get/set/list lustre.lov xattr
11813         echo "get/set/list lustre.lov xattr ..."
11814         test_mkdir $DIR/$tdir
11815         chown $RUNAS_ID $DIR/$tdir
11816         local testfile=$DIR/$tdir/$tfile
11817         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11818                 error "setstripe failed"
11819         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11820                 error "getstripe failed"
11821         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11822         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11823
11824         local testfile2=${testfile}2
11825         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11826                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11827
11828         $RUNAS $MCREATE $testfile2
11829         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11830         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11831         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11832         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11833         [ $stripe_count -eq $STRIPECOUNT ] ||
11834                 error "stripe count $stripe_count != $STRIPECOUNT"
11835 }
11836 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11837
11838 compare_stripe_info1() {
11839         local stripe_index_all_zero=true
11840
11841         for num in 1 2 3 4; do
11842                 for count in $(seq 1 $STRIPE_COUNT); do
11843                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11844                                 local size=$((STRIPE_SIZE * num))
11845                                 local file=file"$num-$offset-$count"
11846                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11847                                 [[ $stripe_size -ne $size ]] &&
11848                                     error "$file: size $stripe_size != $size"
11849                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11850                                 # allow fewer stripes to be created, ORI-601
11851                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11852                                     error "$file: count $stripe_count != $count"
11853                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11854                                 [[ $stripe_index -ne 0 ]] &&
11855                                         stripe_index_all_zero=false
11856                         done
11857                 done
11858         done
11859         $stripe_index_all_zero &&
11860                 error "all files are being extracted starting from OST index 0"
11861         return 0
11862 }
11863
11864 have_xattrs_include() {
11865         tar --help | grep -q xattrs-include &&
11866                 echo --xattrs-include="lustre.*"
11867 }
11868
11869 test_102d() {
11870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11871         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11872
11873         XINC=$(have_xattrs_include)
11874         setup_test102
11875         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11876         cd $DIR/$tdir/$tdir
11877         compare_stripe_info1
11878 }
11879 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11880
11881 test_102f() {
11882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11883         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11884
11885         XINC=$(have_xattrs_include)
11886         setup_test102
11887         test_mkdir $DIR/$tdir.restore
11888         cd $DIR
11889         tar cf - --xattrs $tdir | tar xf - \
11890                 -C $DIR/$tdir.restore --xattrs $XINC
11891         cd $DIR/$tdir.restore/$tdir
11892         compare_stripe_info1
11893 }
11894 run_test 102f "tar copy files, not keep osts"
11895
11896 grow_xattr() {
11897         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11898                 skip "must have user_xattr"
11899         [ -z "$(which setfattr 2>/dev/null)" ] &&
11900                 skip_env "could not find setfattr"
11901         [ -z "$(which getfattr 2>/dev/null)" ] &&
11902                 skip_env "could not find getfattr"
11903
11904         local xsize=${1:-1024}  # in bytes
11905         local file=$DIR/$tfile
11906         local value="$(generate_string $xsize)"
11907         local xbig=trusted.big
11908         local toobig=$2
11909
11910         touch $file
11911         log "save $xbig on $file"
11912         if [ -z "$toobig" ]
11913         then
11914                 setfattr -n $xbig -v $value $file ||
11915                         error "saving $xbig on $file failed"
11916         else
11917                 setfattr -n $xbig -v $value $file &&
11918                         error "saving $xbig on $file succeeded"
11919                 return 0
11920         fi
11921
11922         local orig=$(get_xattr_value $xbig $file)
11923         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11924
11925         local xsml=trusted.sml
11926         log "save $xsml on $file"
11927         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11928
11929         local new=$(get_xattr_value $xbig $file)
11930         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11931
11932         log "grow $xsml on $file"
11933         setfattr -n $xsml -v "$value" $file ||
11934                 error "growing $xsml on $file failed"
11935
11936         new=$(get_xattr_value $xbig $file)
11937         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11938         log "$xbig still valid after growing $xsml"
11939
11940         rm -f $file
11941 }
11942
11943 test_102h() { # bug 15777
11944         grow_xattr 1024
11945 }
11946 run_test 102h "grow xattr from inside inode to external block"
11947
11948 test_102ha() {
11949         large_xattr_enabled || skip_env "ea_inode feature disabled"
11950
11951         echo "setting xattr of max xattr size: $(max_xattr_size)"
11952         grow_xattr $(max_xattr_size)
11953
11954         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11955         echo "This should fail:"
11956         grow_xattr $(($(max_xattr_size) + 10)) 1
11957 }
11958 run_test 102ha "grow xattr from inside inode to external inode"
11959
11960 test_102i() { # bug 17038
11961         [ -z "$(which getfattr 2>/dev/null)" ] &&
11962                 skip "could not find getfattr"
11963
11964         touch $DIR/$tfile
11965         ln -s $DIR/$tfile $DIR/${tfile}link
11966         getfattr -n trusted.lov $DIR/$tfile ||
11967                 error "lgetxattr on $DIR/$tfile failed"
11968         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11969                 grep -i "no such attr" ||
11970                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11971         rm -f $DIR/$tfile $DIR/${tfile}link
11972 }
11973 run_test 102i "lgetxattr test on symbolic link ============"
11974
11975 test_102j() {
11976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11977         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11978
11979         XINC=$(have_xattrs_include)
11980         setup_test102 "$RUNAS"
11981         chown $RUNAS_ID $DIR/$tdir
11982         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11983         cd $DIR/$tdir/$tdir
11984         compare_stripe_info1 "$RUNAS"
11985 }
11986 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11987
11988 test_102k() {
11989         [ -z "$(which setfattr 2>/dev/null)" ] &&
11990                 skip "could not find setfattr"
11991
11992         touch $DIR/$tfile
11993         # b22187 just check that does not crash for regular file.
11994         setfattr -n trusted.lov $DIR/$tfile
11995         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11996         local test_kdir=$DIR/$tdir
11997         test_mkdir $test_kdir
11998         local default_size=$($LFS getstripe -S $test_kdir)
11999         local default_count=$($LFS getstripe -c $test_kdir)
12000         local default_offset=$($LFS getstripe -i $test_kdir)
12001         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12002                 error 'dir setstripe failed'
12003         setfattr -n trusted.lov $test_kdir
12004         local stripe_size=$($LFS getstripe -S $test_kdir)
12005         local stripe_count=$($LFS getstripe -c $test_kdir)
12006         local stripe_offset=$($LFS getstripe -i $test_kdir)
12007         [ $stripe_size -eq $default_size ] ||
12008                 error "stripe size $stripe_size != $default_size"
12009         [ $stripe_count -eq $default_count ] ||
12010                 error "stripe count $stripe_count != $default_count"
12011         [ $stripe_offset -eq $default_offset ] ||
12012                 error "stripe offset $stripe_offset != $default_offset"
12013         rm -rf $DIR/$tfile $test_kdir
12014 }
12015 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12016
12017 test_102l() {
12018         [ -z "$(which getfattr 2>/dev/null)" ] &&
12019                 skip "could not find getfattr"
12020
12021         # LU-532 trusted. xattr is invisible to non-root
12022         local testfile=$DIR/$tfile
12023
12024         touch $testfile
12025
12026         echo "listxattr as user..."
12027         chown $RUNAS_ID $testfile
12028         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12029             grep -q "trusted" &&
12030                 error "$testfile trusted xattrs are user visible"
12031
12032         return 0;
12033 }
12034 run_test 102l "listxattr size test =================================="
12035
12036 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12037         local path=$DIR/$tfile
12038         touch $path
12039
12040         listxattr_size_check $path || error "listattr_size_check $path failed"
12041 }
12042 run_test 102m "Ensure listxattr fails on small bufffer ========"
12043
12044 cleanup_test102
12045
12046 getxattr() { # getxattr path name
12047         # Return the base64 encoding of the value of xattr name on path.
12048         local path=$1
12049         local name=$2
12050
12051         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12052         # file: $path
12053         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12054         #
12055         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12056
12057         getfattr --absolute-names --encoding=base64 --name=$name $path |
12058                 awk -F= -v name=$name '$1 == name {
12059                         print substr($0, index($0, "=") + 1);
12060         }'
12061 }
12062
12063 test_102n() { # LU-4101 mdt: protect internal xattrs
12064         [ -z "$(which setfattr 2>/dev/null)" ] &&
12065                 skip "could not find setfattr"
12066         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12067         then
12068                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12069         fi
12070
12071         local file0=$DIR/$tfile.0
12072         local file1=$DIR/$tfile.1
12073         local xattr0=$TMP/$tfile.0
12074         local xattr1=$TMP/$tfile.1
12075         local namelist="lov lma lmv link fid version som hsm"
12076         local name
12077         local value
12078
12079         rm -rf $file0 $file1 $xattr0 $xattr1
12080         touch $file0 $file1
12081
12082         # Get 'before' xattrs of $file1.
12083         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12084
12085         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12086                 namelist+=" lfsck_namespace"
12087         for name in $namelist; do
12088                 # Try to copy xattr from $file0 to $file1.
12089                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12090
12091                 setfattr --name=trusted.$name --value="$value" $file1 ||
12092                         error "setxattr 'trusted.$name' failed"
12093
12094                 # Try to set a garbage xattr.
12095                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12096
12097                 if [[ x$name == "xlov" ]]; then
12098                         setfattr --name=trusted.lov --value="$value" $file1 &&
12099                         error "setxattr invalid 'trusted.lov' success"
12100                 else
12101                         setfattr --name=trusted.$name --value="$value" $file1 ||
12102                                 error "setxattr invalid 'trusted.$name' failed"
12103                 fi
12104
12105                 # Try to remove the xattr from $file1. We don't care if this
12106                 # appears to succeed or fail, we just don't want there to be
12107                 # any changes or crashes.
12108                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12109         done
12110
12111         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12112         then
12113                 name="lfsck_ns"
12114                 # Try to copy xattr from $file0 to $file1.
12115                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12116
12117                 setfattr --name=trusted.$name --value="$value" $file1 ||
12118                         error "setxattr 'trusted.$name' failed"
12119
12120                 # Try to set a garbage xattr.
12121                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12122
12123                 setfattr --name=trusted.$name --value="$value" $file1 ||
12124                         error "setxattr 'trusted.$name' failed"
12125
12126                 # Try to remove the xattr from $file1. We don't care if this
12127                 # appears to succeed or fail, we just don't want there to be
12128                 # any changes or crashes.
12129                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12130         fi
12131
12132         # Get 'after' xattrs of file1.
12133         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12134
12135         if ! diff $xattr0 $xattr1; then
12136                 error "before and after xattrs of '$file1' differ"
12137         fi
12138
12139         rm -rf $file0 $file1 $xattr0 $xattr1
12140
12141         return 0
12142 }
12143 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12144
12145 test_102p() { # LU-4703 setxattr did not check ownership
12146         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12147                 skip "MDS needs to be at least 2.5.56"
12148
12149         local testfile=$DIR/$tfile
12150
12151         touch $testfile
12152
12153         echo "setfacl as user..."
12154         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12155         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12156
12157         echo "setfattr as user..."
12158         setfacl -m "u:$RUNAS_ID:---" $testfile
12159         $RUNAS setfattr -x system.posix_acl_access $testfile
12160         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12161 }
12162 run_test 102p "check setxattr(2) correctly fails without permission"
12163
12164 test_102q() {
12165         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12166                 skip "MDS needs to be at least 2.6.92"
12167
12168         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12169 }
12170 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12171
12172 test_102r() {
12173         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12174                 skip "MDS needs to be at least 2.6.93"
12175
12176         touch $DIR/$tfile || error "touch"
12177         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12178         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12179         rm $DIR/$tfile || error "rm"
12180
12181         #normal directory
12182         mkdir -p $DIR/$tdir || error "mkdir"
12183         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12184         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12185         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12186                 error "$testfile error deleting user.author1"
12187         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12188                 grep "user.$(basename $tdir)" &&
12189                 error "$tdir did not delete user.$(basename $tdir)"
12190         rmdir $DIR/$tdir || error "rmdir"
12191
12192         #striped directory
12193         test_mkdir $DIR/$tdir
12194         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12195         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12196         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12197                 error "$testfile error deleting user.author1"
12198         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12199                 grep "user.$(basename $tdir)" &&
12200                 error "$tdir did not delete user.$(basename $tdir)"
12201         rmdir $DIR/$tdir || error "rm striped dir"
12202 }
12203 run_test 102r "set EAs with empty values"
12204
12205 test_102s() {
12206         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12207                 skip "MDS needs to be at least 2.11.52"
12208
12209         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12210
12211         save_lustre_params client "llite.*.xattr_cache" > $save
12212
12213         for cache in 0 1; do
12214                 lctl set_param llite.*.xattr_cache=$cache
12215
12216                 rm -f $DIR/$tfile
12217                 touch $DIR/$tfile || error "touch"
12218                 for prefix in lustre security system trusted user; do
12219                         # Note getxattr() may fail with 'Operation not
12220                         # supported' or 'No such attribute' depending
12221                         # on prefix and cache.
12222                         getfattr -n $prefix.n102s $DIR/$tfile &&
12223                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12224                 done
12225         done
12226
12227         restore_lustre_params < $save
12228 }
12229 run_test 102s "getting nonexistent xattrs should fail"
12230
12231 test_102t() {
12232         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12233                 skip "MDS needs to be at least 2.11.52"
12234
12235         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12236
12237         save_lustre_params client "llite.*.xattr_cache" > $save
12238
12239         for cache in 0 1; do
12240                 lctl set_param llite.*.xattr_cache=$cache
12241
12242                 for buf_size in 0 256; do
12243                         rm -f $DIR/$tfile
12244                         touch $DIR/$tfile || error "touch"
12245                         setfattr -n user.multiop $DIR/$tfile
12246                         $MULTIOP $DIR/$tfile oa$buf_size ||
12247                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12248                 done
12249         done
12250
12251         restore_lustre_params < $save
12252 }
12253 run_test 102t "zero length xattr values handled correctly"
12254
12255 run_acl_subtest()
12256 {
12257         local test=$LUSTRE/tests/acl/$1.test
12258         local tmp=$(mktemp -t $1-XXXXXX).test
12259         local bin=$2
12260         local dmn=$3
12261         local grp=$4
12262         local nbd=$5
12263         export LANG=C
12264
12265
12266         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12267         local sedgroups="-e s/:users/:$grp/g"
12268         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12269
12270         sed $sedusers $sedgroups < $test > $tmp
12271         stack_trap "rm -f $tmp"
12272         [[ -s $tmp ]] || error "sed failed to create test script"
12273
12274         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12275         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12276 }
12277
12278 test_103a() {
12279         [ "$UID" != 0 ] && skip "must run as root"
12280         $GSS && skip_env "could not run under gss"
12281         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12282                 skip_env "must have acl enabled"
12283         which setfacl || skip_env "could not find setfacl"
12284         remote_mds_nodsh && skip "remote MDS with nodsh"
12285
12286         local mdts=$(comma_list $(mdts_nodes))
12287         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12288
12289         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12290         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12291
12292         ACLBIN=${ACLBIN:-"bin"}
12293         ACLDMN=${ACLDMN:-"daemon"}
12294         ACLGRP=${ACLGRP:-"users"}
12295         ACLNBD=${ACLNBD:-"nobody"}
12296
12297         if ! id $ACLBIN ||
12298            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12299                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12300                 ACLBIN=$USER0
12301                 if ! id $ACLBIN ; then
12302                         cat /etc/passwd
12303                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12304                 fi
12305         fi
12306         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12307            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12308                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12309                 ACLDMN=$USER1
12310                 if ! id $ACLDMN ; then
12311                         cat /etc/passwd
12312                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12313                 fi
12314         fi
12315         if ! getent group $ACLGRP; then
12316                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12317                 ACLGRP="$TSTUSR"
12318                 if ! getent group $ACLGRP; then
12319                         echo "cannot find group '$ACLGRP', adding it"
12320                         cat /etc/group
12321                         add_group 60000 $ACLGRP
12322                 fi
12323         fi
12324
12325         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12326         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12327         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12328
12329         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12330                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12331                 ACLGRP="$TSTUSR"
12332                 if ! getent group $ACLGRP; then
12333                         echo "cannot find group '$ACLGRP', adding it"
12334                         cat /etc/group
12335                         add_group 60000 $ACLGRP
12336                 fi
12337                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12338                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12339                         cat /etc/group
12340                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12341                 fi
12342         fi
12343
12344         gpasswd -a $ACLDMN $ACLBIN ||
12345                 error "setting client group failed"             # LU-5641
12346         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12347                 error "setting MDS group failed"                # LU-5641
12348
12349         declare -a identity_old
12350
12351         for num in $(seq $MDSCOUNT); do
12352                 switch_identity $num true || identity_old[$num]=$?
12353         done
12354
12355         SAVE_UMASK=$(umask)
12356         umask 0022
12357         mkdir -p $DIR/$tdir
12358         cd $DIR/$tdir
12359
12360         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12361         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12362         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12363         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12364         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12365         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12366         if ! id -u $ACLNBD ||
12367            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12368                 ACLNBD="nfsnobody"
12369                 if ! id -u $ACLNBD; then
12370                         ACLNBD=""
12371                 fi
12372         fi
12373         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12374                 add_group $(id -u $ACLNBD) $ACLNBD
12375                 if ! getent group $ACLNBD; then
12376                         ACLNBD=""
12377                 fi
12378         fi
12379         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12380            [[ -n "$ACLNBD" ]] && which setfattr; then
12381                 run_acl_subtest permissions_xattr \
12382                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12383         elif [[ -z "$ACLNBD" ]]; then
12384                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12385         else
12386                 echo "skip 'permission_xattr' test - missing setfattr command"
12387         fi
12388         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12389
12390         # inheritance test got from HP
12391         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12392         chmod +x make-tree || error "chmod +x failed"
12393         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12394         rm -f make-tree
12395
12396         echo "LU-974 ignore umask when acl is enabled..."
12397         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12398         if [ $MDSCOUNT -ge 2 ]; then
12399                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12400         fi
12401
12402         echo "LU-2561 newly created file is same size as directory..."
12403         if [ "$mds1_FSTYPE" != "zfs" ]; then
12404                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12405         else
12406                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12407         fi
12408
12409         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12410
12411         cd $SAVE_PWD
12412         umask $SAVE_UMASK
12413
12414         for num in $(seq $MDSCOUNT); do
12415                 if [ "${identity_old[$num]}" = 1 ]; then
12416                         switch_identity $num false || identity_old[$num]=$?
12417                 fi
12418         done
12419 }
12420 run_test 103a "acl test"
12421
12422 test_103b() {
12423         declare -a pids
12424         local U
12425
12426         stack_trap "rm -f $DIR/$tfile.*"
12427         for U in {0..511}; do
12428                 {
12429                 local O=$(printf "%04o" $U)
12430
12431                 umask $(printf "%04o" $((511 ^ $O)))
12432                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12433                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12434
12435                 (( $S == ($O & 0666) )) ||
12436                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12437
12438                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12439                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12440                 (( $S == ($O & 0666) )) ||
12441                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12442
12443                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12444                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12445                 (( $S == ($O & 0666) )) ||
12446                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12447                 rm -f $DIR/$tfile.[smp]$0
12448                 } &
12449                 local pid=$!
12450
12451                 # limit the concurrently running threads to 64. LU-11878
12452                 local idx=$((U % 64))
12453                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12454                 pids[idx]=$pid
12455         done
12456         wait
12457 }
12458 run_test 103b "umask lfs setstripe"
12459
12460 test_103c() {
12461         mkdir -p $DIR/$tdir
12462         cp -rp $DIR/$tdir $DIR/$tdir.bak
12463
12464         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12465                 error "$DIR/$tdir shouldn't contain default ACL"
12466         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12467                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12468         true
12469 }
12470 run_test 103c "'cp -rp' won't set empty acl"
12471
12472 test_103e() {
12473         local numacl
12474         local fileacl
12475         local saved_debug=$($LCTL get_param -n debug)
12476
12477         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12478                 skip "MDS needs to be at least 2.14.52"
12479
12480         large_xattr_enabled || skip_env "ea_inode feature disabled"
12481
12482         mkdir -p $DIR/$tdir
12483         # add big LOV EA to cause reply buffer overflow earlier
12484         $LFS setstripe -C 1000 $DIR/$tdir
12485         lctl set_param mdc.*-mdc*.stats=clear
12486
12487         $LCTL set_param debug=0
12488         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12489         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12490
12491         # add a large number of default ACLs (expect 8000+ for 2.13+)
12492         for U in {2..7000}; do
12493                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12494                         error "Able to add just $U default ACLs"
12495         done
12496         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12497         echo "$numacl default ACLs created"
12498
12499         stat $DIR/$tdir || error "Cannot stat directory"
12500         # check file creation
12501         touch $DIR/$tdir/$tfile ||
12502                 error "failed to create $tfile with $numacl default ACLs"
12503         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12504         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12505         echo "$fileacl ACLs were inherited"
12506         (( $fileacl == $numacl )) ||
12507                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12508         # check that new ACLs creation adds new ACLs to inherited ACLs
12509         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12510                 error "Cannot set new ACL"
12511         numacl=$((numacl + 1))
12512         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12513         (( $fileacl == $numacl )) ||
12514                 error "failed to add new ACL: $fileacl != $numacl as expected"
12515         # adds more ACLs to a file to reach their maximum at 8000+
12516         numacl=0
12517         for U in {20000..25000}; do
12518                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12519                 numacl=$((numacl + 1))
12520         done
12521         echo "Added $numacl more ACLs to the file"
12522         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12523         echo "Total $fileacl ACLs in file"
12524         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12525         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12526         rmdir $DIR/$tdir || error "Cannot remove directory"
12527 }
12528 run_test 103e "inheritance of big amount of default ACLs"
12529
12530 test_103f() {
12531         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12532                 skip "MDS needs to be at least 2.14.51"
12533
12534         large_xattr_enabled || skip_env "ea_inode feature disabled"
12535
12536         # enable changelog to consume more internal MDD buffers
12537         changelog_register
12538
12539         mkdir -p $DIR/$tdir
12540         # add big LOV EA
12541         $LFS setstripe -C 1000 $DIR/$tdir
12542         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12543         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12544         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12545         rmdir $DIR/$tdir || error "Cannot remove directory"
12546 }
12547 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12548
12549 test_104a() {
12550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12551
12552         touch $DIR/$tfile
12553         lfs df || error "lfs df failed"
12554         lfs df -ih || error "lfs df -ih failed"
12555         lfs df -h $DIR || error "lfs df -h $DIR failed"
12556         lfs df -i $DIR || error "lfs df -i $DIR failed"
12557         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12558         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12559
12560         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12561         lctl --device %$OSC deactivate
12562         lfs df || error "lfs df with deactivated OSC failed"
12563         lctl --device %$OSC activate
12564         # wait the osc back to normal
12565         wait_osc_import_ready client ost
12566
12567         lfs df || error "lfs df with reactivated OSC failed"
12568         rm -f $DIR/$tfile
12569 }
12570 run_test 104a "lfs df [-ih] [path] test ========================="
12571
12572 test_104b() {
12573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12574         [ $RUNAS_ID -eq $UID ] &&
12575                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12576
12577         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12578                         grep "Permission denied" | wc -l)))
12579         if [ $denied_cnt -ne 0 ]; then
12580                 error "lfs check servers test failed"
12581         fi
12582 }
12583 run_test 104b "$RUNAS lfs check servers test ===================="
12584
12585 #
12586 # Verify $1 is within range of $2.
12587 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12588 # $1 is <= 2% of $2. Else Fail.
12589 #
12590 value_in_range() {
12591         # Strip all units (M, G, T)
12592         actual=$(echo $1 | tr -d A-Z)
12593         expect=$(echo $2 | tr -d A-Z)
12594
12595         expect_lo=$(($expect * 98 / 100)) # 2% below
12596         expect_hi=$(($expect * 102 / 100)) # 2% above
12597
12598         # permit 2% drift above and below
12599         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12600 }
12601
12602 test_104c() {
12603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12604         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12605
12606         local ost_param="osd-zfs.$FSNAME-OST0000."
12607         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12608         local ofacets=$(get_facets OST)
12609         local mfacets=$(get_facets MDS)
12610         local saved_ost_blocks=
12611         local saved_mdt_blocks=
12612
12613         echo "Before recordsize change"
12614         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12615         df=($(df -h | grep "$MOUNT"$))
12616
12617         # For checking.
12618         echo "lfs output : ${lfs_df[*]}"
12619         echo "df  output : ${df[*]}"
12620
12621         for facet in ${ofacets//,/ }; do
12622                 if [ -z $saved_ost_blocks ]; then
12623                         saved_ost_blocks=$(do_facet $facet \
12624                                 lctl get_param -n $ost_param.blocksize)
12625                         echo "OST Blocksize: $saved_ost_blocks"
12626                 fi
12627                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12628                 do_facet $facet zfs set recordsize=32768 $ost
12629         done
12630
12631         # BS too small. Sufficient for functional testing.
12632         for facet in ${mfacets//,/ }; do
12633                 if [ -z $saved_mdt_blocks ]; then
12634                         saved_mdt_blocks=$(do_facet $facet \
12635                                 lctl get_param -n $mdt_param.blocksize)
12636                         echo "MDT Blocksize: $saved_mdt_blocks"
12637                 fi
12638                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12639                 do_facet $facet zfs set recordsize=32768 $mdt
12640         done
12641
12642         # Give new values chance to reflect change
12643         sleep 2
12644
12645         echo "After recordsize change"
12646         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12647         df_after=($(df -h | grep "$MOUNT"$))
12648
12649         # For checking.
12650         echo "lfs output : ${lfs_df_after[*]}"
12651         echo "df  output : ${df_after[*]}"
12652
12653         # Verify lfs df
12654         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12655                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12656         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12657                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12658         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12659                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12660
12661         # Verify df
12662         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12663                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12664         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12665                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12666         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12667                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12668
12669         # Restore MDT recordize back to original
12670         for facet in ${mfacets//,/ }; do
12671                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12672                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12673         done
12674
12675         # Restore OST recordize back to original
12676         for facet in ${ofacets//,/ }; do
12677                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12678                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12679         done
12680
12681         return 0
12682 }
12683 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12684
12685 test_104d() {
12686         (( $RUNAS_ID != $UID )) ||
12687                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12688
12689         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12690                 skip "lustre version doesn't support lctl dl with non-root"
12691
12692         # debugfs only allows root users to access files, so the
12693         # previous move of the "devices" file to debugfs broke
12694         # "lctl dl" for non-root users. The LU-9680 Netlink
12695         # interface again allows non-root users to list devices.
12696         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12697                 error "lctl dl doesn't work for non root"
12698
12699         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12700         [ "$ost_count" -eq $OSTCOUNT ]  ||
12701                 error "lctl dl reports wrong number of OST devices"
12702
12703         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12704         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12705                 error "lctl dl reports wrong number of MDT devices"
12706 }
12707 run_test 104d "$RUNAS lctl dl test"
12708
12709 test_105a() {
12710         # doesn't work on 2.4 kernels
12711         touch $DIR/$tfile
12712         if $(flock_is_enabled); then
12713                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12714         else
12715                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12716         fi
12717         rm -f $DIR/$tfile
12718 }
12719 run_test 105a "flock when mounted without -o flock test ========"
12720
12721 test_105b() {
12722         touch $DIR/$tfile
12723         if $(flock_is_enabled); then
12724                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12725         else
12726                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12727         fi
12728         rm -f $DIR/$tfile
12729 }
12730 run_test 105b "fcntl when mounted without -o flock test ========"
12731
12732 test_105c() {
12733         touch $DIR/$tfile
12734         if $(flock_is_enabled); then
12735                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12736         else
12737                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12738         fi
12739         rm -f $DIR/$tfile
12740 }
12741 run_test 105c "lockf when mounted without -o flock test"
12742
12743 test_105d() { # bug 15924
12744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12745
12746         test_mkdir $DIR/$tdir
12747         flock_is_enabled || skip_env "mount w/o flock enabled"
12748         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12749         $LCTL set_param fail_loc=0x80000315
12750         flocks_test 2 $DIR/$tdir
12751 }
12752 run_test 105d "flock race (should not freeze) ========"
12753
12754 test_105e() { # bug 22660 && 22040
12755         flock_is_enabled || skip_env "mount w/o flock enabled"
12756
12757         touch $DIR/$tfile
12758         flocks_test 3 $DIR/$tfile
12759 }
12760 run_test 105e "Two conflicting flocks from same process"
12761
12762 test_106() { #bug 10921
12763         test_mkdir $DIR/$tdir
12764         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12765         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12766 }
12767 run_test 106 "attempt exec of dir followed by chown of that dir"
12768
12769 test_107() {
12770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12771
12772         CDIR=`pwd`
12773         local file=core
12774
12775         cd $DIR
12776         rm -f $file
12777
12778         local save_pattern=$(sysctl -n kernel.core_pattern)
12779         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12780         sysctl -w kernel.core_pattern=$file
12781         sysctl -w kernel.core_uses_pid=0
12782
12783         ulimit -c unlimited
12784         sleep 60 &
12785         SLEEPPID=$!
12786
12787         sleep 1
12788
12789         kill -s 11 $SLEEPPID
12790         wait $SLEEPPID
12791         if [ -e $file ]; then
12792                 size=`stat -c%s $file`
12793                 [ $size -eq 0 ] && error "Fail to create core file $file"
12794         else
12795                 error "Fail to create core file $file"
12796         fi
12797         rm -f $file
12798         sysctl -w kernel.core_pattern=$save_pattern
12799         sysctl -w kernel.core_uses_pid=$save_uses_pid
12800         cd $CDIR
12801 }
12802 run_test 107 "Coredump on SIG"
12803
12804 test_110() {
12805         test_mkdir $DIR/$tdir
12806         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12807         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12808                 error "mkdir with 256 char should fail, but did not"
12809         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12810                 error "create with 255 char failed"
12811         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12812                 error "create with 256 char should fail, but did not"
12813
12814         ls -l $DIR/$tdir
12815         rm -rf $DIR/$tdir
12816 }
12817 run_test 110 "filename length checking"
12818
12819 test_116a() { # was previously test_116()
12820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12822         remote_mds_nodsh && skip "remote MDS with nodsh"
12823
12824         echo -n "Free space priority "
12825         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12826                 head -n1
12827         declare -a AVAIL
12828         free_min_max
12829
12830         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12831         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12832         stack_trap simple_cleanup_common
12833
12834         # Check if we need to generate uneven OSTs
12835         test_mkdir -p $DIR/$tdir/OST${MINI}
12836         local FILL=$((MINV / 4))
12837         local DIFF=$((MAXV - MINV))
12838         local DIFF2=$((DIFF * 100 / MINV))
12839
12840         local threshold=$(do_facet $SINGLEMDS \
12841                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12842         threshold=${threshold%%%}
12843         echo -n "Check for uneven OSTs: "
12844         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12845
12846         if [[ $DIFF2 -gt $threshold ]]; then
12847                 echo "ok"
12848                 echo "Don't need to fill OST$MINI"
12849         else
12850                 # generate uneven OSTs. Write 2% over the QOS threshold value
12851                 echo "no"
12852                 DIFF=$((threshold - DIFF2 + 2))
12853                 DIFF2=$((MINV * DIFF / 100))
12854                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12855                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12856                         error "setstripe failed"
12857                 DIFF=$((DIFF2 / 2048))
12858                 i=0
12859                 while [ $i -lt $DIFF ]; do
12860                         i=$((i + 1))
12861                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12862                                 bs=2M count=1 2>/dev/null
12863                         echo -n .
12864                 done
12865                 echo .
12866                 sync
12867                 sleep_maxage
12868                 free_min_max
12869         fi
12870
12871         DIFF=$((MAXV - MINV))
12872         DIFF2=$((DIFF * 100 / MINV))
12873         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12874         if [ $DIFF2 -gt $threshold ]; then
12875                 echo "ok"
12876         else
12877                 skip "QOS imbalance criteria not met"
12878         fi
12879
12880         MINI1=$MINI
12881         MINV1=$MINV
12882         MAXI1=$MAXI
12883         MAXV1=$MAXV
12884
12885         # now fill using QOS
12886         $LFS setstripe -c 1 $DIR/$tdir
12887         FILL=$((FILL / 200))
12888         if [ $FILL -gt 600 ]; then
12889                 FILL=600
12890         fi
12891         echo "writing $FILL files to QOS-assigned OSTs"
12892         i=0
12893         while [ $i -lt $FILL ]; do
12894                 i=$((i + 1))
12895                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12896                         count=1 2>/dev/null
12897                 echo -n .
12898         done
12899         echo "wrote $i 200k files"
12900         sync
12901         sleep_maxage
12902
12903         echo "Note: free space may not be updated, so measurements might be off"
12904         free_min_max
12905         DIFF2=$((MAXV - MINV))
12906         echo "free space delta: orig $DIFF final $DIFF2"
12907         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12908         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12909         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12910         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12911         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12912         if [[ $DIFF -gt 0 ]]; then
12913                 FILL=$((DIFF2 * 100 / DIFF - 100))
12914                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12915         fi
12916
12917         # Figure out which files were written where
12918         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12919                awk '/'$MINI1': / {print $2; exit}')
12920         echo $UUID
12921         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12922         echo "$MINC files created on smaller OST $MINI1"
12923         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12924                awk '/'$MAXI1': / {print $2; exit}')
12925         echo $UUID
12926         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12927         echo "$MAXC files created on larger OST $MAXI1"
12928         if [[ $MINC -gt 0 ]]; then
12929                 FILL=$((MAXC * 100 / MINC - 100))
12930                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12931         fi
12932         [[ $MAXC -gt $MINC ]] ||
12933                 error_ignore LU-9 "stripe QOS didn't balance free space"
12934 }
12935 run_test 116a "stripe QOS: free space balance ==================="
12936
12937 test_116b() { # LU-2093
12938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12939         remote_mds_nodsh && skip "remote MDS with nodsh"
12940
12941 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12942         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12943                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12944         [ -z "$old_rr" ] && skip "no QOS"
12945         do_facet $SINGLEMDS lctl set_param \
12946                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12947         mkdir -p $DIR/$tdir
12948         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12949         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12950         do_facet $SINGLEMDS lctl set_param fail_loc=0
12951         rm -rf $DIR/$tdir
12952         do_facet $SINGLEMDS lctl set_param \
12953                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12954 }
12955 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12956
12957 test_117() # bug 10891
12958 {
12959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12960
12961         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12962         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12963         lctl set_param fail_loc=0x21e
12964         > $DIR/$tfile || error "truncate failed"
12965         lctl set_param fail_loc=0
12966         echo "Truncate succeeded."
12967         rm -f $DIR/$tfile
12968 }
12969 run_test 117 "verify osd extend =========="
12970
12971 NO_SLOW_RESENDCOUNT=4
12972 export OLD_RESENDCOUNT=""
12973 set_resend_count () {
12974         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12975         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12976         lctl set_param -n $PROC_RESENDCOUNT $1
12977         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12978 }
12979
12980 # for reduce test_118* time (b=14842)
12981 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12982
12983 # Reset async IO behavior after error case
12984 reset_async() {
12985         FILE=$DIR/reset_async
12986
12987         # Ensure all OSCs are cleared
12988         $LFS setstripe -c -1 $FILE
12989         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12990         sync
12991         rm $FILE
12992 }
12993
12994 test_118a() #bug 11710
12995 {
12996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12997
12998         reset_async
12999
13000         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13001         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13002         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13003
13004         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13005                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13006                 return 1;
13007         fi
13008         rm -f $DIR/$tfile
13009 }
13010 run_test 118a "verify O_SYNC works =========="
13011
13012 test_118b()
13013 {
13014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13015         remote_ost_nodsh && skip "remote OST with nodsh"
13016
13017         reset_async
13018
13019         #define OBD_FAIL_SRV_ENOENT 0x217
13020         set_nodes_failloc "$(osts_nodes)" 0x217
13021         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13022         RC=$?
13023         set_nodes_failloc "$(osts_nodes)" 0
13024         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13025         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13026                     grep -c writeback)
13027
13028         if [[ $RC -eq 0 ]]; then
13029                 error "Must return error due to dropped pages, rc=$RC"
13030                 return 1;
13031         fi
13032
13033         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13034                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13035                 return 1;
13036         fi
13037
13038         echo "Dirty pages not leaked on ENOENT"
13039
13040         # Due to the above error the OSC will issue all RPCs syncronously
13041         # until a subsequent RPC completes successfully without error.
13042         $MULTIOP $DIR/$tfile Ow4096yc
13043         rm -f $DIR/$tfile
13044
13045         return 0
13046 }
13047 run_test 118b "Reclaim dirty pages on fatal error =========="
13048
13049 test_118c()
13050 {
13051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13052
13053         # for 118c, restore the original resend count, LU-1940
13054         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13055                                 set_resend_count $OLD_RESENDCOUNT
13056         remote_ost_nodsh && skip "remote OST with nodsh"
13057
13058         reset_async
13059
13060         #define OBD_FAIL_OST_EROFS               0x216
13061         set_nodes_failloc "$(osts_nodes)" 0x216
13062
13063         # multiop should block due to fsync until pages are written
13064         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13065         MULTIPID=$!
13066         sleep 1
13067
13068         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13069                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13070         fi
13071
13072         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13073                     grep -c writeback)
13074         if [[ $WRITEBACK -eq 0 ]]; then
13075                 error "No page in writeback, writeback=$WRITEBACK"
13076         fi
13077
13078         set_nodes_failloc "$(osts_nodes)" 0
13079         wait $MULTIPID
13080         RC=$?
13081         if [[ $RC -ne 0 ]]; then
13082                 error "Multiop fsync failed, rc=$RC"
13083         fi
13084
13085         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13086         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13087                     grep -c writeback)
13088         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13089                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13090         fi
13091
13092         rm -f $DIR/$tfile
13093         echo "Dirty pages flushed via fsync on EROFS"
13094         return 0
13095 }
13096 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13097
13098 # continue to use small resend count to reduce test_118* time (b=14842)
13099 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13100
13101 test_118d()
13102 {
13103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13104         remote_ost_nodsh && skip "remote OST with nodsh"
13105
13106         reset_async
13107
13108         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13109         set_nodes_failloc "$(osts_nodes)" 0x214
13110         # multiop should block due to fsync until pages are written
13111         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13112         MULTIPID=$!
13113         sleep 1
13114
13115         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13116                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13117         fi
13118
13119         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13120                     grep -c writeback)
13121         if [[ $WRITEBACK -eq 0 ]]; then
13122                 error "No page in writeback, writeback=$WRITEBACK"
13123         fi
13124
13125         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13126         set_nodes_failloc "$(osts_nodes)" 0
13127
13128         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13129         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13130                     grep -c writeback)
13131         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13132                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13133         fi
13134
13135         rm -f $DIR/$tfile
13136         echo "Dirty pages gaurenteed flushed via fsync"
13137         return 0
13138 }
13139 run_test 118d "Fsync validation inject a delay of the bulk =========="
13140
13141 test_118f() {
13142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13143
13144         reset_async
13145
13146         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13147         lctl set_param fail_loc=0x8000040a
13148
13149         # Should simulate EINVAL error which is fatal
13150         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13151         RC=$?
13152         if [[ $RC -eq 0 ]]; then
13153                 error "Must return error due to dropped pages, rc=$RC"
13154         fi
13155
13156         lctl set_param fail_loc=0x0
13157
13158         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13159         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13160         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13161                     grep -c writeback)
13162         if [[ $LOCKED -ne 0 ]]; then
13163                 error "Locked pages remain in cache, locked=$LOCKED"
13164         fi
13165
13166         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13167                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13168         fi
13169
13170         rm -f $DIR/$tfile
13171         echo "No pages locked after fsync"
13172
13173         reset_async
13174         return 0
13175 }
13176 run_test 118f "Simulate unrecoverable OSC side error =========="
13177
13178 test_118g() {
13179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13180
13181         reset_async
13182
13183         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13184         lctl set_param fail_loc=0x406
13185
13186         # simulate local -ENOMEM
13187         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13188         RC=$?
13189
13190         lctl set_param fail_loc=0
13191         if [[ $RC -eq 0 ]]; then
13192                 error "Must return error due to dropped pages, rc=$RC"
13193         fi
13194
13195         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13196         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13197         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13198                         grep -c writeback)
13199         if [[ $LOCKED -ne 0 ]]; then
13200                 error "Locked pages remain in cache, locked=$LOCKED"
13201         fi
13202
13203         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13204                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13205         fi
13206
13207         rm -f $DIR/$tfile
13208         echo "No pages locked after fsync"
13209
13210         reset_async
13211         return 0
13212 }
13213 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13214
13215 test_118h() {
13216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13217         remote_ost_nodsh && skip "remote OST with nodsh"
13218
13219         reset_async
13220
13221         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13222         set_nodes_failloc "$(osts_nodes)" 0x20e
13223         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13224         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13225         RC=$?
13226
13227         set_nodes_failloc "$(osts_nodes)" 0
13228         if [[ $RC -eq 0 ]]; then
13229                 error "Must return error due to dropped pages, rc=$RC"
13230         fi
13231
13232         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13233         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13234         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13235                     grep -c writeback)
13236         if [[ $LOCKED -ne 0 ]]; then
13237                 error "Locked pages remain in cache, locked=$LOCKED"
13238         fi
13239
13240         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13241                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13242         fi
13243
13244         rm -f $DIR/$tfile
13245         echo "No pages locked after fsync"
13246
13247         return 0
13248 }
13249 run_test 118h "Verify timeout in handling recoverables errors  =========="
13250
13251 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13252
13253 test_118i() {
13254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13255         remote_ost_nodsh && skip "remote OST with nodsh"
13256
13257         reset_async
13258
13259         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13260         set_nodes_failloc "$(osts_nodes)" 0x20e
13261
13262         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13263         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13264         PID=$!
13265         sleep 5
13266         set_nodes_failloc "$(osts_nodes)" 0
13267
13268         wait $PID
13269         RC=$?
13270         if [[ $RC -ne 0 ]]; then
13271                 error "got error, but should be not, rc=$RC"
13272         fi
13273
13274         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13275         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13276         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13277         if [[ $LOCKED -ne 0 ]]; then
13278                 error "Locked pages remain in cache, locked=$LOCKED"
13279         fi
13280
13281         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13282                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13283         fi
13284
13285         rm -f $DIR/$tfile
13286         echo "No pages locked after fsync"
13287
13288         return 0
13289 }
13290 run_test 118i "Fix error before timeout in recoverable error  =========="
13291
13292 [ "$SLOW" = "no" ] && set_resend_count 4
13293
13294 test_118j() {
13295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13296         remote_ost_nodsh && skip "remote OST with nodsh"
13297
13298         reset_async
13299
13300         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13301         set_nodes_failloc "$(osts_nodes)" 0x220
13302
13303         # return -EIO from OST
13304         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13305         RC=$?
13306         set_nodes_failloc "$(osts_nodes)" 0x0
13307         if [[ $RC -eq 0 ]]; then
13308                 error "Must return error due to dropped pages, rc=$RC"
13309         fi
13310
13311         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13312         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13313         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13314         if [[ $LOCKED -ne 0 ]]; then
13315                 error "Locked pages remain in cache, locked=$LOCKED"
13316         fi
13317
13318         # in recoverable error on OST we want resend and stay until it finished
13319         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13320                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13321         fi
13322
13323         rm -f $DIR/$tfile
13324         echo "No pages locked after fsync"
13325
13326         return 0
13327 }
13328 run_test 118j "Simulate unrecoverable OST side error =========="
13329
13330 test_118k()
13331 {
13332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13333         remote_ost_nodsh && skip "remote OSTs with nodsh"
13334
13335         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13336         set_nodes_failloc "$(osts_nodes)" 0x20e
13337         test_mkdir $DIR/$tdir
13338
13339         for ((i=0;i<10;i++)); do
13340                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13341                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13342                 SLEEPPID=$!
13343                 sleep 0.500s
13344                 kill $SLEEPPID
13345                 wait $SLEEPPID
13346         done
13347
13348         set_nodes_failloc "$(osts_nodes)" 0
13349         rm -rf $DIR/$tdir
13350 }
13351 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13352
13353 test_118l() # LU-646
13354 {
13355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13356
13357         test_mkdir $DIR/$tdir
13358         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13359         rm -rf $DIR/$tdir
13360 }
13361 run_test 118l "fsync dir"
13362
13363 test_118m() # LU-3066
13364 {
13365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13366
13367         test_mkdir $DIR/$tdir
13368         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13369         rm -rf $DIR/$tdir
13370 }
13371 run_test 118m "fdatasync dir ========="
13372
13373 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13374
13375 test_118n()
13376 {
13377         local begin
13378         local end
13379
13380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13381         remote_ost_nodsh && skip "remote OSTs with nodsh"
13382
13383         # Sleep to avoid a cached response.
13384         #define OBD_STATFS_CACHE_SECONDS 1
13385         sleep 2
13386
13387         # Inject a 10 second delay in the OST_STATFS handler.
13388         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13389         set_nodes_failloc "$(osts_nodes)" 0x242
13390
13391         begin=$SECONDS
13392         stat --file-system $MOUNT > /dev/null
13393         end=$SECONDS
13394
13395         set_nodes_failloc "$(osts_nodes)" 0
13396
13397         if ((end - begin > 20)); then
13398             error "statfs took $((end - begin)) seconds, expected 10"
13399         fi
13400 }
13401 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13402
13403 test_119a() # bug 11737
13404 {
13405         BSIZE=$((512 * 1024))
13406         directio write $DIR/$tfile 0 1 $BSIZE
13407         # We ask to read two blocks, which is more than a file size.
13408         # directio will indicate an error when requested and actual
13409         # sizes aren't equeal (a normal situation in this case) and
13410         # print actual read amount.
13411         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13412         if [ "$NOB" != "$BSIZE" ]; then
13413                 error "read $NOB bytes instead of $BSIZE"
13414         fi
13415         rm -f $DIR/$tfile
13416 }
13417 run_test 119a "Short directIO read must return actual read amount"
13418
13419 test_119b() # bug 11737
13420 {
13421         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13422
13423         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13424         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13425         sync
13426         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13427                 error "direct read failed"
13428         rm -f $DIR/$tfile
13429 }
13430 run_test 119b "Sparse directIO read must return actual read amount"
13431
13432 test_119c() # bug 13099
13433 {
13434         BSIZE=1048576
13435         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13436         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13437         rm -f $DIR/$tfile
13438 }
13439 run_test 119c "Testing for direct read hitting hole"
13440
13441 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13442 # Maloo test history
13443
13444 test_119e()
13445 {
13446         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13447
13448         local stripe_size=$((1024 * 1024)) #1 MiB
13449         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13450         local file_size=$((25 * stripe_size))
13451         local bsizes
13452
13453         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13454         stack_trap "rm -f $DIR/$tfile*"
13455
13456         # Just a bit bigger than the largest size in the test set below
13457         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13458                 error "buffered i/o to create file failed"
13459
13460         if zfs_or_rotational; then
13461                 # DIO on ZFS can take up to 2 seconds per IO
13462                 # rotational is better, but still slow.
13463                 # Limit testing on those media to larger sizes
13464                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13465         else
13466                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13467                         $((stripe_size * 4))"
13468         fi
13469
13470         for bs in $bsizes; do
13471                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13472                 echo "Read/write with DIO at size $bs"
13473                 # Read and write with DIO from source to dest
13474                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13475                         iflag=direct oflag=direct ||
13476                         error "dio failed"
13477
13478                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13479                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13480                         error "size incorrect, file copy read/write bsize: $bs"
13481                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13482                         error "files differ, bsize $bs"
13483                 rm -f $DIR/$tfile.2
13484         done
13485 }
13486 run_test 119e "Basic tests of dio read and write at various sizes"
13487
13488 test_119f()
13489 {
13490         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13491
13492         local stripe_size=$((1024 * 1024)) #1 MiB
13493         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13494         local file_size=$((25 * stripe_size))
13495         local bsizes
13496
13497         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13498         stack_trap "rm -f $DIR/$tfile*"
13499
13500         # Just a bit bigger than the largest size in the test set below
13501         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13502                 error "buffered i/o to create file failed"
13503
13504         if zfs_or_rotational; then
13505                 # DIO on ZFS can take up to 2 seconds per IO
13506                 # rotational is better, but still slow.
13507                 # Limit testing on those media to larger sizes
13508                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13509         else
13510                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13511                         $((stripe_size * 4))"
13512         fi
13513
13514         for bs in $bsizes; do
13515                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13516                 # Read and write with DIO from source to dest in two
13517                 # threads - should give correct copy of file
13518
13519                 echo "bs: $bs"
13520                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13521                         oflag=direct conv=notrunc &
13522                 pid_dio1=$!
13523                 # Note block size is different here for a more interesting race
13524                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13525                         iflag=direct oflag=direct conv=notrunc &
13526                 pid_dio2=$!
13527                 wait $pid_dio1
13528                 rc1=$?
13529                 wait $pid_dio2
13530                 rc2=$?
13531                 if (( rc1 != 0 )); then
13532                         error "dio copy 1 w/bsize $bs failed: $rc1"
13533                 fi
13534                 if (( rc2 != 0 )); then
13535                         error "dio copy 2 w/bsize $bs failed: $rc2"
13536                 fi
13537
13538
13539                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13540                         error "size incorrect, file copy read/write bsize: $bs"
13541                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13542                         error "files differ, bsize $bs"
13543                 rm -f $DIR/$tfile.2
13544         done
13545 }
13546 run_test 119f "dio vs dio race"
13547
13548 test_119g()
13549 {
13550         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13551
13552         local stripe_size=$((1024 * 1024)) #1 MiB
13553         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13554         local file_size=$((25 * stripe_size))
13555         local bsizes
13556
13557         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13558         stack_trap "rm -f $DIR/$tfile*"
13559
13560         # Just a bit bigger than the largest size in the test set below
13561         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13562                 error "buffered i/o to create file failed"
13563
13564         if zfs_or_rotational; then
13565                 # DIO on ZFS can take up to 2 seconds per IO
13566                 # rotational is better, but still slow.
13567                 # Limit testing on those media to larger sizes
13568                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13569         else
13570                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13571                         $((stripe_size * 4))"
13572         fi
13573
13574         for bs in $bsizes; do
13575                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13576                 echo "bs: $bs"
13577                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13578                         oflag=direct conv=notrunc &
13579                 pid_dio1=$!
13580                 # Buffered I/O with similar but not the same block size
13581                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13582                 pid_bio2=$!
13583                 wait $pid_dio1
13584                 rc1=$?
13585                 wait $pid_bio2
13586                 rc2=$?
13587                 if (( rc1 != 0 )); then
13588                         error "dio copy 1 w/bsize $bs failed: $rc1"
13589                 fi
13590                 if (( rc2 != 0 )); then
13591                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13592                 fi
13593
13594                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13595                         error "size incorrect"
13596                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13597                         error "files differ, bsize $bs"
13598                 rm -f $DIR/$tfile.2
13599         done
13600 }
13601 run_test 119g "dio vs buffered I/O race"
13602
13603 test_120a() {
13604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13605         remote_mds_nodsh && skip "remote MDS with nodsh"
13606         test_mkdir -i0 -c1 $DIR/$tdir
13607         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13608                 skip_env "no early lock cancel on server"
13609
13610         lru_resize_disable mdc
13611         lru_resize_disable osc
13612         cancel_lru_locks mdc
13613         # asynchronous object destroy at MDT could cause bl ast to client
13614         cancel_lru_locks osc
13615
13616         stat $DIR/$tdir > /dev/null
13617         can1=$(do_facet mds1 \
13618                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13619                awk '/ldlm_cancel/ {print $2}')
13620         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13621                awk '/ldlm_bl_callback/ {print $2}')
13622         test_mkdir -i0 -c1 $DIR/$tdir/d1
13623         can2=$(do_facet mds1 \
13624                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13625                awk '/ldlm_cancel/ {print $2}')
13626         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13627                awk '/ldlm_bl_callback/ {print $2}')
13628         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13629         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13630         lru_resize_enable mdc
13631         lru_resize_enable osc
13632 }
13633 run_test 120a "Early Lock Cancel: mkdir test"
13634
13635 test_120b() {
13636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13637         remote_mds_nodsh && skip "remote MDS with nodsh"
13638         test_mkdir $DIR/$tdir
13639         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13640                 skip_env "no early lock cancel on server"
13641
13642         lru_resize_disable mdc
13643         lru_resize_disable osc
13644         cancel_lru_locks mdc
13645         stat $DIR/$tdir > /dev/null
13646         can1=$(do_facet $SINGLEMDS \
13647                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13648                awk '/ldlm_cancel/ {print $2}')
13649         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13650                awk '/ldlm_bl_callback/ {print $2}')
13651         touch $DIR/$tdir/f1
13652         can2=$(do_facet $SINGLEMDS \
13653                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13654                awk '/ldlm_cancel/ {print $2}')
13655         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13656                awk '/ldlm_bl_callback/ {print $2}')
13657         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13658         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13659         lru_resize_enable mdc
13660         lru_resize_enable osc
13661 }
13662 run_test 120b "Early Lock Cancel: create test"
13663
13664 test_120c() {
13665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13666         remote_mds_nodsh && skip "remote MDS with nodsh"
13667         test_mkdir -i0 -c1 $DIR/$tdir
13668         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13669                 skip "no early lock cancel on server"
13670
13671         lru_resize_disable mdc
13672         lru_resize_disable osc
13673         test_mkdir -i0 -c1 $DIR/$tdir/d1
13674         test_mkdir -i0 -c1 $DIR/$tdir/d2
13675         touch $DIR/$tdir/d1/f1
13676         cancel_lru_locks mdc
13677         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13678         can1=$(do_facet mds1 \
13679                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13680                awk '/ldlm_cancel/ {print $2}')
13681         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13682                awk '/ldlm_bl_callback/ {print $2}')
13683         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13684         can2=$(do_facet mds1 \
13685                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13686                awk '/ldlm_cancel/ {print $2}')
13687         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13688                awk '/ldlm_bl_callback/ {print $2}')
13689         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13690         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13691         lru_resize_enable mdc
13692         lru_resize_enable osc
13693 }
13694 run_test 120c "Early Lock Cancel: link test"
13695
13696 test_120d() {
13697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13698         remote_mds_nodsh && skip "remote MDS with nodsh"
13699         test_mkdir -i0 -c1 $DIR/$tdir
13700         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13701                 skip_env "no early lock cancel on server"
13702
13703         lru_resize_disable mdc
13704         lru_resize_disable osc
13705         touch $DIR/$tdir
13706         cancel_lru_locks mdc
13707         stat $DIR/$tdir > /dev/null
13708         can1=$(do_facet mds1 \
13709                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13710                awk '/ldlm_cancel/ {print $2}')
13711         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13712                awk '/ldlm_bl_callback/ {print $2}')
13713         chmod a+x $DIR/$tdir
13714         can2=$(do_facet mds1 \
13715                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13716                awk '/ldlm_cancel/ {print $2}')
13717         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13718                awk '/ldlm_bl_callback/ {print $2}')
13719         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13720         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13721         lru_resize_enable mdc
13722         lru_resize_enable osc
13723 }
13724 run_test 120d "Early Lock Cancel: setattr test"
13725
13726 test_120e() {
13727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13728         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13729                 skip_env "no early lock cancel on server"
13730         remote_mds_nodsh && skip "remote MDS with nodsh"
13731
13732         local dlmtrace_set=false
13733
13734         test_mkdir -i0 -c1 $DIR/$tdir
13735         lru_resize_disable mdc
13736         lru_resize_disable osc
13737         ! $LCTL get_param debug | grep -q dlmtrace &&
13738                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13739         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13740         cancel_lru_locks mdc
13741         cancel_lru_locks osc
13742         dd if=$DIR/$tdir/f1 of=/dev/null
13743         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13744         # XXX client can not do early lock cancel of OST lock
13745         # during unlink (LU-4206), so cancel osc lock now.
13746         sleep 2
13747         cancel_lru_locks osc
13748         can1=$(do_facet mds1 \
13749                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13750                awk '/ldlm_cancel/ {print $2}')
13751         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13752                awk '/ldlm_bl_callback/ {print $2}')
13753         unlink $DIR/$tdir/f1
13754         sleep 5
13755         can2=$(do_facet mds1 \
13756                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13757                awk '/ldlm_cancel/ {print $2}')
13758         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13759                awk '/ldlm_bl_callback/ {print $2}')
13760         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13761                 $LCTL dk $TMP/cancel.debug.txt
13762         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13763                 $LCTL dk $TMP/blocking.debug.txt
13764         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13765         lru_resize_enable mdc
13766         lru_resize_enable osc
13767 }
13768 run_test 120e "Early Lock Cancel: unlink test"
13769
13770 test_120f() {
13771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13772         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13773                 skip_env "no early lock cancel on server"
13774         remote_mds_nodsh && skip "remote MDS with nodsh"
13775
13776         test_mkdir -i0 -c1 $DIR/$tdir
13777         lru_resize_disable mdc
13778         lru_resize_disable osc
13779         test_mkdir -i0 -c1 $DIR/$tdir/d1
13780         test_mkdir -i0 -c1 $DIR/$tdir/d2
13781         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13782         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13783         cancel_lru_locks mdc
13784         cancel_lru_locks osc
13785         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13786         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13787         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13788         # XXX client can not do early lock cancel of OST lock
13789         # during rename (LU-4206), so cancel osc lock now.
13790         sleep 2
13791         cancel_lru_locks osc
13792         can1=$(do_facet mds1 \
13793                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13794                awk '/ldlm_cancel/ {print $2}')
13795         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13796                awk '/ldlm_bl_callback/ {print $2}')
13797         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13798         sleep 5
13799         can2=$(do_facet mds1 \
13800                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13801                awk '/ldlm_cancel/ {print $2}')
13802         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13803                awk '/ldlm_bl_callback/ {print $2}')
13804         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13805         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13806         lru_resize_enable mdc
13807         lru_resize_enable osc
13808 }
13809 run_test 120f "Early Lock Cancel: rename test"
13810
13811 test_120g() {
13812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13813         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13814                 skip_env "no early lock cancel on server"
13815         remote_mds_nodsh && skip "remote MDS with nodsh"
13816
13817         lru_resize_disable mdc
13818         lru_resize_disable osc
13819         count=10000
13820         echo create $count files
13821         test_mkdir $DIR/$tdir
13822         cancel_lru_locks mdc
13823         cancel_lru_locks osc
13824         t0=$(date +%s)
13825
13826         can0=$(do_facet $SINGLEMDS \
13827                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13828                awk '/ldlm_cancel/ {print $2}')
13829         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13830                awk '/ldlm_bl_callback/ {print $2}')
13831         createmany -o $DIR/$tdir/f $count
13832         sync
13833         can1=$(do_facet $SINGLEMDS \
13834                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13835                awk '/ldlm_cancel/ {print $2}')
13836         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13837                awk '/ldlm_bl_callback/ {print $2}')
13838         t1=$(date +%s)
13839         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13840         echo rm $count files
13841         rm -r $DIR/$tdir
13842         sync
13843         can2=$(do_facet $SINGLEMDS \
13844                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13845                awk '/ldlm_cancel/ {print $2}')
13846         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13847                awk '/ldlm_bl_callback/ {print $2}')
13848         t2=$(date +%s)
13849         echo total: $count removes in $((t2-t1))
13850         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13851         sleep 2
13852         # wait for commitment of removal
13853         lru_resize_enable mdc
13854         lru_resize_enable osc
13855 }
13856 run_test 120g "Early Lock Cancel: performance test"
13857
13858 test_121() { #bug #10589
13859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13860
13861         rm -rf $DIR/$tfile
13862         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13863 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13864         lctl set_param fail_loc=0x310
13865         cancel_lru_locks osc > /dev/null
13866         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13867         lctl set_param fail_loc=0
13868         [[ $reads -eq $writes ]] ||
13869                 error "read $reads blocks, must be $writes blocks"
13870 }
13871 run_test 121 "read cancel race ========="
13872
13873 test_123a_base() { # was test 123, statahead(bug 11401)
13874         local lsx="$1"
13875
13876         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13877
13878         SLOWOK=0
13879         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13880                 log "testing UP system. Performance may be lower than expected."
13881                 SLOWOK=1
13882         fi
13883         running_in_vm && SLOWOK=1
13884
13885         $LCTL set_param mdc.*.batch_stats=0
13886
13887         rm -rf $DIR/$tdir
13888         test_mkdir $DIR/$tdir
13889         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13890         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13891         MULT=10
13892         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13893                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13894
13895                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13896                 lctl set_param -n llite.*.statahead_max 0
13897                 lctl get_param llite.*.statahead_max
13898                 cancel_lru_locks mdc
13899                 cancel_lru_locks osc
13900                 stime=$(date +%s)
13901                 time $lsx $DIR/$tdir | wc -l
13902                 etime=$(date +%s)
13903                 delta=$((etime - stime))
13904                 log "$lsx $i files without statahead: $delta sec"
13905                 lctl set_param llite.*.statahead_max=$max
13906
13907                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13908                          awk '/statahead.wrong:/ { print $NF }')
13909                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13910                 cancel_lru_locks mdc
13911                 cancel_lru_locks osc
13912                 stime=$(date +%s)
13913                 time $lsx $DIR/$tdir | wc -l
13914                 etime=$(date +%s)
13915                 delta_sa=$((etime - stime))
13916                 log "$lsx $i files with statahead: $delta_sa sec"
13917                 lctl get_param -n llite.*.statahead_stats
13918                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13919                          awk '/statahead.wrong:/ { print $NF }')
13920
13921                 [[ $swrong -lt $ewrong ]] &&
13922                         log "statahead was stopped, maybe too many locks held!"
13923                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13924
13925                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13926                         max=$(lctl get_param -n llite.*.statahead_max |
13927                                 head -n 1)
13928                         lctl set_param -n llite.*.statahead_max 0
13929                         lctl get_param llite.*.statahead_max
13930                         cancel_lru_locks mdc
13931                         cancel_lru_locks osc
13932                         stime=$(date +%s)
13933                         time $lsx $DIR/$tdir | wc -l
13934                         etime=$(date +%s)
13935                         delta=$((etime - stime))
13936                         log "$lsx $i files again without statahead: $delta sec"
13937                         lctl set_param llite.*.statahead_max=$max
13938                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13939                                 if [ $SLOWOK -eq 0 ]; then
13940                                         error "$lsx $i files is slower with statahead!"
13941                                 else
13942                                         log "$lsx $i files is slower with statahead!"
13943                                 fi
13944                                 break
13945                         fi
13946                 fi
13947
13948                 [ $delta -gt 20 ] && break
13949                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13950                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13951         done
13952         log "$lsx done"
13953
13954         stime=$(date +%s)
13955         rm -r $DIR/$tdir
13956         sync
13957         etime=$(date +%s)
13958         delta=$((etime - stime))
13959         log "rm -r $DIR/$tdir/: $delta seconds"
13960         log "rm done"
13961         lctl get_param -n llite.*.statahead_stats
13962         $LCTL get_param mdc.*.batch_stats
13963 }
13964
13965 test_123aa() {
13966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13967
13968         test_123a_base "ls -l"
13969 }
13970 run_test 123aa "verify statahead work"
13971
13972 test_123ab() {
13973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13974
13975         statx_supported || skip_env "Test must be statx() syscall supported"
13976
13977         test_123a_base "$STATX -l"
13978 }
13979 run_test 123ab "verify statahead work by using statx"
13980
13981 test_123ac() {
13982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13983
13984         statx_supported || skip_env "Test must be statx() syscall supported"
13985
13986         local rpcs_before
13987         local rpcs_after
13988         local agl_before
13989         local agl_after
13990
13991         cancel_lru_locks $OSC
13992         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13993         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13994                      awk '/agl.total:/ { print $NF }')
13995         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13996         test_123a_base "$STATX --cached=always -D"
13997         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13998                     awk '/agl.total:/ { print $NF }')
13999         [ $agl_before -eq $agl_after ] ||
14000                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14001         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14002         [ $rpcs_after -eq $rpcs_before ] ||
14003                 error "$STATX should not send glimpse RPCs to $OSC"
14004 }
14005 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14006
14007 test_batch_statahead() {
14008         local max=$1
14009         local batch_max=$2
14010         local num=10000
14011         local batch_rpcs
14012         local unbatch_rpcs
14013         local hit_total
14014
14015         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14016         $LCTL set_param mdc.*.batch_stats=0
14017         $LCTL set_param llite.*.statahead_max=$max
14018         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14019         # Verify that batched statahead is faster than one without statahead
14020         test_123a_base "ls -l"
14021
14022         stack_trap "rm -rf $DIR/$tdir" EXIT
14023         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14024         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14025
14026         # unbatched statahead
14027         $LCTL set_param llite.*.statahead_batch_max=0
14028         $LCTL set_param llite.*.statahead_stats=clear
14029         $LCTL set_param mdc.*.stats=clear
14030         cancel_lru_locks mdc
14031         cancel_lru_locks osc
14032         time ls -l $DIR/$tdir | wc -l
14033         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14034         sleep 2
14035         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14036                     awk '/hit.total:/ { print $NF }')
14037         # hit ratio should be larger than 75% (7500).
14038         (( $hit_total > 7500 )) ||
14039                 error "unbatched statahead hit count ($hit_total) is too low"
14040
14041         # batched statahead
14042         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14043         $LCTL set_param llite.*.statahead_stats=clear
14044         $LCTL set_param mdc.*.batch_stats=clear
14045         $LCTL set_param mdc.*.stats=clear
14046         cancel_lru_locks mdc
14047         cancel_lru_locks osc
14048         time ls -l $DIR/$tdir | wc -l
14049         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14050         # wait for statahead thread to quit and update statahead stats
14051         sleep 2
14052         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14053                     awk '/hit.total:/ { print $NF }')
14054         # hit ratio should be larger than 75% (7500).
14055         (( $hit_total > 7500 )) ||
14056                 error "batched statahead hit count ($hit_total) is too low"
14057
14058         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14059         (( $unbatch_rpcs > $batch_rpcs )) ||
14060                 error "batched statahead does not reduce RPC count"
14061         $LCTL get_param mdc.*.batch_stats
14062 }
14063
14064 test_123ad() {
14065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14066
14067         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14068                 skip "Need server version at least 2.15.53"
14069
14070         local max
14071         local batch_max
14072
14073         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14074         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14075
14076         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14077         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14078
14079         test_batch_statahead 32 32
14080         test_batch_statahead 2048 256
14081 }
14082 run_test 123ad "Verify batching statahead works correctly"
14083
14084 test_123b () { # statahead(bug 15027)
14085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14086
14087         test_mkdir $DIR/$tdir
14088         createmany -o $DIR/$tdir/$tfile-%d 1000
14089
14090         cancel_lru_locks mdc
14091         cancel_lru_locks osc
14092
14093 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14094         lctl set_param fail_loc=0x80000803
14095         ls -lR $DIR/$tdir > /dev/null
14096         log "ls done"
14097         lctl set_param fail_loc=0x0
14098         lctl get_param -n llite.*.statahead_stats
14099         rm -r $DIR/$tdir
14100         sync
14101
14102 }
14103 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14104
14105 test_123c() {
14106         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14107
14108         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14109         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14110         touch $DIR/$tdir.1/{1..3}
14111         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14112
14113         remount_client $MOUNT
14114
14115         $MULTIOP $DIR/$tdir.0 Q
14116
14117         # let statahead to complete
14118         ls -l $DIR/$tdir.0 > /dev/null
14119
14120         testid=$(echo $TESTNAME | tr '_' ' ')
14121         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14122                 error "statahead warning" || true
14123 }
14124 run_test 123c "Can not initialize inode warning on DNE statahead"
14125
14126 test_123d() {
14127         local num=100
14128         local swrong
14129         local ewrong
14130
14131         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14132         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14133                 error "setdirstripe $DIR/$tdir failed"
14134         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14135         remount_client $MOUNT
14136         $LCTL get_param llite.*.statahead_max
14137         $LCTL set_param llite.*.statahead_stats=0 ||
14138                 error "clear statahead_stats failed"
14139         swrong=$(lctl get_param -n llite.*.statahead_stats |
14140                  awk '/statahead.wrong:/ { print $NF }')
14141         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14142         # wait for statahead thread finished to update hit/miss stats.
14143         sleep 1
14144         $LCTL get_param -n llite.*.statahead_stats
14145         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14146                  awk '/statahead.wrong:/ { print $NF }')
14147         (( $swrong == $ewrong )) ||
14148                 log "statahead was stopped, maybe too many locks held!"
14149 }
14150 run_test 123d "Statahead on striped directories works correctly"
14151
14152 test_123e() {
14153         local max
14154         local batch_max
14155         local dir=$DIR/$tdir
14156
14157         mkdir $dir || error "mkdir $dir failed"
14158         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14159         stack_trap "rm -rf $dir"
14160
14161         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14162
14163         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14164         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14165         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14166         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14167
14168         $LCTL set_param llite.*.statahead_max=2048
14169         $LCTL set_param llite.*.statahead_batch_max=1024
14170
14171         ls -l $dir
14172         $LCTL get_param mdc.*.batch_stats
14173         $LCTL get_param llite.*.statahead_*
14174 }
14175 run_test 123e "statahead with large wide striping"
14176
14177 test_123f() {
14178         local max
14179         local batch_max
14180         local dir=$DIR/$tdir
14181
14182         mkdir $dir || error "mkdir $dir failed"
14183         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14184         stack_trap "rm -rf $dir"
14185
14186         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14187
14188         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14189         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14190
14191         $LCTL set_param llite.*.statahead_max=64
14192         $LCTL set_param llite.*.statahead_batch_max=64
14193
14194         ls -l $dir
14195         lctl get_param mdc.*.batch_stats
14196         lctl get_param llite.*.statahead_*
14197
14198         $LCTL set_param llite.*.statahead_max=$max
14199         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14200 }
14201 run_test 123f "Retry mechanism with large wide striping files"
14202
14203 test_124a() {
14204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14205         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14206                 skip_env "no lru resize on server"
14207
14208         local NR=2000
14209
14210         test_mkdir $DIR/$tdir
14211
14212         log "create $NR files at $DIR/$tdir"
14213         createmany -o $DIR/$tdir/f $NR ||
14214                 error "failed to create $NR files in $DIR/$tdir"
14215
14216         cancel_lru_locks mdc
14217         ls -l $DIR/$tdir > /dev/null
14218
14219         local NSDIR=""
14220         local LRU_SIZE=0
14221         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14222                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14223                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14224                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14225                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14226                         log "NSDIR=$NSDIR"
14227                         log "NS=$(basename $NSDIR)"
14228                         break
14229                 fi
14230         done
14231
14232         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14233                 skip "Not enough cached locks created!"
14234         fi
14235         log "LRU=$LRU_SIZE"
14236
14237         local SLEEP=30
14238
14239         # We know that lru resize allows one client to hold $LIMIT locks
14240         # for 10h. After that locks begin to be killed by client.
14241         local MAX_HRS=10
14242         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14243         log "LIMIT=$LIMIT"
14244         if [ $LIMIT -lt $LRU_SIZE ]; then
14245                 skip "Limit is too small $LIMIT"
14246         fi
14247
14248         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14249         # killing locks. Some time was spent for creating locks. This means
14250         # that up to the moment of sleep finish we must have killed some of
14251         # them (10-100 locks). This depends on how fast ther were created.
14252         # Many of them were touched in almost the same moment and thus will
14253         # be killed in groups.
14254         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14255
14256         # Use $LRU_SIZE_B here to take into account real number of locks
14257         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14258         local LRU_SIZE_B=$LRU_SIZE
14259         log "LVF=$LVF"
14260         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14261         log "OLD_LVF=$OLD_LVF"
14262         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14263
14264         # Let's make sure that we really have some margin. Client checks
14265         # cached locks every 10 sec.
14266         SLEEP=$((SLEEP+20))
14267         log "Sleep ${SLEEP} sec"
14268         local SEC=0
14269         while ((SEC<$SLEEP)); do
14270                 echo -n "..."
14271                 sleep 5
14272                 SEC=$((SEC+5))
14273                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14274                 echo -n "$LRU_SIZE"
14275         done
14276         echo ""
14277         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14278         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14279
14280         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14281                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14282                 unlinkmany $DIR/$tdir/f $NR
14283                 return
14284         }
14285
14286         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14287         log "unlink $NR files at $DIR/$tdir"
14288         unlinkmany $DIR/$tdir/f $NR
14289 }
14290 run_test 124a "lru resize ======================================="
14291
14292 get_max_pool_limit()
14293 {
14294         local limit=$($LCTL get_param \
14295                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14296         local max=0
14297         for l in $limit; do
14298                 if [[ $l -gt $max ]]; then
14299                         max=$l
14300                 fi
14301         done
14302         echo $max
14303 }
14304
14305 test_124b() {
14306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14307         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14308                 skip_env "no lru resize on server"
14309
14310         LIMIT=$(get_max_pool_limit)
14311
14312         NR=$(($(default_lru_size)*20))
14313         if [[ $NR -gt $LIMIT ]]; then
14314                 log "Limit lock number by $LIMIT locks"
14315                 NR=$LIMIT
14316         fi
14317
14318         IFree=$(mdsrate_inodes_available)
14319         if [ $IFree -lt $NR ]; then
14320                 log "Limit lock number by $IFree inodes"
14321                 NR=$IFree
14322         fi
14323
14324         lru_resize_disable mdc
14325         test_mkdir -p $DIR/$tdir/disable_lru_resize
14326
14327         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14328         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14329         cancel_lru_locks mdc
14330         stime=`date +%s`
14331         PID=""
14332         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14333         PID="$PID $!"
14334         sleep 2
14335         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14336         PID="$PID $!"
14337         sleep 2
14338         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14339         PID="$PID $!"
14340         wait $PID
14341         etime=`date +%s`
14342         nolruresize_delta=$((etime-stime))
14343         log "ls -la time: $nolruresize_delta seconds"
14344         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14345         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14346
14347         lru_resize_enable mdc
14348         test_mkdir -p $DIR/$tdir/enable_lru_resize
14349
14350         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14351         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14352         cancel_lru_locks mdc
14353         stime=`date +%s`
14354         PID=""
14355         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14356         PID="$PID $!"
14357         sleep 2
14358         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14359         PID="$PID $!"
14360         sleep 2
14361         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14362         PID="$PID $!"
14363         wait $PID
14364         etime=`date +%s`
14365         lruresize_delta=$((etime-stime))
14366         log "ls -la time: $lruresize_delta seconds"
14367         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14368
14369         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14370                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14371         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14372                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14373         else
14374                 log "lru resize performs the same with no lru resize"
14375         fi
14376         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14377 }
14378 run_test 124b "lru resize (performance test) ======================="
14379
14380 test_124c() {
14381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14382         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14383                 skip_env "no lru resize on server"
14384
14385         # cache ununsed locks on client
14386         local nr=100
14387         cancel_lru_locks mdc
14388         test_mkdir $DIR/$tdir
14389         createmany -o $DIR/$tdir/f $nr ||
14390                 error "failed to create $nr files in $DIR/$tdir"
14391         ls -l $DIR/$tdir > /dev/null
14392
14393         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14394         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14395         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14396         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14397         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14398
14399         # set lru_max_age to 1 sec
14400         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14401         echo "sleep $((recalc_p * 2)) seconds..."
14402         sleep $((recalc_p * 2))
14403
14404         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14405         # restore lru_max_age
14406         $LCTL set_param -n $nsdir.lru_max_age $max_age
14407         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14408         unlinkmany $DIR/$tdir/f $nr
14409 }
14410 run_test 124c "LRUR cancel very aged locks"
14411
14412 test_124d() {
14413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14414         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14415                 skip_env "no lru resize on server"
14416
14417         # cache ununsed locks on client
14418         local nr=100
14419
14420         lru_resize_disable mdc
14421         stack_trap "lru_resize_enable mdc" EXIT
14422
14423         cancel_lru_locks mdc
14424
14425         # asynchronous object destroy at MDT could cause bl ast to client
14426         test_mkdir $DIR/$tdir
14427         createmany -o $DIR/$tdir/f $nr ||
14428                 error "failed to create $nr files in $DIR/$tdir"
14429         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14430
14431         ls -l $DIR/$tdir > /dev/null
14432
14433         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14434         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14435         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14436         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14437
14438         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14439
14440         # set lru_max_age to 1 sec
14441         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14442         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14443
14444         echo "sleep $((recalc_p * 2)) seconds..."
14445         sleep $((recalc_p * 2))
14446
14447         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14448
14449         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14450 }
14451 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14452
14453 test_125() { # 13358
14454         $LCTL get_param -n llite.*.client_type | grep -q local ||
14455                 skip "must run as local client"
14456         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14457                 skip_env "must have acl enabled"
14458         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14459         id $USER0 || skip_env "missing user $USER0"
14460
14461         test_mkdir $DIR/$tdir
14462         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14463         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14464                 error "setfacl $DIR/$tdir failed"
14465         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14466 }
14467 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14468
14469 test_126() { # bug 12829/13455
14470         $GSS && skip_env "must run as gss disabled"
14471         $LCTL get_param -n llite.*.client_type | grep -q local ||
14472                 skip "must run as local client"
14473         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14474
14475         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14476         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14477         rm -f $DIR/$tfile
14478         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14479 }
14480 run_test 126 "check that the fsgid provided by the client is taken into account"
14481
14482 test_127a() { # bug 15521
14483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14484         local name count samp unit min max sum sumsq
14485         local tmpfile=$TMP/$tfile.tmp
14486
14487         # enable stats header if it is disabled
14488         $LCTL set_param enable_stats_header=1
14489
14490         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14491         echo "stats before reset"
14492         stack_trap "rm -f $tmpfile"
14493         local now=$(date +%s)
14494
14495         $LCTL get_param osc.*.stats | tee $tmpfile
14496
14497         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14498         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14499         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14500         local uptime=$(awk '{ print $1 }' /proc/uptime)
14501
14502         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14503         (( ${snapshot_time%\.*} >= $now - 5 &&
14504            ${snapshot_time%\.*} <= $now + 5 )) ||
14505                 error "snapshot_time=$snapshot_time != now=$now"
14506         # elapsed _should_ be from mount, but at least less than uptime
14507         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14508                 error "elapsed=$elapsed > uptime=$uptime"
14509         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14510            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14511                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14512
14513         $LCTL set_param osc.*.stats=0
14514         local reset=$(date +%s)
14515         local fsize=$((2048 * 1024))
14516
14517         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14518         cancel_lru_locks osc
14519         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14520
14521         now=$(date +%s)
14522         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14523         while read name count samp unit min max sum sumsq; do
14524                 [[ "$samp" == "samples" ]] || continue
14525
14526                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14527                 [ ! $min ] && error "Missing min value for $name proc entry"
14528                 eval $name=$count || error "Wrong proc format"
14529
14530                 case $name in
14531                 read_bytes|write_bytes)
14532                         [[ "$unit" =~ "bytes" ]] ||
14533                                 error "unit is not 'bytes': $unit"
14534                         (( $min >= 4096 )) || error "min is too small: $min"
14535                         (( $min <= $fsize )) || error "min is too big: $min"
14536                         (( $max >= 4096 )) || error "max is too small: $max"
14537                         (( $max <= $fsize )) || error "max is too big: $max"
14538                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14539                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14540                                 error "sumsquare is too small: $sumsq"
14541                         (( $sumsq <= $fsize * $fsize )) ||
14542                                 error "sumsquare is too big: $sumsq"
14543                         ;;
14544                 ost_read|ost_write)
14545                         [[ "$unit" =~ "usec" ]] ||
14546                                 error "unit is not 'usec': $unit"
14547                         ;;
14548                 *)      ;;
14549                 esac
14550         done < $tmpfile
14551
14552         #check that we actually got some stats
14553         [ "$read_bytes" ] || error "Missing read_bytes stats"
14554         [ "$write_bytes" ] || error "Missing write_bytes stats"
14555         [ "$read_bytes" != 0 ] || error "no read done"
14556         [ "$write_bytes" != 0 ] || error "no write done"
14557
14558         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14559         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14560         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14561
14562         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14563         (( ${snapshot_time%\.*} >= $now - 5 &&
14564            ${snapshot_time%\.*} <= $now + 5 )) ||
14565                 error "reset snapshot_time=$snapshot_time != now=$now"
14566         # elapsed should be from time of stats reset
14567         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14568            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14569                 error "reset elapsed=$elapsed > $now - $reset"
14570         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14571            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14572                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14573 }
14574 run_test 127a "verify the client stats are sane"
14575
14576 test_127b() { # bug LU-333
14577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14578         local name count samp unit min max sum sumsq
14579
14580         echo "stats before reset"
14581         $LCTL get_param llite.*.stats
14582         $LCTL set_param llite.*.stats=0
14583
14584         # perform 2 reads and writes so MAX is different from SUM.
14585         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14586         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14587         cancel_lru_locks osc
14588         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14589         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14590
14591         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14592         stack_trap "rm -f $TMP/$tfile.tmp"
14593         while read name count samp unit min max sum sumsq; do
14594                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14595                 eval $name=$count || error "Wrong proc format"
14596
14597                 case $name in
14598                 read_bytes|write_bytes)
14599                         [[ "$unit" =~ "bytes" ]] ||
14600                                 error "unit is not 'bytes': $unit"
14601                         (( $count == 2 )) || error "count is not 2: $count"
14602                         (( $min == $PAGE_SIZE )) ||
14603                                 error "min is not $PAGE_SIZE: $min"
14604                         (( $max == $PAGE_SIZE )) ||
14605                                 error "max is not $PAGE_SIZE: $max"
14606                         (( $sum == $PAGE_SIZE * 2 )) ||
14607                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14608                         ;;
14609                 read|write)
14610                         [[ "$unit" =~ "usec" ]] ||
14611                                 error "unit is not 'usec': $unit"
14612                         ;;
14613                 *)      ;;
14614                 esac
14615         done < $TMP/$tfile.tmp
14616
14617         #check that we actually got some stats
14618         [ "$read_bytes" ] || error "Missing read_bytes stats"
14619         [ "$write_bytes" ] || error "Missing write_bytes stats"
14620         [ "$read_bytes" != 0 ] || error "no read done"
14621         [ "$write_bytes" != 0 ] || error "no write done"
14622 }
14623 run_test 127b "verify the llite client stats are sane"
14624
14625 test_127c() { # LU-12394
14626         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14627         local size
14628         local bsize
14629         local reads
14630         local writes
14631         local count
14632
14633         $LCTL set_param llite.*.extents_stats=1
14634         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14635
14636         # Use two stripes so there is enough space in default config
14637         $LFS setstripe -c 2 $DIR/$tfile
14638
14639         # Extent stats start at 0-4K and go in power of two buckets
14640         # LL_HIST_START = 12 --> 2^12 = 4K
14641         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14642         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14643         # small configs
14644         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14645                 do
14646                 # Write and read, 2x each, second time at a non-zero offset
14647                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14648                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14649                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14650                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14651                 rm -f $DIR/$tfile
14652         done
14653
14654         $LCTL get_param llite.*.extents_stats
14655
14656         count=2
14657         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14658                 do
14659                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14660                                 grep -m 1 $bsize)
14661                 reads=$(echo $bucket | awk '{print $5}')
14662                 writes=$(echo $bucket | awk '{print $9}')
14663                 [ "$reads" -eq $count ] ||
14664                         error "$reads reads in < $bsize bucket, expect $count"
14665                 [ "$writes" -eq $count ] ||
14666                         error "$writes writes in < $bsize bucket, expect $count"
14667         done
14668
14669         # Test mmap write and read
14670         $LCTL set_param llite.*.extents_stats=c
14671         size=512
14672         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14673         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14674         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14675
14676         $LCTL get_param llite.*.extents_stats
14677
14678         count=$(((size*1024) / PAGE_SIZE))
14679
14680         bsize=$((2 * PAGE_SIZE / 1024))K
14681
14682         bucket=$($LCTL get_param -n llite.*.extents_stats |
14683                         grep -m 1 $bsize)
14684         reads=$(echo $bucket | awk '{print $5}')
14685         writes=$(echo $bucket | awk '{print $9}')
14686         # mmap writes fault in the page first, creating an additonal read
14687         [ "$reads" -eq $((2 * count)) ] ||
14688                 error "$reads reads in < $bsize bucket, expect $count"
14689         [ "$writes" -eq $count ] ||
14690                 error "$writes writes in < $bsize bucket, expect $count"
14691 }
14692 run_test 127c "test llite extent stats with regular & mmap i/o"
14693
14694 test_128() { # bug 15212
14695         touch $DIR/$tfile
14696         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14697                 find $DIR/$tfile
14698                 find $DIR/$tfile
14699         EOF
14700
14701         result=$(grep error $TMP/$tfile.log)
14702         rm -f $DIR/$tfile $TMP/$tfile.log
14703         [ -z "$result" ] ||
14704                 error "consecutive find's under interactive lfs failed"
14705 }
14706 run_test 128 "interactive lfs for 2 consecutive find's"
14707
14708 set_dir_limits () {
14709         local mntdev
14710         local canondev
14711         local node
14712
14713         local ldproc=/proc/fs/ldiskfs
14714         local facets=$(get_facets MDS)
14715
14716         for facet in ${facets//,/ }; do
14717                 canondev=$(ldiskfs_canon \
14718                            *.$(convert_facet2label $facet).mntdev $facet)
14719                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14720                         ldproc=/sys/fs/ldiskfs
14721                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14722                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14723         done
14724 }
14725
14726 check_mds_dmesg() {
14727         local facets=$(get_facets MDS)
14728         for facet in ${facets//,/ }; do
14729                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14730         done
14731         return 1
14732 }
14733
14734 test_129() {
14735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14736         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14737                 skip "Need MDS version with at least 2.5.56"
14738         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14739                 skip_env "ldiskfs only test"
14740         fi
14741         remote_mds_nodsh && skip "remote MDS with nodsh"
14742
14743         local ENOSPC=28
14744         local has_warning=false
14745
14746         rm -rf $DIR/$tdir
14747         mkdir -p $DIR/$tdir
14748
14749         # block size of mds1
14750         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14751         set_dir_limits $maxsize $((maxsize * 6 / 8))
14752         stack_trap "set_dir_limits 0 0"
14753         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14754         local dirsize=$(stat -c%s "$DIR/$tdir")
14755         local nfiles=0
14756         while (( $dirsize <= $maxsize )); do
14757                 $MCREATE $DIR/$tdir/file_base_$nfiles
14758                 rc=$?
14759                 # check two errors:
14760                 # ENOSPC for ext4 max_dir_size, which has been used since
14761                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14762                 if (( rc == ENOSPC )); then
14763                         set_dir_limits 0 0
14764                         echo "rc=$rc returned as expected after $nfiles files"
14765
14766                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14767                                 error "create failed w/o dir size limit"
14768
14769                         # messages may be rate limited if test is run repeatedly
14770                         check_mds_dmesg '"is approaching max"' ||
14771                                 echo "warning message should be output"
14772                         check_mds_dmesg '"has reached max"' ||
14773                                 echo "reached message should be output"
14774
14775                         dirsize=$(stat -c%s "$DIR/$tdir")
14776
14777                         [[ $dirsize -ge $maxsize ]] && return 0
14778                         error "dirsize $dirsize < $maxsize after $nfiles files"
14779                 elif (( rc != 0 )); then
14780                         break
14781                 fi
14782                 nfiles=$((nfiles + 1))
14783                 dirsize=$(stat -c%s "$DIR/$tdir")
14784         done
14785
14786         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14787 }
14788 run_test 129 "test directory size limit ========================"
14789
14790 OLDIFS="$IFS"
14791 cleanup_130() {
14792         trap 0
14793         IFS="$OLDIFS"
14794         rm -f $DIR/$tfile
14795 }
14796
14797 test_130a() {
14798         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14799         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14800
14801         trap cleanup_130 EXIT RETURN
14802
14803         local fm_file=$DIR/$tfile
14804         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14805         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14806                 error "dd failed for $fm_file"
14807
14808         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14809         filefrag -ves $fm_file
14810         local rc=$?
14811         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14812                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14813         (( $rc == 0 )) || error "filefrag $fm_file failed"
14814
14815         filefrag_op=$(filefrag -ve -k $fm_file |
14816                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14817         local lun=$($LFS getstripe -i $fm_file)
14818
14819         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14820         IFS=$'\n'
14821         local tot_len=0
14822         for line in $filefrag_op; do
14823                 local frag_lun=$(echo $line | cut -d: -f5)
14824                 local ext_len=$(echo $line | cut -d: -f4)
14825
14826                 if (( $frag_lun != $lun )); then
14827                         error "FIEMAP on 1-stripe file($fm_file) failed"
14828                         return
14829                 fi
14830                 (( tot_len += ext_len ))
14831         done
14832
14833         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14834                 error "FIEMAP on 1-stripe file($fm_file) failed"
14835                 return
14836         fi
14837
14838         echo "FIEMAP on single striped file succeeded"
14839 }
14840 run_test 130a "FIEMAP (1-stripe file)"
14841
14842 test_130b() {
14843         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14844
14845         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14846         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14847         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14848                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14849
14850         trap cleanup_130 EXIT RETURN
14851
14852         local fm_file=$DIR/$tfile
14853         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14854                 error "setstripe on $fm_file"
14855
14856         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14857                 error "dd failed on $fm_file"
14858
14859         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14860         filefrag_op=$(filefrag -ve -k $fm_file |
14861                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14862
14863         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14864                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14865
14866         IFS=$'\n'
14867         local tot_len=0
14868         local num_luns=1
14869
14870         for line in $filefrag_op; do
14871                 local frag_lun=$(echo $line | cut -d: -f5 |
14872                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14873                 local ext_len=$(echo $line | cut -d: -f4)
14874                 if (( $frag_lun != $last_lun )); then
14875                         if (( tot_len != 1024 )); then
14876                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14877                                 return
14878                         else
14879                                 (( num_luns += 1 ))
14880                                 tot_len=0
14881                         fi
14882                 fi
14883                 (( tot_len += ext_len ))
14884                 last_lun=$frag_lun
14885         done
14886         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14887                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14888                 return
14889         fi
14890
14891         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14892 }
14893 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14894
14895 test_130c() {
14896         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14897
14898         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14899         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14900         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14901                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14902
14903         trap cleanup_130 EXIT RETURN
14904
14905         local fm_file=$DIR/$tfile
14906         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14907
14908         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14909                 error "dd failed on $fm_file"
14910
14911         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14912         filefrag_op=$(filefrag -ve -k $fm_file |
14913                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14914
14915         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14916                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14917
14918         IFS=$'\n'
14919         local tot_len=0
14920         local num_luns=1
14921         for line in $filefrag_op; do
14922                 local frag_lun=$(echo $line | cut -d: -f5 |
14923                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14924                 local ext_len=$(echo $line | cut -d: -f4)
14925                 if (( $frag_lun != $last_lun )); then
14926                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14927                         if (( logical != 512 )); then
14928                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14929                                 return
14930                         fi
14931                         if (( tot_len != 512 )); then
14932                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14933                                 return
14934                         else
14935                                 (( num_luns += 1 ))
14936                                 tot_len=0
14937                         fi
14938                 fi
14939                 (( tot_len += ext_len ))
14940                 last_lun=$frag_lun
14941         done
14942         if (( num_luns != 2 || tot_len != 512 )); then
14943                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14944                 return
14945         fi
14946
14947         echo "FIEMAP on 2-stripe file with hole succeeded"
14948 }
14949 run_test 130c "FIEMAP (2-stripe file with hole)"
14950
14951 test_130d() {
14952         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14953
14954         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14955         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14956         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14957                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14958
14959         trap cleanup_130 EXIT RETURN
14960
14961         local fm_file=$DIR/$tfile
14962         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14963                         error "setstripe on $fm_file"
14964
14965         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14966         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14967                 error "dd failed on $fm_file"
14968
14969         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14970         filefrag_op=$(filefrag -ve -k $fm_file |
14971                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14972
14973         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14974                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14975
14976         IFS=$'\n'
14977         local tot_len=0
14978         local num_luns=1
14979         for line in $filefrag_op; do
14980                 local frag_lun=$(echo $line | cut -d: -f5 |
14981                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14982                 local ext_len=$(echo $line | cut -d: -f4)
14983                 if (( $frag_lun != $last_lun )); then
14984                         if (( tot_len != 1024 )); then
14985                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14986                                 return
14987                         else
14988                                 (( num_luns += 1 ))
14989                                 local tot_len=0
14990                         fi
14991                 fi
14992                 (( tot_len += ext_len ))
14993                 last_lun=$frag_lun
14994         done
14995         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14996                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14997                 return
14998         fi
14999
15000         echo "FIEMAP on N-stripe file succeeded"
15001 }
15002 run_test 130d "FIEMAP (N-stripe file)"
15003
15004 test_130e() {
15005         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15006
15007         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15008         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15009         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15010                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15011
15012         trap cleanup_130 EXIT RETURN
15013
15014         local fm_file=$DIR/$tfile
15015         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15016         stack_trap "rm -f $fm_file"
15017
15018         local num_blks=512
15019         local expected_len=$(( (num_blks / 2) * 64 ))
15020         for ((i = 0; i < $num_blks; i++)); do
15021                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15022                         conv=notrunc > /dev/null 2>&1
15023         done
15024
15025         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15026         filefrag_op=$(filefrag -ve -k $fm_file |
15027                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15028
15029         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15030
15031         IFS=$'\n'
15032         local tot_len=0
15033         local num_luns=1
15034         for line in $filefrag_op; do
15035                 local frag_lun=$(echo $line | cut -d: -f5)
15036                 local ext_len=$(echo $line | cut -d: -f4)
15037                 if (( $frag_lun != $last_lun )); then
15038                         if (( tot_len != $expected_len )); then
15039                                 error "OST$last_lun $tot_len != $expected_len"
15040                         else
15041                                 (( num_luns += 1 ))
15042                                 tot_len=0
15043                         fi
15044                 fi
15045                 (( tot_len += ext_len ))
15046                 last_lun=$frag_lun
15047         done
15048         if (( num_luns != 2 || tot_len != $expected_len )); then
15049                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15050         fi
15051
15052         echo "FIEMAP with continuation calls succeeded"
15053 }
15054 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15055
15056 test_130f() {
15057         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15058         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15059         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15060                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15061
15062         local fm_file=$DIR/$tfile
15063         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15064                 error "multiop create with lov_delay_create on $fm_file"
15065
15066         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15067         filefrag_extents=$(filefrag -vek $fm_file |
15068                            awk '/extents? found/ { print $2 }')
15069         if (( $filefrag_extents != 0 )); then
15070                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15071         fi
15072
15073         rm -f $fm_file
15074 }
15075 run_test 130f "FIEMAP (unstriped file)"
15076
15077 test_130g() {
15078         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15079                 skip "Need MDS version with at least 2.12.53 for overstriping"
15080         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15081         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15082         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15083                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15084
15085         local file=$DIR/$tfile
15086         local nr=$((OSTCOUNT * 100))
15087
15088         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
15089
15090         stack_trap "rm -f $file"
15091         dd if=/dev/zero of=$file count=$nr bs=1M
15092         sync
15093         nr=$($LFS getstripe -c $file)
15094
15095         local extents=$(filefrag -v $file |
15096                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15097
15098         echo "filefrag list $extents extents in file with stripecount $nr"
15099         if (( extents < nr )); then
15100                 $LFS getstripe $file
15101                 filefrag -v $file
15102                 error "filefrag printed $extents < $nr extents"
15103         fi
15104 }
15105 run_test 130g "FIEMAP (overstripe file)"
15106
15107 # Test for writev/readv
15108 test_131a() {
15109         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15110                 error "writev test failed"
15111         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15112                 error "readv failed"
15113         rm -f $DIR/$tfile
15114 }
15115 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15116
15117 test_131b() {
15118         local fsize=$((524288 + 1048576 + 1572864))
15119         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15120                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15121                         error "append writev test failed"
15122
15123         ((fsize += 1572864 + 1048576))
15124         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15125                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15126                         error "append writev test failed"
15127         rm -f $DIR/$tfile
15128 }
15129 run_test 131b "test append writev"
15130
15131 test_131c() {
15132         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15133         error "NOT PASS"
15134 }
15135 run_test 131c "test read/write on file w/o objects"
15136
15137 test_131d() {
15138         rwv -f $DIR/$tfile -w -n 1 1572864
15139         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15140         if [ "$NOB" != 1572864 ]; then
15141                 error "Short read filed: read $NOB bytes instead of 1572864"
15142         fi
15143         rm -f $DIR/$tfile
15144 }
15145 run_test 131d "test short read"
15146
15147 test_131e() {
15148         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15149         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15150         error "read hitting hole failed"
15151         rm -f $DIR/$tfile
15152 }
15153 run_test 131e "test read hitting hole"
15154
15155 check_stats() {
15156         local facet=$1
15157         local op=$2
15158         local want=${3:-0}
15159         local res
15160
15161         # open             11 samples [usecs] 468 4793 13658 35791898
15162         case $facet in
15163         mds*) res=($(do_facet $facet \
15164                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15165                  ;;
15166         ost*) res=($(do_facet $facet \
15167                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15168                  ;;
15169         *) error "Wrong facet '$facet'" ;;
15170         esac
15171         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15172         # if $want is zero, it means any stat increment is ok.
15173         if (( $want > 0 )); then
15174                 local count=${res[1]}
15175
15176                 if (( $count != $want )); then
15177                         if [[ $facet =~ "mds" ]]; then
15178                                 do_nodes $(comma_list $(mdts_nodes)) \
15179                                         $LCTL get_param mdt.*.md_stats
15180                         else
15181                                 do_nodes $(comma_list $(osts-nodes)) \
15182                                         $LCTL get_param obdfilter.*.stats
15183                         fi
15184                         error "The $op counter on $facet is $count, not $want"
15185                 fi
15186         fi
15187 }
15188
15189 test_133a() {
15190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15191         remote_ost_nodsh && skip "remote OST with nodsh"
15192         remote_mds_nodsh && skip "remote MDS with nodsh"
15193         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15194                 skip_env "MDS doesn't support rename stats"
15195
15196         local testdir=$DIR/${tdir}/stats_testdir
15197
15198         mkdir -p $DIR/${tdir}
15199
15200         # clear stats.
15201         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15202         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15203
15204         # verify mdt stats first.
15205         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15206         check_stats $SINGLEMDS "mkdir" 1
15207
15208         # clear "open" from "lfs mkdir" above
15209         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15210         touch ${testdir}/${tfile} || error "touch failed"
15211         check_stats $SINGLEMDS "open" 1
15212         check_stats $SINGLEMDS "close" 1
15213         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15214                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15215                 check_stats $SINGLEMDS "mknod" 2
15216         }
15217         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15218         check_stats $SINGLEMDS "unlink" 1
15219         rm -f ${testdir}/${tfile} || error "file remove failed"
15220         check_stats $SINGLEMDS "unlink" 2
15221
15222         # remove working dir and check mdt stats again.
15223         rmdir ${testdir} || error "rmdir failed"
15224         check_stats $SINGLEMDS "rmdir" 1
15225
15226         local testdir1=$DIR/${tdir}/stats_testdir1
15227         mkdir_on_mdt0 -p ${testdir}
15228         mkdir_on_mdt0 -p ${testdir1}
15229         touch ${testdir1}/test1
15230         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15231         check_stats $SINGLEMDS "crossdir_rename" 1
15232
15233         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15234         check_stats $SINGLEMDS "samedir_rename" 1
15235
15236         rm -rf $DIR/${tdir}
15237 }
15238 run_test 133a "Verifying MDT stats ========================================"
15239
15240 test_133b() {
15241         local res
15242
15243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15244         remote_ost_nodsh && skip "remote OST with nodsh"
15245         remote_mds_nodsh && skip "remote MDS with nodsh"
15246
15247         local testdir=$DIR/${tdir}/stats_testdir
15248
15249         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15250         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15251         touch ${testdir}/${tfile} || error "touch failed"
15252         cancel_lru_locks mdc
15253
15254         # clear stats.
15255         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15256         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15257
15258         # extra mdt stats verification.
15259         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15260         check_stats $SINGLEMDS "setattr" 1
15261         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15262         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15263         then            # LU-1740
15264                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15265                 check_stats $SINGLEMDS "getattr" 1
15266         fi
15267         rm -rf $DIR/${tdir}
15268
15269         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15270         # so the check below is not reliable
15271         [ $MDSCOUNT -eq 1 ] || return 0
15272
15273         # Sleep to avoid a cached response.
15274         #define OBD_STATFS_CACHE_SECONDS 1
15275         sleep 2
15276         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15277         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15278         $LFS df || error "lfs failed"
15279         check_stats $SINGLEMDS "statfs" 1
15280
15281         # check aggregated statfs (LU-10018)
15282         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15283                 return 0
15284         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15285                 return 0
15286         sleep 2
15287         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15288         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15289         df $DIR
15290         check_stats $SINGLEMDS "statfs" 1
15291
15292         # We want to check that the client didn't send OST_STATFS to
15293         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15294         # extra care is needed here.
15295         if remote_mds; then
15296                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15297                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15298
15299                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15300                 [ "$res" ] && error "OST got STATFS"
15301         fi
15302
15303         return 0
15304 }
15305 run_test 133b "Verifying extra MDT stats =================================="
15306
15307 test_133c() {
15308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15309         remote_ost_nodsh && skip "remote OST with nodsh"
15310         remote_mds_nodsh && skip "remote MDS with nodsh"
15311
15312         local testdir=$DIR/$tdir/stats_testdir
15313
15314         test_mkdir -p $testdir
15315
15316         # verify obdfilter stats.
15317         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15318         sync
15319         cancel_lru_locks osc
15320         wait_delete_completed
15321
15322         # clear stats.
15323         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15324         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15325
15326         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15327                 error "dd failed"
15328         sync
15329         cancel_lru_locks osc
15330         check_stats ost1 "write" 1
15331
15332         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15333         check_stats ost1 "read" 1
15334
15335         > $testdir/$tfile || error "truncate failed"
15336         check_stats ost1 "punch" 1
15337
15338         rm -f $testdir/$tfile || error "file remove failed"
15339         wait_delete_completed
15340         check_stats ost1 "destroy" 1
15341
15342         rm -rf $DIR/$tdir
15343 }
15344 run_test 133c "Verifying OST stats ========================================"
15345
15346 order_2() {
15347         local value=$1
15348         local orig=$value
15349         local order=1
15350
15351         while [ $value -ge 2 ]; do
15352                 order=$((order*2))
15353                 value=$((value/2))
15354         done
15355
15356         if [ $orig -gt $order ]; then
15357                 order=$((order*2))
15358         fi
15359         echo $order
15360 }
15361
15362 size_in_KMGT() {
15363     local value=$1
15364     local size=('K' 'M' 'G' 'T');
15365     local i=0
15366     local size_string=$value
15367
15368     while [ $value -ge 1024 ]; do
15369         if [ $i -gt 3 ]; then
15370             #T is the biggest unit we get here, if that is bigger,
15371             #just return XXXT
15372             size_string=${value}T
15373             break
15374         fi
15375         value=$((value >> 10))
15376         if [ $value -lt 1024 ]; then
15377             size_string=${value}${size[$i]}
15378             break
15379         fi
15380         i=$((i + 1))
15381     done
15382
15383     echo $size_string
15384 }
15385
15386 get_rename_size() {
15387         local size=$1
15388         local context=${2:-.}
15389         local sample=$(do_facet $SINGLEMDS $LCTL \
15390                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15391                 grep -A1 $context |
15392                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15393         echo $sample
15394 }
15395
15396 test_133d() {
15397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15398         remote_ost_nodsh && skip "remote OST with nodsh"
15399         remote_mds_nodsh && skip "remote MDS with nodsh"
15400         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15401                 skip_env "MDS doesn't support rename stats"
15402
15403         local testdir1=$DIR/${tdir}/stats_testdir1
15404         local testdir2=$DIR/${tdir}/stats_testdir2
15405         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15406
15407         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15408
15409         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15410         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15411
15412         createmany -o $testdir1/test 512 || error "createmany failed"
15413
15414         # check samedir rename size
15415         mv ${testdir1}/test0 ${testdir1}/test_0
15416
15417         local testdir1_size=$(ls -l $DIR/${tdir} |
15418                 awk '/stats_testdir1/ {print $5}')
15419         local testdir2_size=$(ls -l $DIR/${tdir} |
15420                 awk '/stats_testdir2/ {print $5}')
15421
15422         testdir1_size=$(order_2 $testdir1_size)
15423         testdir2_size=$(order_2 $testdir2_size)
15424
15425         testdir1_size=$(size_in_KMGT $testdir1_size)
15426         testdir2_size=$(size_in_KMGT $testdir2_size)
15427
15428         echo "source rename dir size: ${testdir1_size}"
15429         echo "target rename dir size: ${testdir2_size}"
15430
15431         local cmd="do_facet $SINGLEMDS $LCTL "
15432         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15433
15434         eval $cmd || error "$cmd failed"
15435         local samedir=$($cmd | grep 'same_dir')
15436         local same_sample=$(get_rename_size $testdir1_size)
15437         [ -z "$samedir" ] && error "samedir_rename_size count error"
15438         [[ $same_sample -eq 1 ]] ||
15439                 error "samedir_rename_size error $same_sample"
15440         echo "Check same dir rename stats success"
15441
15442         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15443
15444         # check crossdir rename size
15445         mv ${testdir1}/test_0 ${testdir2}/test_0
15446
15447         testdir1_size=$(ls -l $DIR/${tdir} |
15448                 awk '/stats_testdir1/ {print $5}')
15449         testdir2_size=$(ls -l $DIR/${tdir} |
15450                 awk '/stats_testdir2/ {print $5}')
15451
15452         testdir1_size=$(order_2 $testdir1_size)
15453         testdir2_size=$(order_2 $testdir2_size)
15454
15455         testdir1_size=$(size_in_KMGT $testdir1_size)
15456         testdir2_size=$(size_in_KMGT $testdir2_size)
15457
15458         echo "source rename dir size: ${testdir1_size}"
15459         echo "target rename dir size: ${testdir2_size}"
15460
15461         eval $cmd || error "$cmd failed"
15462         local crossdir=$($cmd | grep 'crossdir')
15463         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15464         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15465         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15466         [[ $src_sample -eq 1 ]] ||
15467                 error "crossdir_rename_size error $src_sample"
15468         [[ $tgt_sample -eq 1 ]] ||
15469                 error "crossdir_rename_size error $tgt_sample"
15470         echo "Check cross dir rename stats success"
15471         rm -rf $DIR/${tdir}
15472 }
15473 run_test 133d "Verifying rename_stats ========================================"
15474
15475 test_133e() {
15476         remote_mds_nodsh && skip "remote MDS with nodsh"
15477         remote_ost_nodsh && skip "remote OST with nodsh"
15478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15479
15480         local testdir=$DIR/${tdir}/stats_testdir
15481         local ctr f0 f1 bs=32768 count=42 sum
15482
15483         mkdir -p ${testdir} || error "mkdir failed"
15484
15485         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15486
15487         for ctr in {write,read}_bytes; do
15488                 sync
15489                 cancel_lru_locks osc
15490
15491                 do_facet ost1 $LCTL set_param -n \
15492                         "obdfilter.*.exports.clear=clear"
15493
15494                 if [ $ctr = write_bytes ]; then
15495                         f0=/dev/zero
15496                         f1=${testdir}/${tfile}
15497                 else
15498                         f0=${testdir}/${tfile}
15499                         f1=/dev/null
15500                 fi
15501
15502                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15503                         error "dd failed"
15504                 sync
15505                 cancel_lru_locks osc
15506
15507                 sum=$(do_facet ost1 $LCTL get_param \
15508                         "obdfilter.*.exports.*.stats" |
15509                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15510                                 $1 == ctr { sum += $7 }
15511                                 END { printf("%0.0f", sum) }')
15512
15513                 if ((sum != bs * count)); then
15514                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15515                 fi
15516         done
15517
15518         rm -rf $DIR/${tdir}
15519 }
15520 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15521
15522 test_133f() {
15523         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15524                 skip "too old lustre for get_param -R ($facet_ver)"
15525
15526         # verifying readability.
15527         $LCTL get_param -R '*' &> /dev/null
15528
15529         # Verifing writability with badarea_io.
15530         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15531         local skipped_params='force_lbug|changelog_mask|daemon_file'
15532         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15533                 egrep -v "$skipped_params" |
15534                 xargs -n 1 find $proc_dirs -name |
15535                 xargs -n 1 badarea_io ||
15536                 error "client badarea_io failed"
15537
15538         # remount the FS in case writes/reads /proc break the FS
15539         cleanup || error "failed to unmount"
15540         setup || error "failed to setup"
15541 }
15542 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15543
15544 test_133g() {
15545         remote_mds_nodsh && skip "remote MDS with nodsh"
15546         remote_ost_nodsh && skip "remote OST with nodsh"
15547
15548         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15549         local proc_dirs_str=$(eval echo $proc_dirs)
15550         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15551         local facet
15552         for facet in mds1 ost1; do
15553                 local facet_ver=$(lustre_version_code $facet)
15554                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15555                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15556                 else
15557                         log "$facet: too old lustre for get_param -R"
15558                 fi
15559                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15560                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15561                                 tr -d = | egrep -v $skipped_params |
15562                                 xargs -n 1 find $proc_dirs_str -name |
15563                                 xargs -n 1 badarea_io" ||
15564                                         error "$facet badarea_io failed"
15565                 else
15566                         skip_noexit "$facet: too old lustre for get_param -R"
15567                 fi
15568         done
15569
15570         # remount the FS in case writes/reads /proc break the FS
15571         cleanup || error "failed to unmount"
15572         setup || error "failed to setup"
15573 }
15574 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15575
15576 test_133h() {
15577         remote_mds_nodsh && skip "remote MDS with nodsh"
15578         remote_ost_nodsh && skip "remote OST with nodsh"
15579         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15580                 skip "Need MDS version at least 2.9.54"
15581
15582         local facet
15583         for facet in client mds1 ost1; do
15584                 # Get the list of files that are missing the terminating newline
15585                 local plist=$(do_facet $facet
15586                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15587                 local ent
15588                 for ent in $plist; do
15589                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15590                                 awk -v FS='\v' -v RS='\v\v' \
15591                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15592                                         print FILENAME}'" 2>/dev/null)
15593                         [ -z $missing ] || {
15594                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15595                                 error "file does not end with newline: $facet-$ent"
15596                         }
15597                 done
15598         done
15599 }
15600 run_test 133h "Proc files should end with newlines"
15601
15602 test_134a() {
15603         remote_mds_nodsh && skip "remote MDS with nodsh"
15604         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15605                 skip "Need MDS version at least 2.7.54"
15606
15607         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15608         cancel_lru_locks mdc
15609
15610         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15611         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15612         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15613
15614         local nr=1000
15615         createmany -o $DIR/$tdir/f $nr ||
15616                 error "failed to create $nr files in $DIR/$tdir"
15617         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15618
15619         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15620         do_facet mds1 $LCTL set_param fail_loc=0x327
15621         do_facet mds1 $LCTL set_param fail_val=500
15622         touch $DIR/$tdir/m
15623
15624         echo "sleep 10 seconds ..."
15625         sleep 10
15626         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15627
15628         do_facet mds1 $LCTL set_param fail_loc=0
15629         do_facet mds1 $LCTL set_param fail_val=0
15630         [ $lck_cnt -lt $unused ] ||
15631                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15632
15633         rm $DIR/$tdir/m
15634         unlinkmany $DIR/$tdir/f $nr
15635 }
15636 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15637
15638 test_134b() {
15639         remote_mds_nodsh && skip "remote MDS with nodsh"
15640         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15641                 skip "Need MDS version at least 2.7.54"
15642
15643         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15644         cancel_lru_locks mdc
15645
15646         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15647                         ldlm.lock_reclaim_threshold_mb)
15648         # disable reclaim temporarily
15649         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15650
15651         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15652         do_facet mds1 $LCTL set_param fail_loc=0x328
15653         do_facet mds1 $LCTL set_param fail_val=500
15654
15655         $LCTL set_param debug=+trace
15656
15657         local nr=600
15658         createmany -o $DIR/$tdir/f $nr &
15659         local create_pid=$!
15660
15661         echo "Sleep $TIMEOUT seconds ..."
15662         sleep $TIMEOUT
15663         if ! ps -p $create_pid  > /dev/null 2>&1; then
15664                 do_facet mds1 $LCTL set_param fail_loc=0
15665                 do_facet mds1 $LCTL set_param fail_val=0
15666                 do_facet mds1 $LCTL set_param \
15667                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15668                 error "createmany finished incorrectly!"
15669         fi
15670         do_facet mds1 $LCTL set_param fail_loc=0
15671         do_facet mds1 $LCTL set_param fail_val=0
15672         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15673         wait $create_pid || return 1
15674
15675         unlinkmany $DIR/$tdir/f $nr
15676 }
15677 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15678
15679 test_135() {
15680         remote_mds_nodsh && skip "remote MDS with nodsh"
15681         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15682                 skip "Need MDS version at least 2.13.50"
15683         local fname
15684
15685         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15686
15687 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15688         #set only one record at plain llog
15689         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15690
15691         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15692
15693         #fill already existed plain llog each 64767
15694         #wrapping whole catalog
15695         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15696
15697         createmany -o $DIR/$tdir/$tfile_ 64700
15698         for (( i = 0; i < 64700; i = i + 2 ))
15699         do
15700                 rm $DIR/$tdir/$tfile_$i &
15701                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15702                 local pid=$!
15703                 wait $pid
15704         done
15705
15706         #waiting osp synchronization
15707         wait_delete_completed
15708 }
15709 run_test 135 "Race catalog processing"
15710
15711 test_136() {
15712         remote_mds_nodsh && skip "remote MDS with nodsh"
15713         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15714                 skip "Need MDS version at least 2.13.50"
15715         local fname
15716
15717         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15718         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15719         #set only one record at plain llog
15720 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15721         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15722
15723         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15724
15725         #fill already existed 2 plain llogs each 64767
15726         #wrapping whole catalog
15727         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15728         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15729         wait_delete_completed
15730
15731         createmany -o $DIR/$tdir/$tfile_ 10
15732         sleep 25
15733
15734         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15735         for (( i = 0; i < 10; i = i + 3 ))
15736         do
15737                 rm $DIR/$tdir/$tfile_$i &
15738                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15739                 local pid=$!
15740                 wait $pid
15741                 sleep 7
15742                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15743         done
15744
15745         #waiting osp synchronization
15746         wait_delete_completed
15747 }
15748 run_test 136 "Race catalog processing 2"
15749
15750 test_140() { #bug-17379
15751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15752
15753         test_mkdir $DIR/$tdir
15754         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15755         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15756
15757         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15758         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15759         local i=0
15760         while i=$((i + 1)); do
15761                 test_mkdir $i
15762                 cd $i || error "Changing to $i"
15763                 ln -s ../stat stat || error "Creating stat symlink"
15764                 # Read the symlink until ELOOP present,
15765                 # not LBUGing the system is considered success,
15766                 # we didn't overrun the stack.
15767                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15768                 if [ $ret -ne 0 ]; then
15769                         if [ $ret -eq 40 ]; then
15770                                 break  # -ELOOP
15771                         else
15772                                 error "Open stat symlink"
15773                                         return
15774                         fi
15775                 fi
15776         done
15777         i=$((i - 1))
15778         echo "The symlink depth = $i"
15779         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15780                 error "Invalid symlink depth"
15781
15782         # Test recursive symlink
15783         ln -s symlink_self symlink_self
15784         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15785         echo "open symlink_self returns $ret"
15786         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15787 }
15788 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15789
15790 test_150a() {
15791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15792
15793         local TF="$TMP/$tfile"
15794
15795         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15796         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15797         cp $TF $DIR/$tfile
15798         cancel_lru_locks $OSC
15799         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15800         remount_client $MOUNT
15801         df -P $MOUNT
15802         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15803
15804         $TRUNCATE $TF 6000
15805         $TRUNCATE $DIR/$tfile 6000
15806         cancel_lru_locks $OSC
15807         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15808
15809         echo "12345" >>$TF
15810         echo "12345" >>$DIR/$tfile
15811         cancel_lru_locks $OSC
15812         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15813
15814         echo "12345" >>$TF
15815         echo "12345" >>$DIR/$tfile
15816         cancel_lru_locks $OSC
15817         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15818 }
15819 run_test 150a "truncate/append tests"
15820
15821 test_150b() {
15822         check_set_fallocate_or_skip
15823         local out
15824
15825         touch $DIR/$tfile
15826         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15827         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15828                 skip_eopnotsupp "$out|check_fallocate failed"
15829 }
15830 run_test 150b "Verify fallocate (prealloc) functionality"
15831
15832 test_150bb() {
15833         check_set_fallocate_or_skip
15834
15835         touch $DIR/$tfile
15836         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15837         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15838         > $DIR/$tfile
15839         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15840         # precomputed md5sum for 20MB of zeroes
15841         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15842         local sum=($(md5sum $DIR/$tfile))
15843
15844         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15845
15846         check_set_fallocate 1
15847
15848         > $DIR/$tfile
15849         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15850         sum=($(md5sum $DIR/$tfile))
15851
15852         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15853 }
15854 run_test 150bb "Verify fallocate modes both zero space"
15855
15856 test_150c() {
15857         check_set_fallocate_or_skip
15858         local striping="-c2"
15859
15860         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15861         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15862         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15863         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15864         local want=$((OSTCOUNT * 1048576))
15865
15866         # Must allocate all requested space, not more than 5% extra
15867         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15868                 error "bytes $bytes is not $want"
15869
15870         rm -f $DIR/$tfile
15871
15872         echo "verify fallocate on PFL file"
15873
15874         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15875
15876         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15877                 error "Create $DIR/$tfile failed"
15878         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15879         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15880         want=$((512 * 1048576))
15881
15882         # Must allocate all requested space, not more than 5% extra
15883         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15884                 error "bytes $bytes is not $want"
15885 }
15886 run_test 150c "Verify fallocate Size and Blocks"
15887
15888 test_150d() {
15889         check_set_fallocate_or_skip
15890         local striping="-c2"
15891
15892         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15893
15894         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15895         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15896                 error "setstripe failed"
15897         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15898         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15899         local want=$((OSTCOUNT * 1048576))
15900
15901         # Must allocate all requested space, not more than 5% extra
15902         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15903                 error "bytes $bytes is not $want"
15904 }
15905 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15906
15907 test_150e() {
15908         check_set_fallocate_or_skip
15909
15910         echo "df before:"
15911         $LFS df
15912         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15913         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15914                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15915
15916         # Find OST with Minimum Size
15917         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15918                        sort -un | head -1)
15919
15920         # Get 100MB per OST of the available space to reduce run time
15921         # else 60% of the available space if we are running SLOW tests
15922         if [ $SLOW == "no" ]; then
15923                 local space=$((1024 * 100 * OSTCOUNT))
15924         else
15925                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15926         fi
15927
15928         fallocate -l${space}k $DIR/$tfile ||
15929                 error "fallocate ${space}k $DIR/$tfile failed"
15930         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15931
15932         # get size immediately after fallocate. This should be correctly
15933         # updated
15934         local size=$(stat -c '%s' $DIR/$tfile)
15935         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15936
15937         # Sleep for a while for statfs to get updated. And not pull from cache.
15938         sleep 2
15939
15940         echo "df after fallocate:"
15941         $LFS df
15942
15943         (( size / 1024 == space )) || error "size $size != requested $space"
15944         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15945                 error "used $used < space $space"
15946
15947         rm $DIR/$tfile || error "rm failed"
15948         sync
15949         wait_delete_completed
15950
15951         echo "df after unlink:"
15952         $LFS df
15953 }
15954 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15955
15956 test_150f() {
15957         local size
15958         local blocks
15959         local want_size_before=20480 # in bytes
15960         local want_blocks_before=40 # 512 sized blocks
15961         local want_blocks_after=24  # 512 sized blocks
15962         local length=$(((want_blocks_before - want_blocks_after) * 512))
15963
15964         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15965                 skip "need at least 2.14.0 for fallocate punch"
15966
15967         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15968                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15969         fi
15970
15971         check_set_fallocate_or_skip
15972         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15973
15974         [[ "x$DOM" == "xyes" ]] &&
15975                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15976
15977         echo "Verify fallocate punch: Range within the file range"
15978         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15979                 error "dd failed for bs 4096 and count 5"
15980
15981         # Call fallocate with punch range which is within the file range
15982         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15983                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15984         # client must see changes immediately after fallocate
15985         size=$(stat -c '%s' $DIR/$tfile)
15986         blocks=$(stat -c '%b' $DIR/$tfile)
15987
15988         # Verify punch worked.
15989         (( blocks == want_blocks_after )) ||
15990                 error "punch failed: blocks $blocks != $want_blocks_after"
15991
15992         (( size == want_size_before )) ||
15993                 error "punch failed: size $size != $want_size_before"
15994
15995         # Verify there is hole in file
15996         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15997         # precomputed md5sum
15998         local expect="4a9a834a2db02452929c0a348273b4aa"
15999
16000         cksum=($(md5sum $DIR/$tfile))
16001         [[ "${cksum[0]}" == "$expect" ]] ||
16002                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16003
16004         # Start second sub-case for fallocate punch.
16005         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16006         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16007                 error "dd failed for bs 4096 and count 5"
16008
16009         # Punch range less than block size will have no change in block count
16010         want_blocks_after=40  # 512 sized blocks
16011
16012         # Punch overlaps two blocks and less than blocksize
16013         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16014                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16015         size=$(stat -c '%s' $DIR/$tfile)
16016         blocks=$(stat -c '%b' $DIR/$tfile)
16017
16018         # Verify punch worked.
16019         (( blocks == want_blocks_after )) ||
16020                 error "punch failed: blocks $blocks != $want_blocks_after"
16021
16022         (( size == want_size_before )) ||
16023                 error "punch failed: size $size != $want_size_before"
16024
16025         # Verify if range is really zero'ed out. We expect Zeros.
16026         # precomputed md5sum
16027         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16028         cksum=($(md5sum $DIR/$tfile))
16029         [[ "${cksum[0]}" == "$expect" ]] ||
16030                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16031 }
16032 run_test 150f "Verify fallocate punch functionality"
16033
16034 test_150g() {
16035         local space
16036         local size
16037         local blocks
16038         local blocks_after
16039         local size_after
16040         local BS=4096 # Block size in bytes
16041
16042         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16043                 skip "need at least 2.14.0 for fallocate punch"
16044
16045         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16046                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16047         fi
16048
16049         check_set_fallocate_or_skip
16050         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16051
16052         if [[ "x$DOM" == "xyes" ]]; then
16053                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16054                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16055         else
16056                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16057                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16058         fi
16059
16060         # Get 100MB per OST of the available space to reduce run time
16061         # else 60% of the available space if we are running SLOW tests
16062         if [ $SLOW == "no" ]; then
16063                 space=$((1024 * 100 * OSTCOUNT))
16064         else
16065                 # Find OST with Minimum Size
16066                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16067                         sort -un | head -1)
16068                 echo "min size OST: $space"
16069                 space=$(((space * 60)/100 * OSTCOUNT))
16070         fi
16071         # space in 1k units, round to 4k blocks
16072         local blkcount=$((space * 1024 / $BS))
16073
16074         echo "Verify fallocate punch: Very large Range"
16075         fallocate -l${space}k $DIR/$tfile ||
16076                 error "fallocate ${space}k $DIR/$tfile failed"
16077         # write 1M at the end, start and in the middle
16078         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16079                 error "dd failed: bs $BS count 256"
16080         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16081                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16082         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16083                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16084
16085         # Gather stats.
16086         size=$(stat -c '%s' $DIR/$tfile)
16087
16088         # gather punch length.
16089         local punch_size=$((size - (BS * 2)))
16090
16091         echo "punch_size = $punch_size"
16092         echo "size - punch_size: $((size - punch_size))"
16093         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16094
16095         # Call fallocate to punch all except 2 blocks. We leave the
16096         # first and the last block
16097         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16098         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16099                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16100
16101         size_after=$(stat -c '%s' $DIR/$tfile)
16102         blocks_after=$(stat -c '%b' $DIR/$tfile)
16103
16104         # Verify punch worked.
16105         # Size should be kept
16106         (( size == size_after )) ||
16107                 error "punch failed: size $size != $size_after"
16108
16109         # two 4k data blocks to remain plus possible 1 extra extent block
16110         (( blocks_after <= ((BS / 512) * 3) )) ||
16111                 error "too many blocks remains: $blocks_after"
16112
16113         # Verify that file has hole between the first and the last blocks
16114         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16115         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16116
16117         echo "Hole at [$hole_start, $hole_end)"
16118         (( hole_start == BS )) ||
16119                 error "no hole at offset $BS after punch"
16120
16121         (( hole_end == BS + punch_size )) ||
16122                 error "data at offset $hole_end < $((BS + punch_size))"
16123 }
16124 run_test 150g "Verify fallocate punch on large range"
16125
16126 test_150h() {
16127         local file=$DIR/$tfile
16128         local size
16129
16130         check_set_fallocate_or_skip
16131         statx_supported || skip_env "Test must be statx() syscall supported"
16132
16133         # fallocate() does not update the size information on the MDT
16134         fallocate -l 16K $file || error "failed to fallocate $file"
16135         cancel_lru_locks $OSC
16136         # STATX with cached-always mode will not send glimpse RPCs to OST,
16137         # it uses the caching attrs on the client side as much as possible.
16138         size=$($STATX --cached=always -c %s $file)
16139         [ $size == 16384 ] ||
16140                 error "size after fallocate() is $size, expected 16384"
16141 }
16142 run_test 150h "Verify extend fallocate updates the file size"
16143
16144 #LU-2902 roc_hit was not able to read all values from lproc
16145 function roc_hit_init() {
16146         local list=$(comma_list $(osts_nodes))
16147         local dir=$DIR/$tdir-check
16148         local file=$dir/$tfile
16149         local BEFORE
16150         local AFTER
16151         local idx
16152
16153         test_mkdir $dir
16154         #use setstripe to do a write to every ost
16155         for i in $(seq 0 $((OSTCOUNT-1))); do
16156                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16157                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16158                 idx=$(printf %04x $i)
16159                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16160                         awk '$1 == "cache_access" {sum += $7}
16161                                 END { printf("%0.0f", sum) }')
16162
16163                 cancel_lru_locks osc
16164                 cat $file >/dev/null
16165
16166                 AFTER=$(get_osd_param $list *OST*$idx stats |
16167                         awk '$1 == "cache_access" {sum += $7}
16168                                 END { printf("%0.0f", sum) }')
16169
16170                 echo BEFORE:$BEFORE AFTER:$AFTER
16171                 if ! let "AFTER - BEFORE == 4"; then
16172                         rm -rf $dir
16173                         error "roc_hit is not safe to use"
16174                 fi
16175                 rm $file
16176         done
16177
16178         rm -rf $dir
16179 }
16180
16181 function roc_hit() {
16182         local list=$(comma_list $(osts_nodes))
16183         echo $(get_osd_param $list '' stats |
16184                 awk '$1 == "cache_hit" {sum += $7}
16185                         END { printf("%0.0f", sum) }')
16186 }
16187
16188 function set_cache() {
16189         local on=1
16190
16191         if [ "$2" == "off" ]; then
16192                 on=0;
16193         fi
16194         local list=$(comma_list $(osts_nodes))
16195         set_osd_param $list '' $1_cache_enable $on
16196
16197         cancel_lru_locks osc
16198 }
16199
16200 test_151() {
16201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16202         remote_ost_nodsh && skip "remote OST with nodsh"
16203         (( CLIENT_VERSION == OST1_VERSION )) ||
16204                 skip "LU-13081: no interop testing for OSS cache"
16205
16206         local CPAGES=3
16207         local list=$(comma_list $(osts_nodes))
16208
16209         # check whether obdfilter is cache capable at all
16210         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16211                 skip "not cache-capable obdfilter"
16212         fi
16213
16214         # check cache is enabled on all obdfilters
16215         if get_osd_param $list '' read_cache_enable | grep 0; then
16216                 skip "oss cache is disabled"
16217         fi
16218
16219         set_osd_param $list '' writethrough_cache_enable 1
16220
16221         # check write cache is enabled on all obdfilters
16222         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16223                 skip "oss write cache is NOT enabled"
16224         fi
16225
16226         roc_hit_init
16227
16228         #define OBD_FAIL_OBD_NO_LRU  0x609
16229         do_nodes $list $LCTL set_param fail_loc=0x609
16230
16231         # pages should be in the case right after write
16232         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16233                 error "dd failed"
16234
16235         local BEFORE=$(roc_hit)
16236         cancel_lru_locks osc
16237         cat $DIR/$tfile >/dev/null
16238         local AFTER=$(roc_hit)
16239
16240         do_nodes $list $LCTL set_param fail_loc=0
16241
16242         if ! let "AFTER - BEFORE == CPAGES"; then
16243                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16244         fi
16245
16246         cancel_lru_locks osc
16247         # invalidates OST cache
16248         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16249         set_osd_param $list '' read_cache_enable 0
16250         cat $DIR/$tfile >/dev/null
16251
16252         # now data shouldn't be found in the cache
16253         BEFORE=$(roc_hit)
16254         cancel_lru_locks osc
16255         cat $DIR/$tfile >/dev/null
16256         AFTER=$(roc_hit)
16257         if let "AFTER - BEFORE != 0"; then
16258                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16259         fi
16260
16261         set_osd_param $list '' read_cache_enable 1
16262         rm -f $DIR/$tfile
16263 }
16264 run_test 151 "test cache on oss and controls ==============================="
16265
16266 test_152() {
16267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16268
16269         local TF="$TMP/$tfile"
16270
16271         # simulate ENOMEM during write
16272 #define OBD_FAIL_OST_NOMEM      0x226
16273         lctl set_param fail_loc=0x80000226
16274         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16275         cp $TF $DIR/$tfile
16276         sync || error "sync failed"
16277         lctl set_param fail_loc=0
16278
16279         # discard client's cache
16280         cancel_lru_locks osc
16281
16282         # simulate ENOMEM during read
16283         lctl set_param fail_loc=0x80000226
16284         cmp $TF $DIR/$tfile || error "cmp failed"
16285         lctl set_param fail_loc=0
16286
16287         rm -f $TF
16288 }
16289 run_test 152 "test read/write with enomem ============================"
16290
16291 test_153() {
16292         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16293 }
16294 run_test 153 "test if fdatasync does not crash ======================="
16295
16296 dot_lustre_fid_permission_check() {
16297         local fid=$1
16298         local ffid=$MOUNT/.lustre/fid/$fid
16299         local test_dir=$2
16300
16301         echo "stat fid $fid"
16302         stat $ffid || error "stat $ffid failed."
16303         echo "touch fid $fid"
16304         touch $ffid || error "touch $ffid failed."
16305         echo "write to fid $fid"
16306         cat /etc/hosts > $ffid || error "write $ffid failed."
16307         echo "read fid $fid"
16308         diff /etc/hosts $ffid || error "read $ffid failed."
16309         echo "append write to fid $fid"
16310         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16311         echo "rename fid $fid"
16312         mv $ffid $test_dir/$tfile.1 &&
16313                 error "rename $ffid to $tfile.1 should fail."
16314         touch $test_dir/$tfile.1
16315         mv $test_dir/$tfile.1 $ffid &&
16316                 error "rename $tfile.1 to $ffid should fail."
16317         rm -f $test_dir/$tfile.1
16318         echo "truncate fid $fid"
16319         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16320         echo "link fid $fid"
16321         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16322         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16323                 id $USER0 || skip_env "missing user $USER0"
16324                 echo "setfacl fid $fid"
16325                 setfacl -R -m u:$USER0:rwx $ffid ||
16326                         error "setfacl $ffid failed"
16327                 echo "getfacl fid $fid"
16328                 getfacl $ffid || error "getfacl $ffid failed."
16329         fi
16330         echo "unlink fid $fid"
16331         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16332         echo "mknod fid $fid"
16333         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16334
16335         fid=[0xf00000400:0x1:0x0]
16336         ffid=$MOUNT/.lustre/fid/$fid
16337
16338         echo "stat non-exist fid $fid"
16339         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16340         echo "write to non-exist fid $fid"
16341         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16342         echo "link new fid $fid"
16343         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16344
16345         mkdir -p $test_dir/$tdir
16346         touch $test_dir/$tdir/$tfile
16347         fid=$($LFS path2fid $test_dir/$tdir)
16348         rc=$?
16349         [ $rc -ne 0 ] &&
16350                 error "error: could not get fid for $test_dir/$dir/$tfile."
16351
16352         ffid=$MOUNT/.lustre/fid/$fid
16353
16354         echo "ls $fid"
16355         ls $ffid || error "ls $ffid failed."
16356         echo "touch $fid/$tfile.1"
16357         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16358
16359         echo "touch $MOUNT/.lustre/fid/$tfile"
16360         touch $MOUNT/.lustre/fid/$tfile && \
16361                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16362
16363         echo "setxattr to $MOUNT/.lustre/fid"
16364         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16365
16366         echo "listxattr for $MOUNT/.lustre/fid"
16367         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16368
16369         echo "delxattr from $MOUNT/.lustre/fid"
16370         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16371
16372         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16373         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16374                 error "touch invalid fid should fail."
16375
16376         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16377         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16378                 error "touch non-normal fid should fail."
16379
16380         echo "rename $tdir to $MOUNT/.lustre/fid"
16381         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16382                 error "rename to $MOUNT/.lustre/fid should fail."
16383
16384         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16385         then            # LU-3547
16386                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16387                 local new_obf_mode=777
16388
16389                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16390                 chmod $new_obf_mode $DIR/.lustre/fid ||
16391                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16392
16393                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16394                 [ $obf_mode -eq $new_obf_mode ] ||
16395                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16396
16397                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16398                 chmod $old_obf_mode $DIR/.lustre/fid ||
16399                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16400         fi
16401
16402         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16403         fid=$($LFS path2fid $test_dir/$tfile-2)
16404
16405         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16406         then # LU-5424
16407                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16408                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16409                         error "create lov data thru .lustre failed"
16410         fi
16411         echo "cp /etc/passwd $test_dir/$tfile-2"
16412         cp /etc/passwd $test_dir/$tfile-2 ||
16413                 error "copy to $test_dir/$tfile-2 failed."
16414         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16415         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16416                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16417
16418         rm -rf $test_dir/tfile.lnk
16419         rm -rf $test_dir/$tfile-2
16420 }
16421
16422 test_154A() {
16423         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16424                 skip "Need MDS version at least 2.4.1"
16425
16426         local tf=$DIR/$tfile
16427         touch $tf
16428
16429         local fid=$($LFS path2fid $tf)
16430         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16431
16432         # check that we get the same pathname back
16433         local rootpath
16434         local found
16435         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16436                 echo "$rootpath $fid"
16437                 found=$($LFS fid2path $rootpath "$fid")
16438                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16439                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16440         done
16441
16442         # check wrong root path format
16443         rootpath=$MOUNT"_wrong"
16444         found=$($LFS fid2path $rootpath "$fid")
16445         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16446 }
16447 run_test 154A "lfs path2fid and fid2path basic checks"
16448
16449 test_154B() {
16450         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16451                 skip "Need MDS version at least 2.4.1"
16452
16453         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16454         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16455         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16456         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16457
16458         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16459         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16460
16461         # check that we get the same pathname
16462         echo "PFID: $PFID, name: $name"
16463         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16464         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16465         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16466                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16467
16468         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16469 }
16470 run_test 154B "verify the ll_decode_linkea tool"
16471
16472 test_154a() {
16473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16474         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16475         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16476                 skip "Need MDS version at least 2.2.51"
16477         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16478
16479         cp /etc/hosts $DIR/$tfile
16480
16481         fid=$($LFS path2fid $DIR/$tfile)
16482         rc=$?
16483         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16484
16485         dot_lustre_fid_permission_check "$fid" $DIR ||
16486                 error "dot lustre permission check $fid failed"
16487
16488         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16489
16490         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16491
16492         touch $MOUNT/.lustre/file &&
16493                 error "creation is not allowed under .lustre"
16494
16495         mkdir $MOUNT/.lustre/dir &&
16496                 error "mkdir is not allowed under .lustre"
16497
16498         rm -rf $DIR/$tfile
16499 }
16500 run_test 154a "Open-by-FID"
16501
16502 test_154b() {
16503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16504         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16506         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16507                 skip "Need MDS version at least 2.2.51"
16508
16509         local remote_dir=$DIR/$tdir/remote_dir
16510         local MDTIDX=1
16511         local rc=0
16512
16513         mkdir -p $DIR/$tdir
16514         $LFS mkdir -i $MDTIDX $remote_dir ||
16515                 error "create remote directory failed"
16516
16517         cp /etc/hosts $remote_dir/$tfile
16518
16519         fid=$($LFS path2fid $remote_dir/$tfile)
16520         rc=$?
16521         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16522
16523         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16524                 error "dot lustre permission check $fid failed"
16525         rm -rf $DIR/$tdir
16526 }
16527 run_test 154b "Open-by-FID for remote directory"
16528
16529 test_154c() {
16530         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16531                 skip "Need MDS version at least 2.4.1"
16532
16533         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16534         local FID1=$($LFS path2fid $DIR/$tfile.1)
16535         local FID2=$($LFS path2fid $DIR/$tfile.2)
16536         local FID3=$($LFS path2fid $DIR/$tfile.3)
16537
16538         local N=1
16539         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16540                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16541                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16542                 local want=FID$N
16543                 [ "$FID" = "${!want}" ] ||
16544                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16545                 N=$((N + 1))
16546         done
16547
16548         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16549         do
16550                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16551                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16552                 N=$((N + 1))
16553         done
16554 }
16555 run_test 154c "lfs path2fid and fid2path multiple arguments"
16556
16557 test_154d() {
16558         remote_mds_nodsh && skip "remote MDS with nodsh"
16559         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16560                 skip "Need MDS version at least 2.5.53"
16561
16562         if remote_mds; then
16563                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16564         else
16565                 nid="0@lo"
16566         fi
16567         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16568         local fd
16569         local cmd
16570
16571         rm -f $DIR/$tfile
16572         touch $DIR/$tfile
16573
16574         local fid=$($LFS path2fid $DIR/$tfile)
16575         # Open the file
16576         fd=$(free_fd)
16577         cmd="exec $fd<$DIR/$tfile"
16578         eval $cmd
16579         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16580         echo "$fid_list" | grep "$fid"
16581         rc=$?
16582
16583         cmd="exec $fd>/dev/null"
16584         eval $cmd
16585         if [ $rc -ne 0 ]; then
16586                 error "FID $fid not found in open files list $fid_list"
16587         fi
16588 }
16589 run_test 154d "Verify open file fid"
16590
16591 test_154e()
16592 {
16593         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16594                 skip "Need MDS version at least 2.6.50"
16595
16596         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16597                 error ".lustre returned by readdir"
16598         fi
16599 }
16600 run_test 154e ".lustre is not returned by readdir"
16601
16602 test_154f() {
16603         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16604
16605         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16606         mkdir_on_mdt0 $DIR/$tdir
16607         # test dirs inherit from its stripe
16608         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16609         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16610         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16611         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16612         touch $DIR/f
16613
16614         # get fid of parents
16615         local FID0=$($LFS path2fid $DIR/$tdir)
16616         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16617         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16618         local FID3=$($LFS path2fid $DIR)
16619
16620         # check that path2fid --parents returns expected <parent_fid>/name
16621         # 1) test for a directory (single parent)
16622         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16623         [ "$parent" == "$FID0/foo1" ] ||
16624                 error "expected parent: $FID0/foo1, got: $parent"
16625
16626         # 2) test for a file with nlink > 1 (multiple parents)
16627         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16628         echo "$parent" | grep -F "$FID1/$tfile" ||
16629                 error "$FID1/$tfile not returned in parent list"
16630         echo "$parent" | grep -F "$FID2/link" ||
16631                 error "$FID2/link not returned in parent list"
16632
16633         # 3) get parent by fid
16634         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16635         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16636         echo "$parent" | grep -F "$FID1/$tfile" ||
16637                 error "$FID1/$tfile not returned in parent list (by fid)"
16638         echo "$parent" | grep -F "$FID2/link" ||
16639                 error "$FID2/link not returned in parent list (by fid)"
16640
16641         # 4) test for entry in root directory
16642         parent=$($LFS path2fid --parents $DIR/f)
16643         echo "$parent" | grep -F "$FID3/f" ||
16644                 error "$FID3/f not returned in parent list"
16645
16646         # 5) test it on root directory
16647         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16648                 error "$MOUNT should not have parents"
16649
16650         # enable xattr caching and check that linkea is correctly updated
16651         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16652         save_lustre_params client "llite.*.xattr_cache" > $save
16653         lctl set_param llite.*.xattr_cache 1
16654
16655         # 6.1) linkea update on rename
16656         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16657
16658         # get parents by fid
16659         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16660         # foo1 should no longer be returned in parent list
16661         echo "$parent" | grep -F "$FID1" &&
16662                 error "$FID1 should no longer be in parent list"
16663         # the new path should appear
16664         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16665                 error "$FID2/$tfile.moved is not in parent list"
16666
16667         # 6.2) linkea update on unlink
16668         rm -f $DIR/$tdir/foo2/link
16669         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16670         # foo2/link should no longer be returned in parent list
16671         echo "$parent" | grep -F "$FID2/link" &&
16672                 error "$FID2/link should no longer be in parent list"
16673         true
16674
16675         rm -f $DIR/f
16676         restore_lustre_params < $save
16677         rm -f $save
16678 }
16679 run_test 154f "get parent fids by reading link ea"
16680
16681 test_154g()
16682 {
16683         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16684            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16685                 skip "Need MDS version at least 2.6.92"
16686
16687         mkdir_on_mdt0 $DIR/$tdir
16688         llapi_fid_test -d $DIR/$tdir
16689 }
16690 run_test 154g "various llapi FID tests"
16691
16692 test_154h()
16693 {
16694         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16695                 skip "Need client at least version 2.15.55.1"
16696
16697         # Create an empty file
16698         touch $DIR/$tfile
16699
16700         # Get FID (interactive mode) and save under $TMP/$tfile.log
16701         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16702                 path2fid $DIR/$tfile
16703         EOF
16704
16705         fid=$(cat $TMP/$tfile.log)
16706         # $fid should not be empty
16707         [[ ! -z $fid ]] || error "FID is empty"
16708         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16709 }
16710 run_test 154h "Verify interactive path2fid"
16711
16712 test_155_small_load() {
16713     local temp=$TMP/$tfile
16714     local file=$DIR/$tfile
16715
16716     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16717         error "dd of=$temp bs=6096 count=1 failed"
16718     cp $temp $file
16719     cancel_lru_locks $OSC
16720     cmp $temp $file || error "$temp $file differ"
16721
16722     $TRUNCATE $temp 6000
16723     $TRUNCATE $file 6000
16724     cmp $temp $file || error "$temp $file differ (truncate1)"
16725
16726     echo "12345" >>$temp
16727     echo "12345" >>$file
16728     cmp $temp $file || error "$temp $file differ (append1)"
16729
16730     echo "12345" >>$temp
16731     echo "12345" >>$file
16732     cmp $temp $file || error "$temp $file differ (append2)"
16733
16734     rm -f $temp $file
16735     true
16736 }
16737
16738 test_155_big_load() {
16739         remote_ost_nodsh && skip "remote OST with nodsh"
16740
16741         local temp=$TMP/$tfile
16742         local file=$DIR/$tfile
16743
16744         free_min_max
16745         local cache_size=$(do_facet ost$((MAXI+1)) \
16746                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16747
16748         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16749         # pre-set value
16750         if [ -z "$cache_size" ]; then
16751                 cache_size=256
16752         fi
16753         local large_file_size=$((cache_size * 2))
16754
16755         echo "OSS cache size: $cache_size KB"
16756         echo "Large file size: $large_file_size KB"
16757
16758         [ $MAXV -le $large_file_size ] &&
16759                 skip_env "max available OST size needs > $large_file_size KB"
16760
16761         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16762
16763         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16764                 error "dd of=$temp bs=$large_file_size count=1k failed"
16765         cp $temp $file
16766         ls -lh $temp $file
16767         cancel_lru_locks osc
16768         cmp $temp $file || error "$temp $file differ"
16769
16770         rm -f $temp $file
16771         true
16772 }
16773
16774 save_writethrough() {
16775         local facets=$(get_facets OST)
16776
16777         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16778 }
16779
16780 test_155a() {
16781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16782
16783         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16784
16785         save_writethrough $p
16786
16787         set_cache read on
16788         set_cache writethrough on
16789         test_155_small_load
16790         restore_lustre_params < $p
16791         rm -f $p
16792 }
16793 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16794
16795 test_155b() {
16796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16797
16798         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16799
16800         save_writethrough $p
16801
16802         set_cache read on
16803         set_cache writethrough off
16804         test_155_small_load
16805         restore_lustre_params < $p
16806         rm -f $p
16807 }
16808 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16809
16810 test_155c() {
16811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16812
16813         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16814
16815         save_writethrough $p
16816
16817         set_cache read off
16818         set_cache writethrough on
16819         test_155_small_load
16820         restore_lustre_params < $p
16821         rm -f $p
16822 }
16823 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16824
16825 test_155d() {
16826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16827
16828         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16829
16830         save_writethrough $p
16831
16832         set_cache read off
16833         set_cache writethrough off
16834         test_155_small_load
16835         restore_lustre_params < $p
16836         rm -f $p
16837 }
16838 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16839
16840 test_155e() {
16841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16842
16843         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16844
16845         save_writethrough $p
16846
16847         set_cache read on
16848         set_cache writethrough on
16849         test_155_big_load
16850         restore_lustre_params < $p
16851         rm -f $p
16852 }
16853 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16854
16855 test_155f() {
16856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16857
16858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16859
16860         save_writethrough $p
16861
16862         set_cache read on
16863         set_cache writethrough off
16864         test_155_big_load
16865         restore_lustre_params < $p
16866         rm -f $p
16867 }
16868 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16869
16870 test_155g() {
16871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16872
16873         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16874
16875         save_writethrough $p
16876
16877         set_cache read off
16878         set_cache writethrough on
16879         test_155_big_load
16880         restore_lustre_params < $p
16881         rm -f $p
16882 }
16883 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16884
16885 test_155h() {
16886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16887
16888         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16889
16890         save_writethrough $p
16891
16892         set_cache read off
16893         set_cache writethrough off
16894         test_155_big_load
16895         restore_lustre_params < $p
16896         rm -f $p
16897 }
16898 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16899
16900 test_156() {
16901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16902         remote_ost_nodsh && skip "remote OST with nodsh"
16903         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16904                 skip "stats not implemented on old servers"
16905         [ "$ost1_FSTYPE" = "zfs" ] &&
16906                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16907         (( CLIENT_VERSION == OST1_VERSION )) ||
16908                 skip "LU-13081: no interop testing for OSS cache"
16909
16910         local CPAGES=3
16911         local BEFORE
16912         local AFTER
16913         local file="$DIR/$tfile"
16914         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16915
16916         save_writethrough $p
16917         roc_hit_init
16918
16919         log "Turn on read and write cache"
16920         set_cache read on
16921         set_cache writethrough on
16922
16923         log "Write data and read it back."
16924         log "Read should be satisfied from the cache."
16925         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16926         BEFORE=$(roc_hit)
16927         cancel_lru_locks osc
16928         cat $file >/dev/null
16929         AFTER=$(roc_hit)
16930         if ! let "AFTER - BEFORE == CPAGES"; then
16931                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16932         else
16933                 log "cache hits: before: $BEFORE, after: $AFTER"
16934         fi
16935
16936         log "Read again; it should be satisfied from the cache."
16937         BEFORE=$AFTER
16938         cancel_lru_locks osc
16939         cat $file >/dev/null
16940         AFTER=$(roc_hit)
16941         if ! let "AFTER - BEFORE == CPAGES"; then
16942                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16943         else
16944                 log "cache hits:: before: $BEFORE, after: $AFTER"
16945         fi
16946
16947         log "Turn off the read cache and turn on the write cache"
16948         set_cache read off
16949         set_cache writethrough on
16950
16951         log "Read again; it should be satisfied from the cache."
16952         BEFORE=$(roc_hit)
16953         cancel_lru_locks osc
16954         cat $file >/dev/null
16955         AFTER=$(roc_hit)
16956         if ! let "AFTER - BEFORE == CPAGES"; then
16957                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16958         else
16959                 log "cache hits:: before: $BEFORE, after: $AFTER"
16960         fi
16961
16962         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16963                 # > 2.12.56 uses pagecache if cached
16964                 log "Read again; it should not be satisfied from the cache."
16965                 BEFORE=$AFTER
16966                 cancel_lru_locks osc
16967                 cat $file >/dev/null
16968                 AFTER=$(roc_hit)
16969                 if ! let "AFTER - BEFORE == 0"; then
16970                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16971                 else
16972                         log "cache hits:: before: $BEFORE, after: $AFTER"
16973                 fi
16974         fi
16975
16976         log "Write data and read it back."
16977         log "Read should be satisfied from the cache."
16978         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16979         BEFORE=$(roc_hit)
16980         cancel_lru_locks osc
16981         cat $file >/dev/null
16982         AFTER=$(roc_hit)
16983         if ! let "AFTER - BEFORE == CPAGES"; then
16984                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16985         else
16986                 log "cache hits:: before: $BEFORE, after: $AFTER"
16987         fi
16988
16989         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16990                 # > 2.12.56 uses pagecache if cached
16991                 log "Read again; it should not be satisfied from the cache."
16992                 BEFORE=$AFTER
16993                 cancel_lru_locks osc
16994                 cat $file >/dev/null
16995                 AFTER=$(roc_hit)
16996                 if ! let "AFTER - BEFORE == 0"; then
16997                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16998                 else
16999                         log "cache hits:: before: $BEFORE, after: $AFTER"
17000                 fi
17001         fi
17002
17003         log "Turn off read and write cache"
17004         set_cache read off
17005         set_cache writethrough off
17006
17007         log "Write data and read it back"
17008         log "It should not be satisfied from the cache."
17009         rm -f $file
17010         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17011         cancel_lru_locks osc
17012         BEFORE=$(roc_hit)
17013         cat $file >/dev/null
17014         AFTER=$(roc_hit)
17015         if ! let "AFTER - BEFORE == 0"; then
17016                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17017         else
17018                 log "cache hits:: before: $BEFORE, after: $AFTER"
17019         fi
17020
17021         log "Turn on the read cache and turn off the write cache"
17022         set_cache read on
17023         set_cache writethrough off
17024
17025         log "Write data and read it back"
17026         log "It should not be satisfied from the cache."
17027         rm -f $file
17028         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17029         BEFORE=$(roc_hit)
17030         cancel_lru_locks osc
17031         cat $file >/dev/null
17032         AFTER=$(roc_hit)
17033         if ! let "AFTER - BEFORE == 0"; then
17034                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17035         else
17036                 log "cache hits:: before: $BEFORE, after: $AFTER"
17037         fi
17038
17039         log "Read again; it should be satisfied from the cache."
17040         BEFORE=$(roc_hit)
17041         cancel_lru_locks osc
17042         cat $file >/dev/null
17043         AFTER=$(roc_hit)
17044         if ! let "AFTER - BEFORE == CPAGES"; then
17045                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17046         else
17047                 log "cache hits:: before: $BEFORE, after: $AFTER"
17048         fi
17049
17050         restore_lustre_params < $p
17051         rm -f $p $file
17052 }
17053 run_test 156 "Verification of tunables"
17054
17055 test_160a() {
17056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17057         remote_mds_nodsh && skip "remote MDS with nodsh"
17058         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17059                 skip "Need MDS version at least 2.2.0"
17060
17061         changelog_register || error "changelog_register failed"
17062         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17063         changelog_users $SINGLEMDS | grep -q $cl_user ||
17064                 error "User $cl_user not found in changelog_users"
17065
17066         mkdir_on_mdt0 $DIR/$tdir
17067
17068         # change something
17069         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17070         changelog_clear 0 || error "changelog_clear failed"
17071         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17072         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17073         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17074         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17075         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17076         rm $DIR/$tdir/pics/desktop.jpg
17077
17078         echo "verifying changelog mask"
17079         changelog_chmask "-MKDIR"
17080         changelog_chmask "-CLOSE"
17081
17082         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17083         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17084
17085         changelog_chmask "+MKDIR"
17086         changelog_chmask "+CLOSE"
17087
17088         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17089         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17090
17091         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17092         CLOSES=$(changelog_dump | grep -c "CLOSE")
17093         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17094         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17095
17096         # verify contents
17097         echo "verifying target fid"
17098         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17099         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17100         [ "$fidc" == "$fidf" ] ||
17101                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17102         echo "verifying parent fid"
17103         # The FID returned from the Changelog may be the directory shard on
17104         # a different MDT, and not the FID returned by path2fid on the parent.
17105         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17106         # since this is what will matter when recreating this file in the tree.
17107         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17108         local pathp=$($LFS fid2path $MOUNT "$fidp")
17109         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17110                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17111
17112         echo "getting records for $cl_user"
17113         changelog_users $SINGLEMDS
17114         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17115         local nclr=3
17116         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17117                 error "changelog_clear failed"
17118         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17119         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17120         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17121                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17122
17123         local min0_rec=$(changelog_users $SINGLEMDS |
17124                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17125         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17126                           awk '{ print $1; exit; }')
17127
17128         changelog_dump | tail -n 5
17129         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17130         [ $first_rec == $((min0_rec + 1)) ] ||
17131                 error "first index should be $min0_rec + 1 not $first_rec"
17132
17133         # LU-3446 changelog index reset on MDT restart
17134         local cur_rec1=$(changelog_users $SINGLEMDS |
17135                          awk '/^current.index:/ { print $NF }')
17136         changelog_clear 0 ||
17137                 error "clear all changelog records for $cl_user failed"
17138         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17139         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17140                 error "Fail to start $SINGLEMDS"
17141         local cur_rec2=$(changelog_users $SINGLEMDS |
17142                          awk '/^current.index:/ { print $NF }')
17143         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17144         [ $cur_rec1 == $cur_rec2 ] ||
17145                 error "current index should be $cur_rec1 not $cur_rec2"
17146
17147         echo "verifying users from this test are deregistered"
17148         changelog_deregister || error "changelog_deregister failed"
17149         changelog_users $SINGLEMDS | grep -q $cl_user &&
17150                 error "User '$cl_user' still in changelog_users"
17151
17152         # lctl get_param -n mdd.*.changelog_users
17153         # current_index: 144
17154         # ID    index (idle seconds)
17155         # cl3   144   (2) mask=<list>
17156         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17157                 # this is the normal case where all users were deregistered
17158                 # make sure no new records are added when no users are present
17159                 local last_rec1=$(changelog_users $SINGLEMDS |
17160                                   awk '/^current.index:/ { print $NF }')
17161                 touch $DIR/$tdir/chloe
17162                 local last_rec2=$(changelog_users $SINGLEMDS |
17163                                   awk '/^current.index:/ { print $NF }')
17164                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17165                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17166         else
17167                 # any changelog users must be leftovers from a previous test
17168                 changelog_users $SINGLEMDS
17169                 echo "other changelog users; can't verify off"
17170         fi
17171 }
17172 run_test 160a "changelog sanity"
17173
17174 test_160b() { # LU-3587
17175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17176         remote_mds_nodsh && skip "remote MDS with nodsh"
17177         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17178                 skip "Need MDS version at least 2.2.0"
17179
17180         changelog_register || error "changelog_register failed"
17181         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17182         changelog_users $SINGLEMDS | grep -q $cl_user ||
17183                 error "User '$cl_user' not found in changelog_users"
17184
17185         local longname1=$(str_repeat a 255)
17186         local longname2=$(str_repeat b 255)
17187
17188         cd $DIR
17189         echo "creating very long named file"
17190         touch $longname1 || error "create of '$longname1' failed"
17191         echo "renaming very long named file"
17192         mv $longname1 $longname2
17193
17194         changelog_dump | grep RENME | tail -n 5
17195         rm -f $longname2
17196 }
17197 run_test 160b "Verify that very long rename doesn't crash in changelog"
17198
17199 test_160c() {
17200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17201         remote_mds_nodsh && skip "remote MDS with nodsh"
17202
17203         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17204                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17205                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17206                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17207
17208         local rc=0
17209
17210         # Registration step
17211         changelog_register || error "changelog_register failed"
17212
17213         rm -rf $DIR/$tdir
17214         mkdir -p $DIR/$tdir
17215         $MCREATE $DIR/$tdir/foo_160c
17216         changelog_chmask "-TRUNC"
17217         $TRUNCATE $DIR/$tdir/foo_160c 200
17218         changelog_chmask "+TRUNC"
17219         $TRUNCATE $DIR/$tdir/foo_160c 199
17220         changelog_dump | tail -n 5
17221         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17222         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17223 }
17224 run_test 160c "verify that changelog log catch the truncate event"
17225
17226 test_160d() {
17227         remote_mds_nodsh && skip "remote MDS with nodsh"
17228         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17230         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17231                 skip "Need MDS version at least 2.7.60"
17232
17233         # Registration step
17234         changelog_register || error "changelog_register failed"
17235
17236         mkdir -p $DIR/$tdir/migrate_dir
17237         changelog_clear 0 || error "changelog_clear failed"
17238
17239         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17240         changelog_dump | tail -n 5
17241         local migrates=$(changelog_dump | grep -c "MIGRT")
17242         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17243 }
17244 run_test 160d "verify that changelog log catch the migrate event"
17245
17246 test_160e() {
17247         remote_mds_nodsh && skip "remote MDS with nodsh"
17248
17249         # Create a user
17250         changelog_register || error "changelog_register failed"
17251
17252         local MDT0=$(facet_svc $SINGLEMDS)
17253         local rc
17254
17255         # No user (expect fail)
17256         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17257         rc=$?
17258         if [ $rc -eq 0 ]; then
17259                 error "Should fail without user"
17260         elif [ $rc -ne 4 ]; then
17261                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17262         fi
17263
17264         # Delete a future user (expect fail)
17265         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17266         rc=$?
17267         if [ $rc -eq 0 ]; then
17268                 error "Deleted non-existant user cl77"
17269         elif [ $rc -ne 2 ]; then
17270                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17271         fi
17272
17273         # Clear to a bad index (1 billion should be safe)
17274         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17275         rc=$?
17276
17277         if [ $rc -eq 0 ]; then
17278                 error "Successfully cleared to invalid CL index"
17279         elif [ $rc -ne 22 ]; then
17280                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17281         fi
17282 }
17283 run_test 160e "changelog negative testing (should return errors)"
17284
17285 test_160f() {
17286         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17287         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17288                 skip "Need MDS version at least 2.10.56"
17289
17290         local mdts=$(comma_list $(mdts_nodes))
17291
17292         # Create a user
17293         changelog_register || error "first changelog_register failed"
17294         changelog_register || error "second changelog_register failed"
17295         local cl_users
17296         declare -A cl_user1
17297         declare -A cl_user2
17298         local user_rec1
17299         local user_rec2
17300         local i
17301
17302         # generate some changelog records to accumulate on each MDT
17303         # use all_char because created files should be evenly distributed
17304         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17305                 error "test_mkdir $tdir failed"
17306         log "$(date +%s): creating first files"
17307         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17308                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17309                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17310         done
17311
17312         # check changelogs have been generated
17313         local start=$SECONDS
17314         local idle_time=$((MDSCOUNT * 5 + 5))
17315         local nbcl=$(changelog_dump | wc -l)
17316         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17317
17318         for param in "changelog_max_idle_time=$idle_time" \
17319                      "changelog_gc=1" \
17320                      "changelog_min_gc_interval=2" \
17321                      "changelog_min_free_cat_entries=3"; do
17322                 local MDT0=$(facet_svc $SINGLEMDS)
17323                 local var="${param%=*}"
17324                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17325
17326                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17327                 do_nodes $mdts $LCTL set_param mdd.*.$param
17328         done
17329
17330         # force cl_user2 to be idle (1st part), but also cancel the
17331         # cl_user1 records so that it is not evicted later in the test.
17332         local sleep1=$((idle_time / 2))
17333         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17334         sleep $sleep1
17335
17336         # simulate changelog catalog almost full
17337         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17338         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17339
17340         for i in $(seq $MDSCOUNT); do
17341                 cl_users=(${CL_USERS[mds$i]})
17342                 cl_user1[mds$i]="${cl_users[0]}"
17343                 cl_user2[mds$i]="${cl_users[1]}"
17344
17345                 [ -n "${cl_user1[mds$i]}" ] ||
17346                         error "mds$i: no user registered"
17347                 [ -n "${cl_user2[mds$i]}" ] ||
17348                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17349
17350                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17351                 [ -n "$user_rec1" ] ||
17352                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17353                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17354                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17355                 [ -n "$user_rec2" ] ||
17356                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17357                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17358                      "$user_rec1 + 2 == $user_rec2"
17359                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17360                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17361                               "$user_rec1 + 2, but is $user_rec2"
17362                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17363                 [ -n "$user_rec2" ] ||
17364                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17365                 [ $user_rec1 == $user_rec2 ] ||
17366                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17367                               "$user_rec1, but is $user_rec2"
17368         done
17369
17370         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17371         local sleep2=$((idle_time - (SECONDS - start) + 1))
17372         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17373         sleep $sleep2
17374
17375         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17376         # cl_user1 should be OK because it recently processed records.
17377         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17378         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17379                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17380                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17381         done
17382
17383         # ensure gc thread is done
17384         for i in $(mdts_nodes); do
17385                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17386                         error "$i: GC-thread not done"
17387         done
17388
17389         local first_rec
17390         for (( i = 1; i <= MDSCOUNT; i++ )); do
17391                 # check cl_user1 still registered
17392                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17393                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17394                 # check cl_user2 unregistered
17395                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17396                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17397
17398                 # check changelogs are present and starting at $user_rec1 + 1
17399                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17400                 [ -n "$user_rec1" ] ||
17401                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17402                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17403                             awk '{ print $1; exit; }')
17404
17405                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17406                 [ $((user_rec1 + 1)) == $first_rec ] ||
17407                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17408         done
17409 }
17410 run_test 160f "changelog garbage collect (timestamped users)"
17411
17412 test_160g() {
17413         remote_mds_nodsh && skip "remote MDS with nodsh"
17414         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17415                 skip "Need MDS version at least 2.14.55"
17416
17417         local mdts=$(comma_list $(mdts_nodes))
17418
17419         # Create a user
17420         changelog_register || error "first changelog_register failed"
17421         changelog_register || error "second changelog_register failed"
17422         local cl_users
17423         declare -A cl_user1
17424         declare -A cl_user2
17425         local user_rec1
17426         local user_rec2
17427         local i
17428
17429         # generate some changelog records to accumulate on each MDT
17430         # use all_char because created files should be evenly distributed
17431         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17432                 error "test_mkdir $tdir failed"
17433         for ((i = 0; i < MDSCOUNT; i++)); do
17434                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17435                         error "create $DIR/$tdir/d$i.1 failed"
17436         done
17437
17438         # check changelogs have been generated
17439         local nbcl=$(changelog_dump | wc -l)
17440         (( $nbcl > 0 )) || error "no changelogs found"
17441
17442         # reduce the max_idle_indexes value to make sure we exceed it
17443         for param in "changelog_max_idle_indexes=2" \
17444                      "changelog_gc=1" \
17445                      "changelog_min_gc_interval=2"; do
17446                 local MDT0=$(facet_svc $SINGLEMDS)
17447                 local var="${param%=*}"
17448                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17449
17450                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17451                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17452                         error "unable to set mdd.*.$param"
17453         done
17454
17455         local start=$SECONDS
17456         for i in $(seq $MDSCOUNT); do
17457                 cl_users=(${CL_USERS[mds$i]})
17458                 cl_user1[mds$i]="${cl_users[0]}"
17459                 cl_user2[mds$i]="${cl_users[1]}"
17460
17461                 [ -n "${cl_user1[mds$i]}" ] ||
17462                         error "mds$i: user1 is not registered"
17463                 [ -n "${cl_user2[mds$i]}" ] ||
17464                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17465
17466                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17467                 [ -n "$user_rec1" ] ||
17468                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17469                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17470                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17471                 [ -n "$user_rec2" ] ||
17472                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17473                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17474                      "$user_rec1 + 2 == $user_rec2"
17475                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17476                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17477                               "expected $user_rec1 + 2, but is $user_rec2"
17478                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17479                 [ -n "$user_rec2" ] ||
17480                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17481                 [ $user_rec1 == $user_rec2 ] ||
17482                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17483                               "expected $user_rec1, but is $user_rec2"
17484         done
17485
17486         # ensure we are past the previous changelog_min_gc_interval set above
17487         local sleep2=$((start + 2 - SECONDS))
17488         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17489         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17490         # cl_user1 should be OK because it recently processed records.
17491         for ((i = 0; i < MDSCOUNT; i++)); do
17492                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17493                         error "create $DIR/$tdir/d$i.3 failed"
17494         done
17495
17496         # ensure gc thread is done
17497         for i in $(mdts_nodes); do
17498                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17499                         error "$i: GC-thread not done"
17500         done
17501
17502         local first_rec
17503         for (( i = 1; i <= MDSCOUNT; i++ )); do
17504                 # check cl_user1 still registered
17505                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17506                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17507                 # check cl_user2 unregistered
17508                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17509                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17510
17511                 # check changelogs are present and starting at $user_rec1 + 1
17512                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17513                 [ -n "$user_rec1" ] ||
17514                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17515                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17516                             awk '{ print $1; exit; }')
17517
17518                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17519                 [ $((user_rec1 + 1)) == $first_rec ] ||
17520                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17521         done
17522 }
17523 run_test 160g "changelog garbage collect on idle records"
17524
17525 test_160h() {
17526         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17527         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17528                 skip "Need MDS version at least 2.10.56"
17529
17530         local mdts=$(comma_list $(mdts_nodes))
17531
17532         # Create a user
17533         changelog_register || error "first changelog_register failed"
17534         changelog_register || error "second changelog_register failed"
17535         local cl_users
17536         declare -A cl_user1
17537         declare -A cl_user2
17538         local user_rec1
17539         local user_rec2
17540         local i
17541
17542         # generate some changelog records to accumulate on each MDT
17543         # use all_char because created files should be evenly distributed
17544         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17545                 error "test_mkdir $tdir failed"
17546         for ((i = 0; i < MDSCOUNT; i++)); do
17547                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17548                         error "create $DIR/$tdir/d$i.1 failed"
17549         done
17550
17551         # check changelogs have been generated
17552         local nbcl=$(changelog_dump | wc -l)
17553         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17554
17555         for param in "changelog_max_idle_time=10" \
17556                      "changelog_gc=1" \
17557                      "changelog_min_gc_interval=2"; do
17558                 local MDT0=$(facet_svc $SINGLEMDS)
17559                 local var="${param%=*}"
17560                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17561
17562                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17563                 do_nodes $mdts $LCTL set_param mdd.*.$param
17564         done
17565
17566         # force cl_user2 to be idle (1st part)
17567         sleep 9
17568
17569         for i in $(seq $MDSCOUNT); do
17570                 cl_users=(${CL_USERS[mds$i]})
17571                 cl_user1[mds$i]="${cl_users[0]}"
17572                 cl_user2[mds$i]="${cl_users[1]}"
17573
17574                 [ -n "${cl_user1[mds$i]}" ] ||
17575                         error "mds$i: no user registered"
17576                 [ -n "${cl_user2[mds$i]}" ] ||
17577                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17578
17579                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17580                 [ -n "$user_rec1" ] ||
17581                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17582                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17583                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17584                 [ -n "$user_rec2" ] ||
17585                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17586                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17587                      "$user_rec1 + 2 == $user_rec2"
17588                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17589                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17590                               "$user_rec1 + 2, but is $user_rec2"
17591                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17592                 [ -n "$user_rec2" ] ||
17593                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17594                 [ $user_rec1 == $user_rec2 ] ||
17595                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17596                               "$user_rec1, but is $user_rec2"
17597         done
17598
17599         # force cl_user2 to be idle (2nd part) and to reach
17600         # changelog_max_idle_time
17601         sleep 2
17602
17603         # force each GC-thread start and block then
17604         # one per MDT/MDD, set fail_val accordingly
17605         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17606         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17607
17608         # generate more changelogs to trigger fail_loc
17609         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17610                 error "create $DIR/$tdir/${tfile}bis failed"
17611
17612         # stop MDT to stop GC-thread, should be done in back-ground as it will
17613         # block waiting for the thread to be released and exit
17614         declare -A stop_pids
17615         for i in $(seq $MDSCOUNT); do
17616                 stop mds$i &
17617                 stop_pids[mds$i]=$!
17618         done
17619
17620         for i in $(mdts_nodes); do
17621                 local facet
17622                 local nb=0
17623                 local facets=$(facets_up_on_host $i)
17624
17625                 for facet in ${facets//,/ }; do
17626                         if [[ $facet == mds* ]]; then
17627                                 nb=$((nb + 1))
17628                         fi
17629                 done
17630                 # ensure each MDS's gc threads are still present and all in "R"
17631                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17632                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17633                         error "$i: expected $nb GC-thread"
17634                 wait_update $i \
17635                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17636                         "R" 20 ||
17637                         error "$i: GC-thread not found in R-state"
17638                 # check umounts of each MDT on MDS have reached kthread_stop()
17639                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17640                         error "$i: expected $nb umount"
17641                 wait_update $i \
17642                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17643                         error "$i: umount not found in D-state"
17644         done
17645
17646         # release all GC-threads
17647         do_nodes $mdts $LCTL set_param fail_loc=0
17648
17649         # wait for MDT stop to complete
17650         for i in $(seq $MDSCOUNT); do
17651                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17652         done
17653
17654         # XXX
17655         # may try to check if any orphan changelog records are present
17656         # via ldiskfs/zfs and llog_reader...
17657
17658         # re-start/mount MDTs
17659         for i in $(seq $MDSCOUNT); do
17660                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17661                         error "Fail to start mds$i"
17662         done
17663
17664         local first_rec
17665         for i in $(seq $MDSCOUNT); do
17666                 # check cl_user1 still registered
17667                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17668                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17669                 # check cl_user2 unregistered
17670                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17671                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17672
17673                 # check changelogs are present and starting at $user_rec1 + 1
17674                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17675                 [ -n "$user_rec1" ] ||
17676                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17677                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17678                             awk '{ print $1; exit; }')
17679
17680                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17681                 [ $((user_rec1 + 1)) == $first_rec ] ||
17682                         error "mds$i: first index should be $user_rec1 + 1, " \
17683                               "but is $first_rec"
17684         done
17685 }
17686 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17687               "during mount"
17688
17689 test_160i() {
17690
17691         local mdts=$(comma_list $(mdts_nodes))
17692
17693         changelog_register || error "first changelog_register failed"
17694
17695         # generate some changelog records to accumulate on each MDT
17696         # use all_char because created files should be evenly distributed
17697         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17698                 error "test_mkdir $tdir failed"
17699         for ((i = 0; i < MDSCOUNT; i++)); do
17700                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17701                         error "create $DIR/$tdir/d$i.1 failed"
17702         done
17703
17704         # check changelogs have been generated
17705         local nbcl=$(changelog_dump | wc -l)
17706         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17707
17708         # simulate race between register and unregister
17709         # XXX as fail_loc is set per-MDS, with DNE configs the race
17710         # simulation will only occur for one MDT per MDS and for the
17711         # others the normal race scenario will take place
17712         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17713         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17714         do_nodes $mdts $LCTL set_param fail_val=1
17715
17716         # unregister 1st user
17717         changelog_deregister &
17718         local pid1=$!
17719         # wait some time for deregister work to reach race rdv
17720         sleep 2
17721         # register 2nd user
17722         changelog_register || error "2nd user register failed"
17723
17724         wait $pid1 || error "1st user deregister failed"
17725
17726         local i
17727         local last_rec
17728         declare -A LAST_REC
17729         for i in $(seq $MDSCOUNT); do
17730                 if changelog_users mds$i | grep "^cl"; then
17731                         # make sure new records are added with one user present
17732                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17733                                           awk '/^current.index:/ { print $NF }')
17734                 else
17735                         error "mds$i has no user registered"
17736                 fi
17737         done
17738
17739         # generate more changelog records to accumulate on each MDT
17740         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17741                 error "create $DIR/$tdir/${tfile}bis failed"
17742
17743         for i in $(seq $MDSCOUNT); do
17744                 last_rec=$(changelog_users $SINGLEMDS |
17745                            awk '/^current.index:/ { print $NF }')
17746                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17747                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17748                         error "changelogs are off on mds$i"
17749         done
17750 }
17751 run_test 160i "changelog user register/unregister race"
17752
17753 test_160j() {
17754         remote_mds_nodsh && skip "remote MDS with nodsh"
17755         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17756                 skip "Need MDS version at least 2.12.56"
17757
17758         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17759         stack_trap "umount $MOUNT2" EXIT
17760
17761         changelog_register || error "first changelog_register failed"
17762         stack_trap "changelog_deregister" EXIT
17763
17764         # generate some changelog
17765         # use all_char because created files should be evenly distributed
17766         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17767                 error "mkdir $tdir failed"
17768         for ((i = 0; i < MDSCOUNT; i++)); do
17769                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17770                         error "create $DIR/$tdir/d$i.1 failed"
17771         done
17772
17773         # open the changelog device
17774         exec 3>/dev/changelog-$FSNAME-MDT0000
17775         stack_trap "exec 3>&-" EXIT
17776         exec 4</dev/changelog-$FSNAME-MDT0000
17777         stack_trap "exec 4<&-" EXIT
17778
17779         # umount the first lustre mount
17780         umount $MOUNT
17781         stack_trap "mount_client $MOUNT" EXIT
17782
17783         # read changelog, which may or may not fail, but should not crash
17784         cat <&4 >/dev/null
17785
17786         # clear changelog
17787         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17788         changelog_users $SINGLEMDS | grep -q $cl_user ||
17789                 error "User $cl_user not found in changelog_users"
17790
17791         printf 'clear:'$cl_user':0' >&3
17792 }
17793 run_test 160j "client can be umounted while its chanangelog is being used"
17794
17795 test_160k() {
17796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17797         remote_mds_nodsh && skip "remote MDS with nodsh"
17798
17799         mkdir -p $DIR/$tdir/1/1
17800
17801         changelog_register || error "changelog_register failed"
17802         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17803
17804         changelog_users $SINGLEMDS | grep -q $cl_user ||
17805                 error "User '$cl_user' not found in changelog_users"
17806 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17807         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17808         rmdir $DIR/$tdir/1/1 & sleep 1
17809         mkdir $DIR/$tdir/2
17810         touch $DIR/$tdir/2/2
17811         rm -rf $DIR/$tdir/2
17812
17813         wait
17814         sleep 4
17815
17816         changelog_dump | grep rmdir || error "rmdir not recorded"
17817 }
17818 run_test 160k "Verify that changelog records are not lost"
17819
17820 # Verifies that a file passed as a parameter has recently had an operation
17821 # performed on it that has generated an MTIME changelog which contains the
17822 # correct parent FID. As files might reside on a different MDT from the
17823 # parent directory in DNE configurations, the FIDs are translated to paths
17824 # before being compared, which should be identical
17825 compare_mtime_changelog() {
17826         local file="${1}"
17827         local mdtidx
17828         local mtime
17829         local cl_fid
17830         local pdir
17831         local dir
17832
17833         mdtidx=$($LFS getstripe --mdt-index $file)
17834         mdtidx=$(printf "%04x" $mdtidx)
17835
17836         # Obtain the parent FID from the MTIME changelog
17837         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17838         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17839
17840         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17841         [ -z "$cl_fid" ] && error "parent FID not present"
17842
17843         # Verify that the path for the parent FID is the same as the path for
17844         # the test directory
17845         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17846
17847         dir=$(dirname $1)
17848
17849         [[ "${pdir%/}" == "$dir" ]] ||
17850                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17851 }
17852
17853 test_160l() {
17854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17855
17856         remote_mds_nodsh && skip "remote MDS with nodsh"
17857         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17858                 skip "Need MDS version at least 2.13.55"
17859
17860         local cl_user
17861
17862         changelog_register || error "changelog_register failed"
17863         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17864
17865         changelog_users $SINGLEMDS | grep -q $cl_user ||
17866                 error "User '$cl_user' not found in changelog_users"
17867
17868         # Clear some types so that MTIME changelogs are generated
17869         changelog_chmask "-CREAT"
17870         changelog_chmask "-CLOSE"
17871
17872         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17873
17874         # Test CL_MTIME during setattr
17875         touch $DIR/$tdir/$tfile
17876         compare_mtime_changelog $DIR/$tdir/$tfile
17877
17878         # Test CL_MTIME during close
17879         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17880         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17881 }
17882 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17883
17884 test_160m() {
17885         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17886         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17887                 skip "Need MDS version at least 2.14.51"
17888         local cl_users
17889         local cl_user1
17890         local cl_user2
17891         local pid1
17892
17893         # Create a user
17894         changelog_register || error "first changelog_register failed"
17895         changelog_register || error "second changelog_register failed"
17896
17897         cl_users=(${CL_USERS[mds1]})
17898         cl_user1="${cl_users[0]}"
17899         cl_user2="${cl_users[1]}"
17900         # generate some changelog records to accumulate on MDT0
17901         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17902         createmany -m $DIR/$tdir/$tfile 50 ||
17903                 error "create $DIR/$tdir/$tfile failed"
17904         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17905         rm -f $DIR/$tdir
17906
17907         # check changelogs have been generated
17908         local nbcl=$(changelog_dump | wc -l)
17909         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17910
17911 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17912         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17913
17914         __changelog_clear mds1 $cl_user1 +10
17915         __changelog_clear mds1 $cl_user2 0 &
17916         pid1=$!
17917         sleep 2
17918         __changelog_clear mds1 $cl_user1 0 ||
17919                 error "fail to cancel record for $cl_user1"
17920         wait $pid1
17921         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17922 }
17923 run_test 160m "Changelog clear race"
17924
17925 test_160n() {
17926         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17927         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17928                 skip "Need MDS version at least 2.14.51"
17929         local cl_users
17930         local cl_user1
17931         local cl_user2
17932         local pid1
17933         local first_rec
17934         local last_rec=0
17935
17936         # Create a user
17937         changelog_register || error "first changelog_register failed"
17938
17939         cl_users=(${CL_USERS[mds1]})
17940         cl_user1="${cl_users[0]}"
17941
17942         # generate some changelog records to accumulate on MDT0
17943         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17944         first_rec=$(changelog_users $SINGLEMDS |
17945                         awk '/^current.index:/ { print $NF }')
17946         while (( last_rec < (( first_rec + 65000)) )); do
17947                 createmany -m $DIR/$tdir/$tfile 10000 ||
17948                         error "create $DIR/$tdir/$tfile failed"
17949
17950                 for i in $(seq 0 10000); do
17951                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17952                                 > /dev/null
17953                 done
17954
17955                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17956                         error "unlinkmany failed unlink"
17957                 last_rec=$(changelog_users $SINGLEMDS |
17958                         awk '/^current.index:/ { print $NF }')
17959                 echo last record $last_rec
17960                 (( last_rec == 0 )) && error "no changelog found"
17961         done
17962
17963 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17964         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17965
17966         __changelog_clear mds1 $cl_user1 0 &
17967         pid1=$!
17968         sleep 2
17969         __changelog_clear mds1 $cl_user1 0 ||
17970                 error "fail to cancel record for $cl_user1"
17971         wait $pid1
17972         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17973 }
17974 run_test 160n "Changelog destroy race"
17975
17976 test_160o() {
17977         local mdt="$(facet_svc $SINGLEMDS)"
17978
17979         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17980         remote_mds_nodsh && skip "remote MDS with nodsh"
17981         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17982                 skip "Need MDS version at least 2.14.52"
17983
17984         changelog_register --user test_160o -m unlnk+close+open ||
17985                 error "changelog_register failed"
17986
17987         do_facet $SINGLEMDS $LCTL --device $mdt \
17988                                 changelog_register -u "Tt3_-#" &&
17989                 error "bad symbols in name should fail"
17990
17991         do_facet $SINGLEMDS $LCTL --device $mdt \
17992                                 changelog_register -u test_160o &&
17993                 error "the same name registration should fail"
17994
17995         do_facet $SINGLEMDS $LCTL --device $mdt \
17996                         changelog_register -u test_160toolongname &&
17997                 error "too long name registration should fail"
17998
17999         changelog_chmask "MARK+HSM"
18000         lctl get_param mdd.*.changelog*mask
18001         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18002         changelog_users $SINGLEMDS | grep -q $cl_user ||
18003                 error "User $cl_user not found in changelog_users"
18004         #verify username
18005         echo $cl_user | grep -q test_160o ||
18006                 error "User $cl_user has no specific name 'test160o'"
18007
18008         # change something
18009         changelog_clear 0 || error "changelog_clear failed"
18010         # generate some changelog records to accumulate on MDT0
18011         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18012         touch $DIR/$tdir/$tfile                 # open 1
18013
18014         OPENS=$(changelog_dump | grep -c "OPEN")
18015         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18016
18017         # must be no MKDIR it wasn't set as user mask
18018         MKDIR=$(changelog_dump | grep -c "MKDIR")
18019         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18020
18021         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18022                                 mdd.$mdt.changelog_current_mask -n)
18023         # register maskless user
18024         changelog_register || error "changelog_register failed"
18025         # effective mask should be not changed because it is not minimal
18026         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18027                                 mdd.$mdt.changelog_current_mask -n)
18028         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18029         # set server mask to minimal value
18030         changelog_chmask "MARK"
18031         # check effective mask again, should be treated as DEFMASK now
18032         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18033                                 mdd.$mdt.changelog_current_mask -n)
18034         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18035
18036         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18037                 # set server mask back to some value
18038                 changelog_chmask "CLOSE,UNLNK"
18039                 # check effective mask again, should not remain as DEFMASK
18040                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18041                                 mdd.$mdt.changelog_current_mask -n)
18042                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18043         fi
18044
18045         do_facet $SINGLEMDS $LCTL --device $mdt \
18046                                 changelog_deregister -u test_160o ||
18047                 error "cannot deregister by name"
18048 }
18049 run_test 160o "changelog user name and mask"
18050
18051 test_160p() {
18052         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18053         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18054                 skip "Need MDS version at least 2.14.51"
18055         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18056         local cl_users
18057         local cl_user1
18058         local entry_count
18059
18060         # Create a user
18061         changelog_register || error "first changelog_register failed"
18062
18063         cl_users=(${CL_USERS[mds1]})
18064         cl_user1="${cl_users[0]}"
18065
18066         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18067         createmany -m $DIR/$tdir/$tfile 50 ||
18068                 error "create $DIR/$tdir/$tfile failed"
18069         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18070         rm -rf $DIR/$tdir
18071
18072         # check changelogs have been generated
18073         entry_count=$(changelog_dump | wc -l)
18074         ((entry_count != 0)) || error "no changelog entries found"
18075
18076         # remove changelog_users and check that orphan entries are removed
18077         stop mds1
18078         local dev=$(mdsdevname 1)
18079         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18080         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18081         entry_count=$(changelog_dump | wc -l)
18082         ((entry_count == 0)) ||
18083                 error "found $entry_count changelog entries, expected none"
18084 }
18085 run_test 160p "Changelog orphan cleanup with no users"
18086
18087 test_160q() {
18088         local mdt="$(facet_svc $SINGLEMDS)"
18089         local clu
18090
18091         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18092         remote_mds_nodsh && skip "remote MDS with nodsh"
18093         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18094                 skip "Need MDS version at least 2.14.54"
18095
18096         # set server mask to minimal value like server init does
18097         changelog_chmask "MARK"
18098         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18099                 error "changelog_register failed"
18100         # check effective mask again, should be treated as DEFMASK now
18101         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18102                                 mdd.$mdt.changelog_current_mask -n)
18103         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18104                 error "changelog_deregister failed"
18105         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18106 }
18107 run_test 160q "changelog effective mask is DEFMASK if not set"
18108
18109 test_160s() {
18110         remote_mds_nodsh && skip "remote MDS with nodsh"
18111         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18112                 skip "Need MDS version at least 2.14.55"
18113
18114         local mdts=$(comma_list $(mdts_nodes))
18115
18116         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18117         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18118                                        fail_val=$((24 * 3600 * 10))
18119
18120         # Create a user which is 10 days old
18121         changelog_register || error "first changelog_register failed"
18122         local cl_users
18123         declare -A cl_user1
18124         local i
18125
18126         # generate some changelog records to accumulate on each MDT
18127         # use all_char because created files should be evenly distributed
18128         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18129                 error "test_mkdir $tdir failed"
18130         for ((i = 0; i < MDSCOUNT; i++)); do
18131                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18132                         error "create $DIR/$tdir/d$i.1 failed"
18133         done
18134
18135         # check changelogs have been generated
18136         local nbcl=$(changelog_dump | wc -l)
18137         (( nbcl > 0 )) || error "no changelogs found"
18138
18139         # reduce the max_idle_indexes value to make sure we exceed it
18140         for param in "changelog_max_idle_indexes=2097446912" \
18141                      "changelog_max_idle_time=2592000" \
18142                      "changelog_gc=1" \
18143                      "changelog_min_gc_interval=2"; do
18144                 local MDT0=$(facet_svc $SINGLEMDS)
18145                 local var="${param%=*}"
18146                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18147
18148                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18149                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18150                         error "unable to set mdd.*.$param"
18151         done
18152
18153         local start=$SECONDS
18154         for i in $(seq $MDSCOUNT); do
18155                 cl_users=(${CL_USERS[mds$i]})
18156                 cl_user1[mds$i]="${cl_users[0]}"
18157
18158                 [[ -n "${cl_user1[mds$i]}" ]] ||
18159                         error "mds$i: no user registered"
18160         done
18161
18162         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18163         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18164
18165         # ensure we are past the previous changelog_min_gc_interval set above
18166         local sleep2=$((start + 2 - SECONDS))
18167         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18168
18169         # Generate one more changelog to trigger GC
18170         for ((i = 0; i < MDSCOUNT; i++)); do
18171                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18172                         error "create $DIR/$tdir/d$i.3 failed"
18173         done
18174
18175         # ensure gc thread is done
18176         for node in $(mdts_nodes); do
18177                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18178                         error "$node: GC-thread not done"
18179         done
18180
18181         do_nodes $mdts $LCTL set_param fail_loc=0
18182
18183         for (( i = 1; i <= MDSCOUNT; i++ )); do
18184                 # check cl_user1 is purged
18185                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18186                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18187         done
18188         return 0
18189 }
18190 run_test 160s "changelog garbage collect on idle records * time"
18191
18192 test_160t() {
18193         remote_mds_nodsh && skip "remote MDS with nodsh"
18194         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18195                 skip "Need MDS version at least 2.15.50"
18196
18197         local MDT0=$(facet_svc $SINGLEMDS)
18198         local cl_users
18199         local cl_user1
18200         local cl_user2
18201         local start
18202
18203         changelog_register --user user1 -m all ||
18204                 error "user1 failed to register"
18205
18206         mkdir_on_mdt0 $DIR/$tdir
18207         # create default overstripe to maximize changelog size
18208         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18209         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18210         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18211
18212         # user2 consumes less records so less space
18213         changelog_register --user user2 || error "user2 failed to register"
18214         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18215         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18216
18217         # check changelogs have been generated
18218         local nbcl=$(changelog_dump | wc -l)
18219         (( nbcl > 0 )) || error "no changelogs found"
18220
18221         # reduce the changelog_min_gc_interval to force check
18222         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18223                 local var="${param%=*}"
18224                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18225
18226                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18227                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18228                         error "unable to set mdd.*.$param"
18229         done
18230
18231         start=$SECONDS
18232         cl_users=(${CL_USERS[mds1]})
18233         cl_user1="${cl_users[0]}"
18234         cl_user2="${cl_users[1]}"
18235
18236         [[ -n $cl_user1 ]] ||
18237                 error "mds1: user #1 isn't registered"
18238         [[ -n $cl_user2 ]] ||
18239                 error "mds1: user #2 isn't registered"
18240
18241         # ensure we are past the previous changelog_min_gc_interval set above
18242         local sleep2=$((start + 2 - SECONDS))
18243         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18244
18245         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18246         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18247                         fail_val=$(((llog_size1 + llog_size2) / 2))
18248
18249         # Generate more changelog to trigger GC
18250         createmany -o $DIR/$tdir/u3_ 4 ||
18251                 error "create failed for more files"
18252
18253         # ensure gc thread is done
18254         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18255                 error "mds1: GC-thread not done"
18256
18257         do_facet mds1 $LCTL set_param fail_loc=0
18258
18259         # check cl_user1 is purged
18260         changelog_users mds1 | grep -q "$cl_user1" &&
18261                 error "User $cl_user1 is registered"
18262         # check cl_user2 is not purged
18263         changelog_users mds1 | grep -q "$cl_user2" ||
18264                 error "User $cl_user2 is not registered"
18265 }
18266 run_test 160t "changelog garbage collect on lack of space"
18267
18268 test_161a() {
18269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18270
18271         test_mkdir -c1 $DIR/$tdir
18272         cp /etc/hosts $DIR/$tdir/$tfile
18273         test_mkdir -c1 $DIR/$tdir/foo1
18274         test_mkdir -c1 $DIR/$tdir/foo2
18275         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18276         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18277         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18278         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18279         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18280         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18281                 $LFS fid2path $DIR $FID
18282                 error "bad link ea"
18283         fi
18284         # middle
18285         rm $DIR/$tdir/foo2/zachary
18286         # last
18287         rm $DIR/$tdir/foo2/thor
18288         # first
18289         rm $DIR/$tdir/$tfile
18290         # rename
18291         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18292         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18293                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18294         rm $DIR/$tdir/foo2/maggie
18295
18296         # overflow the EA
18297         local longname=$tfile.avg_len_is_thirty_two_
18298         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18299                 error_noexit 'failed to unlink many hardlinks'" EXIT
18300         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18301                 error "failed to hardlink many files"
18302         links=$($LFS fid2path $DIR $FID | wc -l)
18303         echo -n "${links}/1000 links in link EA"
18304         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18305 }
18306 run_test 161a "link ea sanity"
18307
18308 test_161b() {
18309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18310         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18311
18312         local MDTIDX=1
18313         local remote_dir=$DIR/$tdir/remote_dir
18314
18315         mkdir -p $DIR/$tdir
18316         $LFS mkdir -i $MDTIDX $remote_dir ||
18317                 error "create remote directory failed"
18318
18319         cp /etc/hosts $remote_dir/$tfile
18320         mkdir -p $remote_dir/foo1
18321         mkdir -p $remote_dir/foo2
18322         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18323         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18324         ln $remote_dir/$tfile $remote_dir/foo1/luna
18325         ln $remote_dir/$tfile $remote_dir/foo2/thor
18326
18327         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18328                      tr -d ']')
18329         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18330                 $LFS fid2path $DIR $FID
18331                 error "bad link ea"
18332         fi
18333         # middle
18334         rm $remote_dir/foo2/zachary
18335         # last
18336         rm $remote_dir/foo2/thor
18337         # first
18338         rm $remote_dir/$tfile
18339         # rename
18340         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18341         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18342         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18343                 $LFS fid2path $DIR $FID
18344                 error "bad link rename"
18345         fi
18346         rm $remote_dir/foo2/maggie
18347
18348         # overflow the EA
18349         local longname=filename_avg_len_is_thirty_two_
18350         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18351                 error "failed to hardlink many files"
18352         links=$($LFS fid2path $DIR $FID | wc -l)
18353         echo -n "${links}/1000 links in link EA"
18354         [[ ${links} -gt 60 ]] ||
18355                 error "expected at least 60 links in link EA"
18356         unlinkmany $remote_dir/foo2/$longname 1000 ||
18357         error "failed to unlink many hardlinks"
18358 }
18359 run_test 161b "link ea sanity under remote directory"
18360
18361 test_161c() {
18362         remote_mds_nodsh && skip "remote MDS with nodsh"
18363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18364         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18365                 skip "Need MDS version at least 2.1.5"
18366
18367         # define CLF_RENAME_LAST 0x0001
18368         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18369         changelog_register || error "changelog_register failed"
18370
18371         rm -rf $DIR/$tdir
18372         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18373         touch $DIR/$tdir/foo_161c
18374         touch $DIR/$tdir/bar_161c
18375         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18376         changelog_dump | grep RENME | tail -n 5
18377         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18378         changelog_clear 0 || error "changelog_clear failed"
18379         if [ x$flags != "x0x1" ]; then
18380                 error "flag $flags is not 0x1"
18381         fi
18382
18383         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18384         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18385         touch $DIR/$tdir/foo_161c
18386         touch $DIR/$tdir/bar_161c
18387         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18388         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18389         changelog_dump | grep RENME | tail -n 5
18390         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18391         changelog_clear 0 || error "changelog_clear failed"
18392         if [ x$flags != "x0x0" ]; then
18393                 error "flag $flags is not 0x0"
18394         fi
18395         echo "rename overwrite a target having nlink > 1," \
18396                 "changelog record has flags of $flags"
18397
18398         # rename doesn't overwrite a target (changelog flag 0x0)
18399         touch $DIR/$tdir/foo_161c
18400         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18401         changelog_dump | grep RENME | tail -n 5
18402         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18403         changelog_clear 0 || error "changelog_clear failed"
18404         if [ x$flags != "x0x0" ]; then
18405                 error "flag $flags is not 0x0"
18406         fi
18407         echo "rename doesn't overwrite a target," \
18408                 "changelog record has flags of $flags"
18409
18410         # define CLF_UNLINK_LAST 0x0001
18411         # unlink a file having nlink = 1 (changelog flag 0x1)
18412         rm -f $DIR/$tdir/foo2_161c
18413         changelog_dump | grep UNLNK | tail -n 5
18414         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18415         changelog_clear 0 || error "changelog_clear failed"
18416         if [ x$flags != "x0x1" ]; then
18417                 error "flag $flags is not 0x1"
18418         fi
18419         echo "unlink a file having nlink = 1," \
18420                 "changelog record has flags of $flags"
18421
18422         # unlink a file having nlink > 1 (changelog flag 0x0)
18423         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18424         rm -f $DIR/$tdir/foobar_161c
18425         changelog_dump | grep UNLNK | tail -n 5
18426         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18427         changelog_clear 0 || error "changelog_clear failed"
18428         if [ x$flags != "x0x0" ]; then
18429                 error "flag $flags is not 0x0"
18430         fi
18431         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18432 }
18433 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18434
18435 test_161d() {
18436         remote_mds_nodsh && skip "remote MDS with nodsh"
18437         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18438
18439         local pid
18440         local fid
18441
18442         changelog_register || error "changelog_register failed"
18443
18444         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18445         # interfer with $MOUNT/.lustre/fid/ access
18446         mkdir $DIR/$tdir
18447         [[ $? -eq 0 ]] || error "mkdir failed"
18448
18449         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18450         $LCTL set_param fail_loc=0x8000140c
18451         # 5s pause
18452         $LCTL set_param fail_val=5
18453
18454         # create file
18455         echo foofoo > $DIR/$tdir/$tfile &
18456         pid=$!
18457
18458         # wait for create to be delayed
18459         sleep 2
18460
18461         ps -p $pid
18462         [[ $? -eq 0 ]] || error "create should be blocked"
18463
18464         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18465         stack_trap "rm -f $tempfile"
18466         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18467         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18468         # some delay may occur during ChangeLog publishing and file read just
18469         # above, that could allow file write to happen finally
18470         [[ -s $tempfile ]] && echo "file should be empty"
18471
18472         $LCTL set_param fail_loc=0
18473
18474         wait $pid
18475         [[ $? -eq 0 ]] || error "create failed"
18476 }
18477 run_test 161d "create with concurrent .lustre/fid access"
18478
18479 check_path() {
18480         local expected="$1"
18481         shift
18482         local fid="$2"
18483
18484         local path
18485         path=$($LFS fid2path "$@")
18486         local rc=$?
18487
18488         if [ $rc -ne 0 ]; then
18489                 error "path looked up of '$expected' failed: rc=$rc"
18490         elif [ "$path" != "$expected" ]; then
18491                 error "path looked up '$path' instead of '$expected'"
18492         else
18493                 echo "FID '$fid' resolves to path '$path' as expected"
18494         fi
18495 }
18496
18497 test_162a() { # was test_162
18498         test_mkdir -p -c1 $DIR/$tdir/d2
18499         touch $DIR/$tdir/d2/$tfile
18500         touch $DIR/$tdir/d2/x1
18501         touch $DIR/$tdir/d2/x2
18502         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18503         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18504         # regular file
18505         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18506         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18507
18508         # softlink
18509         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18510         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18511         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18512
18513         # softlink to wrong file
18514         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18515         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18516         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18517
18518         # hardlink
18519         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18520         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18521         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18522         # fid2path dir/fsname should both work
18523         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18524         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18525
18526         # hardlink count: check that there are 2 links
18527         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18528         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18529
18530         # hardlink indexing: remove the first link
18531         rm $DIR/$tdir/d2/p/q/r/hlink
18532         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18533 }
18534 run_test 162a "path lookup sanity"
18535
18536 test_162b() {
18537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18538         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18539
18540         mkdir $DIR/$tdir
18541         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18542                                 error "create striped dir failed"
18543
18544         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18545                                         tail -n 1 | awk '{print $2}')
18546         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18547
18548         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18549         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18550
18551         # regular file
18552         for ((i=0;i<5;i++)); do
18553                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18554                         error "get fid for f$i failed"
18555                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18556
18557                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18558                         error "get fid for d$i failed"
18559                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18560         done
18561
18562         return 0
18563 }
18564 run_test 162b "striped directory path lookup sanity"
18565
18566 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18567 test_162c() {
18568         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18569                 skip "Need MDS version at least 2.7.51"
18570
18571         local lpath=$tdir.local
18572         local rpath=$tdir.remote
18573
18574         test_mkdir $DIR/$lpath
18575         test_mkdir $DIR/$rpath
18576
18577         for ((i = 0; i <= 101; i++)); do
18578                 lpath="$lpath/$i"
18579                 mkdir $DIR/$lpath
18580                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18581                         error "get fid for local directory $DIR/$lpath failed"
18582                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18583
18584                 rpath="$rpath/$i"
18585                 test_mkdir $DIR/$rpath
18586                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18587                         error "get fid for remote directory $DIR/$rpath failed"
18588                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18589         done
18590
18591         return 0
18592 }
18593 run_test 162c "fid2path works with paths 100 or more directories deep"
18594
18595 oalr_event_count() {
18596         local event="${1}"
18597         local trace="${2}"
18598
18599         awk -v name="${FSNAME}-OST0000" \
18600             -v event="${event}" \
18601             '$1 == "TRACE" && $2 == event && $3 == name' \
18602             "${trace}" |
18603         wc -l
18604 }
18605
18606 oalr_expect_event_count() {
18607         local event="${1}"
18608         local trace="${2}"
18609         local expect="${3}"
18610         local count
18611
18612         count=$(oalr_event_count "${event}" "${trace}")
18613         if ((count == expect)); then
18614                 return 0
18615         fi
18616
18617         error_noexit "${event} event count was '${count}', expected ${expect}"
18618         cat "${trace}" >&2
18619         exit 1
18620 }
18621
18622 cleanup_165() {
18623         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18624         stop ost1
18625         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18626 }
18627
18628 setup_165() {
18629         sync # Flush previous IOs so we can count log entries.
18630         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18631         stack_trap cleanup_165 EXIT
18632 }
18633
18634 test_165a() {
18635         local trace="/tmp/${tfile}.trace"
18636         local rc
18637         local count
18638
18639         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18640                 skip "OFD access log unsupported"
18641
18642         setup_165
18643         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18644         sleep 5
18645
18646         do_facet ost1 ofd_access_log_reader --list
18647         stop ost1
18648
18649         do_facet ost1 killall -TERM ofd_access_log_reader
18650         wait
18651         rc=$?
18652
18653         if ((rc != 0)); then
18654                 error "ofd_access_log_reader exited with rc = '${rc}'"
18655         fi
18656
18657         # Parse trace file for discovery events:
18658         oalr_expect_event_count alr_log_add "${trace}" 1
18659         oalr_expect_event_count alr_log_eof "${trace}" 1
18660         oalr_expect_event_count alr_log_free "${trace}" 1
18661 }
18662 run_test 165a "ofd access log discovery"
18663
18664 test_165b() {
18665         local trace="/tmp/${tfile}.trace"
18666         local file="${DIR}/${tfile}"
18667         local pfid1
18668         local pfid2
18669         local -a entry
18670         local rc
18671         local count
18672         local size
18673         local flags
18674
18675         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18676                 skip "OFD access log unsupported"
18677
18678         setup_165
18679         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18680         sleep 5
18681
18682         do_facet ost1 ofd_access_log_reader --list
18683
18684         lfs setstripe -c 1 -i 0 "${file}"
18685         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18686                 error "cannot create '${file}'"
18687
18688         sleep 5
18689         do_facet ost1 killall -TERM ofd_access_log_reader
18690         wait
18691         rc=$?
18692
18693         if ((rc != 0)); then
18694                 error "ofd_access_log_reader exited with rc = '${rc}'"
18695         fi
18696
18697         oalr_expect_event_count alr_log_entry "${trace}" 1
18698
18699         pfid1=$($LFS path2fid "${file}")
18700
18701         # 1     2             3   4    5     6   7    8    9     10
18702         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18703         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18704
18705         echo "entry = '${entry[*]}'" >&2
18706
18707         pfid2=${entry[4]}
18708         if [[ "${pfid1}" != "${pfid2}" ]]; then
18709                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18710         fi
18711
18712         size=${entry[8]}
18713         if ((size != 1048576)); then
18714                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18715         fi
18716
18717         flags=${entry[10]}
18718         if [[ "${flags}" != "w" ]]; then
18719                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18720         fi
18721
18722         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18723         sleep 5
18724
18725         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18726                 error "cannot read '${file}'"
18727         sleep 5
18728
18729         do_facet ost1 killall -TERM ofd_access_log_reader
18730         wait
18731         rc=$?
18732
18733         if ((rc != 0)); then
18734                 error "ofd_access_log_reader exited with rc = '${rc}'"
18735         fi
18736
18737         oalr_expect_event_count alr_log_entry "${trace}" 1
18738
18739         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18740         echo "entry = '${entry[*]}'" >&2
18741
18742         pfid2=${entry[4]}
18743         if [[ "${pfid1}" != "${pfid2}" ]]; then
18744                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18745         fi
18746
18747         size=${entry[8]}
18748         if ((size != 524288)); then
18749                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18750         fi
18751
18752         flags=${entry[10]}
18753         if [[ "${flags}" != "r" ]]; then
18754                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18755         fi
18756 }
18757 run_test 165b "ofd access log entries are produced and consumed"
18758
18759 test_165c() {
18760         local trace="/tmp/${tfile}.trace"
18761         local file="${DIR}/${tdir}/${tfile}"
18762
18763         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18764                 skip "OFD access log unsupported"
18765
18766         test_mkdir "${DIR}/${tdir}"
18767
18768         setup_165
18769         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18770         sleep 5
18771
18772         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18773
18774         # 4096 / 64 = 64. Create twice as many entries.
18775         for ((i = 0; i < 128; i++)); do
18776                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18777                         error "cannot create file"
18778         done
18779
18780         sync
18781
18782         do_facet ost1 killall -TERM ofd_access_log_reader
18783         wait
18784         rc=$?
18785         if ((rc != 0)); then
18786                 error "ofd_access_log_reader exited with rc = '${rc}'"
18787         fi
18788
18789         unlinkmany  "${file}-%d" 128
18790 }
18791 run_test 165c "full ofd access logs do not block IOs"
18792
18793 oal_get_read_count() {
18794         local stats="$1"
18795
18796         # STATS lustre-OST0001 alr_read_count 1
18797
18798         do_facet ost1 cat "${stats}" |
18799         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18800              END { print count; }'
18801 }
18802
18803 oal_expect_read_count() {
18804         local stats="$1"
18805         local count
18806         local expect="$2"
18807
18808         # Ask ofd_access_log_reader to write stats.
18809         do_facet ost1 killall -USR1 ofd_access_log_reader
18810
18811         # Allow some time for things to happen.
18812         sleep 1
18813
18814         count=$(oal_get_read_count "${stats}")
18815         if ((count == expect)); then
18816                 return 0
18817         fi
18818
18819         error_noexit "bad read count, got ${count}, expected ${expect}"
18820         do_facet ost1 cat "${stats}" >&2
18821         exit 1
18822 }
18823
18824 test_165d() {
18825         local stats="/tmp/${tfile}.stats"
18826         local file="${DIR}/${tdir}/${tfile}"
18827         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18828
18829         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18830                 skip "OFD access log unsupported"
18831
18832         test_mkdir "${DIR}/${tdir}"
18833
18834         setup_165
18835         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18836         sleep 5
18837
18838         lfs setstripe -c 1 -i 0 "${file}"
18839
18840         do_facet ost1 lctl set_param "${param}=rw"
18841         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18842                 error "cannot create '${file}'"
18843         oal_expect_read_count "${stats}" 1
18844
18845         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18846                 error "cannot read '${file}'"
18847         oal_expect_read_count "${stats}" 2
18848
18849         do_facet ost1 lctl set_param "${param}=r"
18850         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18851                 error "cannot create '${file}'"
18852         oal_expect_read_count "${stats}" 2
18853
18854         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18855                 error "cannot read '${file}'"
18856         oal_expect_read_count "${stats}" 3
18857
18858         do_facet ost1 lctl set_param "${param}=w"
18859         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18860                 error "cannot create '${file}'"
18861         oal_expect_read_count "${stats}" 4
18862
18863         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18864                 error "cannot read '${file}'"
18865         oal_expect_read_count "${stats}" 4
18866
18867         do_facet ost1 lctl set_param "${param}=0"
18868         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18869                 error "cannot create '${file}'"
18870         oal_expect_read_count "${stats}" 4
18871
18872         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18873                 error "cannot read '${file}'"
18874         oal_expect_read_count "${stats}" 4
18875
18876         do_facet ost1 killall -TERM ofd_access_log_reader
18877         wait
18878         rc=$?
18879         if ((rc != 0)); then
18880                 error "ofd_access_log_reader exited with rc = '${rc}'"
18881         fi
18882 }
18883 run_test 165d "ofd_access_log mask works"
18884
18885 test_165e() {
18886         local stats="/tmp/${tfile}.stats"
18887         local file0="${DIR}/${tdir}-0/${tfile}"
18888         local file1="${DIR}/${tdir}-1/${tfile}"
18889
18890         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18891                 skip "OFD access log unsupported"
18892
18893         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18894
18895         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18896         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18897
18898         lfs setstripe -c 1 -i 0 "${file0}"
18899         lfs setstripe -c 1 -i 0 "${file1}"
18900
18901         setup_165
18902         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18903         sleep 5
18904
18905         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18906                 error "cannot create '${file0}'"
18907         sync
18908         oal_expect_read_count "${stats}" 0
18909
18910         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18911                 error "cannot create '${file1}'"
18912         sync
18913         oal_expect_read_count "${stats}" 1
18914
18915         do_facet ost1 killall -TERM ofd_access_log_reader
18916         wait
18917         rc=$?
18918         if ((rc != 0)); then
18919                 error "ofd_access_log_reader exited with rc = '${rc}'"
18920         fi
18921 }
18922 run_test 165e "ofd_access_log MDT index filter works"
18923
18924 test_165f() {
18925         local trace="/tmp/${tfile}.trace"
18926         local rc
18927         local count
18928
18929         setup_165
18930         do_facet ost1 timeout 60 ofd_access_log_reader \
18931                 --exit-on-close --debug=- --trace=- > "${trace}" &
18932         sleep 5
18933         stop ost1
18934
18935         wait
18936         rc=$?
18937
18938         if ((rc != 0)); then
18939                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18940                 cat "${trace}"
18941                 exit 1
18942         fi
18943 }
18944 run_test 165f "ofd_access_log_reader --exit-on-close works"
18945
18946 test_169() {
18947         # do directio so as not to populate the page cache
18948         log "creating a 10 Mb file"
18949         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18950                 error "multiop failed while creating a file"
18951         log "starting reads"
18952         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18953         log "truncating the file"
18954         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18955                 error "multiop failed while truncating the file"
18956         log "killing dd"
18957         kill %+ || true # reads might have finished
18958         echo "wait until dd is finished"
18959         wait
18960         log "removing the temporary file"
18961         rm -rf $DIR/$tfile || error "tmp file removal failed"
18962 }
18963 run_test 169 "parallel read and truncate should not deadlock"
18964
18965 test_170() {
18966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18967
18968         $LCTL clear     # bug 18514
18969         $LCTL debug_daemon start $TMP/${tfile}_log_good
18970         touch $DIR/$tfile
18971         $LCTL debug_daemon stop
18972         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18973                 error "sed failed to read log_good"
18974
18975         $LCTL debug_daemon start $TMP/${tfile}_log_good
18976         rm -rf $DIR/$tfile
18977         $LCTL debug_daemon stop
18978
18979         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18980                error "lctl df log_bad failed"
18981
18982         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18983         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18984
18985         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18986         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18987
18988         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18989                 error "bad_line good_line1 good_line2 are empty"
18990
18991         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18992         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18993         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18994
18995         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18996         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18997         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18998
18999         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19000                 error "bad_line_new good_line_new are empty"
19001
19002         local expected_good=$((good_line1 + good_line2*2))
19003
19004         rm -f $TMP/${tfile}*
19005         # LU-231, short malformed line may not be counted into bad lines
19006         if [ $bad_line -ne $bad_line_new ] &&
19007                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19008                 error "expected $bad_line bad lines, but got $bad_line_new"
19009                 return 1
19010         fi
19011
19012         if [ $expected_good -ne $good_line_new ]; then
19013                 error "expected $expected_good good lines, but got $good_line_new"
19014                 return 2
19015         fi
19016         true
19017 }
19018 run_test 170 "test lctl df to handle corrupted log ====================="
19019
19020 test_171() { # bug20592
19021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19022
19023         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19024         $LCTL set_param fail_loc=0x50e
19025         $LCTL set_param fail_val=3000
19026         multiop_bg_pause $DIR/$tfile O_s || true
19027         local MULTIPID=$!
19028         kill -USR1 $MULTIPID
19029         # cause log dump
19030         sleep 3
19031         wait $MULTIPID
19032         if dmesg | grep "recursive fault"; then
19033                 error "caught a recursive fault"
19034         fi
19035         $LCTL set_param fail_loc=0
19036         true
19037 }
19038 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19039
19040 test_172() {
19041
19042         #define OBD_FAIL_OBD_CLEANUP  0x60e
19043         $LCTL set_param fail_loc=0x60e
19044         umount $MOUNT || error "umount $MOUNT failed"
19045         stack_trap "mount_client $MOUNT"
19046
19047         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19048                 error "no client OBDs are remained"
19049
19050         $LCTL dl | while read devno state type name foo; do
19051                 case $type in
19052                 lov|osc|lmv|mdc)
19053                         $LCTL --device $name cleanup
19054                         $LCTL --device $name detach
19055                         ;;
19056                 *)
19057                         # skip server devices
19058                         ;;
19059                 esac
19060         done
19061
19062         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19063                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19064                 error "some client OBDs are still remained"
19065         fi
19066
19067 }
19068 run_test 172 "manual device removal with lctl cleanup/detach ======"
19069
19070 # it would be good to share it with obdfilter-survey/iokit-libecho code
19071 setup_obdecho_osc () {
19072         local rc=0
19073         local ost_nid=$1
19074         local obdfilter_name=$2
19075         echo "Creating new osc for $obdfilter_name on $ost_nid"
19076         # make sure we can find loopback nid
19077         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19078
19079         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19080                            ${obdfilter_name}_osc_UUID || rc=2; }
19081         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19082                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19083         return $rc
19084 }
19085
19086 cleanup_obdecho_osc () {
19087         local obdfilter_name=$1
19088         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19089         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19090         return 0
19091 }
19092
19093 obdecho_test() {
19094         local OBD=$1
19095         local node=$2
19096         local pages=${3:-64}
19097         local rc=0
19098         local id
19099
19100         local count=10
19101         local obd_size=$(get_obd_size $node $OBD)
19102         local page_size=$(get_page_size $node)
19103         if [[ -n "$obd_size" ]]; then
19104                 local new_count=$((obd_size / (pages * page_size / 1024)))
19105                 [[ $new_count -ge $count ]] || count=$new_count
19106         fi
19107
19108         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19109         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19110                            rc=2; }
19111         if [ $rc -eq 0 ]; then
19112             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19113             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19114         fi
19115         echo "New object id is $id"
19116         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19117                            rc=4; }
19118         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19119                            "test_brw $count w v $pages $id" || rc=4; }
19120         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19121                            rc=4; }
19122         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19123                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19124         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19125                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19126         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19127         return $rc
19128 }
19129
19130 test_180a() {
19131         skip "obdecho on osc is no longer supported"
19132 }
19133 run_test 180a "test obdecho on osc"
19134
19135 test_180b() {
19136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19137         remote_ost_nodsh && skip "remote OST with nodsh"
19138
19139         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19140                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19141                 error "failed to load module obdecho"
19142
19143         local target=$(do_facet ost1 $LCTL dl |
19144                        awk '/obdfilter/ { print $4; exit; }')
19145
19146         if [ -n "$target" ]; then
19147                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19148         else
19149                 do_facet ost1 $LCTL dl
19150                 error "there is no obdfilter target on ost1"
19151         fi
19152 }
19153 run_test 180b "test obdecho directly on obdfilter"
19154
19155 test_180c() { # LU-2598
19156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19157         remote_ost_nodsh && skip "remote OST with nodsh"
19158         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19159                 skip "Need MDS version at least 2.4.0"
19160
19161         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19162                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19163                 error "failed to load module obdecho"
19164
19165         local target=$(do_facet ost1 $LCTL dl |
19166                        awk '/obdfilter/ { print $4; exit; }')
19167
19168         if [ -n "$target" ]; then
19169                 local pages=16384 # 64MB bulk I/O RPC size
19170
19171                 obdecho_test "$target" ost1 "$pages" ||
19172                         error "obdecho_test with pages=$pages failed with $?"
19173         else
19174                 do_facet ost1 $LCTL dl
19175                 error "there is no obdfilter target on ost1"
19176         fi
19177 }
19178 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19179
19180 test_181() { # bug 22177
19181         test_mkdir $DIR/$tdir
19182         # create enough files to index the directory
19183         createmany -o $DIR/$tdir/foobar 4000
19184         # print attributes for debug purpose
19185         lsattr -d .
19186         # open dir
19187         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19188         MULTIPID=$!
19189         # remove the files & current working dir
19190         unlinkmany $DIR/$tdir/foobar 4000
19191         rmdir $DIR/$tdir
19192         kill -USR1 $MULTIPID
19193         wait $MULTIPID
19194         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19195         return 0
19196 }
19197 run_test 181 "Test open-unlinked dir ========================"
19198
19199 test_182a() {
19200         local fcount=1000
19201         local tcount=10
19202
19203         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19204
19205         $LCTL set_param mdc.*.rpc_stats=clear
19206
19207         for (( i = 0; i < $tcount; i++ )) ; do
19208                 mkdir $DIR/$tdir/$i
19209         done
19210
19211         for (( i = 0; i < $tcount; i++ )) ; do
19212                 createmany -o $DIR/$tdir/$i/f- $fcount &
19213         done
19214         wait
19215
19216         for (( i = 0; i < $tcount; i++ )) ; do
19217                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19218         done
19219         wait
19220
19221         $LCTL get_param mdc.*.rpc_stats
19222
19223         rm -rf $DIR/$tdir
19224 }
19225 run_test 182a "Test parallel modify metadata operations from mdc"
19226
19227 test_182b() {
19228         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19229         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19230         local dcount=1000
19231         local tcount=10
19232         local stime
19233         local etime
19234         local delta
19235
19236         do_facet mds1 $LCTL list_param \
19237                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19238                 skip "MDS lacks parallel RPC handling"
19239
19240         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19241
19242         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19243                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19244
19245         stime=$(date +%s)
19246         createmany -i 0 -d $DIR/$tdir/t- $tcount
19247
19248         for (( i = 0; i < $tcount; i++ )) ; do
19249                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19250         done
19251         wait
19252         etime=$(date +%s)
19253         delta=$((etime - stime))
19254         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19255
19256         stime=$(date +%s)
19257         for (( i = 0; i < $tcount; i++ )) ; do
19258                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19259         done
19260         wait
19261         etime=$(date +%s)
19262         delta=$((etime - stime))
19263         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19264
19265         rm -rf $DIR/$tdir
19266
19267         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19268
19269         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19270
19271         stime=$(date +%s)
19272         createmany -i 0 -d $DIR/$tdir/t- $tcount
19273
19274         for (( i = 0; i < $tcount; i++ )) ; do
19275                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19276         done
19277         wait
19278         etime=$(date +%s)
19279         delta=$((etime - stime))
19280         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19281
19282         stime=$(date +%s)
19283         for (( i = 0; i < $tcount; i++ )) ; do
19284                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19285         done
19286         wait
19287         etime=$(date +%s)
19288         delta=$((etime - stime))
19289         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19290
19291         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19292 }
19293 run_test 182b "Test parallel modify metadata operations from osp"
19294
19295 test_183() { # LU-2275
19296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19297         remote_mds_nodsh && skip "remote MDS with nodsh"
19298         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19299                 skip "Need MDS version at least 2.3.56"
19300
19301         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19302         echo aaa > $DIR/$tdir/$tfile
19303
19304 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19305         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19306
19307         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19308         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19309
19310         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19311
19312         # Flush negative dentry cache
19313         touch $DIR/$tdir/$tfile
19314
19315         # We are not checking for any leaked references here, they'll
19316         # become evident next time we do cleanup with module unload.
19317         rm -rf $DIR/$tdir
19318 }
19319 run_test 183 "No crash or request leak in case of strange dispositions ========"
19320
19321 # test suite 184 is for LU-2016, LU-2017
19322 test_184a() {
19323         check_swap_layouts_support
19324
19325         dir0=$DIR/$tdir/$testnum
19326         test_mkdir -p -c1 $dir0
19327         ref1=/etc/passwd
19328         ref2=/etc/group
19329         file1=$dir0/f1
19330         file2=$dir0/f2
19331         $LFS setstripe -c1 $file1
19332         cp $ref1 $file1
19333         $LFS setstripe -c2 $file2
19334         cp $ref2 $file2
19335         gen1=$($LFS getstripe -g $file1)
19336         gen2=$($LFS getstripe -g $file2)
19337
19338         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19339         gen=$($LFS getstripe -g $file1)
19340         [[ $gen1 != $gen ]] ||
19341                 error "Layout generation on $file1 does not change"
19342         gen=$($LFS getstripe -g $file2)
19343         [[ $gen2 != $gen ]] ||
19344                 error "Layout generation on $file2 does not change"
19345
19346         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19347         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19348
19349         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19350 }
19351 run_test 184a "Basic layout swap"
19352
19353 test_184b() {
19354         check_swap_layouts_support
19355
19356         dir0=$DIR/$tdir/$testnum
19357         mkdir -p $dir0 || error "creating dir $dir0"
19358         file1=$dir0/f1
19359         file2=$dir0/f2
19360         file3=$dir0/f3
19361         dir1=$dir0/d1
19362         dir2=$dir0/d2
19363         mkdir $dir1 $dir2
19364         $LFS setstripe -c1 $file1
19365         $LFS setstripe -c2 $file2
19366         $LFS setstripe -c1 $file3
19367         chown $RUNAS_ID $file3
19368         gen1=$($LFS getstripe -g $file1)
19369         gen2=$($LFS getstripe -g $file2)
19370
19371         $LFS swap_layouts $dir1 $dir2 &&
19372                 error "swap of directories layouts should fail"
19373         $LFS swap_layouts $dir1 $file1 &&
19374                 error "swap of directory and file layouts should fail"
19375         $RUNAS $LFS swap_layouts $file1 $file2 &&
19376                 error "swap of file we cannot write should fail"
19377         $LFS swap_layouts $file1 $file3 &&
19378                 error "swap of file with different owner should fail"
19379         /bin/true # to clear error code
19380 }
19381 run_test 184b "Forbidden layout swap (will generate errors)"
19382
19383 test_184c() {
19384         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19385         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19386         check_swap_layouts_support
19387         check_swap_layout_no_dom $DIR
19388
19389         local dir0=$DIR/$tdir/$testnum
19390         mkdir -p $dir0 || error "creating dir $dir0"
19391
19392         local ref1=$dir0/ref1
19393         local ref2=$dir0/ref2
19394         local file1=$dir0/file1
19395         local file2=$dir0/file2
19396         # create a file large enough for the concurrent test
19397         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19398         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19399         echo "ref file size: ref1($(stat -c %s $ref1))," \
19400              "ref2($(stat -c %s $ref2))"
19401
19402         cp $ref2 $file2
19403         dd if=$ref1 of=$file1 bs=16k &
19404         local DD_PID=$!
19405
19406         # Make sure dd starts to copy file, but wait at most 5 seconds
19407         local loops=0
19408         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19409
19410         $LFS swap_layouts $file1 $file2
19411         local rc=$?
19412         wait $DD_PID
19413         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19414         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19415
19416         # how many bytes copied before swapping layout
19417         local copied=$(stat -c %s $file2)
19418         local remaining=$(stat -c %s $ref1)
19419         remaining=$((remaining - copied))
19420         echo "Copied $copied bytes before swapping layout..."
19421
19422         cmp -n $copied $file1 $ref2 | grep differ &&
19423                 error "Content mismatch [0, $copied) of ref2 and file1"
19424         cmp -n $copied $file2 $ref1 ||
19425                 error "Content mismatch [0, $copied) of ref1 and file2"
19426         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19427                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19428
19429         # clean up
19430         rm -f $ref1 $ref2 $file1 $file2
19431 }
19432 run_test 184c "Concurrent write and layout swap"
19433
19434 test_184d() {
19435         check_swap_layouts_support
19436         check_swap_layout_no_dom $DIR
19437         [ -z "$(which getfattr 2>/dev/null)" ] &&
19438                 skip_env "no getfattr command"
19439
19440         local file1=$DIR/$tdir/$tfile-1
19441         local file2=$DIR/$tdir/$tfile-2
19442         local file3=$DIR/$tdir/$tfile-3
19443         local lovea1
19444         local lovea2
19445
19446         mkdir -p $DIR/$tdir
19447         touch $file1 || error "create $file1 failed"
19448         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19449                 error "create $file2 failed"
19450         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19451                 error "create $file3 failed"
19452         lovea1=$(get_layout_param $file1)
19453
19454         $LFS swap_layouts $file2 $file3 ||
19455                 error "swap $file2 $file3 layouts failed"
19456         $LFS swap_layouts $file1 $file2 ||
19457                 error "swap $file1 $file2 layouts failed"
19458
19459         lovea2=$(get_layout_param $file2)
19460         echo "$lovea1"
19461         echo "$lovea2"
19462         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19463
19464         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19465         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19466 }
19467 run_test 184d "allow stripeless layouts swap"
19468
19469 test_184e() {
19470         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19471                 skip "Need MDS version at least 2.6.94"
19472         check_swap_layouts_support
19473         check_swap_layout_no_dom $DIR
19474         [ -z "$(which getfattr 2>/dev/null)" ] &&
19475                 skip_env "no getfattr command"
19476
19477         local file1=$DIR/$tdir/$tfile-1
19478         local file2=$DIR/$tdir/$tfile-2
19479         local file3=$DIR/$tdir/$tfile-3
19480         local lovea
19481
19482         mkdir -p $DIR/$tdir
19483         touch $file1 || error "create $file1 failed"
19484         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19485                 error "create $file2 failed"
19486         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19487                 error "create $file3 failed"
19488
19489         $LFS swap_layouts $file1 $file2 ||
19490                 error "swap $file1 $file2 layouts failed"
19491
19492         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19493         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19494
19495         echo 123 > $file1 || error "Should be able to write into $file1"
19496
19497         $LFS swap_layouts $file1 $file3 ||
19498                 error "swap $file1 $file3 layouts failed"
19499
19500         echo 123 > $file1 || error "Should be able to write into $file1"
19501
19502         rm -rf $file1 $file2 $file3
19503 }
19504 run_test 184e "Recreate layout after stripeless layout swaps"
19505
19506 test_184f() {
19507         # Create a file with name longer than sizeof(struct stat) ==
19508         # 144 to see if we can get chars from the file name to appear
19509         # in the returned striping. Note that 'f' == 0x66.
19510         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19511
19512         mkdir -p $DIR/$tdir
19513         mcreate $DIR/$tdir/$file
19514         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19515                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19516         fi
19517 }
19518 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19519
19520 test_185() { # LU-2441
19521         # LU-3553 - no volatile file support in old servers
19522         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19523                 skip "Need MDS version at least 2.3.60"
19524
19525         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19526         touch $DIR/$tdir/spoo
19527         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19528         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19529                 error "cannot create/write a volatile file"
19530         [ "$FILESET" == "" ] &&
19531         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19532                 error "FID is still valid after close"
19533
19534         multiop_bg_pause $DIR/$tdir Vw4096_c
19535         local multi_pid=$!
19536
19537         local OLD_IFS=$IFS
19538         IFS=":"
19539         local fidv=($fid)
19540         IFS=$OLD_IFS
19541         # assume that the next FID for this client is sequential, since stdout
19542         # is unfortunately eaten by multiop_bg_pause
19543         local n=$((${fidv[1]} + 1))
19544         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19545         if [ "$FILESET" == "" ]; then
19546                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19547                         error "FID is missing before close"
19548         fi
19549         kill -USR1 $multi_pid
19550         # 1 second delay, so if mtime change we will see it
19551         sleep 1
19552         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19553         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19554 }
19555 run_test 185 "Volatile file support"
19556
19557 function create_check_volatile() {
19558         local idx=$1
19559         local tgt
19560
19561         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19562         local PID=$!
19563         sleep 1
19564         local FID=$(cat /tmp/${tfile}.fid)
19565         [ "$FID" == "" ] && error "can't get FID for volatile"
19566         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19567         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19568         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19569         kill -USR1 $PID
19570         wait
19571         sleep 1
19572         cancel_lru_locks mdc # flush opencache
19573         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19574         return 0
19575 }
19576
19577 test_185a(){
19578         # LU-12516 - volatile creation via .lustre
19579         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19580                 skip "Need MDS version at least 2.3.55"
19581
19582         create_check_volatile 0
19583         [ $MDSCOUNT -lt 2 ] && return 0
19584
19585         # DNE case
19586         create_check_volatile 1
19587
19588         return 0
19589 }
19590 run_test 185a "Volatile file creation in .lustre/fid/"
19591
19592 test_187a() {
19593         remote_mds_nodsh && skip "remote MDS with nodsh"
19594         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19595                 skip "Need MDS version at least 2.3.0"
19596
19597         local dir0=$DIR/$tdir/$testnum
19598         mkdir -p $dir0 || error "creating dir $dir0"
19599
19600         local file=$dir0/file1
19601         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19602         stack_trap "rm -f $file"
19603         local dv1=$($LFS data_version $file)
19604         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19605         local dv2=$($LFS data_version $file)
19606         [[ $dv1 != $dv2 ]] ||
19607                 error "data version did not change on write $dv1 == $dv2"
19608 }
19609 run_test 187a "Test data version change"
19610
19611 test_187b() {
19612         remote_mds_nodsh && skip "remote MDS with nodsh"
19613         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19614                 skip "Need MDS version at least 2.3.0"
19615
19616         local dir0=$DIR/$tdir/$testnum
19617         mkdir -p $dir0 || error "creating dir $dir0"
19618
19619         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19620         [[ ${DV[0]} != ${DV[1]} ]] ||
19621                 error "data version did not change on write"\
19622                       " ${DV[0]} == ${DV[1]}"
19623
19624         # clean up
19625         rm -f $file1
19626 }
19627 run_test 187b "Test data version change on volatile file"
19628
19629 test_200() {
19630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19631         remote_mgs_nodsh && skip "remote MGS with nodsh"
19632         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19633
19634         local POOL=${POOL:-cea1}
19635         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19636         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19637         # Pool OST targets
19638         local first_ost=0
19639         local last_ost=$(($OSTCOUNT - 1))
19640         local ost_step=2
19641         local ost_list=$(seq $first_ost $ost_step $last_ost)
19642         local ost_range="$first_ost $last_ost $ost_step"
19643         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19644         local file_dir=$POOL_ROOT/file_tst
19645         local subdir=$test_path/subdir
19646         local rc=0
19647
19648         while : ; do
19649                 # former test_200a test_200b
19650                 pool_add $POOL                          || { rc=$? ; break; }
19651                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19652                 # former test_200c test_200d
19653                 mkdir -p $test_path
19654                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19655                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19656                 mkdir -p $subdir
19657                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19658                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19659                                                         || { rc=$? ; break; }
19660                 # former test_200e test_200f
19661                 local files=$((OSTCOUNT*3))
19662                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19663                                                         || { rc=$? ; break; }
19664                 pool_create_files $POOL $file_dir $files "$ost_list" \
19665                                                         || { rc=$? ; break; }
19666                 # former test_200g test_200h
19667                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19668                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19669
19670                 # former test_201a test_201b test_201c
19671                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19672
19673                 local f=$test_path/$tfile
19674                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19675                 pool_remove $POOL $f                    || { rc=$? ; break; }
19676                 break
19677         done
19678
19679         destroy_test_pools
19680
19681         return $rc
19682 }
19683 run_test 200 "OST pools"
19684
19685 # usage: default_attr <count | size | offset>
19686 default_attr() {
19687         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19688 }
19689
19690 # usage: check_default_stripe_attr
19691 check_default_stripe_attr() {
19692         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19693         case $1 in
19694         --stripe-count|-c)
19695                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19696         --stripe-size|-S)
19697                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19698         --stripe-index|-i)
19699                 EXPECTED=-1;;
19700         *)
19701                 error "unknown getstripe attr '$1'"
19702         esac
19703
19704         [ $ACTUAL == $EXPECTED ] ||
19705                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19706 }
19707
19708 test_204a() {
19709         test_mkdir $DIR/$tdir
19710         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19711
19712         check_default_stripe_attr --stripe-count
19713         check_default_stripe_attr --stripe-size
19714         check_default_stripe_attr --stripe-index
19715 }
19716 run_test 204a "Print default stripe attributes"
19717
19718 test_204b() {
19719         test_mkdir $DIR/$tdir
19720         $LFS setstripe --stripe-count 1 $DIR/$tdir
19721
19722         check_default_stripe_attr --stripe-size
19723         check_default_stripe_attr --stripe-index
19724 }
19725 run_test 204b "Print default stripe size and offset"
19726
19727 test_204c() {
19728         test_mkdir $DIR/$tdir
19729         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19730
19731         check_default_stripe_attr --stripe-count
19732         check_default_stripe_attr --stripe-index
19733 }
19734 run_test 204c "Print default stripe count and offset"
19735
19736 test_204d() {
19737         test_mkdir $DIR/$tdir
19738         $LFS setstripe --stripe-index 0 $DIR/$tdir
19739
19740         check_default_stripe_attr --stripe-count
19741         check_default_stripe_attr --stripe-size
19742 }
19743 run_test 204d "Print default stripe count and size"
19744
19745 test_204e() {
19746         test_mkdir $DIR/$tdir
19747         $LFS setstripe -d $DIR/$tdir
19748
19749         # LU-16904 check if root is set as PFL layout
19750         local numcomp=$($LFS getstripe --component-count $MOUNT)
19751
19752         if [[ $numcomp -gt 0 ]]; then
19753                 check_default_stripe_attr --stripe-count
19754         else
19755                 check_default_stripe_attr --stripe-count --raw
19756         fi
19757         check_default_stripe_attr --stripe-size --raw
19758         check_default_stripe_attr --stripe-index --raw
19759 }
19760 run_test 204e "Print raw stripe attributes"
19761
19762 test_204f() {
19763         test_mkdir $DIR/$tdir
19764         $LFS setstripe --stripe-count 1 $DIR/$tdir
19765
19766         check_default_stripe_attr --stripe-size --raw
19767         check_default_stripe_attr --stripe-index --raw
19768 }
19769 run_test 204f "Print raw stripe size and offset"
19770
19771 test_204g() {
19772         test_mkdir $DIR/$tdir
19773         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19774
19775         check_default_stripe_attr --stripe-count --raw
19776         check_default_stripe_attr --stripe-index --raw
19777 }
19778 run_test 204g "Print raw stripe count and offset"
19779
19780 test_204h() {
19781         test_mkdir $DIR/$tdir
19782         $LFS setstripe --stripe-index 0 $DIR/$tdir
19783
19784         check_default_stripe_attr --stripe-count --raw
19785         check_default_stripe_attr --stripe-size --raw
19786 }
19787 run_test 204h "Print raw stripe count and size"
19788
19789 # Figure out which job scheduler is being used, if any,
19790 # or use a fake one
19791 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19792         JOBENV=SLURM_JOB_ID
19793 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19794         JOBENV=LSB_JOBID
19795 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19796         JOBENV=PBS_JOBID
19797 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19798         JOBENV=LOADL_STEP_ID
19799 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19800         JOBENV=JOB_ID
19801 else
19802         $LCTL list_param jobid_name > /dev/null 2>&1
19803         if [ $? -eq 0 ]; then
19804                 JOBENV=nodelocal
19805         else
19806                 JOBENV=FAKE_JOBID
19807         fi
19808 fi
19809 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19810
19811 verify_jobstats() {
19812         local cmd=($1)
19813         shift
19814         local facets="$@"
19815
19816 # we don't really need to clear the stats for this test to work, since each
19817 # command has a unique jobid, but it makes debugging easier if needed.
19818 #       for facet in $facets; do
19819 #               local dev=$(convert_facet2label $facet)
19820 #               # clear old jobstats
19821 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19822 #       done
19823
19824         # use a new JobID for each test, or we might see an old one
19825         [ "$JOBENV" = "FAKE_JOBID" ] &&
19826                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19827
19828         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19829
19830         [ "$JOBENV" = "nodelocal" ] && {
19831                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19832                 $LCTL set_param jobid_name=$FAKE_JOBID
19833                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19834         }
19835
19836         log "Test: ${cmd[*]}"
19837         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19838
19839         if [ $JOBENV = "FAKE_JOBID" ]; then
19840                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19841         else
19842                 ${cmd[*]}
19843         fi
19844
19845         # all files are created on OST0000
19846         for facet in $facets; do
19847                 local stats="*.$(convert_facet2label $facet).job_stats"
19848
19849                 # strip out libtool wrappers for in-tree executables
19850                 if (( $(do_facet $facet lctl get_param $stats |
19851                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19852                         do_facet $facet lctl get_param $stats
19853                         error "No jobstats for $JOBVAL found on $facet::$stats"
19854                 fi
19855         done
19856 }
19857
19858 jobstats_set() {
19859         local new_jobenv=$1
19860
19861         set_persistent_param_and_check client "jobid_var" \
19862                 "$FSNAME.sys.jobid_var" $new_jobenv
19863 }
19864
19865 test_205a() { # Job stats
19866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19867         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19868                 skip "Need MDS version with at least 2.7.1"
19869         remote_mgs_nodsh && skip "remote MGS with nodsh"
19870         remote_mds_nodsh && skip "remote MDS with nodsh"
19871         remote_ost_nodsh && skip "remote OST with nodsh"
19872         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19873                 skip "Server doesn't support jobstats"
19874         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19875
19876         local old_jobenv=$($LCTL get_param -n jobid_var)
19877         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19878         stack_trap "jobstats_set $old_jobenv" EXIT
19879
19880         changelog_register
19881
19882         local old_jobid_name=$($LCTL get_param jobid_name)
19883         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19884
19885         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19886                                 mdt.*.job_cleanup_interval | head -n 1)
19887         local new_interval=5
19888         do_facet $SINGLEMDS \
19889                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19890         stack_trap "do_facet $SINGLEMDS \
19891                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19892         local start=$SECONDS
19893
19894         local cmd
19895         # mkdir
19896         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19897         verify_jobstats "$cmd" "$SINGLEMDS"
19898         # rmdir
19899         cmd="rmdir $DIR/$tdir"
19900         verify_jobstats "$cmd" "$SINGLEMDS"
19901         # mkdir on secondary MDT
19902         if [ $MDSCOUNT -gt 1 ]; then
19903                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19904                 verify_jobstats "$cmd" "mds2"
19905         fi
19906         # mknod
19907         cmd="mknod $DIR/$tfile c 1 3"
19908         verify_jobstats "$cmd" "$SINGLEMDS"
19909         # unlink
19910         cmd="rm -f $DIR/$tfile"
19911         verify_jobstats "$cmd" "$SINGLEMDS"
19912         # create all files on OST0000 so verify_jobstats can find OST stats
19913         # open & close
19914         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19915         verify_jobstats "$cmd" "$SINGLEMDS"
19916         # setattr
19917         cmd="touch $DIR/$tfile"
19918         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19919         # write
19920         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19921         verify_jobstats "$cmd" "ost1"
19922         # read
19923         cancel_lru_locks osc
19924         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19925         verify_jobstats "$cmd" "ost1"
19926         # truncate
19927         cmd="$TRUNCATE $DIR/$tfile 0"
19928         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19929         # rename
19930         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19931         verify_jobstats "$cmd" "$SINGLEMDS"
19932         # jobstats expiry - sleep until old stats should be expired
19933         local left=$((new_interval + 5 - (SECONDS - start)))
19934         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19935                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19936                         "0" $left
19937         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19938         verify_jobstats "$cmd" "$SINGLEMDS"
19939         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19940             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19941
19942         # Ensure that jobid are present in changelog (if supported by MDS)
19943         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19944                 changelog_dump | tail -10
19945                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19946                 [ $jobids -eq 9 ] ||
19947                         error "Wrong changelog jobid count $jobids != 9"
19948
19949                 # LU-5862
19950                 JOBENV="disable"
19951                 jobstats_set $JOBENV
19952                 touch $DIR/$tfile
19953                 changelog_dump | grep $tfile
19954                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19955                 [ $jobids -eq 0 ] ||
19956                         error "Unexpected jobids when jobid_var=$JOBENV"
19957         fi
19958
19959         # test '%j' access to environment variable - if supported
19960         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19961                 JOBENV="JOBCOMPLEX"
19962                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19963
19964                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19965         fi
19966
19967         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19968                 JOBENV="JOBCOMPLEX"
19969                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19970
19971                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19972         fi
19973
19974         # test '%j' access to per-session jobid - if supported
19975         if lctl list_param jobid_this_session > /dev/null 2>&1
19976         then
19977                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19978                 lctl set_param jobid_this_session=$USER
19979
19980                 JOBENV="JOBCOMPLEX"
19981                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19982
19983                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19984         fi
19985 }
19986 run_test 205a "Verify job stats"
19987
19988 # LU-13117, LU-13597, LU-16599
19989 test_205b() {
19990         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19991                 skip "Need MDS version at least 2.13.54.91"
19992
19993         local job_stats="mdt.*.job_stats"
19994         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19995
19996         do_facet mds1 $LCTL set_param $job_stats=clear
19997
19998         # Setting jobid_var to USER might not be supported
19999         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20000         $LCTL set_param jobid_var=USER || true
20001         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20002         $LCTL set_param jobid_name="%j.%e.%u"
20003
20004         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20005         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20006                 { do_facet mds1 $LCTL get_param $job_stats;
20007                   error "Unexpected jobid found"; }
20008         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20009                 { do_facet mds1 $LCTL get_param $job_stats;
20010                   error "wrong job_stats format found"; }
20011
20012         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20013                 echo "MDS does not yet escape jobid" && return 0
20014
20015         mkdir_on_mdt0 $DIR/$tdir
20016         $LCTL set_param jobid_var=TEST205b
20017         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20018         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20019                       awk '/has\\x20sp/ {print $3}')
20020         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20021                   error "jobid not escaped"; }
20022
20023         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20024                 # need to run such a command on mds1:
20025                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20026                 #
20027                 # there might be multiple MDTs on single mds server, so need to
20028                 # specifiy MDT0000. Or the command will fail due to other MDTs
20029                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20030                         error "cannot clear escaped jobid in job_stats";
20031         else
20032                 echo "MDS does not support clearing escaped jobid"
20033         fi
20034 }
20035 run_test 205b "Verify job stats jobid and output format"
20036
20037 # LU-13733
20038 test_205c() {
20039         $LCTL set_param llite.*.stats=0
20040         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20041         $LCTL get_param llite.*.stats
20042         $LCTL get_param llite.*.stats | grep \
20043                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20044                         error "wrong client stats format found"
20045 }
20046 run_test 205c "Verify client stats format"
20047
20048 test_205d() {
20049         local file=$DIR/$tdir/$tfile
20050
20051         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20052                 skip "need lustre >= 2.15.53 for lljobstat"
20053         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20054                 skip "need lustre >= 2.15.53 for lljobstat"
20055         verify_yaml_available || skip_env "YAML verification not installed"
20056
20057         test_mkdir -i 0 $DIR/$tdir
20058         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20059         stack_trap "rm -rf $DIR/$tdir"
20060
20061         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20062                 error "failed to write data to $file"
20063         mv $file $file.2
20064
20065         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20066         echo -n 'verify rename_stats...'
20067         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20068                 verify_yaml || error "rename_stats is not valid YAML"
20069         echo " OK"
20070
20071         echo -n 'verify mdt job_stats...'
20072         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20073                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20074         echo " OK"
20075
20076         echo -n 'verify ost job_stats...'
20077         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20078                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20079         echo " OK"
20080 }
20081 run_test 205d "verify the format of some stats files"
20082
20083 test_205e() {
20084         local ops_comma
20085         local file=$DIR/$tdir/$tfile
20086         local -a cli_params
20087
20088         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20089                 skip "need lustre >= 2.15.53 for lljobstat"
20090         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20091                 skip "need lustre >= 2.15.53 for lljobstat"
20092         verify_yaml_available || skip_env "YAML verification not installed"
20093
20094         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20095         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20096         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20097
20098         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20099         stack_trap "rm -rf $DIR/$tdir"
20100
20101         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20102                 error "failed to create $file on ost1"
20103         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20104                 error "failed to write data to $file"
20105
20106         do_facet mds1 "$LCTL get_param *.*.job_stats"
20107         do_facet ost1 "$LCTL get_param *.*.job_stats"
20108
20109         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20110         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20111                 error "The output of lljobstat is not an valid YAML"
20112
20113         # verify that job dd.0 does exist and has some ops on ost1
20114         # typically this line is like:
20115         # - 205e.dd.0:            {ops: 20, ...}
20116         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20117                     awk '$2=="205e.dd.0:" {print $4}')
20118
20119         (( ${ops_comma%,} >= 10 )) ||
20120                 error "cannot find job 205e.dd.0 with ops >= 10"
20121 }
20122 run_test 205e "verify the output of lljobstat"
20123
20124 test_205f() {
20125         verify_yaml_available || skip_env "YAML verification not installed"
20126
20127         # check both qos_ost_weights and qos_mdt_weights
20128         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20129         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20130                 error "qos_ost_weights is not valid YAML"
20131 }
20132 run_test 205f "verify qos_ost_weights YAML format "
20133
20134 __test_205_jobstats_dump() {
20135         local -a pids
20136         local nbr_instance=$1
20137
20138         while true; do
20139                 if (( ${#pids[@]} >= nbr_instance )); then
20140                         wait ${pids[@]}
20141                         pids=()
20142                 fi
20143
20144                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20145                 pids+=( $! )
20146         done
20147 }
20148
20149 __test_205_cleanup() {
20150         kill $@
20151         # Clear all job entries
20152         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20153 }
20154
20155 test_205g() {
20156         local -a mds1_params
20157         local -a cli_params
20158         local pids
20159         local interval=5
20160
20161         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20162         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20163         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20164
20165         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20166         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20167         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20168
20169         # start jobs loop
20170         export TEST205G_ID=205g
20171         stack_trap "unset TEST205G_ID" EXIT
20172         while true; do
20173                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20174         done & pids="$! "
20175
20176         __test_205_jobstats_dump 4 & pids+="$! "
20177         stack_trap "__test_205_cleanup $pids" EXIT INT
20178
20179         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20180 }
20181 run_test 205g "stress test for job_stats procfile"
20182
20183 test_205h() {
20184         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20185
20186         local dir=$DIR/$tdir
20187         local f=$dir/$tfile
20188         local f2=$dir/$tfile-2
20189         local f3=$dir/$tfile-3
20190         local subdir=$DIR/dir
20191         local val
20192
20193         local mdts=$(comma_list $(mdts_nodes))
20194         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20195         local client_saved=$($LCTL get_param -n jobid_var)
20196
20197         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20198         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20199
20200         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20201                 error "failed to set job_xattr parameter to user.job"
20202         $LCTL set_param jobid_var=procname.uid ||
20203                 error "failed to set jobid_var parameter"
20204
20205         test_mkdir $dir
20206
20207         touch $f
20208         val=$(getfattr -n user.job $f | grep user.job)
20209         [[ $val = user.job=\"touch.0\" ]] ||
20210                 error "expected user.job=\"touch.0\", got '$val'"
20211
20212         mkdir $subdir
20213         val=$(getfattr -n user.job $subdir | grep user.job)
20214         [[ $val = user.job=\"mkdir.0\" ]] ||
20215                 error "expected user.job=\"mkdir.0\", got '$val'"
20216
20217         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20218                 error "failed to set job_xattr parameter to NONE"
20219
20220         touch $f2
20221         val=$(getfattr -d $f2)
20222         [[ -z $val ]] ||
20223                 error "expected no user xattr, got '$val'"
20224
20225         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20226                 error "failed to set job_xattr parameter to trusted.job"
20227
20228         touch $f3
20229         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20230         [[ $val = trusted.job=\"touch.0\" ]] ||
20231                 error "expected trusted.job=\"touch.0\", got '$val'"
20232 }
20233 run_test 205h "check jobid xattr is stored correctly"
20234
20235 test_205i() {
20236         local mdts=$(comma_list $(mdts_nodes))
20237         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20238
20239         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20240
20241         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20242                 error "failed to set mdt.*.job_xattr to user.1234567"
20243
20244         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20245                 error "failed to reject too long job_xattr name"
20246
20247         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20248                 error "failed to reject job_xattr name in bad format"
20249
20250         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20251                 error "failed to reject job_xattr name with invalid character"
20252
20253         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20254                         xargs $LCTL set_param" &&
20255                 error "failed to reject job_xattr name with non-ascii character"
20256
20257         return 0
20258 }
20259 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20260
20261 # LU-1480, LU-1773 and LU-1657
20262 test_206() {
20263         mkdir -p $DIR/$tdir
20264         $LFS setstripe -c -1 $DIR/$tdir
20265 #define OBD_FAIL_LOV_INIT 0x1403
20266         $LCTL set_param fail_loc=0xa0001403
20267         $LCTL set_param fail_val=1
20268         touch $DIR/$tdir/$tfile || true
20269 }
20270 run_test 206 "fail lov_init_raid0() doesn't lbug"
20271
20272 test_207a() {
20273         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20274         local fsz=`stat -c %s $DIR/$tfile`
20275         cancel_lru_locks mdc
20276
20277         # do not return layout in getattr intent
20278 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20279         $LCTL set_param fail_loc=0x170
20280         local sz=`stat -c %s $DIR/$tfile`
20281
20282         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20283
20284         rm -rf $DIR/$tfile
20285 }
20286 run_test 207a "can refresh layout at glimpse"
20287
20288 test_207b() {
20289         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20290         local cksum=`md5sum $DIR/$tfile`
20291         local fsz=`stat -c %s $DIR/$tfile`
20292         cancel_lru_locks mdc
20293         cancel_lru_locks osc
20294
20295         # do not return layout in getattr intent
20296 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20297         $LCTL set_param fail_loc=0x171
20298
20299         # it will refresh layout after the file is opened but before read issues
20300         echo checksum is "$cksum"
20301         echo "$cksum" |md5sum -c --quiet || error "file differs"
20302
20303         rm -rf $DIR/$tfile
20304 }
20305 run_test 207b "can refresh layout at open"
20306
20307 test_208() {
20308         # FIXME: in this test suite, only RD lease is used. This is okay
20309         # for now as only exclusive open is supported. After generic lease
20310         # is done, this test suite should be revised. - Jinshan
20311
20312         remote_mds_nodsh && skip "remote MDS with nodsh"
20313         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20314                 skip "Need MDS version at least 2.4.52"
20315
20316         echo "==== test 1: verify get lease work"
20317         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20318
20319         echo "==== test 2: verify lease can be broken by upcoming open"
20320         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20321         local PID=$!
20322         sleep 2
20323
20324         $MULTIOP $DIR/$tfile oO_RDWR:c
20325         kill -USR1 $PID && wait $PID || error "break lease error"
20326
20327         echo "==== test 3: verify lease can't be granted if an open already exists"
20328         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20329         local PID=$!
20330         sleep 2
20331
20332         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20333         kill -USR1 $PID && wait $PID || error "open file error"
20334
20335         echo "==== test 4: lease can sustain over recovery"
20336         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20337         PID=$!
20338         sleep 2
20339
20340         fail mds1
20341
20342         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20343
20344         echo "==== test 5: lease broken can't be regained by replay"
20345         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20346         PID=$!
20347         sleep 2
20348
20349         # open file to break lease and then recovery
20350         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20351         fail mds1
20352
20353         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20354
20355         rm -f $DIR/$tfile
20356 }
20357 run_test 208 "Exclusive open"
20358
20359 test_209() {
20360         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20361                 skip_env "must have disp_stripe"
20362
20363         touch $DIR/$tfile
20364         sync; sleep 5; sync;
20365
20366         echo 3 > /proc/sys/vm/drop_caches
20367         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20368                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20369         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20370
20371         # open/close 500 times
20372         for i in $(seq 500); do
20373                 cat $DIR/$tfile
20374         done
20375
20376         echo 3 > /proc/sys/vm/drop_caches
20377         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20378                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20379         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20380
20381         echo "before: $req_before, after: $req_after"
20382         [ $((req_after - req_before)) -ge 300 ] &&
20383                 error "open/close requests are not freed"
20384         return 0
20385 }
20386 run_test 209 "read-only open/close requests should be freed promptly"
20387
20388 test_210() {
20389         local pid
20390
20391         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20392         pid=$!
20393         sleep 1
20394
20395         $LFS getstripe $DIR/$tfile
20396         kill -USR1 $pid
20397         wait $pid || error "multiop failed"
20398
20399         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20400         pid=$!
20401         sleep 1
20402
20403         $LFS getstripe $DIR/$tfile
20404         kill -USR1 $pid
20405         wait $pid || error "multiop failed"
20406 }
20407 run_test 210 "lfs getstripe does not break leases"
20408
20409 function test_211() {
20410         local PID
20411         local id
20412         local rc
20413
20414         stack_trap "rm -f $DIR/$tfile" EXIT
20415         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20416                 error "can't create file"
20417         $LFS mirror extend -N $DIR/$tfile ||
20418                 error "can't create a replica"
20419         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20420         $LFS getstripe $DIR/$tfile
20421         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20422         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20423
20424         $MULTIOP $DIR/$tfile OeW_E+eUc &
20425         PID=$!
20426         sleep 0.3
20427
20428         id=$($LFS getstripe $DIR/$tfile |
20429                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20430         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20431                 error "removed last in-sync replica?"
20432
20433         kill -USR1 $PID
20434         wait $PID
20435         (( $? == 0 )) || error "failed split broke the lease"
20436 }
20437 run_test 211 "failed mirror split doesn't break write lease"
20438
20439 test_212() {
20440         size=`date +%s`
20441         size=$((size % 8192 + 1))
20442         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20443         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20444         rm -f $DIR/f212 $DIR/f212.xyz
20445 }
20446 run_test 212 "Sendfile test ============================================"
20447
20448 test_213() {
20449         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20450         cancel_lru_locks osc
20451         lctl set_param fail_loc=0x8000040f
20452         # generate a read lock
20453         cat $DIR/$tfile > /dev/null
20454         # write to the file, it will try to cancel the above read lock.
20455         cat /etc/hosts >> $DIR/$tfile
20456 }
20457 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20458
20459 test_214() { # for bug 20133
20460         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20461         for (( i=0; i < 340; i++ )) ; do
20462                 touch $DIR/$tdir/d214c/a$i
20463         done
20464
20465         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20466         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20467         ls $DIR/d214c || error "ls $DIR/d214c failed"
20468         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20469         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20470 }
20471 run_test 214 "hash-indexed directory test - bug 20133"
20472
20473 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20474 create_lnet_proc_files() {
20475         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20476 }
20477
20478 # counterpart of create_lnet_proc_files
20479 remove_lnet_proc_files() {
20480         rm -f $TMP/lnet_$1.sys
20481 }
20482
20483 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20484 # 3rd arg as regexp for body
20485 check_lnet_proc_stats() {
20486         local l=$(cat "$TMP/lnet_$1" |wc -l)
20487         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20488
20489         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20490 }
20491
20492 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20493 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20494 # optional and can be regexp for 2nd line (lnet.routes case)
20495 check_lnet_proc_entry() {
20496         local blp=2          # blp stands for 'position of 1st line of body'
20497         [ -z "$5" ] || blp=3 # lnet.routes case
20498
20499         local l=$(cat "$TMP/lnet_$1" |wc -l)
20500         # subtracting one from $blp because the body can be empty
20501         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20502
20503         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20504                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20505
20506         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20507                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20508
20509         # bail out if any unexpected line happened
20510         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20511         [ "$?" != 0 ] || error "$2 misformatted"
20512 }
20513
20514 test_215() { # for bugs 18102, 21079, 21517
20515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20516
20517         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20518         local P='[1-9][0-9]*'           # positive numeric
20519         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20520         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20521         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20522         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20523
20524         local L1 # regexp for 1st line
20525         local L2 # regexp for 2nd line (optional)
20526         local BR # regexp for the rest (body)
20527
20528         # lnet.stats should look as 11 space-separated non-negative numerics
20529         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20530         create_lnet_proc_files "stats"
20531         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20532         remove_lnet_proc_files "stats"
20533
20534         # lnet.routes should look like this:
20535         # Routing disabled/enabled
20536         # net hops priority state router
20537         # where net is a string like tcp0, hops > 0, priority >= 0,
20538         # state is up/down,
20539         # router is a string like 192.168.1.1@tcp2
20540         L1="^Routing (disabled|enabled)$"
20541         L2="^net +hops +priority +state +router$"
20542         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20543         create_lnet_proc_files "routes"
20544         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20545         remove_lnet_proc_files "routes"
20546
20547         # lnet.routers should look like this:
20548         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20549         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20550         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20551         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20552         L1="^ref +rtr_ref +alive +router$"
20553         BR="^$P +$P +(up|down) +$NID$"
20554         create_lnet_proc_files "routers"
20555         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20556         remove_lnet_proc_files "routers"
20557
20558         # lnet.peers should look like this:
20559         # nid refs state last max rtr min tx min queue
20560         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20561         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20562         # numeric (0 or >0 or <0), queue >= 0.
20563         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20564         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20565         create_lnet_proc_files "peers"
20566         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20567         remove_lnet_proc_files "peers"
20568
20569         # lnet.buffers  should look like this:
20570         # pages count credits min
20571         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20572         L1="^pages +count +credits +min$"
20573         BR="^ +$N +$N +$I +$I$"
20574         create_lnet_proc_files "buffers"
20575         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20576         remove_lnet_proc_files "buffers"
20577
20578         # lnet.nis should look like this:
20579         # nid status alive refs peer rtr max tx min
20580         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20581         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20582         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20583         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20584         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20585         create_lnet_proc_files "nis"
20586         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20587         remove_lnet_proc_files "nis"
20588
20589         # can we successfully write to lnet.stats?
20590         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20591 }
20592 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20593
20594 test_216() { # bug 20317
20595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20596         remote_ost_nodsh && skip "remote OST with nodsh"
20597
20598         local node
20599         local facets=$(get_facets OST)
20600         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20601
20602         save_lustre_params client "osc.*.contention_seconds" > $p
20603         save_lustre_params $facets \
20604                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20605         save_lustre_params $facets \
20606                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20607         save_lustre_params $facets \
20608                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20609         clear_stats osc.*.osc_stats
20610
20611         # agressive lockless i/o settings
20612         do_nodes $(comma_list $(osts_nodes)) \
20613                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20614                         ldlm.namespaces.filter-*.contended_locks=0 \
20615                         ldlm.namespaces.filter-*.contention_seconds=60"
20616         lctl set_param -n osc.*.contention_seconds=60
20617
20618         $DIRECTIO write $DIR/$tfile 0 10 4096
20619         $CHECKSTAT -s 40960 $DIR/$tfile
20620
20621         # disable lockless i/o
20622         do_nodes $(comma_list $(osts_nodes)) \
20623                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20624                         ldlm.namespaces.filter-*.contended_locks=32 \
20625                         ldlm.namespaces.filter-*.contention_seconds=0"
20626         lctl set_param -n osc.*.contention_seconds=0
20627         clear_stats osc.*.osc_stats
20628
20629         dd if=/dev/zero of=$DIR/$tfile count=0
20630         $CHECKSTAT -s 0 $DIR/$tfile
20631
20632         restore_lustre_params <$p
20633         rm -f $p
20634         rm $DIR/$tfile
20635 }
20636 run_test 216 "check lockless direct write updates file size and kms correctly"
20637
20638 test_217() { # bug 22430
20639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20640
20641         local node
20642
20643         for node in $(nodes_list); do
20644                 local nid=$(host_nids_address $node $NETTYPE)
20645                 local node_ip=$(do_node $node getent ahostsv4 $node |
20646                                 awk '{ print $1; exit; }')
20647
20648                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20649                 # if hostname matches any NID, use hostname for better testing
20650                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20651                         echo "lctl ping node $node@$NETTYPE"
20652                         lctl ping $node@$NETTYPE
20653                 else # otherwise, at least test 'lctl ping' is working
20654                         echo "lctl ping nid $(h2nettype $nid)"
20655                         lctl ping $(h2nettype $nid)
20656                         echo "skipping $node (no hyphen detected)"
20657                 fi
20658         done
20659 }
20660 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20661
20662 test_218() {
20663         # do directio so as not to populate the page cache
20664         log "creating a 10 Mb file"
20665         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20666                 error "multiop failed while creating a file"
20667         log "starting reads"
20668         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20669         log "truncating the file"
20670         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20671                 error "multiop failed while truncating the file"
20672         log "killing dd"
20673         kill %+ || true # reads might have finished
20674         echo "wait until dd is finished"
20675         wait
20676         log "removing the temporary file"
20677         rm -rf $DIR/$tfile || error "tmp file removal failed"
20678 }
20679 run_test 218 "parallel read and truncate should not deadlock"
20680
20681 test_219() {
20682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20683
20684         # write one partial page
20685         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20686         # set no grant so vvp_io_commit_write will do sync write
20687         $LCTL set_param fail_loc=0x411
20688         # write a full page at the end of file
20689         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20690
20691         $LCTL set_param fail_loc=0
20692         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20693         $LCTL set_param fail_loc=0x411
20694         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20695
20696         # LU-4201
20697         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20698         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20699 }
20700 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20701
20702 test_220() { #LU-325
20703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20704         remote_ost_nodsh && skip "remote OST with nodsh"
20705         remote_mds_nodsh && skip "remote MDS with nodsh"
20706         remote_mgs_nodsh && skip "remote MGS with nodsh"
20707
20708         local OSTIDX=0
20709
20710         # create on MDT0000 so the last_id and next_id are correct
20711         mkdir_on_mdt0 $DIR/$tdir
20712         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20713         OST=${OST%_UUID}
20714
20715         # on the mdt's osc
20716         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20717         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20718                         osp.$mdtosc_proc1.prealloc_last_id)
20719         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20720                         osp.$mdtosc_proc1.prealloc_next_id)
20721
20722         $LFS df -i
20723
20724         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20725         #define OBD_FAIL_OST_ENOINO              0x229
20726         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20727         create_pool $FSNAME.$TESTNAME || return 1
20728         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20729
20730         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20731
20732         MDSOBJS=$((last_id - next_id))
20733         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20734
20735         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20736         echo "OST still has $count kbytes free"
20737
20738         echo "create $MDSOBJS files @next_id..."
20739         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20740
20741         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20742                         osp.$mdtosc_proc1.prealloc_last_id)
20743         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20744                         osp.$mdtosc_proc1.prealloc_next_id)
20745
20746         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20747         $LFS df -i
20748
20749         echo "cleanup..."
20750
20751         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20752         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20753
20754         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20755                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20756         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20757                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20758         echo "unlink $MDSOBJS files @$next_id..."
20759         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20760 }
20761 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20762
20763 test_221() {
20764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20765
20766         dd if=`which date` of=$MOUNT/date oflag=sync
20767         chmod +x $MOUNT/date
20768
20769         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20770         $LCTL set_param fail_loc=0x80001401
20771
20772         $MOUNT/date > /dev/null
20773         rm -f $MOUNT/date
20774 }
20775 run_test 221 "make sure fault and truncate race to not cause OOM"
20776
20777 test_222a () {
20778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20779
20780         rm -rf $DIR/$tdir
20781         test_mkdir $DIR/$tdir
20782         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20783         createmany -o $DIR/$tdir/$tfile 10
20784         cancel_lru_locks mdc
20785         cancel_lru_locks osc
20786         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20787         $LCTL set_param fail_loc=0x31a
20788         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20789         $LCTL set_param fail_loc=0
20790         rm -r $DIR/$tdir
20791 }
20792 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20793
20794 test_222b () {
20795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20796
20797         rm -rf $DIR/$tdir
20798         test_mkdir $DIR/$tdir
20799         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20800         createmany -o $DIR/$tdir/$tfile 10
20801         cancel_lru_locks mdc
20802         cancel_lru_locks osc
20803         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20804         $LCTL set_param fail_loc=0x31a
20805         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20806         $LCTL set_param fail_loc=0
20807 }
20808 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20809
20810 test_223 () {
20811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20812
20813         rm -rf $DIR/$tdir
20814         test_mkdir $DIR/$tdir
20815         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20816         createmany -o $DIR/$tdir/$tfile 10
20817         cancel_lru_locks mdc
20818         cancel_lru_locks osc
20819         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20820         $LCTL set_param fail_loc=0x31b
20821         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20822         $LCTL set_param fail_loc=0
20823         rm -r $DIR/$tdir
20824 }
20825 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20826
20827 test_224a() { # LU-1039, MRP-303
20828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20829         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20830         $LCTL set_param fail_loc=0x508
20831         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20832         $LCTL set_param fail_loc=0
20833         df $DIR
20834 }
20835 run_test 224a "Don't panic on bulk IO failure"
20836
20837 test_224bd_sub() { # LU-1039, MRP-303
20838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20839         local timeout=$1
20840
20841         shift
20842         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20843
20844         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20845
20846         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20847         cancel_lru_locks osc
20848         set_checksums 0
20849         stack_trap "set_checksums $ORIG_CSUM" EXIT
20850         local at_max_saved=0
20851
20852         # adaptive timeouts may prevent seeing the issue
20853         if at_is_enabled; then
20854                 at_max_saved=$(at_max_get mds)
20855                 at_max_set 0 mds client
20856                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20857         fi
20858
20859         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20860         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20861         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20862
20863         do_facet ost1 $LCTL set_param fail_loc=0
20864         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20865         df $DIR
20866 }
20867
20868 test_224b() {
20869         test_224bd_sub 3 error "dd failed"
20870 }
20871 run_test 224b "Don't panic on bulk IO failure"
20872
20873 test_224c() { # LU-6441
20874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20875         remote_mds_nodsh && skip "remote MDS with nodsh"
20876
20877         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20878         save_writethrough $p
20879         set_cache writethrough on
20880
20881         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20882         local at_max=$($LCTL get_param -n at_max)
20883         local timeout=$($LCTL get_param -n timeout)
20884         local test_at="at_max"
20885         local param_at="$FSNAME.sys.at_max"
20886         local test_timeout="timeout"
20887         local param_timeout="$FSNAME.sys.timeout"
20888
20889         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20890
20891         set_persistent_param_and_check client "$test_at" "$param_at" 0
20892         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20893
20894         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20895         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20896         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20897         stack_trap "rm -f $DIR/$tfile"
20898         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20899         sync
20900         do_facet ost1 "$LCTL set_param fail_loc=0"
20901
20902         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20903         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20904                 $timeout
20905
20906         $LCTL set_param -n $pages_per_rpc
20907         restore_lustre_params < $p
20908         rm -f $p
20909 }
20910 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20911
20912 test_224d() { # LU-11169
20913         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20914 }
20915 run_test 224d "Don't corrupt data on bulk IO timeout"
20916
20917 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20918 test_225a () {
20919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20920         if [ -z ${MDSSURVEY} ]; then
20921                 skip_env "mds-survey not found"
20922         fi
20923         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20924                 skip "Need MDS version at least 2.2.51"
20925
20926         local mds=$(facet_host $SINGLEMDS)
20927         local target=$(do_nodes $mds 'lctl dl' |
20928                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20929
20930         local cmd1="file_count=1000 thrhi=4"
20931         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20932         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20933         local cmd="$cmd1 $cmd2 $cmd3"
20934
20935         rm -f ${TMP}/mds_survey*
20936         echo + $cmd
20937         eval $cmd || error "mds-survey with zero-stripe failed"
20938         cat ${TMP}/mds_survey*
20939         rm -f ${TMP}/mds_survey*
20940 }
20941 run_test 225a "Metadata survey sanity with zero-stripe"
20942
20943 test_225b () {
20944         if [ -z ${MDSSURVEY} ]; then
20945                 skip_env "mds-survey not found"
20946         fi
20947         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20948                 skip "Need MDS version at least 2.2.51"
20949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20950         remote_mds_nodsh && skip "remote MDS with nodsh"
20951         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20952                 skip_env "Need to mount OST to test"
20953         fi
20954
20955         local mds=$(facet_host $SINGLEMDS)
20956         local target=$(do_nodes $mds 'lctl dl' |
20957                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20958
20959         local cmd1="file_count=1000 thrhi=4"
20960         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20961         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20962         local cmd="$cmd1 $cmd2 $cmd3"
20963
20964         rm -f ${TMP}/mds_survey*
20965         echo + $cmd
20966         eval $cmd || error "mds-survey with stripe_count failed"
20967         cat ${TMP}/mds_survey*
20968         rm -f ${TMP}/mds_survey*
20969 }
20970 run_test 225b "Metadata survey sanity with stripe_count = 1"
20971
20972 mcreate_path2fid () {
20973         local mode=$1
20974         local major=$2
20975         local minor=$3
20976         local name=$4
20977         local desc=$5
20978         local path=$DIR/$tdir/$name
20979         local fid
20980         local rc
20981         local fid_path
20982
20983         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20984                 error "cannot create $desc"
20985
20986         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20987         rc=$?
20988         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20989
20990         fid_path=$($LFS fid2path $MOUNT $fid)
20991         rc=$?
20992         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20993
20994         [ "$path" == "$fid_path" ] ||
20995                 error "fid2path returned $fid_path, expected $path"
20996
20997         echo "pass with $path and $fid"
20998 }
20999
21000 test_226a () {
21001         rm -rf $DIR/$tdir
21002         mkdir -p $DIR/$tdir
21003
21004         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21005         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21006         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21007         mcreate_path2fid 0040666 0 0 dir "directory"
21008         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21009         mcreate_path2fid 0100666 0 0 file "regular file"
21010         mcreate_path2fid 0120666 0 0 link "symbolic link"
21011         mcreate_path2fid 0140666 0 0 sock "socket"
21012 }
21013 run_test 226a "call path2fid and fid2path on files of all type"
21014
21015 test_226b () {
21016         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21017
21018         local MDTIDX=1
21019
21020         rm -rf $DIR/$tdir
21021         mkdir -p $DIR/$tdir
21022         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21023                 error "create remote directory failed"
21024         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21025         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21026                                 "character special file (null)"
21027         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21028                                 "character special file (no device)"
21029         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21030         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21031                                 "block special file (loop)"
21032         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21033         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21034         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21035 }
21036 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21037
21038 test_226c () {
21039         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21040         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21041                 skip "Need MDS version at least 2.13.55"
21042
21043         local submnt=/mnt/submnt
21044         local srcfile=/etc/passwd
21045         local dstfile=$submnt/passwd
21046         local path
21047         local fid
21048
21049         rm -rf $DIR/$tdir
21050         rm -rf $submnt
21051         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21052                 error "create remote directory failed"
21053         mkdir -p $submnt || error "create $submnt failed"
21054         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21055                 error "mount $submnt failed"
21056         stack_trap "umount $submnt" EXIT
21057
21058         cp $srcfile $dstfile
21059         fid=$($LFS path2fid $dstfile)
21060         path=$($LFS fid2path $submnt "$fid")
21061         [ "$path" = "$dstfile" ] ||
21062                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21063 }
21064 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21065
21066 test_226d () {
21067         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21068                 skip "Need client at least version 2.15.57"
21069
21070         # Define First test dataset
21071         local testdirs_01=$DIR/$tdir
21072         local testdata_01=$testdirs_01/${tdir}_01
21073         local testresult_01=${tdir}_01
21074         # Define Second test dataset
21075         local testdirs_02=$DIR/$tdir/$tdir
21076         local testdata_02=$testdirs_02/${tdir}_02
21077         local testresult_02=${tdir}_02
21078         # Define third test dataset (top level)
21079         local testdata_03=$DIR/${tdir}_03
21080         local testresult_03=${tdir}_03
21081
21082         # Create first test dataset
21083         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21084         touch $testdata_01 || error "cannot create file $testdata_01"
21085
21086         # Create second test dataset
21087         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21088         touch $testdata_02 || error "cannot create file $testdata_02"
21089
21090         # Create third test dataset
21091         touch $testdata_03 || error "cannot create file $testdata_03"
21092
21093         local fid01=$($LFS getstripe -F "$testdata_01") ||
21094                 error "getstripe failed on $testdata_01"
21095         local fid02=$($LFS getstripe -F "$testdata_02") ||
21096                 error "getstripe failed on $testdata_01"
21097         local fid03=$($LFS getstripe -F "$testdata_03") ||
21098                 error "getstripe failed on $testdata_03"
21099
21100         # Verify only -n option
21101         local out1=$($LFS fid2path -n $DIR $fid01) ||
21102                 error "fid2path failed on $fid01"
21103         local out2=$($LFS fid2path -n $DIR $fid02) ||
21104                 error "fid2path failed on $fid02"
21105         local out3=$($LFS fid2path -n $DIR $fid03) ||
21106                 error "fid2path failed on $fid03"
21107
21108         [[ "$out1" == "$testresult_01" ]] ||
21109                 error "fid2path failed: Expected $testresult_01 got $out1"
21110         [[ "$out2" == "$testresult_02" ]] ||
21111                 error "fid2path failed: Expected $testresult_02 got $out2"
21112         [[ "$out3" == "$testresult_03" ]] ||
21113                 error "fid2path failed: Expected $testresult_03 got $out3"
21114
21115         # Verify with option -fn together
21116         out1=$($LFS fid2path -fn $DIR $fid01) ||
21117                 error "fid2path -fn failed on $fid01"
21118         out2=$($LFS fid2path -fn $DIR $fid02) ||
21119                 error "fid2path -fn failed on $fid02"
21120         out3=$($LFS fid2path -fn $DIR $fid03) ||
21121                 error "fid2path -fn failed on $fid03"
21122
21123         local tmpout=$(echo $out1 | cut -d" " -f2)
21124         [[ "$tmpout" == "$testresult_01" ]] ||
21125                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21126
21127         tmpout=$(echo $out2 | cut -d" " -f2)
21128         [[ "$tmpout" == "$testresult_02" ]] ||
21129                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21130
21131         tmpout=$(echo $out3 | cut -d" " -f2)
21132         [[ "$tmpout" == "$testresult_03" ]] ||
21133                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21134 }
21135 run_test 226d "verify fid2path with -n and -fn option"
21136
21137 test_226e () {
21138         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21139                 skip "Need client at least version 2.15.56"
21140
21141         # Define filename with 'newline' and a space
21142         local testfile="Test"$'\n'"file 01"
21143         # Define link name with multiple 'newline' and a space
21144         local linkfile="Link"$'\n'"file "$'\n'"01"
21145         # Remove prior hard link
21146         rm -f $DIR/"$linkfile"
21147
21148         # Create file
21149         touch $DIR/"$testfile"
21150         # Create link
21151         ln $DIR/"$testfile" $DIR/"$linkfile"
21152
21153         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21154                 error "getstripe failed on $DIR/$testfile"
21155
21156         # Call with -0 option
21157         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21158                 echo "FILE:" | grep -c "FILE:")
21159
21160         # With -0 option the output should be exactly 2 lines.
21161         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21162 }
21163 run_test 226e "Verify path2fid -0 option with newline and space"
21164
21165 # LU-1299 Executing or running ldd on a truncated executable does not
21166 # cause an out-of-memory condition.
21167 test_227() {
21168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21169         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21170
21171         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21172         chmod +x $MOUNT/date
21173
21174         $MOUNT/date > /dev/null
21175         ldd $MOUNT/date > /dev/null
21176         rm -f $MOUNT/date
21177 }
21178 run_test 227 "running truncated executable does not cause OOM"
21179
21180 # LU-1512 try to reuse idle OI blocks
21181 test_228a() {
21182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21183         remote_mds_nodsh && skip "remote MDS with nodsh"
21184         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21185
21186         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21187         local myDIR=$DIR/$tdir
21188
21189         mkdir -p $myDIR
21190         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21191         $LCTL set_param fail_loc=0x80001002
21192         createmany -o $myDIR/t- 10000
21193         $LCTL set_param fail_loc=0
21194         # The guard is current the largest FID holder
21195         touch $myDIR/guard
21196         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21197                     tr -d '[')
21198         local IDX=$(($SEQ % 64))
21199
21200         do_facet $SINGLEMDS sync
21201         # Make sure journal flushed.
21202         sleep 6
21203         local blk1=$(do_facet $SINGLEMDS \
21204                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21205                      grep Blockcount | awk '{print $4}')
21206
21207         # Remove old files, some OI blocks will become idle.
21208         unlinkmany $myDIR/t- 10000
21209         # Create new files, idle OI blocks should be reused.
21210         createmany -o $myDIR/t- 2000
21211         do_facet $SINGLEMDS sync
21212         # Make sure journal flushed.
21213         sleep 6
21214         local blk2=$(do_facet $SINGLEMDS \
21215                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21216                      grep Blockcount | awk '{print $4}')
21217
21218         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21219 }
21220 run_test 228a "try to reuse idle OI blocks"
21221
21222 test_228b() {
21223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21224         remote_mds_nodsh && skip "remote MDS with nodsh"
21225         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21226
21227         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21228         local myDIR=$DIR/$tdir
21229
21230         mkdir -p $myDIR
21231         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21232         $LCTL set_param fail_loc=0x80001002
21233         createmany -o $myDIR/t- 10000
21234         $LCTL set_param fail_loc=0
21235         # The guard is current the largest FID holder
21236         touch $myDIR/guard
21237         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21238                     tr -d '[')
21239         local IDX=$(($SEQ % 64))
21240
21241         do_facet $SINGLEMDS sync
21242         # Make sure journal flushed.
21243         sleep 6
21244         local blk1=$(do_facet $SINGLEMDS \
21245                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21246                      grep Blockcount | awk '{print $4}')
21247
21248         # Remove old files, some OI blocks will become idle.
21249         unlinkmany $myDIR/t- 10000
21250
21251         # stop the MDT
21252         stop $SINGLEMDS || error "Fail to stop MDT."
21253         # remount the MDT
21254         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21255                 error "Fail to start MDT."
21256
21257         client_up || error "Fail to df."
21258         # Create new files, idle OI blocks should be reused.
21259         createmany -o $myDIR/t- 2000
21260         do_facet $SINGLEMDS sync
21261         # Make sure journal flushed.
21262         sleep 6
21263         local blk2=$(do_facet $SINGLEMDS \
21264                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21265                      grep Blockcount | awk '{print $4}')
21266
21267         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21268 }
21269 run_test 228b "idle OI blocks can be reused after MDT restart"
21270
21271 #LU-1881
21272 test_228c() {
21273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21274         remote_mds_nodsh && skip "remote MDS with nodsh"
21275         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21276
21277         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21278         local myDIR=$DIR/$tdir
21279
21280         mkdir -p $myDIR
21281         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21282         $LCTL set_param fail_loc=0x80001002
21283         # 20000 files can guarantee there are index nodes in the OI file
21284         createmany -o $myDIR/t- 20000
21285         $LCTL set_param fail_loc=0
21286         # The guard is current the largest FID holder
21287         touch $myDIR/guard
21288         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21289                     tr -d '[')
21290         local IDX=$(($SEQ % 64))
21291
21292         do_facet $SINGLEMDS sync
21293         # Make sure journal flushed.
21294         sleep 6
21295         local blk1=$(do_facet $SINGLEMDS \
21296                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21297                      grep Blockcount | awk '{print $4}')
21298
21299         # Remove old files, some OI blocks will become idle.
21300         unlinkmany $myDIR/t- 20000
21301         rm -f $myDIR/guard
21302         # The OI file should become empty now
21303
21304         # Create new files, idle OI blocks should be reused.
21305         createmany -o $myDIR/t- 2000
21306         do_facet $SINGLEMDS sync
21307         # Make sure journal flushed.
21308         sleep 6
21309         local blk2=$(do_facet $SINGLEMDS \
21310                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21311                      grep Blockcount | awk '{print $4}')
21312
21313         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21314 }
21315 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21316
21317 test_229() { # LU-2482, LU-3448
21318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21319         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21320         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21321                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21322
21323         rm -f $DIR/$tfile
21324
21325         # Create a file with a released layout and stripe count 2.
21326         $MULTIOP $DIR/$tfile H2c ||
21327                 error "failed to create file with released layout"
21328
21329         $LFS getstripe -v $DIR/$tfile
21330
21331         local pattern=$($LFS getstripe -L $DIR/$tfile)
21332         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21333
21334         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21335                 error "getstripe"
21336         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21337         stat $DIR/$tfile || error "failed to stat released file"
21338
21339         chown $RUNAS_ID $DIR/$tfile ||
21340                 error "chown $RUNAS_ID $DIR/$tfile failed"
21341
21342         chgrp $RUNAS_ID $DIR/$tfile ||
21343                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21344
21345         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21346         rm $DIR/$tfile || error "failed to remove released file"
21347 }
21348 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21349
21350 test_230a() {
21351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21353         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21354                 skip "Need MDS version at least 2.11.52"
21355
21356         local MDTIDX=1
21357
21358         test_mkdir $DIR/$tdir
21359         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21360         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21361         [ $mdt_idx -ne 0 ] &&
21362                 error "create local directory on wrong MDT $mdt_idx"
21363
21364         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21365                         error "create remote directory failed"
21366         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21367         [ $mdt_idx -ne $MDTIDX ] &&
21368                 error "create remote directory on wrong MDT $mdt_idx"
21369
21370         createmany -o $DIR/$tdir/test_230/t- 10 ||
21371                 error "create files on remote directory failed"
21372         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21373         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21374         rm -r $DIR/$tdir || error "unlink remote directory failed"
21375 }
21376 run_test 230a "Create remote directory and files under the remote directory"
21377
21378 test_230b() {
21379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21381         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21382                 skip "Need MDS version at least 2.11.52"
21383
21384         local MDTIDX=1
21385         local mdt_index
21386         local i
21387         local file
21388         local pid
21389         local stripe_count
21390         local migrate_dir=$DIR/$tdir/migrate_dir
21391         local other_dir=$DIR/$tdir/other_dir
21392
21393         test_mkdir $DIR/$tdir
21394         test_mkdir -i0 -c1 $migrate_dir
21395         test_mkdir -i0 -c1 $other_dir
21396         for ((i=0; i<10; i++)); do
21397                 mkdir -p $migrate_dir/dir_${i}
21398                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21399                         error "create files under remote dir failed $i"
21400         done
21401
21402         cp /etc/passwd $migrate_dir/$tfile
21403         cp /etc/passwd $other_dir/$tfile
21404         chattr +SAD $migrate_dir
21405         chattr +SAD $migrate_dir/$tfile
21406
21407         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21408         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21409         local old_dir_mode=$(stat -c%f $migrate_dir)
21410         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21411
21412         mkdir -p $migrate_dir/dir_default_stripe2
21413         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21414         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21415
21416         mkdir -p $other_dir
21417         ln $migrate_dir/$tfile $other_dir/luna
21418         ln $migrate_dir/$tfile $migrate_dir/sofia
21419         ln $other_dir/$tfile $migrate_dir/david
21420         ln -s $migrate_dir/$tfile $other_dir/zachary
21421         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21422         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21423
21424         local len
21425         local lnktgt
21426
21427         # inline symlink
21428         for len in 58 59 60; do
21429                 lnktgt=$(str_repeat 'l' $len)
21430                 touch $migrate_dir/$lnktgt
21431                 ln -s $lnktgt $migrate_dir/${len}char_ln
21432         done
21433
21434         # PATH_MAX
21435         for len in 4094 4095; do
21436                 lnktgt=$(str_repeat 'l' $len)
21437                 ln -s $lnktgt $migrate_dir/${len}char_ln
21438         done
21439
21440         # NAME_MAX
21441         for len in 254 255; do
21442                 touch $migrate_dir/$(str_repeat 'l' $len)
21443         done
21444
21445         $LFS migrate -m $MDTIDX $migrate_dir ||
21446                 error "fails on migrating remote dir to MDT1"
21447
21448         echo "migratate to MDT1, then checking.."
21449         for ((i = 0; i < 10; i++)); do
21450                 for file in $(find $migrate_dir/dir_${i}); do
21451                         mdt_index=$($LFS getstripe -m $file)
21452                         # broken symlink getstripe will fail
21453                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21454                                 error "$file is not on MDT${MDTIDX}"
21455                 done
21456         done
21457
21458         # the multiple link file should still in MDT0
21459         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21460         [ $mdt_index == 0 ] ||
21461                 error "$file is not on MDT${MDTIDX}"
21462
21463         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21464         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21465                 error " expect $old_dir_flag get $new_dir_flag"
21466
21467         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21468         [ "$old_file_flag" = "$new_file_flag" ] ||
21469                 error " expect $old_file_flag get $new_file_flag"
21470
21471         local new_dir_mode=$(stat -c%f $migrate_dir)
21472         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21473                 error "expect mode $old_dir_mode get $new_dir_mode"
21474
21475         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21476         [ "$old_file_mode" = "$new_file_mode" ] ||
21477                 error "expect mode $old_file_mode get $new_file_mode"
21478
21479         diff /etc/passwd $migrate_dir/$tfile ||
21480                 error "$tfile different after migration"
21481
21482         diff /etc/passwd $other_dir/luna ||
21483                 error "luna different after migration"
21484
21485         diff /etc/passwd $migrate_dir/sofia ||
21486                 error "sofia different after migration"
21487
21488         diff /etc/passwd $migrate_dir/david ||
21489                 error "david different after migration"
21490
21491         diff /etc/passwd $other_dir/zachary ||
21492                 error "zachary different after migration"
21493
21494         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21495                 error "${tfile}_ln different after migration"
21496
21497         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21498                 error "${tfile}_ln_other different after migration"
21499
21500         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21501         [ $stripe_count = 2 ] ||
21502                 error "dir strpe_count $d != 2 after migration."
21503
21504         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21505         [ $stripe_count = 2 ] ||
21506                 error "file strpe_count $d != 2 after migration."
21507
21508         #migrate back to MDT0
21509         MDTIDX=0
21510
21511         $LFS migrate -m $MDTIDX $migrate_dir ||
21512                 error "fails on migrating remote dir to MDT0"
21513
21514         echo "migrate back to MDT0, checking.."
21515         for file in $(find $migrate_dir); do
21516                 mdt_index=$($LFS getstripe -m $file)
21517                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21518                         error "$file is not on MDT${MDTIDX}"
21519         done
21520
21521         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21522         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21523                 error " expect $old_dir_flag get $new_dir_flag"
21524
21525         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21526         [ "$old_file_flag" = "$new_file_flag" ] ||
21527                 error " expect $old_file_flag get $new_file_flag"
21528
21529         local new_dir_mode=$(stat -c%f $migrate_dir)
21530         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21531                 error "expect mode $old_dir_mode get $new_dir_mode"
21532
21533         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21534         [ "$old_file_mode" = "$new_file_mode" ] ||
21535                 error "expect mode $old_file_mode get $new_file_mode"
21536
21537         diff /etc/passwd ${migrate_dir}/$tfile ||
21538                 error "$tfile different after migration"
21539
21540         diff /etc/passwd ${other_dir}/luna ||
21541                 error "luna different after migration"
21542
21543         diff /etc/passwd ${migrate_dir}/sofia ||
21544                 error "sofia different after migration"
21545
21546         diff /etc/passwd ${other_dir}/zachary ||
21547                 error "zachary different after migration"
21548
21549         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21550                 error "${tfile}_ln different after migration"
21551
21552         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21553                 error "${tfile}_ln_other different after migration"
21554
21555         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21556         [ $stripe_count = 2 ] ||
21557                 error "dir strpe_count $d != 2 after migration."
21558
21559         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21560         [ $stripe_count = 2 ] ||
21561                 error "file strpe_count $d != 2 after migration."
21562
21563         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21564 }
21565 run_test 230b "migrate directory"
21566
21567 test_230c() {
21568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21569         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21570         remote_mds_nodsh && skip "remote MDS with nodsh"
21571         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21572                 skip "Need MDS version at least 2.11.52"
21573
21574         local MDTIDX=1
21575         local total=3
21576         local mdt_index
21577         local file
21578         local migrate_dir=$DIR/$tdir/migrate_dir
21579
21580         #If migrating directory fails in the middle, all entries of
21581         #the directory is still accessiable.
21582         test_mkdir $DIR/$tdir
21583         test_mkdir -i0 -c1 $migrate_dir
21584         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21585         stat $migrate_dir
21586         createmany -o $migrate_dir/f $total ||
21587                 error "create files under ${migrate_dir} failed"
21588
21589         # fail after migrating top dir, and this will fail only once, so the
21590         # first sub file migration will fail (currently f3), others succeed.
21591         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21592         do_facet mds1 lctl set_param fail_loc=0x1801
21593         local t=$(ls $migrate_dir | wc -l)
21594         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21595                 error "migrate should fail"
21596         local u=$(ls $migrate_dir | wc -l)
21597         [ "$u" == "$t" ] || error "$u != $t during migration"
21598
21599         # add new dir/file should succeed
21600         mkdir $migrate_dir/dir ||
21601                 error "mkdir failed under migrating directory"
21602         touch $migrate_dir/file ||
21603                 error "create file failed under migrating directory"
21604
21605         # add file with existing name should fail
21606         for file in $migrate_dir/f*; do
21607                 stat $file > /dev/null || error "stat $file failed"
21608                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21609                         error "open(O_CREAT|O_EXCL) $file should fail"
21610                 $MULTIOP $file m && error "create $file should fail"
21611                 touch $DIR/$tdir/remote_dir/$tfile ||
21612                         error "touch $tfile failed"
21613                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21614                         error "link $file should fail"
21615                 mdt_index=$($LFS getstripe -m $file)
21616                 if [ $mdt_index == 0 ]; then
21617                         # file failed to migrate is not allowed to rename to
21618                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21619                                 error "rename to $file should fail"
21620                 else
21621                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21622                                 error "rename to $file failed"
21623                 fi
21624                 echo hello >> $file || error "write $file failed"
21625         done
21626
21627         # resume migration with different options should fail
21628         $LFS migrate -m 0 $migrate_dir &&
21629                 error "migrate -m 0 $migrate_dir should fail"
21630
21631         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21632                 error "migrate -c 2 $migrate_dir should fail"
21633
21634         # resume migration should succeed
21635         $LFS migrate -m $MDTIDX $migrate_dir ||
21636                 error "migrate $migrate_dir failed"
21637
21638         echo "Finish migration, then checking.."
21639         for file in $(find $migrate_dir); do
21640                 mdt_index=$($LFS getstripe -m $file)
21641                 [ $mdt_index == $MDTIDX ] ||
21642                         error "$file is not on MDT${MDTIDX}"
21643         done
21644
21645         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21646 }
21647 run_test 230c "check directory accessiblity if migration failed"
21648
21649 test_230d() {
21650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21652         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21653                 skip "Need MDS version at least 2.11.52"
21654         # LU-11235
21655         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21656
21657         local migrate_dir=$DIR/$tdir/migrate_dir
21658         local old_index
21659         local new_index
21660         local old_count
21661         local new_count
21662         local new_hash
21663         local mdt_index
21664         local i
21665         local j
21666
21667         old_index=$((RANDOM % MDSCOUNT))
21668         old_count=$((MDSCOUNT - old_index))
21669         new_index=$((RANDOM % MDSCOUNT))
21670         new_count=$((MDSCOUNT - new_index))
21671         new_hash=1 # for all_char
21672
21673         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21674         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21675
21676         test_mkdir $DIR/$tdir
21677         test_mkdir -i $old_index -c $old_count $migrate_dir
21678
21679         for ((i=0; i<100; i++)); do
21680                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21681                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21682                         error "create files under remote dir failed $i"
21683         done
21684
21685         echo -n "Migrate from MDT$old_index "
21686         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21687         echo -n "to MDT$new_index"
21688         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21689         echo
21690
21691         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21692         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21693                 error "migrate remote dir error"
21694
21695         echo "Finish migration, then checking.."
21696         for file in $(find $migrate_dir -maxdepth 1); do
21697                 mdt_index=$($LFS getstripe -m $file)
21698                 if [ $mdt_index -lt $new_index ] ||
21699                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21700                         error "$file is on MDT$mdt_index"
21701                 fi
21702         done
21703
21704         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21705 }
21706 run_test 230d "check migrate big directory"
21707
21708 test_230e() {
21709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21710         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21711         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21712                 skip "Need MDS version at least 2.11.52"
21713
21714         local i
21715         local j
21716         local a_fid
21717         local b_fid
21718
21719         mkdir_on_mdt0 $DIR/$tdir
21720         mkdir $DIR/$tdir/migrate_dir
21721         mkdir $DIR/$tdir/other_dir
21722         touch $DIR/$tdir/migrate_dir/a
21723         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21724         ls $DIR/$tdir/other_dir
21725
21726         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21727                 error "migrate dir fails"
21728
21729         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21730         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21731
21732         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21733         [ $mdt_index == 0 ] || error "a is not on MDT0"
21734
21735         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21736                 error "migrate dir fails"
21737
21738         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21739         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21740
21741         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21742         [ $mdt_index == 1 ] || error "a is not on MDT1"
21743
21744         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21745         [ $mdt_index == 1 ] || error "b is not on MDT1"
21746
21747         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21748         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21749
21750         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21751
21752         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21753 }
21754 run_test 230e "migrate mulitple local link files"
21755
21756 test_230f() {
21757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21759         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21760                 skip "Need MDS version at least 2.11.52"
21761
21762         local a_fid
21763         local ln_fid
21764
21765         mkdir -p $DIR/$tdir
21766         mkdir $DIR/$tdir/migrate_dir
21767         $LFS mkdir -i1 $DIR/$tdir/other_dir
21768         touch $DIR/$tdir/migrate_dir/a
21769         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21770         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21771         ls $DIR/$tdir/other_dir
21772
21773         # a should be migrated to MDT1, since no other links on MDT0
21774         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21775                 error "#1 migrate dir fails"
21776         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21777         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21778         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21779         [ $mdt_index == 1 ] || error "a is not on MDT1"
21780
21781         # a should stay on MDT1, because it is a mulitple link file
21782         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21783                 error "#2 migrate dir fails"
21784         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21785         [ $mdt_index == 1 ] || error "a is not on MDT1"
21786
21787         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21788                 error "#3 migrate dir fails"
21789
21790         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21791         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21792         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21793
21794         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21795         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21796
21797         # a should be migrated to MDT0, since no other links on MDT1
21798         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21799                 error "#4 migrate dir fails"
21800         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21801         [ $mdt_index == 0 ] || error "a is not on MDT0"
21802
21803         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21804 }
21805 run_test 230f "migrate mulitple remote link files"
21806
21807 test_230g() {
21808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21811                 skip "Need MDS version at least 2.11.52"
21812
21813         mkdir -p $DIR/$tdir/migrate_dir
21814
21815         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21816                 error "migrating dir to non-exist MDT succeeds"
21817         true
21818 }
21819 run_test 230g "migrate dir to non-exist MDT"
21820
21821 test_230h() {
21822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21823         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21824         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21825                 skip "Need MDS version at least 2.11.52"
21826
21827         local mdt_index
21828
21829         mkdir -p $DIR/$tdir/migrate_dir
21830
21831         $LFS migrate -m1 $DIR &&
21832                 error "migrating mountpoint1 should fail"
21833
21834         $LFS migrate -m1 $DIR/$tdir/.. &&
21835                 error "migrating mountpoint2 should fail"
21836
21837         # same as mv
21838         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21839                 error "migrating $tdir/migrate_dir/.. should fail"
21840
21841         true
21842 }
21843 run_test 230h "migrate .. and root"
21844
21845 test_230i() {
21846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21847         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21848         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21849                 skip "Need MDS version at least 2.11.52"
21850
21851         mkdir -p $DIR/$tdir/migrate_dir
21852
21853         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21854                 error "migration fails with a tailing slash"
21855
21856         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21857                 error "migration fails with two tailing slashes"
21858 }
21859 run_test 230i "lfs migrate -m tolerates trailing slashes"
21860
21861 test_230j() {
21862         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21863         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21864                 skip "Need MDS version at least 2.11.52"
21865
21866         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21867         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21868                 error "create $tfile failed"
21869         cat /etc/passwd > $DIR/$tdir/$tfile
21870
21871         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21872
21873         cmp /etc/passwd $DIR/$tdir/$tfile ||
21874                 error "DoM file mismatch after migration"
21875 }
21876 run_test 230j "DoM file data not changed after dir migration"
21877
21878 test_230k() {
21879         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21880         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21881                 skip "Need MDS version at least 2.11.56"
21882
21883         local total=20
21884         local files_on_starting_mdt=0
21885
21886         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21887         $LFS getdirstripe $DIR/$tdir
21888         for i in $(seq $total); do
21889                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21890                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21891                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21892         done
21893
21894         echo "$files_on_starting_mdt files on MDT0"
21895
21896         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21897         $LFS getdirstripe $DIR/$tdir
21898
21899         files_on_starting_mdt=0
21900         for i in $(seq $total); do
21901                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21902                         error "file $tfile.$i mismatch after migration"
21903                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21904                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21905         done
21906
21907         echo "$files_on_starting_mdt files on MDT1 after migration"
21908         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21909
21910         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21911         $LFS getdirstripe $DIR/$tdir
21912
21913         files_on_starting_mdt=0
21914         for i in $(seq $total); do
21915                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21916                         error "file $tfile.$i mismatch after 2nd migration"
21917                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21918                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21919         done
21920
21921         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21922         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21923
21924         true
21925 }
21926 run_test 230k "file data not changed after dir migration"
21927
21928 test_230l() {
21929         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21930         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21931                 skip "Need MDS version at least 2.11.56"
21932
21933         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21934         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21935                 error "create files under remote dir failed $i"
21936         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21937 }
21938 run_test 230l "readdir between MDTs won't crash"
21939
21940 test_230m() {
21941         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21942         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21943                 skip "Need MDS version at least 2.11.56"
21944
21945         local MDTIDX=1
21946         local mig_dir=$DIR/$tdir/migrate_dir
21947         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21948         local shortstr="b"
21949         local val
21950
21951         echo "Creating files and dirs with xattrs"
21952         test_mkdir $DIR/$tdir
21953         test_mkdir -i0 -c1 $mig_dir
21954         mkdir $mig_dir/dir
21955         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21956                 error "cannot set xattr attr1 on dir"
21957         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21958                 error "cannot set xattr attr2 on dir"
21959         touch $mig_dir/dir/f0
21960         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21961                 error "cannot set xattr attr1 on file"
21962         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21963                 error "cannot set xattr attr2 on file"
21964         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21965         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21966         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21967         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21968         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21969         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21970         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21971         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21972         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21973
21974         echo "Migrating to MDT1"
21975         $LFS migrate -m $MDTIDX $mig_dir ||
21976                 error "fails on migrating dir to MDT1"
21977
21978         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21979         echo "Checking xattrs"
21980         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21981         [ "$val" = $longstr ] ||
21982                 error "expecting xattr1 $longstr on dir, found $val"
21983         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21984         [ "$val" = $shortstr ] ||
21985                 error "expecting xattr2 $shortstr on dir, found $val"
21986         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21987         [ "$val" = $longstr ] ||
21988                 error "expecting xattr1 $longstr on file, found $val"
21989         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21990         [ "$val" = $shortstr ] ||
21991                 error "expecting xattr2 $shortstr on file, found $val"
21992 }
21993 run_test 230m "xattrs not changed after dir migration"
21994
21995 test_230n() {
21996         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21997         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21998                 skip "Need MDS version at least 2.13.53"
21999
22000         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22001         cat /etc/hosts > $DIR/$tdir/$tfile
22002         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22003         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22004
22005         cmp /etc/hosts $DIR/$tdir/$tfile ||
22006                 error "File data mismatch after migration"
22007 }
22008 run_test 230n "Dir migration with mirrored file"
22009
22010 test_230o() {
22011         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22012         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22013                 skip "Need MDS version at least 2.13.52"
22014
22015         local mdts=$(comma_list $(mdts_nodes))
22016         local timeout=100
22017         local restripe_status
22018         local delta
22019         local i
22020
22021         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22022
22023         # in case "crush" hash type is not set
22024         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22025
22026         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22027                            mdt.*MDT0000.enable_dir_restripe)
22028         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22029         stack_trap "do_nodes $mdts $LCTL set_param \
22030                     mdt.*.enable_dir_restripe=$restripe_status"
22031
22032         mkdir $DIR/$tdir
22033         createmany -m $DIR/$tdir/f 100 ||
22034                 error "create files under remote dir failed $i"
22035         createmany -d $DIR/$tdir/d 100 ||
22036                 error "create dirs under remote dir failed $i"
22037
22038         for i in $(seq 2 $MDSCOUNT); do
22039                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22040                 $LFS setdirstripe -c $i $DIR/$tdir ||
22041                         error "split -c $i $tdir failed"
22042                 wait_update $HOSTNAME \
22043                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22044                         error "dir split not finished"
22045                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22046                         awk '/migrate/ {sum += $2} END { print sum }')
22047                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22048                 # delta is around total_files/stripe_count
22049                 (( $delta < 200 / (i - 1) + 4 )) ||
22050                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22051         done
22052 }
22053 run_test 230o "dir split"
22054
22055 test_230p() {
22056         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22057         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22058                 skip "Need MDS version at least 2.13.52"
22059
22060         local mdts=$(comma_list $(mdts_nodes))
22061         local timeout=100
22062         local restripe_status
22063         local delta
22064         local c
22065
22066         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22067
22068         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22069
22070         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22071                            mdt.*MDT0000.enable_dir_restripe)
22072         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22073         stack_trap "do_nodes $mdts $LCTL set_param \
22074                     mdt.*.enable_dir_restripe=$restripe_status"
22075
22076         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22077         createmany -m $DIR/$tdir/f 100 ||
22078                 error "create files under remote dir failed"
22079         createmany -d $DIR/$tdir/d 100 ||
22080                 error "create dirs under remote dir failed"
22081
22082         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22083                 local mdt_hash="crush"
22084
22085                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22086                 $LFS setdirstripe -c $c $DIR/$tdir ||
22087                         error "split -c $c $tdir failed"
22088                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22089                         mdt_hash="$mdt_hash,fixed"
22090                 elif [ $c -eq 1 ]; then
22091                         mdt_hash="none"
22092                 fi
22093                 wait_update $HOSTNAME \
22094                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22095                         error "dir merge not finished"
22096                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22097                         awk '/migrate/ {sum += $2} END { print sum }')
22098                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22099                 # delta is around total_files/stripe_count
22100                 (( delta < 200 / c + 4 )) ||
22101                         error "$delta files migrated >= $((200 / c + 4))"
22102         done
22103 }
22104 run_test 230p "dir merge"
22105
22106 test_230q() {
22107         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22108         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22109                 skip "Need MDS version at least 2.13.52"
22110
22111         local mdts=$(comma_list $(mdts_nodes))
22112         local saved_threshold=$(do_facet mds1 \
22113                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22114         local saved_delta=$(do_facet mds1 \
22115                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22116         local threshold=100
22117         local delta=2
22118         local total=0
22119         local stripe_count=0
22120         local stripe_index
22121         local nr_files
22122         local create
22123
22124         # test with fewer files on ZFS
22125         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22126
22127         stack_trap "do_nodes $mdts $LCTL set_param \
22128                     mdt.*.dir_split_count=$saved_threshold"
22129         stack_trap "do_nodes $mdts $LCTL set_param \
22130                     mdt.*.dir_split_delta=$saved_delta"
22131         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22132         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22133         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22134         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22135         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22136         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22137
22138         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22139         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22140
22141         create=$((threshold * 3 / 2))
22142         while [ $stripe_count -lt $MDSCOUNT ]; do
22143                 createmany -m $DIR/$tdir/f $total $create ||
22144                         error "create sub files failed"
22145                 stat $DIR/$tdir > /dev/null
22146                 total=$((total + create))
22147                 stripe_count=$((stripe_count + delta))
22148                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22149
22150                 wait_update $HOSTNAME \
22151                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22152                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22153
22154                 wait_update $HOSTNAME \
22155                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22156                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22157
22158                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22159                 echo "$nr_files/$total files on MDT$stripe_index after split"
22160                 # allow 10% margin of imbalance with crush hash
22161                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22162                         error "$nr_files files on MDT$stripe_index after split"
22163
22164                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22165                 [ $nr_files -eq $total ] ||
22166                         error "total sub files $nr_files != $total"
22167         done
22168
22169         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22170
22171         echo "fixed layout directory won't auto split"
22172         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22173         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22174                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22175         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22176                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22177 }
22178 run_test 230q "dir auto split"
22179
22180 test_230r() {
22181         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22182         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22183         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22184                 skip "Need MDS version at least 2.13.54"
22185
22186         # maximum amount of local locks:
22187         # parent striped dir - 2 locks
22188         # new stripe in parent to migrate to - 1 lock
22189         # source and target - 2 locks
22190         # Total 5 locks for regular file
22191         mkdir -p $DIR/$tdir
22192         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22193         touch $DIR/$tdir/dir1/eee
22194
22195         # create 4 hardlink for 4 more locks
22196         # Total: 9 locks > RS_MAX_LOCKS (8)
22197         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22198         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22199         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22200         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22201         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22202         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22203         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22204         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22205
22206         cancel_lru_locks mdc
22207
22208         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22209                 error "migrate dir fails"
22210
22211         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22212 }
22213 run_test 230r "migrate with too many local locks"
22214
22215 test_230s() {
22216         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22217                 skip "Need MDS version at least 2.14.52"
22218
22219         local mdts=$(comma_list $(mdts_nodes))
22220         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22221                                 mdt.*MDT0000.enable_dir_restripe)
22222
22223         stack_trap "do_nodes $mdts $LCTL set_param \
22224                     mdt.*.enable_dir_restripe=$restripe_status"
22225
22226         local st
22227         for st in 0 1; do
22228                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22229                 test_mkdir $DIR/$tdir
22230                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22231                         error "$LFS mkdir should return EEXIST if target exists"
22232                 rmdir $DIR/$tdir
22233         done
22234 }
22235 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22236
22237 test_230t()
22238 {
22239         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22240         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22241                 skip "Need MDS version at least 2.14.50"
22242
22243         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22244         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22245         $LFS project -p 1 -s $DIR/$tdir ||
22246                 error "set $tdir project id failed"
22247         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22248                 error "set subdir project id failed"
22249         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22250 }
22251 run_test 230t "migrate directory with project ID set"
22252
22253 test_230u()
22254 {
22255         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22256         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22257                 skip "Need MDS version at least 2.14.53"
22258
22259         local count
22260
22261         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22262         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22263         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22264         for i in $(seq 0 $((MDSCOUNT - 1))); do
22265                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22266                 echo "$count dirs migrated to MDT$i"
22267         done
22268         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22269         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22270 }
22271 run_test 230u "migrate directory by QOS"
22272
22273 test_230v()
22274 {
22275         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22276         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22277                 skip "Need MDS version at least 2.14.53"
22278
22279         local count
22280
22281         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22282         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22283         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22284         for i in $(seq 0 $((MDSCOUNT - 1))); do
22285                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22286                 echo "$count subdirs migrated to MDT$i"
22287                 (( i == 3 )) && (( count > 0 )) &&
22288                         error "subdir shouldn't be migrated to MDT3"
22289         done
22290         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22291         (( count == 3 )) || error "dirs migrated to $count MDTs"
22292 }
22293 run_test 230v "subdir migrated to the MDT where its parent is located"
22294
22295 test_230w() {
22296         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22297         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22298                 skip "Need MDS version at least 2.15.0"
22299
22300         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22301         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22302         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22303
22304         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22305                 error "migrate failed"
22306
22307         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22308                 error "$tdir stripe count mismatch"
22309
22310         for i in $(seq 0 9); do
22311                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22312                         error "d$i is striped"
22313         done
22314 }
22315 run_test 230w "non-recursive mode dir migration"
22316
22317 test_230x() {
22318         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22319         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22320                 skip "Need MDS version at least 2.15.0"
22321
22322         mkdir -p $DIR/$tdir || error "mkdir failed"
22323         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22324
22325         local mdt_name=$(mdtname_from_index 0)
22326         local low=$(do_facet mds2 $LCTL get_param -n \
22327                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22328         local high=$(do_facet mds2 $LCTL get_param -n \
22329                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22330         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22331         local maxage=$(do_facet mds2 $LCTL get_param -n \
22332                 osp.*$mdt_name-osp-MDT0001.maxage)
22333
22334         stack_trap "do_facet mds2 $LCTL set_param -n \
22335                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22336                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22337         stack_trap "do_facet mds2 $LCTL set_param -n \
22338                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22339
22340         do_facet mds2 $LCTL set_param -n \
22341                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22342         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22343         sleep 4
22344         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22345                 error "migrate $tdir should fail"
22346
22347         do_facet mds2 $LCTL set_param -n \
22348                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22349         do_facet mds2 $LCTL set_param -n \
22350                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22351         sleep 4
22352         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22353                 error "migrate failed"
22354         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22355                 error "$tdir stripe count mismatch"
22356 }
22357 run_test 230x "dir migration check space"
22358
22359 test_230y() {
22360         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22361         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22362                 skip "Need MDS version at least 2.15.55.45"
22363
22364         local pid
22365
22366         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22367         $LFS getdirstripe $DIR/$tdir
22368         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22369         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22370         pid=$!
22371         sleep 1
22372
22373         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22374         do_facet mds2 lctl set_param fail_loc=0x1802
22375
22376         wait $pid
22377         do_facet mds2 lctl set_param fail_loc=0
22378         $LFS getdirstripe $DIR/$tdir
22379         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22380         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22381 }
22382 run_test 230y "unlink dir with bad hash type"
22383
22384 test_230z() {
22385         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22386         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22387                 skip "Need MDS version at least 2.15.55.45"
22388
22389         local pid
22390
22391         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22392         $LFS getdirstripe $DIR/$tdir
22393         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22394         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22395         pid=$!
22396         sleep 1
22397
22398         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22399         do_facet mds2 lctl set_param fail_loc=0x1802
22400
22401         wait $pid
22402         do_facet mds2 lctl set_param fail_loc=0
22403         $LFS getdirstripe $DIR/$tdir
22404
22405         # resume migration
22406         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22407                 error "resume migration failed"
22408         $LFS getdirstripe $DIR/$tdir
22409         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22410                 error "migration is not finished"
22411 }
22412 run_test 230z "resume dir migration with bad hash type"
22413
22414 test_231a()
22415 {
22416         # For simplicity this test assumes that max_pages_per_rpc
22417         # is the same across all OSCs
22418         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22419         local bulk_size=$((max_pages * PAGE_SIZE))
22420         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22421                                        head -n 1)
22422
22423         mkdir -p $DIR/$tdir
22424         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22425                 error "failed to set stripe with -S ${brw_size}M option"
22426         stack_trap "rm -rf $DIR/$tdir"
22427
22428         # clear the OSC stats
22429         $LCTL set_param osc.*.stats=0 &>/dev/null
22430         stop_writeback
22431
22432         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22433         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22434                 oflag=direct &>/dev/null || error "dd failed"
22435
22436         sync; sleep 1; sync # just to be safe
22437         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22438         if [ x$nrpcs != "x1" ]; then
22439                 $LCTL get_param osc.*.stats
22440                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22441         fi
22442
22443         start_writeback
22444         # Drop the OSC cache, otherwise we will read from it
22445         cancel_lru_locks osc
22446
22447         # clear the OSC stats
22448         $LCTL set_param osc.*.stats=0 &>/dev/null
22449
22450         # Client reads $bulk_size.
22451         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22452                 iflag=direct &>/dev/null || error "dd failed"
22453
22454         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22455         if [ x$nrpcs != "x1" ]; then
22456                 $LCTL get_param osc.*.stats
22457                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22458         fi
22459 }
22460 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22461
22462 test_231b() {
22463         mkdir -p $DIR/$tdir
22464         stack_trap "rm -rf $DIR/$tdir"
22465         local i
22466         for i in {0..1023}; do
22467                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22468                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22469                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22470         done
22471         sync
22472 }
22473 run_test 231b "must not assert on fully utilized OST request buffer"
22474
22475 test_232a() {
22476         mkdir -p $DIR/$tdir
22477         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22478
22479         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22480         do_facet ost1 $LCTL set_param fail_loc=0x31c
22481
22482         # ignore dd failure
22483         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22484         stack_trap "rm -f $DIR/$tdir/$tfile"
22485
22486         do_facet ost1 $LCTL set_param fail_loc=0
22487         umount_client $MOUNT || error "umount failed"
22488         mount_client $MOUNT || error "mount failed"
22489         stop ost1 || error "cannot stop ost1"
22490         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22491 }
22492 run_test 232a "failed lock should not block umount"
22493
22494 test_232b() {
22495         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22496                 skip "Need MDS version at least 2.10.58"
22497
22498         mkdir -p $DIR/$tdir
22499         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22500         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22501         stack_trap "rm -f $DIR/$tdir/$tfile"
22502         sync
22503         cancel_lru_locks osc
22504
22505         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22506         do_facet ost1 $LCTL set_param fail_loc=0x31c
22507
22508         # ignore failure
22509         $LFS data_version $DIR/$tdir/$tfile || true
22510
22511         do_facet ost1 $LCTL set_param fail_loc=0
22512         umount_client $MOUNT || error "umount failed"
22513         mount_client $MOUNT || error "mount failed"
22514         stop ost1 || error "cannot stop ost1"
22515         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22516 }
22517 run_test 232b "failed data version lock should not block umount"
22518
22519 test_233a() {
22520         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22521                 skip "Need MDS version at least 2.3.64"
22522         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22523
22524         local fid=$($LFS path2fid $MOUNT)
22525
22526         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22527                 error "cannot access $MOUNT using its FID '$fid'"
22528 }
22529 run_test 233a "checking that OBF of the FS root succeeds"
22530
22531 test_233b() {
22532         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22533                 skip "Need MDS version at least 2.5.90"
22534         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22535
22536         local fid=$($LFS path2fid $MOUNT/.lustre)
22537
22538         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22539                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22540
22541         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22542         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22543                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22544 }
22545 run_test 233b "checking that OBF of the FS .lustre succeeds"
22546
22547 test_234() {
22548         local p="$TMP/sanityN-$TESTNAME.parameters"
22549         save_lustre_params client "llite.*.xattr_cache" > $p
22550         lctl set_param llite.*.xattr_cache 1 ||
22551                 skip_env "xattr cache is not supported"
22552
22553         mkdir -p $DIR/$tdir || error "mkdir failed"
22554         touch $DIR/$tdir/$tfile || error "touch failed"
22555         # OBD_FAIL_LLITE_XATTR_ENOMEM
22556         $LCTL set_param fail_loc=0x1405
22557         getfattr -n user.attr $DIR/$tdir/$tfile &&
22558                 error "getfattr should have failed with ENOMEM"
22559         $LCTL set_param fail_loc=0x0
22560         rm -rf $DIR/$tdir
22561
22562         restore_lustre_params < $p
22563         rm -f $p
22564 }
22565 run_test 234 "xattr cache should not crash on ENOMEM"
22566
22567 test_235() {
22568         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22569                 skip "Need MDS version at least 2.4.52"
22570
22571         flock_deadlock $DIR/$tfile
22572         local RC=$?
22573         case $RC in
22574                 0)
22575                 ;;
22576                 124) error "process hangs on a deadlock"
22577                 ;;
22578                 *) error "error executing flock_deadlock $DIR/$tfile"
22579                 ;;
22580         esac
22581 }
22582 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22583
22584 #LU-2935
22585 test_236() {
22586         check_swap_layouts_support
22587
22588         local ref1=/etc/passwd
22589         local ref2=/etc/group
22590         local file1=$DIR/$tdir/f1
22591         local file2=$DIR/$tdir/f2
22592
22593         test_mkdir -c1 $DIR/$tdir
22594         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22595         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22596         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22597         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22598         local fd=$(free_fd)
22599         local cmd="exec $fd<>$file2"
22600         eval $cmd
22601         rm $file2
22602         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22603                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22604         cmd="exec $fd>&-"
22605         eval $cmd
22606         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22607
22608         #cleanup
22609         rm -rf $DIR/$tdir
22610 }
22611 run_test 236 "Layout swap on open unlinked file"
22612
22613 # LU-4659 linkea consistency
22614 test_238() {
22615         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22616                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22617                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22618                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22619
22620         touch $DIR/$tfile
22621         ln $DIR/$tfile $DIR/$tfile.lnk
22622         touch $DIR/$tfile.new
22623         mv $DIR/$tfile.new $DIR/$tfile
22624         local fid1=$($LFS path2fid $DIR/$tfile)
22625         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22626         local path1=$($LFS fid2path $FSNAME "$fid1")
22627         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22628         local path2=$($LFS fid2path $FSNAME "$fid2")
22629         [ $tfile.lnk == $path2 ] ||
22630                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22631         rm -f $DIR/$tfile*
22632 }
22633 run_test 238 "Verify linkea consistency"
22634
22635 test_239A() { # was test_239
22636         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22637                 skip "Need MDS version at least 2.5.60"
22638
22639         local list=$(comma_list $(mdts_nodes))
22640
22641         mkdir -p $DIR/$tdir
22642         createmany -o $DIR/$tdir/f- 5000
22643         unlinkmany $DIR/$tdir/f- 5000
22644         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22645                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22646         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22647                         osp.*MDT*.sync_in_flight" | calc_sum)
22648         [ "$changes" -eq 0 ] || error "$changes not synced"
22649 }
22650 run_test 239A "osp_sync test"
22651
22652 test_239a() { #LU-5297
22653         remote_mds_nodsh && skip "remote MDS with nodsh"
22654
22655         touch $DIR/$tfile
22656         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22657         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22658         chgrp $RUNAS_GID $DIR/$tfile
22659         wait_delete_completed
22660 }
22661 run_test 239a "process invalid osp sync record correctly"
22662
22663 test_239b() { #LU-5297
22664         remote_mds_nodsh && skip "remote MDS with nodsh"
22665
22666         touch $DIR/$tfile1
22667         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22668         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22669         chgrp $RUNAS_GID $DIR/$tfile1
22670         wait_delete_completed
22671         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22672         touch $DIR/$tfile2
22673         chgrp $RUNAS_GID $DIR/$tfile2
22674         wait_delete_completed
22675 }
22676 run_test 239b "process osp sync record with ENOMEM error correctly"
22677
22678 test_240() {
22679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22680         remote_mds_nodsh && skip "remote MDS with nodsh"
22681
22682         mkdir -p $DIR/$tdir
22683
22684         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22685                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22686         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22687                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22688
22689         umount_client $MOUNT || error "umount failed"
22690         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22691         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22692         mount_client $MOUNT || error "failed to mount client"
22693
22694         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22695         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22696 }
22697 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22698
22699 test_241_bio() {
22700         local count=$1
22701         local bsize=$2
22702
22703         for LOOP in $(seq $count); do
22704                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22705                 cancel_lru_locks $OSC || true
22706         done
22707 }
22708
22709 test_241_dio() {
22710         local count=$1
22711         local bsize=$2
22712
22713         for LOOP in $(seq $1); do
22714                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22715                         2>/dev/null
22716         done
22717 }
22718
22719 test_241a() { # was test_241
22720         local bsize=$PAGE_SIZE
22721
22722         (( bsize < 40960 )) && bsize=40960
22723         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22724         ls -la $DIR/$tfile
22725         cancel_lru_locks $OSC
22726         test_241_bio 1000 $bsize &
22727         PID=$!
22728         test_241_dio 1000 $bsize
22729         wait $PID
22730 }
22731 run_test 241a "bio vs dio"
22732
22733 test_241b() {
22734         local bsize=$PAGE_SIZE
22735
22736         (( bsize < 40960 )) && bsize=40960
22737         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22738         ls -la $DIR/$tfile
22739         test_241_dio 1000 $bsize &
22740         PID=$!
22741         test_241_dio 1000 $bsize
22742         wait $PID
22743 }
22744 run_test 241b "dio vs dio"
22745
22746 test_242() {
22747         remote_mds_nodsh && skip "remote MDS with nodsh"
22748
22749         mkdir_on_mdt0 $DIR/$tdir
22750         touch $DIR/$tdir/$tfile
22751
22752         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22753         do_facet mds1 lctl set_param fail_loc=0x105
22754         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22755
22756         do_facet mds1 lctl set_param fail_loc=0
22757         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22758 }
22759 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22760
22761 test_243()
22762 {
22763         test_mkdir $DIR/$tdir
22764         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22765 }
22766 run_test 243 "various group lock tests"
22767
22768 test_244a()
22769 {
22770         test_mkdir $DIR/$tdir
22771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22772         sendfile_grouplock $DIR/$tdir/$tfile || \
22773                 error "sendfile+grouplock failed"
22774         rm -rf $DIR/$tdir
22775 }
22776 run_test 244a "sendfile with group lock tests"
22777
22778 test_244b()
22779 {
22780         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22781
22782         local threads=50
22783         local size=$((1024*1024))
22784
22785         test_mkdir $DIR/$tdir
22786         for i in $(seq 1 $threads); do
22787                 local file=$DIR/$tdir/file_$((i / 10))
22788                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22789                 local pids[$i]=$!
22790         done
22791         for i in $(seq 1 $threads); do
22792                 wait ${pids[$i]}
22793         done
22794 }
22795 run_test 244b "multi-threaded write with group lock"
22796
22797 test_245a() {
22798         local flagname="multi_mod_rpcs"
22799         local connect_data_name="max_mod_rpcs"
22800         local out
22801
22802         # check if multiple modify RPCs flag is set
22803         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22804                 grep "connect_flags:")
22805         echo "$out"
22806
22807         echo "$out" | grep -qw $flagname
22808         if [ $? -ne 0 ]; then
22809                 echo "connect flag $flagname is not set"
22810                 return
22811         fi
22812
22813         # check if multiple modify RPCs data is set
22814         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22815         echo "$out"
22816
22817         echo "$out" | grep -qw $connect_data_name ||
22818                 error "import should have connect data $connect_data_name"
22819 }
22820 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22821
22822 test_245b() {
22823         local flagname="multi_mod_rpcs"
22824         local connect_data_name="max_mod_rpcs"
22825         local out
22826
22827         remote_mds_nodsh && skip "remote MDS with nodsh"
22828         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22829
22830         # check if multiple modify RPCs flag is set
22831         out=$(do_facet mds1 \
22832               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22833               grep "connect_flags:")
22834         echo "$out"
22835
22836         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22837
22838         # check if multiple modify RPCs data is set
22839         out=$(do_facet mds1 \
22840               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22841
22842         [[ "$out" =~ $connect_data_name ]] ||
22843                 {
22844                         echo "$out"
22845                         error "missing connect data $connect_data_name"
22846                 }
22847 }
22848 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22849
22850 cleanup_247() {
22851         local submount=$1
22852
22853         trap 0
22854         umount_client $submount
22855         rmdir $submount
22856 }
22857
22858 test_247a() {
22859         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22860                 grep -q subtree ||
22861                 skip_env "Fileset feature is not supported"
22862
22863         local submount=${MOUNT}_$tdir
22864
22865         mkdir $MOUNT/$tdir
22866         mkdir -p $submount || error "mkdir $submount failed"
22867         FILESET="$FILESET/$tdir" mount_client $submount ||
22868                 error "mount $submount failed"
22869         trap "cleanup_247 $submount" EXIT
22870         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22871         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22872                 error "read $MOUNT/$tdir/$tfile failed"
22873         cleanup_247 $submount
22874 }
22875 run_test 247a "mount subdir as fileset"
22876
22877 test_247b() {
22878         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22879                 skip_env "Fileset feature is not supported"
22880
22881         local submount=${MOUNT}_$tdir
22882
22883         rm -rf $MOUNT/$tdir
22884         mkdir -p $submount || error "mkdir $submount failed"
22885         SKIP_FILESET=1
22886         FILESET="$FILESET/$tdir" mount_client $submount &&
22887                 error "mount $submount should fail"
22888         rmdir $submount
22889 }
22890 run_test 247b "mount subdir that dose not exist"
22891
22892 test_247c() {
22893         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22894                 skip_env "Fileset feature is not supported"
22895
22896         local submount=${MOUNT}_$tdir
22897
22898         mkdir -p $MOUNT/$tdir/dir1
22899         mkdir -p $submount || error "mkdir $submount failed"
22900         trap "cleanup_247 $submount" EXIT
22901         FILESET="$FILESET/$tdir" mount_client $submount ||
22902                 error "mount $submount failed"
22903         local fid=$($LFS path2fid $MOUNT/)
22904         $LFS fid2path $submount $fid && error "fid2path should fail"
22905         cleanup_247 $submount
22906 }
22907 run_test 247c "running fid2path outside subdirectory root"
22908
22909 test_247d() {
22910         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22911                 skip "Fileset feature is not supported"
22912
22913         local submount=${MOUNT}_$tdir
22914
22915         mkdir -p $MOUNT/$tdir/dir1
22916         mkdir -p $submount || error "mkdir $submount failed"
22917         FILESET="$FILESET/$tdir" mount_client $submount ||
22918                 error "mount $submount failed"
22919         trap "cleanup_247 $submount" EXIT
22920
22921         local td=$submount/dir1
22922         local fid=$($LFS path2fid $td)
22923         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22924
22925         # check that we get the same pathname back
22926         local rootpath
22927         local found
22928         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22929                 echo "$rootpath $fid"
22930                 found=$($LFS fid2path $rootpath "$fid")
22931                 [ -n "$found" ] || error "fid2path should succeed"
22932                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22933         done
22934         # check wrong root path format
22935         rootpath=$submount"_wrong"
22936         found=$($LFS fid2path $rootpath "$fid")
22937         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22938
22939         cleanup_247 $submount
22940 }
22941 run_test 247d "running fid2path inside subdirectory root"
22942
22943 # LU-8037
22944 test_247e() {
22945         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22946                 grep -q subtree ||
22947                 skip "Fileset feature is not supported"
22948
22949         local submount=${MOUNT}_$tdir
22950
22951         mkdir $MOUNT/$tdir
22952         mkdir -p $submount || error "mkdir $submount failed"
22953         FILESET="$FILESET/.." mount_client $submount &&
22954                 error "mount $submount should fail"
22955         rmdir $submount
22956 }
22957 run_test 247e "mount .. as fileset"
22958
22959 test_247f() {
22960         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22961         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22962                 skip "Need at least version 2.14.50.162"
22963         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22964                 skip "Fileset feature is not supported"
22965
22966         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22967         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22968                 error "mkdir remote failed"
22969         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22970                 error "mkdir remote/subdir failed"
22971         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22972                 error "mkdir striped failed"
22973         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22974
22975         local submount=${MOUNT}_$tdir
22976
22977         mkdir -p $submount || error "mkdir $submount failed"
22978         stack_trap "rmdir $submount"
22979
22980         local dir
22981         local fileset=$FILESET
22982         local mdts=$(comma_list $(mdts_nodes))
22983
22984         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22985         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22986                 $tdir/striped/subdir $tdir/striped/.; do
22987                 FILESET="$fileset/$dir" mount_client $submount ||
22988                         error "mount $dir failed"
22989                 umount_client $submount
22990         done
22991 }
22992 run_test 247f "mount striped or remote directory as fileset"
22993
22994 test_subdir_mount_lock()
22995 {
22996         local testdir=$1
22997         local submount=${MOUNT}_$(basename $testdir)
22998
22999         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23000
23001         mkdir -p $submount || error "mkdir $submount failed"
23002         stack_trap "rmdir $submount"
23003
23004         FILESET="$fileset/$testdir" mount_client $submount ||
23005                 error "mount $FILESET failed"
23006         stack_trap "umount $submount"
23007
23008         local mdts=$(comma_list $(mdts_nodes))
23009
23010         local nrpcs
23011
23012         stat $submount > /dev/null || error "stat $submount failed"
23013         cancel_lru_locks $MDC
23014         stat $submount > /dev/null || error "stat $submount failed"
23015         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23016         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23017         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23018         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23019                 awk '/getattr/ {sum += $2} END {print sum}')
23020
23021         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23022 }
23023
23024 test_247g() {
23025         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23026
23027         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23028                 error "mkdir $tdir failed"
23029         test_subdir_mount_lock $tdir
23030 }
23031 run_test 247g "striped directory submount revalidate ROOT from cache"
23032
23033 test_247h() {
23034         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23035         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23036                 skip "Need MDS version at least 2.15.51"
23037
23038         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23039         test_subdir_mount_lock $tdir
23040         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23041         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23042                 error "mkdir $tdir.1 failed"
23043         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23044 }
23045 run_test 247h "remote directory submount revalidate ROOT from cache"
23046
23047 test_248a() {
23048         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23049         [ -z "$fast_read_sav" ] && skip "no fast read support"
23050
23051         # create a large file for fast read verification
23052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23053
23054         # make sure the file is created correctly
23055         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23056                 { rm -f $DIR/$tfile; skip "file creation error"; }
23057
23058         echo "Test 1: verify that fast read is 4 times faster on cache read"
23059
23060         # small read with fast read enabled
23061         $LCTL set_param -n llite.*.fast_read=1
23062         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23063                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23064                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23065         # small read with fast read disabled
23066         $LCTL set_param -n llite.*.fast_read=0
23067         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23068                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23069                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23070
23071         # verify that fast read is 4 times faster for cache read
23072         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23073                 error_not_in_vm "fast read was not 4 times faster: " \
23074                            "$t_fast vs $t_slow"
23075
23076         echo "Test 2: verify the performance between big and small read"
23077         $LCTL set_param -n llite.*.fast_read=1
23078
23079         # 1k non-cache read
23080         cancel_lru_locks osc
23081         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23082                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23083                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23084
23085         # 1M non-cache read
23086         cancel_lru_locks osc
23087         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23088                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23089                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23090
23091         # verify that big IO is not 4 times faster than small IO
23092         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23093                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23094
23095         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23096         rm -f $DIR/$tfile
23097 }
23098 run_test 248a "fast read verification"
23099
23100 test_248b() {
23101         # Default short_io_bytes=16384, try both smaller and larger sizes.
23102         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23103         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23104         echo "bs=53248 count=113 normal buffered write"
23105         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23106                 error "dd of initial data file failed"
23107         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23108
23109         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23110         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23111                 error "dd with sync normal writes failed"
23112         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23113
23114         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23115         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23116                 error "dd with sync small writes failed"
23117         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23118
23119         cancel_lru_locks osc
23120
23121         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23122         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23123         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23124         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23125                 iflag=direct || error "dd with O_DIRECT small read failed"
23126         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23127         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23128                 error "compare $TMP/$tfile.1 failed"
23129
23130         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23131         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23132
23133         # just to see what the maximum tunable value is, and test parsing
23134         echo "test invalid parameter 2MB"
23135         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23136                 error "too-large short_io_bytes allowed"
23137         echo "test maximum parameter 512KB"
23138         # if we can set a larger short_io_bytes, run test regardless of version
23139         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23140                 # older clients may not allow setting it this large, that's OK
23141                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23142                         skip "Need at least client version 2.13.50"
23143                 error "medium short_io_bytes failed"
23144         fi
23145         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23146         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23147
23148         echo "test large parameter 64KB"
23149         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23150         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23151
23152         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23153         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23154                 error "dd with sync large writes failed"
23155         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23156
23157         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23158         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23159         num=$((113 * 4096 / PAGE_SIZE))
23160         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23161         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23162                 error "dd with O_DIRECT large writes failed"
23163         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23164                 error "compare $DIR/$tfile.3 failed"
23165
23166         cancel_lru_locks osc
23167
23168         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23169         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23170                 error "dd with O_DIRECT large read failed"
23171         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23172                 error "compare $TMP/$tfile.2 failed"
23173
23174         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23175         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23176                 error "dd with O_DIRECT large read failed"
23177         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23178                 error "compare $TMP/$tfile.3 failed"
23179 }
23180 run_test 248b "test short_io read and write for both small and large sizes"
23181
23182 test_249() { # LU-7890
23183         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23184                 skip "Need at least version 2.8.54"
23185
23186         rm -f $DIR/$tfile
23187         $LFS setstripe -c 1 $DIR/$tfile
23188         # Offset 2T == 4k * 512M
23189         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23190                 error "dd to 2T offset failed"
23191 }
23192 run_test 249 "Write above 2T file size"
23193
23194 test_250() {
23195         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23196          && skip "no 16TB file size limit on ZFS"
23197
23198         $LFS setstripe -c 1 $DIR/$tfile
23199         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23200         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23201         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23202         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23203                 conv=notrunc,fsync && error "append succeeded"
23204         return 0
23205 }
23206 run_test 250 "Write above 16T limit"
23207
23208 test_251() {
23209         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23210
23211         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23212         #Skip once - writing the first stripe will succeed
23213         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23214         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23215                 error "short write happened"
23216
23217         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23218         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23219                 error "short read happened"
23220
23221         rm -f $DIR/$tfile
23222 }
23223 run_test 251 "Handling short read and write correctly"
23224
23225 test_252() {
23226         remote_mds_nodsh && skip "remote MDS with nodsh"
23227         remote_ost_nodsh && skip "remote OST with nodsh"
23228         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23229                 skip_env "ldiskfs only test"
23230         fi
23231
23232         local tgt
23233         local dev
23234         local out
23235         local uuid
23236         local num
23237         local gen
23238
23239         # check lr_reader on OST0000
23240         tgt=ost1
23241         dev=$(facet_device $tgt)
23242         out=$(do_facet $tgt $LR_READER $dev)
23243         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23244         echo "$out"
23245         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23246         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23247                 error "Invalid uuid returned by $LR_READER on target $tgt"
23248         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23249
23250         # check lr_reader -c on MDT0000
23251         tgt=mds1
23252         dev=$(facet_device $tgt)
23253         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23254                 skip "$LR_READER does not support additional options"
23255         fi
23256         out=$(do_facet $tgt $LR_READER -c $dev)
23257         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23258         echo "$out"
23259         num=$(echo "$out" | grep -c "mdtlov")
23260         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23261                 error "Invalid number of mdtlov clients returned by $LR_READER"
23262         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23263
23264         # check lr_reader -cr on MDT0000
23265         out=$(do_facet $tgt $LR_READER -cr $dev)
23266         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23267         echo "$out"
23268         echo "$out" | grep -q "^reply_data:$" ||
23269                 error "$LR_READER should have returned 'reply_data' section"
23270         num=$(echo "$out" | grep -c "client_generation")
23271         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23272 }
23273 run_test 252 "check lr_reader tool"
23274
23275 test_253() {
23276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23277         remote_mds_nodsh && skip "remote MDS with nodsh"
23278         remote_mgs_nodsh && skip "remote MGS with nodsh"
23279
23280         local ostidx=0
23281         local rc=0
23282         local ost_name=$(ostname_from_index $ostidx)
23283
23284         # on the mdt's osc
23285         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23286         do_facet $SINGLEMDS $LCTL get_param -n \
23287                 osp.$mdtosc_proc1.reserved_mb_high ||
23288                 skip  "remote MDS does not support reserved_mb_high"
23289
23290         rm -rf $DIR/$tdir
23291         wait_mds_ost_sync
23292         wait_delete_completed
23293         mkdir $DIR/$tdir
23294         stack_trap "rm -rf $DIR/$tdir"
23295
23296         pool_add $TESTNAME || error "Pool creation failed"
23297         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23298
23299         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23300                 error "Setstripe failed"
23301
23302         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23303
23304         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23305                     grep "watermarks")
23306         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23307
23308         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23309                         osp.$mdtosc_proc1.prealloc_status)
23310         echo "prealloc_status $oa_status"
23311
23312         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23313                 error "File creation should fail"
23314
23315         #object allocation was stopped, but we still able to append files
23316         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23317                 oflag=append || error "Append failed"
23318
23319         rm -f $DIR/$tdir/$tfile.0
23320
23321         # For this test, we want to delete the files we created to go out of
23322         # space but leave the watermark, so we remain nearly out of space
23323         ost_watermarks_enospc_delete_files $tfile $ostidx
23324
23325         wait_delete_completed
23326
23327         sleep_maxage
23328
23329         for i in $(seq 10 12); do
23330                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23331                         2>/dev/null || error "File creation failed after rm"
23332         done
23333
23334         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23335                         osp.$mdtosc_proc1.prealloc_status)
23336         echo "prealloc_status $oa_status"
23337
23338         if (( oa_status != 0 )); then
23339                 error "Object allocation still disable after rm"
23340         fi
23341 }
23342 run_test 253 "Check object allocation limit"
23343
23344 test_254() {
23345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23346         remote_mds_nodsh && skip "remote MDS with nodsh"
23347
23348         local mdt=$(facet_svc $SINGLEMDS)
23349
23350         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23351                 skip "MDS does not support changelog_size"
23352
23353         local cl_user
23354
23355         changelog_register || error "changelog_register failed"
23356
23357         changelog_clear 0 || error "changelog_clear failed"
23358
23359         local size1=$(do_facet $SINGLEMDS \
23360                       $LCTL get_param -n mdd.$mdt.changelog_size)
23361         echo "Changelog size $size1"
23362
23363         rm -rf $DIR/$tdir
23364         $LFS mkdir -i 0 $DIR/$tdir
23365         # change something
23366         mkdir -p $DIR/$tdir/pics/2008/zachy
23367         touch $DIR/$tdir/pics/2008/zachy/timestamp
23368         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23369         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23370         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23371         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23372         rm $DIR/$tdir/pics/desktop.jpg
23373
23374         local size2=$(do_facet $SINGLEMDS \
23375                       $LCTL get_param -n mdd.$mdt.changelog_size)
23376         echo "Changelog size after work $size2"
23377
23378         (( $size2 > $size1 )) ||
23379                 error "new Changelog size=$size2 less than old size=$size1"
23380 }
23381 run_test 254 "Check changelog size"
23382
23383 ladvise_no_type()
23384 {
23385         local type=$1
23386         local file=$2
23387
23388         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23389                 awk -F: '{print $2}' | grep $type > /dev/null
23390         if [ $? -ne 0 ]; then
23391                 return 0
23392         fi
23393         return 1
23394 }
23395
23396 ladvise_no_ioctl()
23397 {
23398         local file=$1
23399
23400         lfs ladvise -a willread $file > /dev/null 2>&1
23401         if [ $? -eq 0 ]; then
23402                 return 1
23403         fi
23404
23405         lfs ladvise -a willread $file 2>&1 |
23406                 grep "Inappropriate ioctl for device" > /dev/null
23407         if [ $? -eq 0 ]; then
23408                 return 0
23409         fi
23410         return 1
23411 }
23412
23413 percent() {
23414         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23415 }
23416
23417 # run a random read IO workload
23418 # usage: random_read_iops <filename> <filesize> <iosize>
23419 random_read_iops() {
23420         local file=$1
23421         local fsize=$2
23422         local iosize=${3:-4096}
23423
23424         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23425                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23426 }
23427
23428 drop_file_oss_cache() {
23429         local file="$1"
23430         local nodes="$2"
23431
23432         $LFS ladvise -a dontneed $file 2>/dev/null ||
23433                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23434 }
23435
23436 ladvise_willread_performance()
23437 {
23438         local repeat=10
23439         local average_origin=0
23440         local average_cache=0
23441         local average_ladvise=0
23442
23443         for ((i = 1; i <= $repeat; i++)); do
23444                 echo "Iter $i/$repeat: reading without willread hint"
23445                 cancel_lru_locks osc
23446                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23447                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23448                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23449                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23450
23451                 cancel_lru_locks osc
23452                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23453                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23454                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23455
23456                 cancel_lru_locks osc
23457                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23458                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23459                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23460                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23461                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23462         done
23463         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23464         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23465         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23466
23467         speedup_cache=$(percent $average_cache $average_origin)
23468         speedup_ladvise=$(percent $average_ladvise $average_origin)
23469
23470         echo "Average uncached read: $average_origin"
23471         echo "Average speedup with OSS cached read: " \
23472                 "$average_cache = +$speedup_cache%"
23473         echo "Average speedup with ladvise willread: " \
23474                 "$average_ladvise = +$speedup_ladvise%"
23475
23476         local lowest_speedup=20
23477         if (( ${average_cache%.*} < $lowest_speedup )); then
23478                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23479                      " got $average_cache%. Skipping ladvise willread check."
23480                 return 0
23481         fi
23482
23483         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23484         # it is still good to run until then to exercise 'ladvise willread'
23485         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23486                 [ "$ost1_FSTYPE" = "zfs" ] &&
23487                 echo "osd-zfs does not support dontneed or drop_caches" &&
23488                 return 0
23489
23490         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23491         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23492                 error_not_in_vm "Speedup with willread is less than " \
23493                         "$lowest_speedup%, got $average_ladvise%"
23494 }
23495
23496 test_255a() {
23497         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23498                 skip "lustre < 2.8.54 does not support ladvise "
23499         remote_ost_nodsh && skip "remote OST with nodsh"
23500
23501         stack_trap "rm -f $DIR/$tfile"
23502         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23503
23504         ladvise_no_type willread $DIR/$tfile &&
23505                 skip "willread ladvise is not supported"
23506
23507         ladvise_no_ioctl $DIR/$tfile &&
23508                 skip "ladvise ioctl is not supported"
23509
23510         local size_mb=100
23511         local size=$((size_mb * 1048576))
23512         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23513                 error "dd to $DIR/$tfile failed"
23514
23515         lfs ladvise -a willread $DIR/$tfile ||
23516                 error "Ladvise failed with no range argument"
23517
23518         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23519                 error "Ladvise failed with no -l or -e argument"
23520
23521         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23522                 error "Ladvise failed with only -e argument"
23523
23524         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23525                 error "Ladvise failed with only -l argument"
23526
23527         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23528                 error "End offset should not be smaller than start offset"
23529
23530         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23531                 error "End offset should not be equal to start offset"
23532
23533         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23534                 error "Ladvise failed with overflowing -s argument"
23535
23536         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23537                 error "Ladvise failed with overflowing -e argument"
23538
23539         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23540                 error "Ladvise failed with overflowing -l argument"
23541
23542         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23543                 error "Ladvise succeeded with conflicting -l and -e arguments"
23544
23545         echo "Synchronous ladvise should wait"
23546         local delay=8
23547 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23548         do_nodes $(comma_list $(osts_nodes)) \
23549                 $LCTL set_param fail_val=$delay fail_loc=0x237
23550         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23551                 $LCTL set_param fail_loc=0"
23552
23553         local start_ts=$SECONDS
23554         lfs ladvise -a willread $DIR/$tfile ||
23555                 error "Ladvise failed with no range argument"
23556         local end_ts=$SECONDS
23557         local inteval_ts=$((end_ts - start_ts))
23558
23559         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23560                 error "Synchronous advice didn't wait reply"
23561         fi
23562
23563         echo "Asynchronous ladvise shouldn't wait"
23564         local start_ts=$SECONDS
23565         lfs ladvise -a willread -b $DIR/$tfile ||
23566                 error "Ladvise failed with no range argument"
23567         local end_ts=$SECONDS
23568         local inteval_ts=$((end_ts - start_ts))
23569
23570         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23571                 error "Asynchronous advice blocked"
23572         fi
23573
23574         ladvise_willread_performance
23575 }
23576 run_test 255a "check 'lfs ladvise -a willread'"
23577
23578 facet_meminfo() {
23579         local facet=$1
23580         local info=$2
23581
23582         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23583 }
23584
23585 test_255b() {
23586         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23587                 skip "lustre < 2.8.54 does not support ladvise "
23588         remote_ost_nodsh && skip "remote OST with nodsh"
23589
23590         stack_trap "rm -f $DIR/$tfile"
23591         lfs setstripe -c 1 -i 0 $DIR/$tfile
23592
23593         ladvise_no_type dontneed $DIR/$tfile &&
23594                 skip "dontneed ladvise is not supported"
23595
23596         ladvise_no_ioctl $DIR/$tfile &&
23597                 skip "ladvise ioctl is not supported"
23598
23599         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23600                 [ "$ost1_FSTYPE" = "zfs" ] &&
23601                 skip "zfs-osd does not support 'ladvise dontneed'"
23602
23603         local size_mb=100
23604         local size=$((size_mb * 1048576))
23605         # In order to prevent disturbance of other processes, only check 3/4
23606         # of the memory usage
23607         local kibibytes=$((size_mb * 1024 * 3 / 4))
23608
23609         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23610                 error "dd to $DIR/$tfile failed"
23611
23612         #force write to complete before dropping OST cache & checking memory
23613         sync
23614
23615         local total=$(facet_meminfo ost1 MemTotal)
23616         echo "Total memory: $total KiB"
23617
23618         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23619         local before_read=$(facet_meminfo ost1 Cached)
23620         echo "Cache used before read: $before_read KiB"
23621
23622         lfs ladvise -a willread $DIR/$tfile ||
23623                 error "Ladvise willread failed"
23624         local after_read=$(facet_meminfo ost1 Cached)
23625         echo "Cache used after read: $after_read KiB"
23626
23627         lfs ladvise -a dontneed $DIR/$tfile ||
23628                 error "Ladvise dontneed again failed"
23629         local no_read=$(facet_meminfo ost1 Cached)
23630         echo "Cache used after dontneed ladvise: $no_read KiB"
23631
23632         if [ $total -lt $((before_read + kibibytes)) ]; then
23633                 echo "Memory is too small, abort checking"
23634                 return 0
23635         fi
23636
23637         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23638                 error "Ladvise willread should use more memory" \
23639                         "than $kibibytes KiB"
23640         fi
23641
23642         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23643                 error "Ladvise dontneed should release more memory" \
23644                         "than $kibibytes KiB"
23645         fi
23646 }
23647 run_test 255b "check 'lfs ladvise -a dontneed'"
23648
23649 test_255c() {
23650         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23651                 skip "lustre < 2.10.50 does not support lockahead"
23652
23653         local ost1_imp=$(get_osc_import_name client ost1)
23654         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23655                          cut -d'.' -f2)
23656         local count
23657         local new_count
23658         local difference
23659         local i
23660         local rc
23661
23662         test_mkdir -p $DIR/$tdir
23663         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23664
23665         #test 10 returns only success/failure
23666         i=10
23667         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23668         rc=$?
23669         if [ $rc -eq 255 ]; then
23670                 error "Ladvise test${i} failed, ${rc}"
23671         fi
23672
23673         #test 11 counts lock enqueue requests, all others count new locks
23674         i=11
23675         count=$(do_facet ost1 \
23676                 $LCTL get_param -n ost.OSS.ost.stats)
23677         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23678
23679         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23680         rc=$?
23681         if [ $rc -eq 255 ]; then
23682                 error "Ladvise test${i} failed, ${rc}"
23683         fi
23684
23685         new_count=$(do_facet ost1 \
23686                 $LCTL get_param -n ost.OSS.ost.stats)
23687         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23688                    awk '{ print $2 }')
23689
23690         difference="$((new_count - count))"
23691         if [ $difference -ne $rc ]; then
23692                 error "Ladvise test${i}, bad enqueue count, returned " \
23693                       "${rc}, actual ${difference}"
23694         fi
23695
23696         for i in $(seq 12 21); do
23697                 # If we do not do this, we run the risk of having too many
23698                 # locks and starting lock cancellation while we are checking
23699                 # lock counts.
23700                 cancel_lru_locks osc
23701
23702                 count=$($LCTL get_param -n \
23703                        ldlm.namespaces.$imp_name.lock_unused_count)
23704
23705                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23706                 rc=$?
23707                 if [ $rc -eq 255 ]; then
23708                         error "Ladvise test ${i} failed, ${rc}"
23709                 fi
23710
23711                 new_count=$($LCTL get_param -n \
23712                        ldlm.namespaces.$imp_name.lock_unused_count)
23713                 difference="$((new_count - count))"
23714
23715                 # Test 15 output is divided by 100 to map down to valid return
23716                 if [ $i -eq 15 ]; then
23717                         rc="$((rc * 100))"
23718                 fi
23719
23720                 if [ $difference -ne $rc ]; then
23721                         error "Ladvise test ${i}, bad lock count, returned " \
23722                               "${rc}, actual ${difference}"
23723                 fi
23724         done
23725
23726         #test 22 returns only success/failure
23727         i=22
23728         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23729         rc=$?
23730         if [ $rc -eq 255 ]; then
23731                 error "Ladvise test${i} failed, ${rc}"
23732         fi
23733 }
23734 run_test 255c "suite of ladvise lockahead tests"
23735
23736 test_256() {
23737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23738         remote_mds_nodsh && skip "remote MDS with nodsh"
23739         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23740         changelog_users $SINGLEMDS | grep "^cl" &&
23741                 skip "active changelog user"
23742
23743         local cl_user
23744         local cat_sl
23745         local mdt_dev
23746
23747         mdt_dev=$(facet_device $SINGLEMDS)
23748         echo $mdt_dev
23749
23750         changelog_register || error "changelog_register failed"
23751
23752         rm -rf $DIR/$tdir
23753         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23754
23755         changelog_clear 0 || error "changelog_clear failed"
23756
23757         # change something
23758         touch $DIR/$tdir/{1..10}
23759
23760         # stop the MDT
23761         stop $SINGLEMDS || error "Fail to stop MDT"
23762
23763         # remount the MDT
23764         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23765                 error "Fail to start MDT"
23766
23767         #after mount new plainllog is used
23768         touch $DIR/$tdir/{11..19}
23769         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23770         stack_trap "rm -f $tmpfile"
23771         cat_sl=$(do_facet $SINGLEMDS "sync; \
23772                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23773                  llog_reader $tmpfile | grep -c type=1064553b")
23774         do_facet $SINGLEMDS llog_reader $tmpfile
23775
23776         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23777
23778         changelog_clear 0 || error "changelog_clear failed"
23779
23780         cat_sl=$(do_facet $SINGLEMDS "sync; \
23781                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23782                  llog_reader $tmpfile | grep -c type=1064553b")
23783
23784         if (( cat_sl == 2 )); then
23785                 error "Empty plain llog was not deleted from changelog catalog"
23786         elif (( cat_sl != 1 )); then
23787                 error "Active plain llog shouldn't be deleted from catalog"
23788         fi
23789 }
23790 run_test 256 "Check llog delete for empty and not full state"
23791
23792 test_257() {
23793         remote_mds_nodsh && skip "remote MDS with nodsh"
23794         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23795                 skip "Need MDS version at least 2.8.55"
23796
23797         test_mkdir $DIR/$tdir
23798
23799         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23800                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23801         stat $DIR/$tdir
23802
23803 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23804         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23805         local facet=mds$((mdtidx + 1))
23806         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23807         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23808
23809         stop $facet || error "stop MDS failed"
23810         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23811                 error "start MDS fail"
23812         wait_recovery_complete $facet
23813 }
23814 run_test 257 "xattr locks are not lost"
23815
23816 # Verify we take the i_mutex when security requires it
23817 test_258a() {
23818 #define OBD_FAIL_IMUTEX_SEC 0x141c
23819         $LCTL set_param fail_loc=0x141c
23820         touch $DIR/$tfile
23821         chmod u+s $DIR/$tfile
23822         chmod a+rwx $DIR/$tfile
23823         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23824         RC=$?
23825         if [ $RC -ne 0 ]; then
23826                 error "error, failed to take i_mutex, rc=$?"
23827         fi
23828         rm -f $DIR/$tfile
23829 }
23830 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23831
23832 # Verify we do NOT take the i_mutex in the normal case
23833 test_258b() {
23834 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23835         $LCTL set_param fail_loc=0x141d
23836         touch $DIR/$tfile
23837         chmod a+rwx $DIR
23838         chmod a+rw $DIR/$tfile
23839         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23840         RC=$?
23841         if [ $RC -ne 0 ]; then
23842                 error "error, took i_mutex unnecessarily, rc=$?"
23843         fi
23844         rm -f $DIR/$tfile
23845
23846 }
23847 run_test 258b "verify i_mutex security behavior"
23848
23849 test_259() {
23850         local file=$DIR/$tfile
23851         local before
23852         local after
23853
23854         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23855
23856         stack_trap "rm -f $file" EXIT
23857
23858         wait_delete_completed
23859         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23860         echo "before: $before"
23861
23862         $LFS setstripe -i 0 -c 1 $file
23863         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23864         sync_all_data
23865         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23866         echo "after write: $after"
23867
23868 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23869         do_facet ost1 $LCTL set_param fail_loc=0x2301
23870         $TRUNCATE $file 0
23871         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23872         echo "after truncate: $after"
23873
23874         stop ost1
23875         do_facet ost1 $LCTL set_param fail_loc=0
23876         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23877         sleep 2
23878         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23879         echo "after restart: $after"
23880         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23881                 error "missing truncate?"
23882
23883         return 0
23884 }
23885 run_test 259 "crash at delayed truncate"
23886
23887 test_260() {
23888 #define OBD_FAIL_MDC_CLOSE               0x806
23889         $LCTL set_param fail_loc=0x80000806
23890         touch $DIR/$tfile
23891
23892 }
23893 run_test 260 "Check mdc_close fail"
23894
23895 ### Data-on-MDT sanity tests ###
23896 test_270a() {
23897         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23898                 skip "Need MDS version at least 2.10.55 for DoM"
23899
23900         # create DoM file
23901         local dom=$DIR/$tdir/dom_file
23902         local tmp=$DIR/$tdir/tmp_file
23903
23904         mkdir_on_mdt0 $DIR/$tdir
23905
23906         # basic checks for DoM component creation
23907         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23908                 error "Can set MDT layout to non-first entry"
23909
23910         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23911                 error "Can define multiple entries as MDT layout"
23912
23913         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23914
23915         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23916         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23917         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23918
23919         local mdtidx=$($LFS getstripe -m $dom)
23920         local mdtname=MDT$(printf %04x $mdtidx)
23921         local facet=mds$((mdtidx + 1))
23922         local space_check=1
23923
23924         # Skip free space checks with ZFS
23925         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23926
23927         # write
23928         sync
23929         local size_tmp=$((65536 * 3))
23930         local mdtfree1=$(do_facet $facet \
23931                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23932
23933         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23934         # check also direct IO along write
23935         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23936         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23937         sync
23938         cmp $tmp $dom || error "file data is different"
23939         [ $(stat -c%s $dom) == $size_tmp ] ||
23940                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23941         if [ $space_check == 1 ]; then
23942                 local mdtfree2=$(do_facet $facet \
23943                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23944
23945                 # increase in usage from by $size_tmp
23946                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23947                         error "MDT free space wrong after write: " \
23948                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23949         fi
23950
23951         # truncate
23952         local size_dom=10000
23953
23954         $TRUNCATE $dom $size_dom
23955         [ $(stat -c%s $dom) == $size_dom ] ||
23956                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23957         if [ $space_check == 1 ]; then
23958                 mdtfree1=$(do_facet $facet \
23959                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23960                 # decrease in usage from $size_tmp to new $size_dom
23961                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23962                   $(((size_tmp - size_dom) / 1024)) ] ||
23963                         error "MDT free space is wrong after truncate: " \
23964                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23965         fi
23966
23967         # append
23968         cat $tmp >> $dom
23969         sync
23970         size_dom=$((size_dom + size_tmp))
23971         [ $(stat -c%s $dom) == $size_dom ] ||
23972                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23973         if [ $space_check == 1 ]; then
23974                 mdtfree2=$(do_facet $facet \
23975                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23976                 # increase in usage by $size_tmp from previous
23977                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23978                         error "MDT free space is wrong after append: " \
23979                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23980         fi
23981
23982         # delete
23983         rm $dom
23984         if [ $space_check == 1 ]; then
23985                 mdtfree1=$(do_facet $facet \
23986                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23987                 # decrease in usage by $size_dom from previous
23988                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23989                         error "MDT free space is wrong after removal: " \
23990                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23991         fi
23992
23993         # combined striping
23994         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23995                 error "Can't create DoM + OST striping"
23996
23997         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23998         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23999         # check also direct IO along write
24000         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24001         sync
24002         cmp $tmp $dom || error "file data is different"
24003         [ $(stat -c%s $dom) == $size_tmp ] ||
24004                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24005         rm $dom $tmp
24006
24007         return 0
24008 }
24009 run_test 270a "DoM: basic functionality tests"
24010
24011 test_270b() {
24012         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24013                 skip "Need MDS version at least 2.10.55"
24014
24015         local dom=$DIR/$tdir/dom_file
24016         local max_size=1048576
24017
24018         mkdir -p $DIR/$tdir
24019         $LFS setstripe -E $max_size -L mdt $dom
24020
24021         # truncate over the limit
24022         $TRUNCATE $dom $(($max_size + 1)) &&
24023                 error "successful truncate over the maximum size"
24024         # write over the limit
24025         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24026                 error "successful write over the maximum size"
24027         # append over the limit
24028         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24029         echo "12345" >> $dom && error "successful append over the maximum size"
24030         rm $dom
24031
24032         return 0
24033 }
24034 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24035
24036 test_270c() {
24037         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24038                 skip "Need MDS version at least 2.10.55"
24039
24040         mkdir -p $DIR/$tdir
24041         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24042
24043         # check files inherit DoM EA
24044         touch $DIR/$tdir/first
24045         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24046                 error "bad pattern"
24047         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24048                 error "bad stripe count"
24049         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24050                 error "bad stripe size"
24051
24052         # check directory inherits DoM EA and uses it as default
24053         mkdir $DIR/$tdir/subdir
24054         touch $DIR/$tdir/subdir/second
24055         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24056                 error "bad pattern in sub-directory"
24057         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24058                 error "bad stripe count in sub-directory"
24059         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24060                 error "bad stripe size in sub-directory"
24061         return 0
24062 }
24063 run_test 270c "DoM: DoM EA inheritance tests"
24064
24065 test_270d() {
24066         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24067                 skip "Need MDS version at least 2.10.55"
24068
24069         mkdir -p $DIR/$tdir
24070         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24071
24072         # inherit default DoM striping
24073         mkdir $DIR/$tdir/subdir
24074         touch $DIR/$tdir/subdir/f1
24075
24076         # change default directory striping
24077         $LFS setstripe -c 1 $DIR/$tdir/subdir
24078         touch $DIR/$tdir/subdir/f2
24079         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24080                 error "wrong default striping in file 2"
24081         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24082                 error "bad pattern in file 2"
24083         return 0
24084 }
24085 run_test 270d "DoM: change striping from DoM to RAID0"
24086
24087 test_270e() {
24088         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24089                 skip "Need MDS version at least 2.10.55"
24090
24091         mkdir -p $DIR/$tdir/dom
24092         mkdir -p $DIR/$tdir/norm
24093         DOMFILES=20
24094         NORMFILES=10
24095         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24096         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24097
24098         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24099         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24100
24101         # find DoM files by layout
24102         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24103         [ $NUM -eq  $DOMFILES ] ||
24104                 error "lfs find -L: found $NUM, expected $DOMFILES"
24105         echo "Test 1: lfs find 20 DOM files by layout: OK"
24106
24107         # there should be 1 dir with default DOM striping
24108         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24109         [ $NUM -eq  1 ] ||
24110                 error "lfs find -L: found $NUM, expected 1 dir"
24111         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24112
24113         # find DoM files by stripe size
24114         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24115         [ $NUM -eq  $DOMFILES ] ||
24116                 error "lfs find -S: found $NUM, expected $DOMFILES"
24117         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24118
24119         # find files by stripe offset except DoM files
24120         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24121         [ $NUM -eq  $NORMFILES ] ||
24122                 error "lfs find -i: found $NUM, expected $NORMFILES"
24123         echo "Test 5: lfs find no DOM files by stripe index: OK"
24124         return 0
24125 }
24126 run_test 270e "DoM: lfs find with DoM files test"
24127
24128 test_270f() {
24129         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24130                 skip "Need MDS version at least 2.10.55"
24131
24132         local mdtname=${FSNAME}-MDT0000-mdtlov
24133         local dom=$DIR/$tdir/dom_file
24134         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24135                                                 lod.$mdtname.dom_stripesize)
24136         local dom_limit=131072
24137
24138         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24139         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24140                                                 lod.$mdtname.dom_stripesize)
24141         [ ${dom_limit} -eq ${dom_current} ] ||
24142                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24143
24144         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24145         $LFS setstripe -d $DIR/$tdir
24146         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24147                 error "Can't set directory default striping"
24148
24149         # exceed maximum stripe size
24150         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24151                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24152         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24153                 error "Able to create DoM component size more than LOD limit"
24154
24155         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24156         dom_current=$(do_facet mds1 $LCTL get_param -n \
24157                                                 lod.$mdtname.dom_stripesize)
24158         [ 0 -eq ${dom_current} ] ||
24159                 error "Can't set zero DoM stripe limit"
24160         rm $dom
24161
24162         # attempt to create DoM file on server with disabled DoM should
24163         # remove DoM entry from layout and be succeed
24164         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24165                 error "Can't create DoM file (DoM is disabled)"
24166         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24167                 error "File has DoM component while DoM is disabled"
24168         rm $dom
24169
24170         # attempt to create DoM file with only DoM stripe should return error
24171         $LFS setstripe -E $dom_limit -L mdt $dom &&
24172                 error "Able to create DoM-only file while DoM is disabled"
24173
24174         # too low values to be aligned with smallest stripe size 64K
24175         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24176         dom_current=$(do_facet mds1 $LCTL get_param -n \
24177                                                 lod.$mdtname.dom_stripesize)
24178         [ 30000 -eq ${dom_current} ] &&
24179                 error "Can set too small DoM stripe limit"
24180
24181         # 64K is a minimal stripe size in Lustre, expect limit of that size
24182         [ 65536 -eq ${dom_current} ] ||
24183                 error "Limit is not set to 64K but ${dom_current}"
24184
24185         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24186         dom_current=$(do_facet mds1 $LCTL get_param -n \
24187                                                 lod.$mdtname.dom_stripesize)
24188         echo $dom_current
24189         [ 2147483648 -eq ${dom_current} ] &&
24190                 error "Can set too large DoM stripe limit"
24191
24192         do_facet mds1 $LCTL set_param -n \
24193                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24194         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24195                 error "Can't create DoM component size after limit change"
24196         do_facet mds1 $LCTL set_param -n \
24197                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24198         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24199                 error "Can't create DoM file after limit decrease"
24200         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24201                 error "Can create big DoM component after limit decrease"
24202         touch ${dom}_def ||
24203                 error "Can't create file with old default layout"
24204
24205         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24206         return 0
24207 }
24208 run_test 270f "DoM: maximum DoM stripe size checks"
24209
24210 test_270g() {
24211         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24212                 skip "Need MDS version at least 2.13.52"
24213         local dom=$DIR/$tdir/$tfile
24214
24215         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24216         local lodname=${FSNAME}-MDT0000-mdtlov
24217
24218         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24219         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24220         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24221         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24222
24223         local dom_limit=1024
24224         local dom_threshold="50%"
24225
24226         $LFS setstripe -d $DIR/$tdir
24227         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24228                 error "Can't set directory default striping"
24229
24230         do_facet mds1 $LCTL set_param -n \
24231                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24232         # set 0 threshold and create DOM file to change tunable stripesize
24233         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24234         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24235                 error "Failed to create $dom file"
24236         # now tunable dom_cur_stripesize should reach maximum
24237         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24238                                         lod.${lodname}.dom_stripesize_cur_kb)
24239         [[ $dom_current == $dom_limit ]] ||
24240                 error "Current DOM stripesize is not maximum"
24241         rm $dom
24242
24243         # set threshold for further tests
24244         do_facet mds1 $LCTL set_param -n \
24245                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24246         echo "DOM threshold is $dom_threshold free space"
24247         local dom_def
24248         local dom_set
24249         # Spoof bfree to exceed threshold
24250         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24251         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24252         for spfree in 40 20 0 15 30 55; do
24253                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24254                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24255                         error "Failed to create $dom file"
24256                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24257                                         lod.${lodname}.dom_stripesize_cur_kb)
24258                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24259                 [[ $dom_def != $dom_current ]] ||
24260                         error "Default stripe size was not changed"
24261                 if (( spfree > 0 )) ; then
24262                         dom_set=$($LFS getstripe -S $dom)
24263                         (( dom_set == dom_def * 1024 )) ||
24264                                 error "DOM component size is still old"
24265                 else
24266                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24267                                 error "DoM component is set with no free space"
24268                 fi
24269                 rm $dom
24270                 dom_current=$dom_def
24271         done
24272 }
24273 run_test 270g "DoM: default DoM stripe size depends on free space"
24274
24275 test_270h() {
24276         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24277                 skip "Need MDS version at least 2.13.53"
24278
24279         local mdtname=${FSNAME}-MDT0000-mdtlov
24280         local dom=$DIR/$tdir/$tfile
24281         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24282
24283         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24284         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24285
24286         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24287         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24288                 error "can't create OST file"
24289         # mirrored file with DOM entry in the second mirror
24290         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24291                 error "can't create mirror with DoM component"
24292
24293         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24294
24295         # DOM component in the middle and has other enries in the same mirror,
24296         # should succeed but lost DoM component
24297         $LFS setstripe --copy=${dom}_1 $dom ||
24298                 error "Can't create file from OST|DOM mirror layout"
24299         # check new file has no DoM layout after all
24300         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24301                 error "File has DoM component while DoM is disabled"
24302 }
24303 run_test 270h "DoM: DoM stripe removal when disabled on server"
24304
24305 test_270i() {
24306         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24307                 skip "Need MDS version at least 2.14.54"
24308
24309         mkdir $DIR/$tdir
24310         # DoM with plain layout
24311         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24312                 error "default plain layout with DoM must fail"
24313         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24314                 error "setstripe plain file layout with DoM must fail"
24315         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24316                 error "default DoM layout with bad striping must fail"
24317         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24318                 error "setstripe to DoM layout with bad striping must fail"
24319         return 0
24320 }
24321 run_test 270i "DoM: setting invalid DoM striping should fail"
24322
24323 test_270j() {
24324         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24325                 skip "Need MDS version at least 2.15.55.203"
24326
24327         local dom=$DIR/$tdir/$tfile
24328         local odv
24329         local ndv
24330
24331         mkdir -p $DIR/$tdir
24332
24333         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24334
24335         odv=$($LFS data_version $dom)
24336         chmod 666 $dom
24337         mv $dom ${dom}_moved
24338         link ${dom}_moved $dom
24339         setfattr -n user.attrx -v "some_attr" $dom
24340         ndv=$($LFS data_version $dom)
24341         (( $ndv == $odv )) ||
24342                 error "data version was changed by metadata operations"
24343
24344         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24345                 error "failed to write data into $dom"
24346         cancel_lru_locks mdc
24347         ndv=$($LFS data_version $dom)
24348         (( $ndv != $odv )) ||
24349                 error "data version wasn't changed on write"
24350
24351         odv=$ndv
24352         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24353         ndv=$($LFS data_version $dom)
24354         (( $ndv != $odv )) ||
24355                 error "data version wasn't changed on truncate down"
24356
24357         odv=$ndv
24358         $TRUNCATE $dom 25000
24359         ndv=$($LFS data_version $dom)
24360         (( $ndv != $odv )) ||
24361                 error "data version wasn't changed on truncate up"
24362
24363         # check also fallocate for ldiskfs
24364         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24365                 odv=$ndv
24366                 fallocate -l 1048576 $dom
24367                 ndv=$($LFS data_version $dom)
24368                 (( $ndv != $odv )) ||
24369                         error "data version wasn't changed on fallocate"
24370
24371                 odv=$ndv
24372                 fallocate -p --offset 4096 -l 4096 $dom
24373                 ndv=$($LFS data_version $dom)
24374                 (( $ndv != $odv )) ||
24375                         error "data version wasn't changed on fallocate punch"
24376         fi
24377 }
24378 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24379
24380 test_271a() {
24381         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24382                 skip "Need MDS version at least 2.10.55"
24383
24384         local dom=$DIR/$tdir/dom
24385
24386         mkdir -p $DIR/$tdir
24387
24388         $LFS setstripe -E 1024K -L mdt $dom
24389
24390         lctl set_param -n mdc.*.stats=clear
24391         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24392         cat $dom > /dev/null
24393         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24394         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24395         ls $dom
24396         rm -f $dom
24397 }
24398 run_test 271a "DoM: data is cached for read after write"
24399
24400 test_271b() {
24401         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24402                 skip "Need MDS version at least 2.10.55"
24403
24404         local dom=$DIR/$tdir/dom
24405
24406         mkdir -p $DIR/$tdir
24407
24408         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24409
24410         lctl set_param -n mdc.*.stats=clear
24411         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24412         cancel_lru_locks mdc
24413         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24414         # second stat to check size is cached on client
24415         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24416         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24417         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24418         rm -f $dom
24419 }
24420 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24421
24422 test_271ba() {
24423         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24424                 skip "Need MDS version at least 2.10.55"
24425
24426         local dom=$DIR/$tdir/dom
24427
24428         mkdir -p $DIR/$tdir
24429
24430         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24431
24432         lctl set_param -n mdc.*.stats=clear
24433         lctl set_param -n osc.*.stats=clear
24434         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24435         cancel_lru_locks mdc
24436         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24437         # second stat to check size is cached on client
24438         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24439         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24440         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24441         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24442         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24443         rm -f $dom
24444 }
24445 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24446
24447
24448 get_mdc_stats() {
24449         local mdtidx=$1
24450         local param=$2
24451         local mdt=MDT$(printf %04x $mdtidx)
24452
24453         if [ -z $param ]; then
24454                 lctl get_param -n mdc.*$mdt*.stats
24455         else
24456                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24457         fi
24458 }
24459
24460 test_271c() {
24461         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24462                 skip "Need MDS version at least 2.10.55"
24463
24464         local dom=$DIR/$tdir/dom
24465
24466         mkdir -p $DIR/$tdir
24467
24468         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24469
24470         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24471         local facet=mds$((mdtidx + 1))
24472
24473         cancel_lru_locks mdc
24474         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24475         createmany -o $dom 1000
24476         lctl set_param -n mdc.*.stats=clear
24477         smalliomany -w $dom 1000 200
24478         get_mdc_stats $mdtidx
24479         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24480         # Each file has 1 open, 1 IO enqueues, total 2000
24481         # but now we have also +1 getxattr for security.capability, total 3000
24482         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24483         unlinkmany $dom 1000
24484
24485         cancel_lru_locks mdc
24486         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24487         createmany -o $dom 1000
24488         lctl set_param -n mdc.*.stats=clear
24489         smalliomany -w $dom 1000 200
24490         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24491         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24492         # for OPEN and IO lock.
24493         [ $((enq - enq_2)) -ge 1000 ] ||
24494                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24495         unlinkmany $dom 1000
24496         return 0
24497 }
24498 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24499
24500 cleanup_271def_tests() {
24501         trap 0
24502         rm -f $1
24503 }
24504
24505 test_271d() {
24506         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24507                 skip "Need MDS version at least 2.10.57"
24508
24509         local dom=$DIR/$tdir/dom
24510         local tmp=$TMP/$tfile
24511         trap "cleanup_271def_tests $tmp" EXIT
24512
24513         mkdir -p $DIR/$tdir
24514
24515         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24516
24517         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24518
24519         cancel_lru_locks mdc
24520         dd if=/dev/urandom of=$tmp bs=1000 count=1
24521         dd if=$tmp of=$dom bs=1000 count=1
24522         cancel_lru_locks mdc
24523
24524         cat /etc/hosts >> $tmp
24525         lctl set_param -n mdc.*.stats=clear
24526
24527         # append data to the same file it should update local page
24528         echo "Append to the same page"
24529         cat /etc/hosts >> $dom
24530         local num=$(get_mdc_stats $mdtidx ost_read)
24531         local ra=$(get_mdc_stats $mdtidx req_active)
24532         local rw=$(get_mdc_stats $mdtidx req_waittime)
24533
24534         [ -z $num ] || error "$num READ RPC occured"
24535         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24536         echo "... DONE"
24537
24538         # compare content
24539         cmp $tmp $dom || error "file miscompare"
24540
24541         cancel_lru_locks mdc
24542         lctl set_param -n mdc.*.stats=clear
24543
24544         echo "Open and read file"
24545         cat $dom > /dev/null
24546         local num=$(get_mdc_stats $mdtidx ost_read)
24547         local ra=$(get_mdc_stats $mdtidx req_active)
24548         local rw=$(get_mdc_stats $mdtidx req_waittime)
24549
24550         [ -z $num ] || error "$num READ RPC occured"
24551         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24552         echo "... DONE"
24553
24554         # compare content
24555         cmp $tmp $dom || error "file miscompare"
24556
24557         return 0
24558 }
24559 run_test 271d "DoM: read on open (1K file in reply buffer)"
24560
24561 test_271f() {
24562         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24563                 skip "Need MDS version at least 2.10.57"
24564
24565         local dom=$DIR/$tdir/dom
24566         local tmp=$TMP/$tfile
24567         trap "cleanup_271def_tests $tmp" EXIT
24568
24569         mkdir -p $DIR/$tdir
24570
24571         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24572
24573         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24574
24575         cancel_lru_locks mdc
24576         dd if=/dev/urandom of=$tmp bs=265000 count=1
24577         dd if=$tmp of=$dom bs=265000 count=1
24578         cancel_lru_locks mdc
24579         cat /etc/hosts >> $tmp
24580         lctl set_param -n mdc.*.stats=clear
24581
24582         echo "Append to the same page"
24583         cat /etc/hosts >> $dom
24584         local num=$(get_mdc_stats $mdtidx ost_read)
24585         local ra=$(get_mdc_stats $mdtidx req_active)
24586         local rw=$(get_mdc_stats $mdtidx req_waittime)
24587
24588         [ -z $num ] || error "$num READ RPC occured"
24589         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24590         echo "... DONE"
24591
24592         # compare content
24593         cmp $tmp $dom || error "file miscompare"
24594
24595         cancel_lru_locks mdc
24596         lctl set_param -n mdc.*.stats=clear
24597
24598         echo "Open and read file"
24599         cat $dom > /dev/null
24600         local num=$(get_mdc_stats $mdtidx ost_read)
24601         local ra=$(get_mdc_stats $mdtidx req_active)
24602         local rw=$(get_mdc_stats $mdtidx req_waittime)
24603
24604         [ -z $num ] && num=0
24605         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24606         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24607         echo "... DONE"
24608
24609         # compare content
24610         cmp $tmp $dom || error "file miscompare"
24611
24612         return 0
24613 }
24614 run_test 271f "DoM: read on open (200K file and read tail)"
24615
24616 test_271g() {
24617         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24618                 skip "Skipping due to old client or server version"
24619
24620         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24621         # to get layout
24622         $CHECKSTAT -t file $DIR1/$tfile
24623
24624         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24625         MULTIOP_PID=$!
24626         sleep 1
24627         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24628         $LCTL set_param fail_loc=0x80000314
24629         rm $DIR1/$tfile || error "Unlink fails"
24630         RC=$?
24631         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24632         [ $RC -eq 0 ] || error "Failed write to stale object"
24633 }
24634 run_test 271g "Discard DoM data vs client flush race"
24635
24636 test_272a() {
24637         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24638                 skip "Need MDS version at least 2.11.50"
24639
24640         local dom=$DIR/$tdir/dom
24641         mkdir -p $DIR/$tdir
24642
24643         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24644         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24645                 error "failed to write data into $dom"
24646         local old_md5=$(md5sum $dom)
24647
24648         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24649                 error "failed to migrate to the same DoM component"
24650
24651         local new_md5=$(md5sum $dom)
24652
24653         [ "$old_md5" == "$new_md5" ] ||
24654                 error "md5sum differ: $old_md5, $new_md5"
24655
24656         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24657                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24658 }
24659 run_test 272a "DoM migration: new layout with the same DOM component"
24660
24661 test_272b() {
24662         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24663                 skip "Need MDS version at least 2.11.50"
24664
24665         local dom=$DIR/$tdir/dom
24666         mkdir -p $DIR/$tdir
24667         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24668         stack_trap "rm -rf $DIR/$tdir"
24669
24670         local mdtidx=$($LFS getstripe -m $dom)
24671         local mdtname=MDT$(printf %04x $mdtidx)
24672         local facet=mds$((mdtidx + 1))
24673
24674         local mdtfree1=$(do_facet $facet \
24675                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24676         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24677                 error "failed to write data into $dom"
24678         local old_md5=$(md5sum $dom)
24679         cancel_lru_locks mdc
24680         local mdtfree1=$(do_facet $facet \
24681                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24682
24683         $LFS migrate -c2 $dom ||
24684                 error "failed to migrate to the new composite layout"
24685         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24686                 error "MDT stripe was not removed"
24687         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24688                 error "$dir1 shouldn't have DATAVER EA"
24689
24690         cancel_lru_locks mdc
24691         local new_md5=$(md5sum $dom)
24692         [ "$old_md5" == "$new_md5" ] ||
24693                 error "$old_md5 != $new_md5"
24694
24695         # Skip free space checks with ZFS
24696         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24697                 local mdtfree2=$(do_facet $facet \
24698                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24699                 [ $mdtfree2 -gt $mdtfree1 ] ||
24700                         error "MDT space is not freed after migration"
24701         fi
24702         return 0
24703 }
24704 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24705
24706 test_272c() {
24707         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24708                 skip "Need MDS version at least 2.11.50"
24709
24710         local dom=$DIR/$tdir/$tfile
24711         mkdir -p $DIR/$tdir
24712         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24713         stack_trap "rm -rf $DIR/$tdir"
24714
24715         local mdtidx=$($LFS getstripe -m $dom)
24716         local mdtname=MDT$(printf %04x $mdtidx)
24717         local facet=mds$((mdtidx + 1))
24718
24719         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24720                 error "failed to write data into $dom"
24721         local old_md5=$(md5sum $dom)
24722         cancel_lru_locks mdc
24723         local mdtfree1=$(do_facet $facet \
24724                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24725
24726         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24727                 error "failed to migrate to the new composite layout"
24728         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24729                 error "MDT stripe was not removed"
24730
24731         cancel_lru_locks mdc
24732         local new_md5=$(md5sum $dom)
24733         [ "$old_md5" == "$new_md5" ] ||
24734                 error "$old_md5 != $new_md5"
24735
24736         # Skip free space checks with ZFS
24737         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24738                 local mdtfree2=$(do_facet $facet \
24739                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24740                 [ $mdtfree2 -gt $mdtfree1 ] ||
24741                         error "MDS space is not freed after migration"
24742         fi
24743         return 0
24744 }
24745 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24746
24747 test_272d() {
24748         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24749                 skip "Need MDS version at least 2.12.55"
24750
24751         local dom=$DIR/$tdir/$tfile
24752         mkdir -p $DIR/$tdir
24753         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24754
24755         local mdtidx=$($LFS getstripe -m $dom)
24756         local mdtname=MDT$(printf %04x $mdtidx)
24757         local facet=mds$((mdtidx + 1))
24758
24759         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24760                 error "failed to write data into $dom"
24761         local old_md5=$(md5sum $dom)
24762         cancel_lru_locks mdc
24763         local mdtfree1=$(do_facet $facet \
24764                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24765
24766         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24767                 error "failed mirroring to the new composite layout"
24768         $LFS mirror resync $dom ||
24769                 error "failed mirror resync"
24770         $LFS mirror split --mirror-id 1 -d $dom ||
24771                 error "failed mirror split"
24772
24773         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24774                 error "MDT stripe was not removed"
24775
24776         cancel_lru_locks mdc
24777         local new_md5=$(md5sum $dom)
24778         [ "$old_md5" == "$new_md5" ] ||
24779                 error "$old_md5 != $new_md5"
24780
24781         # Skip free space checks with ZFS
24782         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24783                 local mdtfree2=$(do_facet $facet \
24784                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24785                 [ $mdtfree2 -gt $mdtfree1 ] ||
24786                         error "MDS space is not freed after DOM mirror deletion"
24787         fi
24788         return 0
24789 }
24790 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24791
24792 test_272e() {
24793         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24794                 skip "Need MDS version at least 2.12.55"
24795
24796         local dom=$DIR/$tdir/$tfile
24797         mkdir -p $DIR/$tdir
24798         $LFS setstripe -c 2 $dom
24799
24800         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24801                 error "failed to write data into $dom"
24802         local old_md5=$(md5sum $dom)
24803         cancel_lru_locks
24804
24805         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24806                 error "failed mirroring to the DOM layout"
24807         $LFS mirror resync $dom ||
24808                 error "failed mirror resync"
24809         $LFS mirror split --mirror-id 1 -d $dom ||
24810                 error "failed mirror split"
24811
24812         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24813                 error "MDT stripe wasn't set"
24814
24815         cancel_lru_locks
24816         local new_md5=$(md5sum $dom)
24817         [ "$old_md5" == "$new_md5" ] ||
24818                 error "$old_md5 != $new_md5"
24819
24820         return 0
24821 }
24822 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24823
24824 test_272f() {
24825         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24826                 skip "Need MDS version at least 2.12.55"
24827
24828         local dom=$DIR/$tdir/$tfile
24829         mkdir -p $DIR/$tdir
24830         $LFS setstripe -c 2 $dom
24831
24832         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24833                 error "failed to write data into $dom"
24834         local old_md5=$(md5sum $dom)
24835         cancel_lru_locks
24836
24837         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24838                 error "failed migrating to the DOM file"
24839
24840         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24841                 error "MDT stripe wasn't set"
24842
24843         cancel_lru_locks
24844         local new_md5=$(md5sum $dom)
24845         [ "$old_md5" != "$new_md5" ] &&
24846                 error "$old_md5 != $new_md5"
24847
24848         return 0
24849 }
24850 run_test 272f "DoM migration: OST-striped file to DOM file"
24851
24852 test_273a() {
24853         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24854                 skip "Need MDS version at least 2.11.50"
24855
24856         # Layout swap cannot be done if either file has DOM component,
24857         # this will never be supported, migration should be used instead
24858
24859         local dom=$DIR/$tdir/$tfile
24860         mkdir -p $DIR/$tdir
24861
24862         $LFS setstripe -c2 ${dom}_plain
24863         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24864         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24865                 error "can swap layout with DoM component"
24866         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24867                 error "can swap layout with DoM component"
24868
24869         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24870         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24871                 error "can swap layout with DoM component"
24872         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24873                 error "can swap layout with DoM component"
24874         return 0
24875 }
24876 run_test 273a "DoM: layout swapping should fail with DOM"
24877
24878 test_273b() {
24879         mkdir -p $DIR/$tdir
24880         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24881
24882 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24883         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24884
24885         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24886 }
24887 run_test 273b "DoM: race writeback and object destroy"
24888
24889 test_273c() {
24890         mkdir -p $DIR/$tdir
24891         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24892
24893         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24894         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24895
24896         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24897 }
24898 run_test 273c "race writeback and object destroy"
24899
24900 test_275() {
24901         remote_ost_nodsh && skip "remote OST with nodsh"
24902         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24903                 skip "Need OST version >= 2.10.57"
24904
24905         local file=$DIR/$tfile
24906         local oss
24907
24908         oss=$(comma_list $(osts_nodes))
24909
24910         dd if=/dev/urandom of=$file bs=1M count=2 ||
24911                 error "failed to create a file"
24912         stack_trap "rm -f $file"
24913         cancel_lru_locks osc
24914
24915         #lock 1
24916         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24917                 error "failed to read a file"
24918
24919 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24920         $LCTL set_param fail_loc=0x8000031f
24921
24922         cancel_lru_locks osc &
24923         sleep 1
24924
24925 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24926         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24927         #IO takes another lock, but matches the PENDING one
24928         #and places it to the IO RPC
24929         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24930                 error "failed to read a file with PENDING lock"
24931 }
24932 run_test 275 "Read on a canceled duplicate lock"
24933
24934 test_276() {
24935         remote_ost_nodsh && skip "remote OST with nodsh"
24936         local pid
24937
24938         do_facet ost1 "(while true; do \
24939                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24940                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24941         pid=$!
24942
24943         for LOOP in $(seq 20); do
24944                 stop ost1
24945                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24946         done
24947         kill -9 $pid
24948         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24949                 rm $TMP/sanity_276_pid"
24950 }
24951 run_test 276 "Race between mount and obd_statfs"
24952
24953 test_277() {
24954         $LCTL set_param ldlm.namespaces.*.lru_size=0
24955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24956         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24957                           awk '/^used_mb/ { print $2 }')
24958         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24959         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24960                 oflag=direct conv=notrunc
24961         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24962                     awk '/^used_mb/ { print $2 }')
24963         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24964 }
24965 run_test 277 "Direct IO shall drop page cache"
24966
24967 test_278() {
24968         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24969         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24970         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24971                 skip "needs the same host for mdt1 mdt2" && return
24972
24973         local pid1
24974         local pid2
24975
24976 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24977         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24978         stop mds2 &
24979         pid2=$!
24980
24981         stop mds1
24982
24983         echo "Starting MDTs"
24984         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24985         wait $pid2
24986 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24987 #will return NULL
24988         do_facet mds2 $LCTL set_param fail_loc=0
24989
24990         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24991         wait_recovery_complete mds2
24992 }
24993 run_test 278 "Race starting MDS between MDTs stop/start"
24994
24995 test_280() {
24996         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24997                 skip "Need MGS version at least 2.13.52"
24998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24999         combined_mgs_mds || skip "needs combined MGS/MDT"
25000
25001         umount_client $MOUNT
25002 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25003         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25004
25005         mount_client $MOUNT &
25006         sleep 1
25007         stop mgs || error "stop mgs failed"
25008         #for a race mgs would crash
25009         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25010         # make sure we unmount client before remounting
25011         wait
25012         umount_client $MOUNT
25013         mount_client $MOUNT || error "mount client failed"
25014 }
25015 run_test 280 "Race between MGS umount and client llog processing"
25016
25017 cleanup_test_300() {
25018         trap 0
25019         umask $SAVE_UMASK
25020 }
25021 test_striped_dir() {
25022         local mdt_index=$1
25023         local stripe_count
25024         local stripe_index
25025
25026         mkdir -p $DIR/$tdir
25027
25028         SAVE_UMASK=$(umask)
25029         trap cleanup_test_300 RETURN EXIT
25030
25031         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25032                                                 $DIR/$tdir/striped_dir ||
25033                 error "set striped dir error"
25034
25035         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25036         [ "$mode" = "755" ] || error "expect 755 got $mode"
25037
25038         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25039                 error "getdirstripe failed"
25040         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25041         if [ "$stripe_count" != "2" ]; then
25042                 error "1:stripe_count is $stripe_count, expect 2"
25043         fi
25044         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25045         if [ "$stripe_count" != "2" ]; then
25046                 error "2:stripe_count is $stripe_count, expect 2"
25047         fi
25048
25049         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25050         if [ "$stripe_index" != "$mdt_index" ]; then
25051                 error "stripe_index is $stripe_index, expect $mdt_index"
25052         fi
25053
25054         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25055                 error "nlink error after create striped dir"
25056
25057         mkdir $DIR/$tdir/striped_dir/a
25058         mkdir $DIR/$tdir/striped_dir/b
25059
25060         stat $DIR/$tdir/striped_dir/a ||
25061                 error "create dir under striped dir failed"
25062         stat $DIR/$tdir/striped_dir/b ||
25063                 error "create dir under striped dir failed"
25064
25065         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25066                 error "nlink error after mkdir"
25067
25068         rmdir $DIR/$tdir/striped_dir/a
25069         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25070                 error "nlink error after rmdir"
25071
25072         rmdir $DIR/$tdir/striped_dir/b
25073         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25074                 error "nlink error after rmdir"
25075
25076         chattr +i $DIR/$tdir/striped_dir
25077         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25078                 error "immutable flags not working under striped dir!"
25079         chattr -i $DIR/$tdir/striped_dir
25080
25081         rmdir $DIR/$tdir/striped_dir ||
25082                 error "rmdir striped dir error"
25083
25084         cleanup_test_300
25085
25086         true
25087 }
25088
25089 test_300a() {
25090         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25091                 skip "skipped for lustre < 2.7.0"
25092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25094
25095         test_striped_dir 0 || error "failed on striped dir on MDT0"
25096         test_striped_dir 1 || error "failed on striped dir on MDT0"
25097 }
25098 run_test 300a "basic striped dir sanity test"
25099
25100 test_300b() {
25101         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25102                 skip "skipped for lustre < 2.7.0"
25103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25105
25106         local i
25107         local mtime1
25108         local mtime2
25109         local mtime3
25110
25111         test_mkdir $DIR/$tdir || error "mkdir fail"
25112         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25113                 error "set striped dir error"
25114         for i in {0..9}; do
25115                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25116                 sleep 1
25117                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25118                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25119                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25120                 sleep 1
25121                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25122                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25123                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25124         done
25125         true
25126 }
25127 run_test 300b "check ctime/mtime for striped dir"
25128
25129 test_300c() {
25130         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25131                 skip "skipped for lustre < 2.7.0"
25132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25134
25135         local file_count
25136
25137         mkdir_on_mdt0 $DIR/$tdir
25138         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25139                 error "set striped dir error"
25140
25141         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25142                 error "chown striped dir failed"
25143
25144         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25145                 error "create 5k files failed"
25146
25147         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25148
25149         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25150
25151         rm -rf $DIR/$tdir
25152 }
25153 run_test 300c "chown && check ls under striped directory"
25154
25155 test_300d() {
25156         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25157                 skip "skipped for lustre < 2.7.0"
25158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25160
25161         local stripe_count
25162         local file
25163
25164         mkdir -p $DIR/$tdir
25165         $LFS setstripe -c 2 $DIR/$tdir
25166
25167         #local striped directory
25168         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25169                 error "set striped dir error"
25170         #look at the directories for debug purposes
25171         ls -l $DIR/$tdir
25172         $LFS getdirstripe $DIR/$tdir
25173         ls -l $DIR/$tdir/striped_dir
25174         $LFS getdirstripe $DIR/$tdir/striped_dir
25175         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25176                 error "create 10 files failed"
25177
25178         #remote striped directory
25179         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25180                 error "set striped dir error"
25181         #look at the directories for debug purposes
25182         ls -l $DIR/$tdir
25183         $LFS getdirstripe $DIR/$tdir
25184         ls -l $DIR/$tdir/remote_striped_dir
25185         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25186         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25187                 error "create 10 files failed"
25188
25189         for file in $(find $DIR/$tdir); do
25190                 stripe_count=$($LFS getstripe -c $file)
25191                 [ $stripe_count -eq 2 ] ||
25192                         error "wrong stripe $stripe_count for $file"
25193         done
25194
25195         rm -rf $DIR/$tdir
25196 }
25197 run_test 300d "check default stripe under striped directory"
25198
25199 test_300e() {
25200         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25201                 skip "Need MDS version at least 2.7.55"
25202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25204
25205         local stripe_count
25206         local file
25207
25208         mkdir -p $DIR/$tdir
25209
25210         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25211                 error "set striped dir error"
25212
25213         touch $DIR/$tdir/striped_dir/a
25214         touch $DIR/$tdir/striped_dir/b
25215         touch $DIR/$tdir/striped_dir/c
25216
25217         mkdir $DIR/$tdir/striped_dir/dir_a
25218         mkdir $DIR/$tdir/striped_dir/dir_b
25219         mkdir $DIR/$tdir/striped_dir/dir_c
25220
25221         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25222                 error "set striped adir under striped dir error"
25223
25224         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25225                 error "set striped bdir under striped dir error"
25226
25227         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25228                 error "set striped cdir under striped dir error"
25229
25230         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25231                 error "rename dir under striped dir fails"
25232
25233         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25234                 error "rename dir under different stripes fails"
25235
25236         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25237                 error "rename file under striped dir should succeed"
25238
25239         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25240                 error "rename dir under striped dir should succeed"
25241
25242         rm -rf $DIR/$tdir
25243 }
25244 run_test 300e "check rename under striped directory"
25245
25246 test_300f() {
25247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25249         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25250                 skip "Need MDS version at least 2.7.55"
25251
25252         local stripe_count
25253         local file
25254
25255         rm -rf $DIR/$tdir
25256         mkdir -p $DIR/$tdir
25257
25258         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25259                 error "set striped dir error"
25260
25261         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25262                 error "set striped dir error"
25263
25264         touch $DIR/$tdir/striped_dir/a
25265         mkdir $DIR/$tdir/striped_dir/dir_a
25266         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25267                 error "create striped dir under striped dir fails"
25268
25269         touch $DIR/$tdir/striped_dir1/b
25270         mkdir $DIR/$tdir/striped_dir1/dir_b
25271         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25272                 error "create striped dir under striped dir fails"
25273
25274         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25275                 error "rename dir under different striped dir should fail"
25276
25277         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25278                 error "rename striped dir under diff striped dir should fail"
25279
25280         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25281                 error "rename file under diff striped dirs fails"
25282
25283         rm -rf $DIR/$tdir
25284 }
25285 run_test 300f "check rename cross striped directory"
25286
25287 test_300_check_default_striped_dir()
25288 {
25289         local dirname=$1
25290         local default_count=$2
25291         local default_index=$3
25292         local stripe_count
25293         local stripe_index
25294         local dir_stripe_index
25295         local dir
25296
25297         echo "checking $dirname $default_count $default_index"
25298         $LFS setdirstripe -D -c $default_count -i $default_index \
25299                                 -H all_char $DIR/$tdir/$dirname ||
25300                 error "set default stripe on striped dir error"
25301         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25302         [ $stripe_count -eq $default_count ] ||
25303                 error "expect $default_count get $stripe_count for $dirname"
25304
25305         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25306         [ $stripe_index -eq $default_index ] ||
25307                 error "expect $default_index get $stripe_index for $dirname"
25308
25309         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25310                                                 error "create dirs failed"
25311
25312         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25313         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25314         for dir in $(find $DIR/$tdir/$dirname/*); do
25315                 stripe_count=$($LFS getdirstripe -c $dir)
25316                 (( $stripe_count == $default_count )) ||
25317                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25318                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25319                 error "stripe count $default_count != $stripe_count for $dir"
25320
25321                 stripe_index=$($LFS getdirstripe -i $dir)
25322                 [ $default_index -eq -1 ] ||
25323                         [ $stripe_index -eq $default_index ] ||
25324                         error "$stripe_index != $default_index for $dir"
25325
25326                 #check default stripe
25327                 stripe_count=$($LFS getdirstripe -D -c $dir)
25328                 [ $stripe_count -eq $default_count ] ||
25329                 error "default count $default_count != $stripe_count for $dir"
25330
25331                 stripe_index=$($LFS getdirstripe -D -i $dir)
25332                 [ $stripe_index -eq $default_index ] ||
25333                 error "default index $default_index != $stripe_index for $dir"
25334         done
25335         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25336 }
25337
25338 test_300g() {
25339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25340         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25341                 skip "Need MDS version at least 2.7.55"
25342
25343         local dir
25344         local stripe_count
25345         local stripe_index
25346
25347         mkdir_on_mdt0 $DIR/$tdir
25348         mkdir $DIR/$tdir/normal_dir
25349
25350         #Checking when client cache stripe index
25351         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25352         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25353                 error "create striped_dir failed"
25354
25355         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25356                 error "create dir0 fails"
25357         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25358         [ $stripe_index -eq 0 ] ||
25359                 error "dir0 expect index 0 got $stripe_index"
25360
25361         mkdir $DIR/$tdir/striped_dir/dir1 ||
25362                 error "create dir1 fails"
25363         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25364         [ $stripe_index -eq 1 ] ||
25365                 error "dir1 expect index 1 got $stripe_index"
25366
25367         #check default stripe count/stripe index
25368         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25369         test_300_check_default_striped_dir normal_dir 1 0
25370         test_300_check_default_striped_dir normal_dir -1 1
25371         test_300_check_default_striped_dir normal_dir 2 -1
25372
25373         #delete default stripe information
25374         echo "delete default stripeEA"
25375         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25376                 error "set default stripe on striped dir error"
25377
25378         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25379         for dir in $(find $DIR/$tdir/normal_dir/*); do
25380                 stripe_count=$($LFS getdirstripe -c $dir)
25381                 [ $stripe_count -eq 0 ] ||
25382                         error "expect 1 get $stripe_count for $dir"
25383         done
25384 }
25385 run_test 300g "check default striped directory for normal directory"
25386
25387 test_300h() {
25388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25389         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25390                 skip "Need MDS version at least 2.7.55"
25391
25392         local dir
25393         local stripe_count
25394
25395         mkdir $DIR/$tdir
25396         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25397                 error "set striped dir error"
25398
25399         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25400         test_300_check_default_striped_dir striped_dir 1 0
25401         test_300_check_default_striped_dir striped_dir -1 1
25402         test_300_check_default_striped_dir striped_dir 2 -1
25403
25404         #delete default stripe information
25405         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25406                 error "set default stripe on striped dir error"
25407
25408         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25409         for dir in $(find $DIR/$tdir/striped_dir/*); do
25410                 stripe_count=$($LFS getdirstripe -c $dir)
25411                 [ $stripe_count -eq 0 ] ||
25412                         error "expect 1 get $stripe_count for $dir"
25413         done
25414 }
25415 run_test 300h "check default striped directory for striped directory"
25416
25417 test_300i() {
25418         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25419         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25420         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25421                 skip "Need MDS version at least 2.7.55"
25422
25423         local stripe_count
25424         local file
25425
25426         mkdir $DIR/$tdir
25427
25428         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25429                 error "set striped dir error"
25430
25431         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25432                 error "create files under striped dir failed"
25433
25434         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25435                 error "set striped hashdir error"
25436
25437         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25438                 error "create dir0 under hash dir failed"
25439         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25440                 error "create dir1 under hash dir failed"
25441         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25442                 error "create dir2 under hash dir failed"
25443
25444         # unfortunately, we need to umount to clear dir layout cache for now
25445         # once we fully implement dir layout, we can drop this
25446         umount_client $MOUNT || error "umount failed"
25447         mount_client $MOUNT || error "mount failed"
25448
25449         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25450         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25451         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25452
25453         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25454                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25455                         error "create crush2 dir $tdir/hashdir/d3 failed"
25456                 $LFS find -H crush2 $DIR/$tdir/hashdir
25457                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25458                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25459
25460                 # mkdir with an invalid hash type (hash=fail_val) from client
25461                 # should be replaced on MDS with a valid (default) hash type
25462                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25463                 $LCTL set_param fail_loc=0x1901 fail_val=99
25464                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25465
25466                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25467                 local expect=$(do_facet mds1 \
25468                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25469                 [[ $hash == $expect ]] ||
25470                         error "d99 hash '$hash' != expected hash '$expect'"
25471         fi
25472
25473         #set the stripe to be unknown hash type on read
25474         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25475         $LCTL set_param fail_loc=0x1901 fail_val=99
25476         for ((i = 0; i < 10; i++)); do
25477                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25478                         error "stat f-$i failed"
25479                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25480         done
25481
25482         touch $DIR/$tdir/striped_dir/f0 &&
25483                 error "create under striped dir with unknown hash should fail"
25484
25485         $LCTL set_param fail_loc=0
25486
25487         umount_client $MOUNT || error "umount failed"
25488         mount_client $MOUNT || error "mount failed"
25489
25490         return 0
25491 }
25492 run_test 300i "client handle unknown hash type striped directory"
25493
25494 test_300j() {
25495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25497         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25498                 skip "Need MDS version at least 2.7.55"
25499
25500         local stripe_count
25501         local file
25502
25503         mkdir $DIR/$tdir
25504
25505         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25506         $LCTL set_param fail_loc=0x1702
25507         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25508                 error "set striped dir error"
25509
25510         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25511                 error "create files under striped dir failed"
25512
25513         $LCTL set_param fail_loc=0
25514
25515         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25516
25517         return 0
25518 }
25519 run_test 300j "test large update record"
25520
25521 test_300k() {
25522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25524         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25525                 skip "Need MDS version at least 2.7.55"
25526
25527         # this test needs a huge transaction
25528         local kb
25529         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25530              osd*.$FSNAME-MDT0000.kbytestotal")
25531         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25532
25533         local stripe_count
25534         local file
25535
25536         mkdir $DIR/$tdir
25537
25538         #define OBD_FAIL_LARGE_STRIPE   0x1703
25539         $LCTL set_param fail_loc=0x1703
25540         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25541                 error "set striped dir error"
25542         $LCTL set_param fail_loc=0
25543
25544         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25545                 error "getstripeddir fails"
25546         rm -rf $DIR/$tdir/striped_dir ||
25547                 error "unlink striped dir fails"
25548
25549         return 0
25550 }
25551 run_test 300k "test large striped directory"
25552
25553 test_300l() {
25554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25555         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25556         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25557                 skip "Need MDS version at least 2.7.55"
25558
25559         local stripe_index
25560
25561         test_mkdir -p $DIR/$tdir/striped_dir
25562         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25563                         error "chown $RUNAS_ID failed"
25564         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25565                 error "set default striped dir failed"
25566
25567         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25568         $LCTL set_param fail_loc=0x80000158
25569         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25570
25571         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25572         [ $stripe_index -eq 1 ] ||
25573                 error "expect 1 get $stripe_index for $dir"
25574 }
25575 run_test 300l "non-root user to create dir under striped dir with stale layout"
25576
25577 test_300m() {
25578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25579         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25580         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25581                 skip "Need MDS version at least 2.7.55"
25582
25583         mkdir -p $DIR/$tdir/striped_dir
25584         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25585                 error "set default stripes dir error"
25586
25587         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25588
25589         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25590         [ $stripe_count -eq 0 ] ||
25591                         error "expect 0 get $stripe_count for a"
25592
25593         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25594                 error "set default stripes dir error"
25595
25596         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25597
25598         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25599         [ $stripe_count -eq 0 ] ||
25600                         error "expect 0 get $stripe_count for b"
25601
25602         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25603                 error "set default stripes dir error"
25604
25605         mkdir $DIR/$tdir/striped_dir/c &&
25606                 error "default stripe_index is invalid, mkdir c should fails"
25607
25608         rm -rf $DIR/$tdir || error "rmdir fails"
25609 }
25610 run_test 300m "setstriped directory on single MDT FS"
25611
25612 cleanup_300n() {
25613         local list=$(comma_list $(mdts_nodes))
25614
25615         trap 0
25616         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25617 }
25618
25619 test_300n() {
25620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25621         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25622         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25623                 skip "Need MDS version at least 2.7.55"
25624         remote_mds_nodsh && skip "remote MDS with nodsh"
25625
25626         local stripe_index
25627         local list=$(comma_list $(mdts_nodes))
25628
25629         trap cleanup_300n RETURN EXIT
25630         mkdir -p $DIR/$tdir
25631         chmod 777 $DIR/$tdir
25632         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25633                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25634                 error "create striped dir succeeds with gid=0"
25635
25636         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25637         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25638                 error "create striped dir fails with gid=-1"
25639
25640         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25641         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25642                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25643                 error "set default striped dir succeeds with gid=0"
25644
25645
25646         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25647         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25648                 error "set default striped dir fails with gid=-1"
25649
25650
25651         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25652         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25653                                         error "create test_dir fails"
25654         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25655                                         error "create test_dir1 fails"
25656         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25657                                         error "create test_dir2 fails"
25658         cleanup_300n
25659 }
25660 run_test 300n "non-root user to create dir under striped dir with default EA"
25661
25662 test_300o() {
25663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25664         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25665         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25666                 skip "Need MDS version at least 2.7.55"
25667
25668         local numfree1
25669         local numfree2
25670
25671         mkdir -p $DIR/$tdir
25672
25673         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25674         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25675         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25676                 skip "not enough free inodes $numfree1 $numfree2"
25677         fi
25678
25679         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25680         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25681         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25682                 skip "not enough free space $numfree1 $numfree2"
25683         fi
25684
25685         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25686                 error "setdirstripe fails"
25687
25688         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25689                 error "create dirs fails"
25690
25691         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25692         ls $DIR/$tdir/striped_dir > /dev/null ||
25693                 error "ls striped dir fails"
25694         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25695                 error "unlink big striped dir fails"
25696 }
25697 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25698
25699 test_300p() {
25700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25701         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25702         remote_mds_nodsh && skip "remote MDS with nodsh"
25703
25704         mkdir_on_mdt0 $DIR/$tdir
25705
25706         #define OBD_FAIL_OUT_ENOSPC     0x1704
25707         do_facet mds2 lctl set_param fail_loc=0x80001704
25708         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25709                  && error "create striped directory should fail"
25710
25711         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25712
25713         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25714         true
25715 }
25716 run_test 300p "create striped directory without space"
25717
25718 test_300q() {
25719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25721
25722         local fd=$(free_fd)
25723         local cmd="exec $fd<$tdir"
25724         cd $DIR
25725         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25726         eval $cmd
25727         cmd="exec $fd<&-"
25728         trap "eval $cmd" EXIT
25729         cd $tdir || error "cd $tdir fails"
25730         rmdir  ../$tdir || error "rmdir $tdir fails"
25731         mkdir local_dir && error "create dir succeeds"
25732         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25733         eval $cmd
25734         return 0
25735 }
25736 run_test 300q "create remote directory under orphan directory"
25737
25738 test_300r() {
25739         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25740                 skip "Need MDS version at least 2.7.55" && return
25741         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25742
25743         mkdir $DIR/$tdir
25744
25745         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25746                 error "set striped dir error"
25747
25748         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25749                 error "getstripeddir fails"
25750
25751         local stripe_count
25752         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25753                       awk '/lmv_stripe_count:/ { print $2 }')
25754
25755         [ $MDSCOUNT -ne $stripe_count ] &&
25756                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25757
25758         rm -rf $DIR/$tdir/striped_dir ||
25759                 error "unlink striped dir fails"
25760 }
25761 run_test 300r "test -1 striped directory"
25762
25763 test_300s_helper() {
25764         local count=$1
25765
25766         local stripe_dir=$DIR/$tdir/striped_dir.$count
25767
25768         $LFS mkdir -c $count $stripe_dir ||
25769                 error "lfs mkdir -c error"
25770
25771         $LFS getdirstripe $stripe_dir ||
25772                 error "lfs getdirstripe fails"
25773
25774         local stripe_count
25775         stripe_count=$($LFS getdirstripe $stripe_dir |
25776                       awk '/lmv_stripe_count:/ { print $2 }')
25777
25778         [ $count -ne $stripe_count ] &&
25779                 error_noexit "bad stripe count $stripe_count expected $count"
25780
25781         local dupe_stripes
25782         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25783                 awk '/0x/ {count[$1] += 1}; END {
25784                         for (idx in count) {
25785                                 if (count[idx]>1) {
25786                                         print "index " idx " count " count[idx]
25787                                 }
25788                         }
25789                 }')
25790
25791         if [[ -n "$dupe_stripes" ]] ; then
25792                 lfs getdirstripe $stripe_dir
25793                 error_noexit "Dupe MDT above: $dupe_stripes "
25794         fi
25795
25796         rm -rf $stripe_dir ||
25797                 error_noexit "unlink $stripe_dir fails"
25798 }
25799
25800 test_300s() {
25801         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25802                 skip "Need MDS version at least 2.7.55" && return
25803         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25804
25805         mkdir $DIR/$tdir
25806         for count in $(seq 2 $MDSCOUNT); do
25807                 test_300s_helper $count
25808         done
25809 }
25810 run_test 300s "test lfs mkdir -c without -i"
25811
25812 test_300t() {
25813         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25814                 skip "need MDS 2.14.55 or later"
25815         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25816
25817         local testdir="$DIR/$tdir/striped_dir"
25818         local dir1=$testdir/dir1
25819         local dir2=$testdir/dir2
25820
25821         mkdir -p $testdir
25822
25823         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25824                 error "failed to set default stripe count for $testdir"
25825
25826         mkdir $dir1
25827         local stripe_count=$($LFS getdirstripe -c $dir1)
25828
25829         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25830
25831         local max_count=$((MDSCOUNT - 1))
25832         local mdts=$(comma_list $(mdts_nodes))
25833
25834         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25835         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25836
25837         mkdir $dir2
25838         stripe_count=$($LFS getdirstripe -c $dir2)
25839
25840         (( $stripe_count == $max_count )) || error "wrong stripe count"
25841 }
25842 run_test 300t "test max_mdt_stripecount"
25843
25844 prepare_remote_file() {
25845         mkdir $DIR/$tdir/src_dir ||
25846                 error "create remote source failed"
25847
25848         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25849                  error "cp to remote source failed"
25850         touch $DIR/$tdir/src_dir/a
25851
25852         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25853                 error "create remote target dir failed"
25854
25855         touch $DIR/$tdir/tgt_dir/b
25856
25857         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25858                 error "rename dir cross MDT failed!"
25859
25860         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25861                 error "src_child still exists after rename"
25862
25863         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25864                 error "missing file(a) after rename"
25865
25866         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25867                 error "diff after rename"
25868 }
25869
25870 test_310a() {
25871         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25873
25874         local remote_file=$DIR/$tdir/tgt_dir/b
25875
25876         mkdir -p $DIR/$tdir
25877
25878         prepare_remote_file || error "prepare remote file failed"
25879
25880         #open-unlink file
25881         $OPENUNLINK $remote_file $remote_file ||
25882                 error "openunlink $remote_file failed"
25883         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25884 }
25885 run_test 310a "open unlink remote file"
25886
25887 test_310b() {
25888         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25890
25891         local remote_file=$DIR/$tdir/tgt_dir/b
25892
25893         mkdir -p $DIR/$tdir
25894
25895         prepare_remote_file || error "prepare remote file failed"
25896
25897         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25898         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25899         $CHECKSTAT -t file $remote_file || error "check file failed"
25900 }
25901 run_test 310b "unlink remote file with multiple links while open"
25902
25903 test_310c() {
25904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25905         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25906
25907         local remote_file=$DIR/$tdir/tgt_dir/b
25908
25909         mkdir -p $DIR/$tdir
25910
25911         prepare_remote_file || error "prepare remote file failed"
25912
25913         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25914         multiop_bg_pause $remote_file O_uc ||
25915                         error "mulitop failed for remote file"
25916         MULTIPID=$!
25917         $MULTIOP $DIR/$tfile Ouc
25918         kill -USR1 $MULTIPID
25919         wait $MULTIPID
25920 }
25921 run_test 310c "open-unlink remote file with multiple links"
25922
25923 #LU-4825
25924 test_311() {
25925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25926         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25927         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25928                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25929         remote_mds_nodsh && skip "remote MDS with nodsh"
25930
25931         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25932         local mdts=$(comma_list $(mdts_nodes))
25933
25934         mkdir -p $DIR/$tdir
25935         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25936         createmany -o $DIR/$tdir/$tfile. 1000
25937
25938         # statfs data is not real time, let's just calculate it
25939         old_iused=$((old_iused + 1000))
25940
25941         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25942                         osp.*OST0000*MDT0000.create_count")
25943         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25944                                 osp.*OST0000*MDT0000.max_create_count")
25945         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25946
25947         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25948         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25949         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25950
25951         unlinkmany $DIR/$tdir/$tfile. 1000
25952
25953         do_nodes $mdts "$LCTL set_param -n \
25954                         osp.*OST0000*.max_create_count=$max_count"
25955         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25956                 do_nodes $mdts "$LCTL set_param -n \
25957                                 osp.*OST0000*.create_count=$count"
25958         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25959                         grep "=0" && error "create_count is zero"
25960
25961         local new_iused
25962         for i in $(seq 120); do
25963                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25964                 # system may be too busy to destroy all objs in time, use
25965                 # a somewhat small value to not fail autotest
25966                 [ $((old_iused - new_iused)) -gt 400 ] && break
25967                 sleep 1
25968         done
25969
25970         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25971         [ $((old_iused - new_iused)) -gt 400 ] ||
25972                 error "objs not destroyed after unlink"
25973 }
25974 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25975
25976 zfs_get_objid()
25977 {
25978         local ost=$1
25979         local tf=$2
25980         local fid=($($LFS getstripe $tf | grep 0x))
25981         local seq=${fid[3]#0x}
25982         local objid=${fid[1]}
25983
25984         local vdevdir=$(dirname $(facet_vdevice $ost))
25985         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25986         local zfs_zapid=$(do_facet $ost $cmd |
25987                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25988                           awk '/Object/{getline; print $1}')
25989         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25990                           awk "/$objid = /"'{printf $3}')
25991
25992         echo $zfs_objid
25993 }
25994
25995 zfs_object_blksz() {
25996         local ost=$1
25997         local objid=$2
25998
25999         local vdevdir=$(dirname $(facet_vdevice $ost))
26000         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26001         local blksz=$(do_facet $ost $cmd $objid |
26002                       awk '/dblk/{getline; printf $4}')
26003
26004         case "${blksz: -1}" in
26005                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26006                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26007                 *) ;;
26008         esac
26009
26010         echo $blksz
26011 }
26012
26013 test_312() { # LU-4856
26014         remote_ost_nodsh && skip "remote OST with nodsh"
26015         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26016
26017         local max_blksz=$(do_facet ost1 \
26018                           $ZFS get -p recordsize $(facet_device ost1) |
26019                           awk '!/VALUE/{print $3}')
26020         local tf=$DIR/$tfile
26021
26022         $LFS setstripe -c1 $tf
26023         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26024
26025         # Get ZFS object id
26026         local zfs_objid=$(zfs_get_objid $facet $tf)
26027         # block size change by sequential overwrite
26028         local bs
26029
26030         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26031                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26032
26033                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26034                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26035         done
26036         rm -f $tf
26037
26038         $LFS setstripe -c1 $tf
26039         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26040
26041         # block size change by sequential append write
26042         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26043         zfs_objid=$(zfs_get_objid $facet $tf)
26044         local count
26045
26046         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26047                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26048                         oflag=sync conv=notrunc
26049
26050                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26051                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26052                         error "blksz error, actual $blksz, " \
26053                                 "expected: 2 * $count * $PAGE_SIZE"
26054         done
26055         rm -f $tf
26056
26057         # random write
26058         $LFS setstripe -c1 $tf
26059         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26060         zfs_objid=$(zfs_get_objid $facet $tf)
26061
26062         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26063         blksz=$(zfs_object_blksz $facet $zfs_objid)
26064         (( blksz == PAGE_SIZE )) ||
26065                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26066
26067         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26068         blksz=$(zfs_object_blksz $facet $zfs_objid)
26069         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26070
26071         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26072         blksz=$(zfs_object_blksz $facet $zfs_objid)
26073         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26074 }
26075 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26076
26077 test_313() {
26078         remote_ost_nodsh && skip "remote OST with nodsh"
26079
26080         local file=$DIR/$tfile
26081
26082         rm -f $file
26083         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26084
26085         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26086         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26087         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26088                 error "write should failed"
26089         do_facet ost1 "$LCTL set_param fail_loc=0"
26090         rm -f $file
26091 }
26092 run_test 313 "io should fail after last_rcvd update fail"
26093
26094 test_314() {
26095         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26096
26097         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26098         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26099         rm -f $DIR/$tfile
26100         wait_delete_completed
26101         do_facet ost1 "$LCTL set_param fail_loc=0"
26102 }
26103 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26104
26105 test_315() { # LU-618
26106         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26107
26108         local file=$DIR/$tfile
26109         rm -f $file
26110
26111         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26112                 error "multiop file write failed"
26113         $MULTIOP $file oO_RDONLY:r4063232_c &
26114         PID=$!
26115
26116         sleep 2
26117
26118         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26119         kill -USR1 $PID
26120
26121         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26122         rm -f $file
26123 }
26124 run_test 315 "read should be accounted"
26125
26126 test_316() {
26127         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26128         large_xattr_enabled || skip "ea_inode feature disabled"
26129
26130         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26131         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26132         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26133         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26134
26135         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26136 }
26137 run_test 316 "lfs migrate of file with large_xattr enabled"
26138
26139 test_317() {
26140         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26141                 skip "Need MDS version at least 2.11.53"
26142         if [ "$ost1_FSTYPE" == "zfs" ]; then
26143                 skip "LU-10370: no implementation for ZFS"
26144         fi
26145
26146         local trunc_sz
26147         local grant_blk_size
26148
26149         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26150                         awk '/grant_block_size:/ { print $2; exit; }')
26151         #
26152         # Create File of size 5M. Truncate it to below size's and verify
26153         # blocks count.
26154         #
26155         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26156                 error "Create file $DIR/$tfile failed"
26157         stack_trap "rm -f $DIR/$tfile" EXIT
26158
26159         for trunc_sz in 2097152 4097 4000 509 0; do
26160                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26161                         error "truncate $tfile to $trunc_sz failed"
26162                 local sz=$(stat --format=%s $DIR/$tfile)
26163                 local blk=$(stat --format=%b $DIR/$tfile)
26164                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26165                                      grant_blk_size) * 8))
26166
26167                 if [[ $blk -ne $trunc_blk ]]; then
26168                         $(which stat) $DIR/$tfile
26169                         error "Expected Block $trunc_blk got $blk for $tfile"
26170                 fi
26171
26172                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26173                         error "Expected Size $trunc_sz got $sz for $tfile"
26174         done
26175
26176         #
26177         # sparse file test
26178         # Create file with a hole and write actual 65536 bytes which aligned
26179         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26180         #
26181         local bs=65536
26182         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26183                 error "Create file : $DIR/$tfile"
26184
26185         #
26186         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26187         # blocks. The block count must drop to 8.
26188         #
26189         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26190                 ((bs - grant_blk_size) + 1)))
26191         $TRUNCATE $DIR/$tfile $trunc_sz ||
26192                 error "truncate $tfile to $trunc_sz failed"
26193
26194         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26195         sz=$(stat --format=%s $DIR/$tfile)
26196         blk=$(stat --format=%b $DIR/$tfile)
26197
26198         if [[ $blk -ne $trunc_bsz ]]; then
26199                 $(which stat) $DIR/$tfile
26200                 error "Expected Block $trunc_bsz got $blk for $tfile"
26201         fi
26202
26203         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26204                 error "Expected Size $trunc_sz got $sz for $tfile"
26205 }
26206 run_test 317 "Verify blocks get correctly update after truncate"
26207
26208 test_318() {
26209         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26210         local old_max_active=$($LCTL get_param -n \
26211                             ${llite_name}.max_read_ahead_async_active \
26212                             2>/dev/null)
26213
26214         $LCTL set_param llite.*.max_read_ahead_async_active=256
26215         local max_active=$($LCTL get_param -n \
26216                            ${llite_name}.max_read_ahead_async_active \
26217                            2>/dev/null)
26218         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26219
26220         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26221                 error "set max_read_ahead_async_active should succeed"
26222
26223         $LCTL set_param llite.*.max_read_ahead_async_active=512
26224         max_active=$($LCTL get_param -n \
26225                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26226         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26227
26228         # restore @max_active
26229         [ $old_max_active -ne 0 ] && $LCTL set_param \
26230                 llite.*.max_read_ahead_async_active=$old_max_active
26231
26232         local old_threshold=$($LCTL get_param -n \
26233                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26234         local max_per_file_mb=$($LCTL get_param -n \
26235                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26236
26237         local invalid=$(($max_per_file_mb + 1))
26238         $LCTL set_param \
26239                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26240                         && error "set $invalid should fail"
26241
26242         local valid=$(($invalid - 1))
26243         $LCTL set_param \
26244                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26245                         error "set $valid should succeed"
26246         local threshold=$($LCTL get_param -n \
26247                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26248         [ $threshold -eq $valid ] || error \
26249                 "expect threshold $valid got $threshold"
26250         $LCTL set_param \
26251                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26252 }
26253 run_test 318 "Verify async readahead tunables"
26254
26255 test_319() {
26256         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26257
26258         local before=$(date +%s)
26259         local evict
26260         local mdir=$DIR/$tdir
26261         local file=$mdir/xxx
26262
26263         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26264         touch $file
26265
26266 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26267         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26268         $LFS migrate -m1 $mdir &
26269
26270         sleep 1
26271         dd if=$file of=/dev/null
26272         wait
26273         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26274           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26275
26276         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26277 }
26278 run_test 319 "lost lease lock on migrate error"
26279
26280 test_398a() { # LU-4198
26281         local ost1_imp=$(get_osc_import_name client ost1)
26282         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26283                          cut -d'.' -f2)
26284
26285         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26286         stack_trap "rm -f $DIR/$tfile"
26287         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26288
26289         # request a new lock on client
26290         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26291
26292         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26293         local lock_count=$($LCTL get_param -n \
26294                            ldlm.namespaces.$imp_name.lru_size)
26295         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26296
26297         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26298
26299         # no lock cached, should use lockless DIO and not enqueue new lock
26300         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26301         lock_count=$($LCTL get_param -n \
26302                      ldlm.namespaces.$imp_name.lru_size)
26303         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26304
26305         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26306
26307         # no lock cached, should use locked DIO append
26308         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26309                 conv=notrunc || error "DIO append failed"
26310         lock_count=$($LCTL get_param -n \
26311                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
26312         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26313 }
26314 run_test 398a "direct IO should cancel lock otherwise lockless"
26315
26316 test_398b() { # LU-4198
26317         local before=$(date +%s)
26318         local njobs=4
26319         local size=48
26320
26321         which fio || skip_env "no fio installed"
26322         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26323         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26324
26325         # Single page, multiple pages, stripe size, 4*stripe size
26326         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26327                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26328                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26329                         --numjobs=$njobs --fallocate=none \
26330                         --iodepth=16 --allow_file_create=0 \
26331                         --size=$((size/njobs))M \
26332                         --filename=$DIR/$tfile &
26333                 bg_pid=$!
26334
26335                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26336                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26337                         --numjobs=$njobs --fallocate=none \
26338                         --iodepth=16 --allow_file_create=0 \
26339                         --size=$((size/njobs))M \
26340                         --filename=$DIR/$tfile || true
26341                 wait $bg_pid
26342         done
26343
26344         evict=$(do_facet client $LCTL get_param \
26345                 osc.$FSNAME-OST*-osc-*/state |
26346             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26347
26348         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26349                 (do_facet client $LCTL get_param \
26350                         osc.$FSNAME-OST*-osc-*/state;
26351                     error "eviction happened: $evict before:$before")
26352
26353         rm -f $DIR/$tfile
26354 }
26355 run_test 398b "DIO and buffer IO race"
26356
26357 test_398c() { # LU-4198
26358         local ost1_imp=$(get_osc_import_name client ost1)
26359         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26360                          cut -d'.' -f2)
26361
26362         which fio || skip_env "no fio installed"
26363
26364         saved_debug=$($LCTL get_param -n debug)
26365         $LCTL set_param debug=0
26366
26367         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26368         ((size /= 1024)) # by megabytes
26369         ((size /= 2)) # write half of the OST at most
26370         [ $size -gt 40 ] && size=40 #reduce test time anyway
26371
26372         $LFS setstripe -c 1 $DIR/$tfile
26373
26374         # it seems like ldiskfs reserves more space than necessary if the
26375         # writing blocks are not mapped, so it extends the file firstly
26376         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26377         cancel_lru_locks osc
26378
26379         # clear and verify rpc_stats later
26380         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26381
26382         local njobs=4
26383         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26384         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26385                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26386                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26387                 --filename=$DIR/$tfile
26388         [ $? -eq 0 ] || error "fio write error"
26389
26390         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26391                 error "Locks were requested while doing AIO"
26392
26393         # get the percentage of 1-page I/O
26394         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26395                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26396                 awk '{print $7}')
26397         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26398
26399         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26400         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26401                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26402                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26403                 --filename=$DIR/$tfile
26404         [ $? -eq 0 ] || error "fio mixed read write error"
26405
26406         echo "AIO with large block size ${size}M"
26407         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26408                 --numjobs=1 --fallocate=none --ioengine=libaio \
26409                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26410                 --filename=$DIR/$tfile
26411         [ $? -eq 0 ] || error "fio large block size failed"
26412
26413         rm -f $DIR/$tfile
26414         $LCTL set_param debug="$saved_debug"
26415 }
26416 run_test 398c "run fio to test AIO"
26417
26418 test_398d() { #  LU-13846
26419         which aiocp || skip_env "no aiocp installed"
26420         local aio_file=$DIR/$tfile.aio
26421
26422         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26423
26424         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26425         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26426         stack_trap "rm -f $DIR/$tfile $aio_file"
26427
26428         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26429
26430         # make sure we don't crash and fail properly
26431         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26432                 error "aio not aligned with PAGE SIZE should fail"
26433
26434         rm -f $DIR/$tfile $aio_file
26435 }
26436 run_test 398d "run aiocp to verify block size > stripe size"
26437
26438 test_398e() {
26439         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26440         touch $DIR/$tfile.new
26441         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26442 }
26443 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26444
26445 test_398f() { #  LU-14687
26446         which aiocp || skip_env "no aiocp installed"
26447         local aio_file=$DIR/$tfile.aio
26448
26449         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26450
26451         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26452         stack_trap "rm -f $DIR/$tfile $aio_file"
26453
26454         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26455         $LCTL set_param fail_loc=0x1418
26456         # make sure we don't crash and fail properly
26457         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26458                 error "aio with page allocation failure succeeded"
26459         $LCTL set_param fail_loc=0
26460         diff $DIR/$tfile $aio_file
26461         [[ $? != 0 ]] || error "no diff after failed aiocp"
26462 }
26463 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26464
26465 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26466 # stripe and i/o size must be > stripe size
26467 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26468 # single RPC in flight.  This test shows async DIO submission is working by
26469 # showing multiple RPCs in flight.
26470 test_398g() { #  LU-13798
26471         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26472
26473         # We need to do some i/o first to acquire enough grant to put our RPCs
26474         # in flight; otherwise a new connection may not have enough grant
26475         # available
26476         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26477                 error "parallel dio failed"
26478         stack_trap "rm -f $DIR/$tfile"
26479
26480         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26481         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26482         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26483         stack_trap "$LCTL set_param -n $pages_per_rpc"
26484
26485         # Recreate file so it's empty
26486         rm -f $DIR/$tfile
26487         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26488         #Pause rpc completion to guarantee we see multiple rpcs in flight
26489         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26490         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26491         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26492
26493         # Clear rpc stats
26494         $LCTL set_param osc.*.rpc_stats=c
26495
26496         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26497                 error "parallel dio failed"
26498         stack_trap "rm -f $DIR/$tfile"
26499
26500         $LCTL get_param osc.*-OST0000-*.rpc_stats
26501         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26502                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26503                 grep "8:" | awk '{print $8}')
26504         # We look at the "8 rpcs in flight" field, and verify A) it is present
26505         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26506         # as expected for an 8M DIO to a file with 1M stripes.
26507         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26508
26509         # Verify turning off parallel dio works as expected
26510         # Clear rpc stats
26511         $LCTL set_param osc.*.rpc_stats=c
26512         $LCTL set_param llite.*.parallel_dio=0
26513         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26514
26515         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26516                 error "dio with parallel dio disabled failed"
26517
26518         # Ideally, we would see only one RPC in flight here, but there is an
26519         # unavoidable race between i/o completion and RPC in flight counting,
26520         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26521         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26522         # So instead we just verify it's always < 8.
26523         $LCTL get_param osc.*-OST0000-*.rpc_stats
26524         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26525                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26526                 grep '^$' -B1 | grep . | awk '{print $1}')
26527         [ $ret != "8:" ] ||
26528                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26529 }
26530 run_test 398g "verify parallel dio async RPC submission"
26531
26532 test_398h() { #  LU-13798
26533         local dio_file=$DIR/$tfile.dio
26534
26535         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26536
26537         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26538         stack_trap "rm -f $DIR/$tfile $dio_file"
26539
26540         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26541                 error "parallel dio failed"
26542         diff $DIR/$tfile $dio_file
26543         [[ $? == 0 ]] || error "file diff after aiocp"
26544 }
26545 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26546
26547 test_398i() { #  LU-13798
26548         local dio_file=$DIR/$tfile.dio
26549
26550         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26551
26552         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26553         stack_trap "rm -f $DIR/$tfile $dio_file"
26554
26555         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26556         $LCTL set_param fail_loc=0x1418
26557         # make sure we don't crash and fail properly
26558         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26559                 error "parallel dio page allocation failure succeeded"
26560         diff $DIR/$tfile $dio_file
26561         [[ $? != 0 ]] || error "no diff after failed aiocp"
26562 }
26563 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26564
26565 test_398j() { #  LU-13798
26566         # Stripe size > RPC size but less than i/o size tests split across
26567         # stripes and RPCs for individual i/o op
26568         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26569
26570         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26571         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26572         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26573         stack_trap "$LCTL set_param -n $pages_per_rpc"
26574
26575         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26576                 error "parallel dio write failed"
26577         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26578
26579         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26580                 error "parallel dio read failed"
26581         diff $DIR/$tfile $DIR/$tfile.2
26582         [[ $? == 0 ]] || error "file diff after parallel dio read"
26583 }
26584 run_test 398j "test parallel dio where stripe size > rpc_size"
26585
26586 test_398k() { #  LU-13798
26587         wait_delete_completed
26588         wait_mds_ost_sync
26589
26590         # 4 stripe file; we will cause out of space on OST0
26591         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26592
26593         # Fill OST0 (if it's not too large)
26594         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26595                    head -n1)
26596         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26597                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26598         fi
26599         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26600         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26601                 error "dd should fill OST0"
26602         stack_trap "rm -f $DIR/$tfile.1"
26603
26604         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26605         err=$?
26606
26607         ls -la $DIR/$tfile
26608         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26609                 error "file is not 0 bytes in size"
26610
26611         # dd above should not succeed, but don't error until here so we can
26612         # get debug info above
26613         [[ $err != 0 ]] ||
26614                 error "parallel dio write with enospc succeeded"
26615         stack_trap "rm -f $DIR/$tfile"
26616 }
26617 run_test 398k "test enospc on first stripe"
26618
26619 test_398l() { #  LU-13798
26620         wait_delete_completed
26621         wait_mds_ost_sync
26622
26623         # 4 stripe file; we will cause out of space on OST0
26624         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26625         # happens on the second i/o chunk we issue
26626         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26627
26628         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26629         stack_trap "rm -f $DIR/$tfile"
26630
26631         # Fill OST0 (if it's not too large)
26632         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26633                    head -n1)
26634         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26635                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26636         fi
26637         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26638         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26639                 error "dd should fill OST0"
26640         stack_trap "rm -f $DIR/$tfile.1"
26641
26642         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26643         err=$?
26644         stack_trap "rm -f $DIR/$tfile.2"
26645
26646         # Check that short write completed as expected
26647         ls -la $DIR/$tfile.2
26648         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26649                 error "file is not 1M in size"
26650
26651         # dd above should not succeed, but don't error until here so we can
26652         # get debug info above
26653         [[ $err != 0 ]] ||
26654                 error "parallel dio write with enospc succeeded"
26655
26656         # Truncate source file to same length as output file and diff them
26657         $TRUNCATE $DIR/$tfile 1048576
26658         diff $DIR/$tfile $DIR/$tfile.2
26659         [[ $? == 0 ]] || error "data incorrect after short write"
26660 }
26661 run_test 398l "test enospc on intermediate stripe/RPC"
26662
26663 test_398m() { #  LU-13798
26664         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26665
26666         # Set up failure on OST0, the first stripe:
26667         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26668         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26669         # OST0 is on ost1, OST1 is on ost2.
26670         # So this fail_val specifies OST0
26671         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26672         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26673
26674         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26675                 error "parallel dio write with failure on first stripe succeeded"
26676         stack_trap "rm -f $DIR/$tfile"
26677         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26678
26679         # Place data in file for read
26680         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26681                 error "parallel dio write failed"
26682
26683         # Fail read on OST0, first stripe
26684         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26685         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26686         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26687                 error "parallel dio read with error on first stripe succeeded"
26688         rm -f $DIR/$tfile.2
26689         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26690
26691         # Switch to testing on OST1, second stripe
26692         # Clear file contents, maintain striping
26693         echo > $DIR/$tfile
26694         # Set up failure on OST1, second stripe:
26695         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26696         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26697
26698         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26699                 error "parallel dio write with failure on second stripe succeeded"
26700         stack_trap "rm -f $DIR/$tfile"
26701         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26702
26703         # Place data in file for read
26704         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26705                 error "parallel dio write failed"
26706
26707         # Fail read on OST1, second stripe
26708         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26709         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26710         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26711                 error "parallel dio read with error on second stripe succeeded"
26712         rm -f $DIR/$tfile.2
26713         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26714 }
26715 run_test 398m "test RPC failures with parallel dio"
26716
26717 # Parallel submission of DIO should not cause problems for append, but it's
26718 # important to verify.
26719 test_398n() { #  LU-13798
26720         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26721
26722         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26723                 error "dd to create source file failed"
26724         stack_trap "rm -f $DIR/$tfile"
26725
26726         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26727                 error "parallel dio write with failure on second stripe succeeded"
26728         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26729         diff $DIR/$tfile $DIR/$tfile.1
26730         [[ $? == 0 ]] || error "data incorrect after append"
26731
26732 }
26733 run_test 398n "test append with parallel DIO"
26734
26735 test_398o() {
26736         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26737 }
26738 run_test 398o "right kms with DIO"
26739
26740 test_398p()
26741 {
26742         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26743         which aiocp || skip_env "no aiocp installed"
26744
26745         local stripe_size=$((1024 * 1024)) #1 MiB
26746         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26747         local file_size=$((25 * stripe_size))
26748
26749         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26750         stack_trap "rm -f $DIR/$tfile*"
26751         # Just a bit bigger than the largest size in the test set below
26752         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26753                 error "buffered i/o to create file failed"
26754
26755         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26756                 $((stripe_size * 4)); do
26757
26758                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26759
26760                 echo "bs: $bs, file_size $file_size"
26761                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26762                         $DIR/$tfile.1 $DIR/$tfile.2 &
26763                 pid_dio1=$!
26764                 # Buffered I/O with similar but not the same block size
26765                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26766                         conv=notrunc &
26767                 pid_bio2=$!
26768                 wait $pid_dio1
26769                 rc1=$?
26770                 wait $pid_bio2
26771                 rc2=$?
26772                 if (( rc1 != 0 )); then
26773                         error "aio copy 1 w/bsize $bs failed: $rc1"
26774                 fi
26775                 if (( rc2 != 0 )); then
26776                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26777                 fi
26778
26779                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26780                         error "size incorrect"
26781                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26782                         error "files differ, bsize $bs"
26783                 rm -f $DIR/$tfile.2
26784         done
26785 }
26786 run_test 398p "race aio with buffered i/o"
26787
26788 test_398q()
26789 {
26790         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26791
26792         local stripe_size=$((1024 * 1024)) #1 MiB
26793         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26794         local file_size=$((25 * stripe_size))
26795
26796         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26797         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26798
26799         # Just a bit bigger than the largest size in the test set below
26800         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26801                 error "buffered i/o to create file failed"
26802
26803         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26804                 $((stripe_size * 4)); do
26805
26806                 echo "bs: $bs, file_size $file_size"
26807                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26808                         conv=notrunc oflag=direct iflag=direct &
26809                 pid_dio1=$!
26810                 # Buffered I/O with similar but not the same block size
26811                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26812                         conv=notrunc &
26813                 pid_bio2=$!
26814                 wait $pid_dio1
26815                 rc1=$?
26816                 wait $pid_bio2
26817                 rc2=$?
26818                 if (( rc1 != 0 )); then
26819                         error "dio copy 1 w/bsize $bs failed: $rc1"
26820                 fi
26821                 if (( rc2 != 0 )); then
26822                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26823                 fi
26824
26825                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26826                         error "size incorrect"
26827                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26828                         error "files differ, bsize $bs"
26829         done
26830
26831         rm -f $DIR/$tfile*
26832 }
26833 run_test 398q "race dio with buffered i/o"
26834
26835 test_fake_rw() {
26836         local read_write=$1
26837         if [ "$read_write" = "write" ]; then
26838                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26839         elif [ "$read_write" = "read" ]; then
26840                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26841         else
26842                 error "argument error"
26843         fi
26844
26845         # turn off debug for performance testing
26846         local saved_debug=$($LCTL get_param -n debug)
26847         $LCTL set_param debug=0
26848
26849         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26850
26851         # get ost1 size - $FSNAME-OST0000
26852         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26853         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26854         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26855
26856         if [ "$read_write" = "read" ]; then
26857                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26858         fi
26859
26860         local start_time=$(date +%s.%N)
26861         $dd_cmd bs=1M count=$blocks oflag=sync ||
26862                 error "real dd $read_write error"
26863         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26864
26865         if [ "$read_write" = "write" ]; then
26866                 rm -f $DIR/$tfile
26867         fi
26868
26869         # define OBD_FAIL_OST_FAKE_RW           0x238
26870         do_facet ost1 $LCTL set_param fail_loc=0x238
26871
26872         local start_time=$(date +%s.%N)
26873         $dd_cmd bs=1M count=$blocks oflag=sync ||
26874                 error "fake dd $read_write error"
26875         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26876
26877         if [ "$read_write" = "write" ]; then
26878                 # verify file size
26879                 cancel_lru_locks osc
26880                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26881                         error "$tfile size not $blocks MB"
26882         fi
26883         do_facet ost1 $LCTL set_param fail_loc=0
26884
26885         echo "fake $read_write $duration_fake vs. normal $read_write" \
26886                 "$duration in seconds"
26887         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26888                 error_not_in_vm "fake write is slower"
26889
26890         $LCTL set_param -n debug="$saved_debug"
26891         rm -f $DIR/$tfile
26892 }
26893 test_399a() { # LU-7655 for OST fake write
26894         remote_ost_nodsh && skip "remote OST with nodsh"
26895
26896         test_fake_rw write
26897 }
26898 run_test 399a "fake write should not be slower than normal write"
26899
26900 test_399b() { # LU-8726 for OST fake read
26901         remote_ost_nodsh && skip "remote OST with nodsh"
26902         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26903                 skip_env "ldiskfs only test"
26904         fi
26905
26906         test_fake_rw read
26907 }
26908 run_test 399b "fake read should not be slower than normal read"
26909
26910 test_400a() { # LU-1606, was conf-sanity test_74
26911         if ! which $CC > /dev/null 2>&1; then
26912                 skip_env "$CC is not installed"
26913         fi
26914
26915         local extra_flags=''
26916         local out=$TMP/$tfile
26917         local prefix=/usr/include/lustre
26918         local prog
26919
26920         # Oleg removes .c files in his test rig so test if any c files exist
26921         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26922                 skip_env "Needed .c test files are missing"
26923
26924         if ! [[ -d $prefix ]]; then
26925                 # Assume we're running in tree and fixup the include path.
26926                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26927                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26928                 extra_flags+=" -L$LUSTRE/utils/.libs"
26929         fi
26930
26931         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26932                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26933                         error "client api broken"
26934         done
26935         rm -f $out
26936 }
26937 run_test 400a "Lustre client api program can compile and link"
26938
26939 test_400b() { # LU-1606, LU-5011
26940         local header
26941         local out=$TMP/$tfile
26942         local prefix=/usr/include/linux/lustre
26943
26944         # We use a hard coded prefix so that this test will not fail
26945         # when run in tree. There are headers in lustre/include/lustre/
26946         # that are not packaged (like lustre_idl.h) and have more
26947         # complicated include dependencies (like config.h and lnet/types.h).
26948         # Since this test about correct packaging we just skip them when
26949         # they don't exist (see below) rather than try to fixup cppflags.
26950
26951         if ! which $CC > /dev/null 2>&1; then
26952                 skip_env "$CC is not installed"
26953         fi
26954
26955         for header in $prefix/*.h; do
26956                 if ! [[ -f "$header" ]]; then
26957                         continue
26958                 fi
26959
26960                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26961                         continue # lustre_ioctl.h is internal header
26962                 fi
26963
26964                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26965                         error "cannot compile '$header'"
26966         done
26967         rm -f $out
26968 }
26969 run_test 400b "packaged headers can be compiled"
26970
26971 test_401a() { #LU-7437
26972         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26973         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26974
26975         #count the number of parameters by "list_param -R"
26976         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26977         #count the number of parameters by listing proc files
26978         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26979         echo "proc_dirs='$proc_dirs'"
26980         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26981         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26982                       sort -u | wc -l)
26983
26984         [ $params -eq $procs ] ||
26985                 error "found $params parameters vs. $procs proc files"
26986
26987         # test the list_param -D option only returns directories
26988         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26989         #count the number of parameters by listing proc directories
26990         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26991                 sort -u | wc -l)
26992
26993         [ $params -eq $procs ] ||
26994                 error "found $params parameters vs. $procs proc files"
26995 }
26996 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26997
26998 test_401b() {
26999         # jobid_var may not allow arbitrary values, so use jobid_name
27000         # if available
27001         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27002                 local testname=jobid_name tmp='testing%p'
27003         else
27004                 local testname=jobid_var tmp=testing
27005         fi
27006
27007         local save=$($LCTL get_param -n $testname)
27008
27009         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27010                 error "no error returned when setting bad parameters"
27011
27012         local jobid_new=$($LCTL get_param -n foe $testname baz)
27013         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27014
27015         $LCTL set_param -n fog=bam $testname=$save bat=fog
27016         local jobid_old=$($LCTL get_param -n foe $testname bag)
27017         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27018 }
27019 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27020
27021 test_401c() {
27022         # jobid_var may not allow arbitrary values, so use jobid_name
27023         # if available
27024         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27025                 local testname=jobid_name
27026         else
27027                 local testname=jobid_var
27028         fi
27029
27030         local jobid_var_old=$($LCTL get_param -n $testname)
27031         local jobid_var_new
27032
27033         $LCTL set_param $testname= &&
27034                 error "no error returned for 'set_param a='"
27035
27036         jobid_var_new=$($LCTL get_param -n $testname)
27037         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27038                 error "$testname was changed by setting without value"
27039
27040         $LCTL set_param $testname &&
27041                 error "no error returned for 'set_param a'"
27042
27043         jobid_var_new=$($LCTL get_param -n $testname)
27044         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27045                 error "$testname was changed by setting without value"
27046 }
27047 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27048
27049 test_401d() {
27050         # jobid_var may not allow arbitrary values, so use jobid_name
27051         # if available
27052         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27053                 local testname=jobid_name new_value='foo=bar%p'
27054         else
27055                 local testname=jobid_var new_valuie=foo=bar
27056         fi
27057
27058         local jobid_var_old=$($LCTL get_param -n $testname)
27059         local jobid_var_new
27060
27061         $LCTL set_param $testname=$new_value ||
27062                 error "'set_param a=b' did not accept a value containing '='"
27063
27064         jobid_var_new=$($LCTL get_param -n $testname)
27065         [[ "$jobid_var_new" == "$new_value" ]] ||
27066                 error "'set_param a=b' failed on a value containing '='"
27067
27068         # Reset the $testname to test the other format
27069         $LCTL set_param $testname=$jobid_var_old
27070         jobid_var_new=$($LCTL get_param -n $testname)
27071         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27072                 error "failed to reset $testname"
27073
27074         $LCTL set_param $testname $new_value ||
27075                 error "'set_param a b' did not accept a value containing '='"
27076
27077         jobid_var_new=$($LCTL get_param -n $testname)
27078         [[ "$jobid_var_new" == "$new_value" ]] ||
27079                 error "'set_param a b' failed on a value containing '='"
27080
27081         $LCTL set_param $testname $jobid_var_old
27082         jobid_var_new=$($LCTL get_param -n $testname)
27083         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27084                 error "failed to reset $testname"
27085 }
27086 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27087
27088 test_401e() { # LU-14779
27089         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27090                 error "lctl list_param MGC* failed"
27091         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27092         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27093                 error "lctl get_param lru_size failed"
27094 }
27095 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27096
27097 test_402() {
27098         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27099         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27100                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27101         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27102                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27103                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27104         remote_mds_nodsh && skip "remote MDS with nodsh"
27105
27106         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27107 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27108         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27109         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27110                 echo "Touch failed - OK"
27111 }
27112 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27113
27114 test_403() {
27115         local file1=$DIR/$tfile.1
27116         local file2=$DIR/$tfile.2
27117         local tfile=$TMP/$tfile
27118
27119         rm -f $file1 $file2 $tfile
27120
27121         touch $file1
27122         ln $file1 $file2
27123
27124         # 30 sec OBD_TIMEOUT in ll_getattr()
27125         # right before populating st_nlink
27126         $LCTL set_param fail_loc=0x80001409
27127         stat -c %h $file1 > $tfile &
27128
27129         # create an alias, drop all locks and reclaim the dentry
27130         < $file2
27131         cancel_lru_locks mdc
27132         cancel_lru_locks osc
27133         sysctl -w vm.drop_caches=2
27134
27135         wait
27136
27137         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27138
27139         rm -f $tfile $file1 $file2
27140 }
27141 run_test 403 "i_nlink should not drop to zero due to aliasing"
27142
27143 test_404() { # LU-6601
27144         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27145                 skip "Need server version newer than 2.8.52"
27146         remote_mds_nodsh && skip "remote MDS with nodsh"
27147
27148         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27149                 awk '/osp .*-osc-MDT/ { print $4}')
27150
27151         local osp
27152         for osp in $mosps; do
27153                 echo "Deactivate: " $osp
27154                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27155                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27156                         awk -vp=$osp '$4 == p { print $2 }')
27157                 [ $stat = IN ] || {
27158                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27159                         error "deactivate error"
27160                 }
27161                 echo "Activate: " $osp
27162                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27163                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27164                         awk -vp=$osp '$4 == p { print $2 }')
27165                 [ $stat = UP ] || {
27166                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27167                         error "activate error"
27168                 }
27169         done
27170 }
27171 run_test 404 "validate manual {de}activated works properly for OSPs"
27172
27173 test_405() {
27174         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27175         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27176                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27177                         skip "Layout swap lock is not supported"
27178
27179         check_swap_layouts_support
27180         check_swap_layout_no_dom $DIR
27181
27182         test_mkdir $DIR/$tdir
27183         swap_lock_test -d $DIR/$tdir ||
27184                 error "One layout swap locked test failed"
27185 }
27186 run_test 405 "Various layout swap lock tests"
27187
27188 test_406() {
27189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27190         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27191         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27193         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27194                 skip "Need MDS version at least 2.8.50"
27195
27196         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27197         local test_pool=$TESTNAME
27198
27199         pool_add $test_pool || error "pool_add failed"
27200         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27201                 error "pool_add_targets failed"
27202
27203         save_layout_restore_at_exit $MOUNT
27204
27205         # parent set default stripe count only, child will stripe from both
27206         # parent and fs default
27207         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27208                 error "setstripe $MOUNT failed"
27209         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27210         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27211         for i in $(seq 10); do
27212                 local f=$DIR/$tdir/$tfile.$i
27213                 touch $f || error "touch failed"
27214                 local count=$($LFS getstripe -c $f)
27215                 [ $count -eq $OSTCOUNT ] ||
27216                         error "$f stripe count $count != $OSTCOUNT"
27217                 local offset=$($LFS getstripe -i $f)
27218                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27219                 local size=$($LFS getstripe -S $f)
27220                 [ $size -eq $((def_stripe_size * 2)) ] ||
27221                         error "$f stripe size $size != $((def_stripe_size * 2))"
27222                 local pool=$($LFS getstripe -p $f)
27223                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27224         done
27225
27226         # change fs default striping, delete parent default striping, now child
27227         # will stripe from new fs default striping only
27228         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27229                 error "change $MOUNT default stripe failed"
27230         $LFS setstripe -c 0 $DIR/$tdir ||
27231                 error "delete $tdir default stripe failed"
27232         for i in $(seq 11 20); do
27233                 local f=$DIR/$tdir/$tfile.$i
27234                 touch $f || error "touch $f failed"
27235                 local count=$($LFS getstripe -c $f)
27236                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27237                 local offset=$($LFS getstripe -i $f)
27238                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27239                 local size=$($LFS getstripe -S $f)
27240                 [ $size -eq $def_stripe_size ] ||
27241                         error "$f stripe size $size != $def_stripe_size"
27242                 local pool=$($LFS getstripe -p $f)
27243                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27244         done
27245
27246         unlinkmany $DIR/$tdir/$tfile. 1 20
27247
27248         local f=$DIR/$tdir/$tfile
27249         pool_remove_all_targets $test_pool $f
27250         pool_remove $test_pool $f
27251 }
27252 run_test 406 "DNE support fs default striping"
27253
27254 test_407() {
27255         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27256         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27257                 skip "Need MDS version at least 2.8.55"
27258         remote_mds_nodsh && skip "remote MDS with nodsh"
27259
27260         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27261                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27262         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27263                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27264         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27265
27266         #define OBD_FAIL_DT_TXN_STOP    0x2019
27267         for idx in $(seq $MDSCOUNT); do
27268                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27269         done
27270         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27271         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27272                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27273         true
27274 }
27275 run_test 407 "transaction fail should cause operation fail"
27276
27277 test_408() {
27278         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27279
27280         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27281         lctl set_param fail_loc=0x8000040a
27282         # let ll_prepare_partial_page() fail
27283         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27284
27285         rm -f $DIR/$tfile
27286
27287         # create at least 100 unused inodes so that
27288         # shrink_icache_memory(0) should not return 0
27289         touch $DIR/$tfile-{0..100}
27290         rm -f $DIR/$tfile-{0..100}
27291         sync
27292
27293         echo 2 > /proc/sys/vm/drop_caches
27294 }
27295 run_test 408 "drop_caches should not hang due to page leaks"
27296
27297 test_409()
27298 {
27299         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27300
27301         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27302         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27303         touch $DIR/$tdir/guard || error "(2) Fail to create"
27304
27305         local PREFIX=$(str_repeat 'A' 128)
27306         echo "Create 1K hard links start at $(date)"
27307         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27308                 error "(3) Fail to hard link"
27309
27310         echo "Links count should be right although linkEA overflow"
27311         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27312         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27313         [ $linkcount -eq 1001 ] ||
27314                 error "(5) Unexpected hard links count: $linkcount"
27315
27316         echo "List all links start at $(date)"
27317         ls -l $DIR/$tdir/foo > /dev/null ||
27318                 error "(6) Fail to list $DIR/$tdir/foo"
27319
27320         echo "Unlink hard links start at $(date)"
27321         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27322                 error "(7) Fail to unlink"
27323         echo "Unlink hard links finished at $(date)"
27324 }
27325 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27326
27327 test_410()
27328 {
27329         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27330                 skip "Need client version at least 2.9.59"
27331         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27332                 skip "Need MODULES build"
27333
27334         # Create a file, and stat it from the kernel
27335         local testfile=$DIR/$tfile
27336         touch $testfile
27337
27338         local run_id=$RANDOM
27339         local my_ino=$(stat --format "%i" $testfile)
27340
27341         # Try to insert the module. This will always fail as the
27342         # module is designed to not be inserted.
27343         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27344             &> /dev/null
27345
27346         # Anything but success is a test failure
27347         dmesg | grep -q \
27348             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27349             error "no inode match"
27350 }
27351 run_test 410 "Test inode number returned from kernel thread"
27352
27353 cleanup_test411_cgroup() {
27354         trap 0
27355         rmdir "$1"
27356 }
27357
27358 test_411() {
27359         local cg_basedir=/sys/fs/cgroup/memory
27360         # LU-9966
27361         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27362                 skip "no setup for cgroup"
27363
27364         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27365                 error "test file creation failed"
27366         cancel_lru_locks osc
27367
27368         # Create a very small memory cgroup to force a slab allocation error
27369         local cgdir=$cg_basedir/osc_slab_alloc
27370         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27371         trap "cleanup_test411_cgroup $cgdir" EXIT
27372         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27373         echo 1M > $cgdir/memory.limit_in_bytes
27374
27375         # Should not LBUG, just be killed by oom-killer
27376         # dd will return 0 even allocation failure in some environment.
27377         # So don't check return value
27378         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27379         cleanup_test411_cgroup $cgdir
27380
27381         return 0
27382 }
27383 run_test 411 "Slab allocation error with cgroup does not LBUG"
27384
27385 test_412() {
27386         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27387         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27388                 skip "Need server version at least 2.10.55"
27389
27390         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27391                 error "mkdir failed"
27392         $LFS getdirstripe $DIR/$tdir
27393         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27394         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27395                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27396         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27397         [ $stripe_count -eq 2 ] ||
27398                 error "expect 2 get $stripe_count"
27399
27400         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27401
27402         local index
27403         local index2
27404
27405         # subdirs should be on the same MDT as parent
27406         for i in $(seq 0 $((MDSCOUNT - 1))); do
27407                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27408                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27409                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27410                 (( index == i )) || error "mdt$i/sub on MDT$index"
27411         done
27412
27413         # stripe offset -1, ditto
27414         for i in {1..10}; do
27415                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27416                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27417                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27418                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27419                 (( index == index2 )) ||
27420                         error "qos$i on MDT$index, sub on MDT$index2"
27421         done
27422
27423         local testdir=$DIR/$tdir/inherit
27424
27425         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27426         # inherit 2 levels
27427         for i in 1 2; do
27428                 testdir=$testdir/s$i
27429                 mkdir $testdir || error "mkdir $testdir failed"
27430                 index=$($LFS getstripe -m $testdir)
27431                 (( index == 1 )) ||
27432                         error "$testdir on MDT$index"
27433         done
27434
27435         # not inherit any more
27436         testdir=$testdir/s3
27437         mkdir $testdir || error "mkdir $testdir failed"
27438         getfattr -d -m dmv $testdir | grep dmv &&
27439                 error "default LMV set on $testdir" || true
27440 }
27441 run_test 412 "mkdir on specific MDTs"
27442
27443 TEST413_COUNT=${TEST413_COUNT:-200}
27444
27445 #
27446 # set_maxage() is used by test_413 only.
27447 # This is a helper function to set maxage. Does not return any value.
27448 # Input: maxage to set
27449 #
27450 set_maxage() {
27451         local lmv_qos_maxage
27452         local lod_qos_maxage
27453         local new_maxage=$1
27454
27455         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27456         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27457         stack_trap "$LCTL set_param \
27458                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27459         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27460                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27461         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27462                 lod.*.mdt_qos_maxage=$new_maxage
27463         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27464                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27465 }
27466
27467 generate_uneven_mdts() {
27468         local threshold=$1
27469         local ffree
27470         local bavail
27471         local max
27472         local min
27473         local max_index
27474         local min_index
27475         local tmp
27476         local i
27477
27478         echo
27479         echo "Check for uneven MDTs: "
27480
27481         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27482         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27483         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27484
27485         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27486         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27487         max_index=0
27488         min_index=0
27489         for ((i = 1; i < ${#ffree[@]}; i++)); do
27490                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27491                 if [ $tmp -gt $max ]; then
27492                         max=$tmp
27493                         max_index=$i
27494                 fi
27495                 if [ $tmp -lt $min ]; then
27496                         min=$tmp
27497                         min_index=$i
27498                 fi
27499         done
27500
27501         (( min > 0 )) || skip "low space on MDT$min_index"
27502         (( ${ffree[min_index]} > 0 )) ||
27503                 skip "no free files on MDT$min_index"
27504         (( ${ffree[min_index]} < 10000000 )) ||
27505                 skip "too many free files on MDT$min_index"
27506
27507         # Check if we need to generate uneven MDTs
27508         local diff=$(((max - min) * 100 / min))
27509         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27510         local testdir # individual folder within $testdirp
27511         local start
27512         local cmd
27513
27514         # fallocate is faster to consume space on MDT, if available
27515         if check_fallocate_supported mds$((min_index + 1)); then
27516                 cmd="fallocate -l 128K "
27517         else
27518                 cmd="dd if=/dev/zero bs=128K count=1 of="
27519         fi
27520
27521         echo "using cmd $cmd"
27522         for (( i = 0; diff < threshold; i++ )); do
27523                 testdir=${testdirp}/$i
27524                 [ -d $testdir ] && continue
27525
27526                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27527
27528                 mkdir -p $testdirp
27529                 # generate uneven MDTs, create till $threshold% diff
27530                 echo -n "weight diff=$diff% must be > $threshold% ..."
27531                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27532                 $LFS mkdir -i $min_index $testdir ||
27533                         error "mkdir $testdir failed"
27534                 $LFS setstripe -E 1M -L mdt $testdir ||
27535                         error "setstripe $testdir failed"
27536                 start=$SECONDS
27537                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27538                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27539                 done
27540                 sync; sleep 1; sync
27541
27542                 # wait for QOS to update
27543                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27544
27545                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27546                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27547                 max=$(((${ffree[max_index]} >> 8) *
27548                         (${bavail[max_index]} * bsize >> 16)))
27549                 min=$(((${ffree[min_index]} >> 8) *
27550                         (${bavail[min_index]} * bsize >> 16)))
27551                 (( min > 0 )) || skip "low space on MDT$min_index"
27552                 diff=$(((max - min) * 100 / min))
27553         done
27554
27555         echo "MDT filesfree available: ${ffree[*]}"
27556         echo "MDT blocks available: ${bavail[*]}"
27557         echo "weight diff=$diff%"
27558 }
27559
27560 test_qos_mkdir() {
27561         local mkdir_cmd=$1
27562         local stripe_count=$2
27563         local mdts=$(comma_list $(mdts_nodes))
27564
27565         local testdir
27566         local lmv_qos_prio_free
27567         local lmv_qos_threshold_rr
27568         local lod_qos_prio_free
27569         local lod_qos_threshold_rr
27570         local total
27571         local count
27572         local i
27573
27574         # @total is total directories created if it's testing plain
27575         # directories, otherwise it's total stripe object count for
27576         # striped directories test.
27577         # remote/striped directory unlinking is slow on zfs and may
27578         # timeout, test with fewer directories
27579         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27580
27581         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27582         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27583         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27584                 head -n1)
27585         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27586         stack_trap "$LCTL set_param \
27587                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27588         stack_trap "$LCTL set_param \
27589                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27590
27591         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27592                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27593         lod_qos_prio_free=${lod_qos_prio_free%%%}
27594         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27595                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27596         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27597         stack_trap "do_nodes $mdts $LCTL set_param \
27598                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27599         stack_trap "do_nodes $mdts $LCTL set_param \
27600                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27601
27602         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27603         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27604
27605         testdir=$DIR/$tdir-s$stripe_count/rr
27606
27607         local stripe_index=$($LFS getstripe -m $testdir)
27608         local test_mkdir_rr=true
27609
27610         getfattr -d -m dmv -e hex $testdir | grep dmv
27611         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27612                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27613                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27614                         test_mkdir_rr=false
27615         fi
27616
27617         echo
27618         $test_mkdir_rr &&
27619                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27620                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27621
27622         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27623         for (( i = 0; i < total / stripe_count; i++ )); do
27624                 eval $mkdir_cmd $testdir/subdir$i ||
27625                         error "$mkdir_cmd subdir$i failed"
27626         done
27627
27628         for (( i = 0; i < $MDSCOUNT; i++ )); do
27629                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27630                 echo "$count directories created on MDT$i"
27631                 if $test_mkdir_rr; then
27632                         (( count == total / stripe_count / MDSCOUNT )) ||
27633                                 error "subdirs are not evenly distributed"
27634                 elif (( i == stripe_index )); then
27635                         (( count == total / stripe_count )) ||
27636                                 error "$count subdirs created on MDT$i"
27637                 else
27638                         (( count == 0 )) ||
27639                                 error "$count subdirs created on MDT$i"
27640                 fi
27641
27642                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27643                         count=$($LFS getdirstripe $testdir/* |
27644                                 grep -c -P "^\s+$i\t")
27645                         echo "$count stripes created on MDT$i"
27646                         # deviation should < 5% of average
27647                         delta=$((count - total / MDSCOUNT))
27648                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27649                                 error "stripes are not evenly distributed"
27650                 fi
27651         done
27652
27653         echo
27654         echo "Check for uneven MDTs: "
27655
27656         local ffree
27657         local bavail
27658         local max
27659         local min
27660         local max_index
27661         local min_index
27662         local tmp
27663
27664         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27665         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27666         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27667
27668         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27669         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27670         max_index=0
27671         min_index=0
27672         for ((i = 1; i < ${#ffree[@]}; i++)); do
27673                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27674                 if [ $tmp -gt $max ]; then
27675                         max=$tmp
27676                         max_index=$i
27677                 fi
27678                 if [ $tmp -lt $min ]; then
27679                         min=$tmp
27680                         min_index=$i
27681                 fi
27682         done
27683         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27684
27685         (( min > 0 )) || skip "low space on MDT$min_index"
27686         (( ${ffree[min_index]} < 10000000 )) ||
27687                 skip "too many free files on MDT$min_index"
27688
27689         generate_uneven_mdts 120
27690
27691         echo "MDT filesfree available: ${ffree[*]}"
27692         echo "MDT blocks available: ${bavail[*]}"
27693         echo "weight diff=$(((max - min) * 100 / min))%"
27694         echo
27695         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27696
27697         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27698         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27699         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27700         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27701         # decrease statfs age, so that it can be updated in time
27702         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27703         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27704
27705         sleep 1
27706
27707         testdir=$DIR/$tdir-s$stripe_count/qos
27708
27709         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27710         for (( i = 0; i < total / stripe_count; i++ )); do
27711                 eval $mkdir_cmd $testdir/subdir$i ||
27712                         error "$mkdir_cmd subdir$i failed"
27713         done
27714
27715         max=0
27716         for (( i = 0; i < $MDSCOUNT; i++ )); do
27717                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27718                 (( count > max )) && max=$count
27719                 echo "$count directories created on MDT$i : curmax=$max"
27720         done
27721
27722         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27723
27724         # D-value should > 10% of average
27725         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27726                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27727
27728         # ditto for stripes
27729         if (( stripe_count > 1 )); then
27730                 max=0
27731                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27732                         count=$($LFS getdirstripe $testdir/* |
27733                                 grep -c -P "^\s+$i\t")
27734                         (( count > max )) && max=$count
27735                         echo "$count stripes created on MDT$i"
27736                 done
27737
27738                 min=$($LFS getdirstripe $testdir/* |
27739                         grep -c -P "^\s+$min_index\t")
27740                 (( max - min > total / MDSCOUNT / 10 )) ||
27741                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27742         fi
27743 }
27744
27745 most_full_mdt() {
27746         local ffree
27747         local bavail
27748         local bsize
27749         local min
27750         local min_index
27751         local tmp
27752
27753         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27754         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27755         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27756
27757         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27758         min_index=0
27759         for ((i = 1; i < ${#ffree[@]}; i++)); do
27760                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27761                 (( tmp < min )) && min=$tmp && min_index=$i
27762         done
27763
27764         echo -n $min_index
27765 }
27766
27767 test_413a() {
27768         [ $MDSCOUNT -lt 2 ] &&
27769                 skip "We need at least 2 MDTs for this test"
27770
27771         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27772                 skip "Need server version at least 2.12.52"
27773
27774         local stripe_max=$((MDSCOUNT - 1))
27775         local stripe_count
27776
27777         # let caller set maxage for latest result
27778         set_maxage 1
27779
27780         # fill MDT unevenly
27781         generate_uneven_mdts 120
27782
27783         # test 4-stripe directory at most, otherwise it's too slow
27784         # We are being very defensive. Although Autotest uses 4 MDTs.
27785         # We make sure stripe_max does not go over 4.
27786         (( stripe_max > 4 )) && stripe_max=4
27787         # unlinking striped directory is slow on zfs, and may timeout, only test
27788         # plain directory
27789         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27790         for stripe_count in $(seq 1 $stripe_max); do
27791                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27792                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27793                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27794                         error "mkdir failed"
27795                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27796         done
27797 }
27798 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27799
27800 test_413b() {
27801         [ $MDSCOUNT -lt 2 ] &&
27802                 skip "We need at least 2 MDTs for this test"
27803
27804         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27805                 skip "Need server version at least 2.12.52"
27806
27807         local stripe_max=$((MDSCOUNT - 1))
27808         local testdir
27809         local stripe_count
27810
27811         # let caller set maxage for latest result
27812         set_maxage 1
27813
27814         # fill MDT unevenly
27815         generate_uneven_mdts 120
27816
27817         # test 4-stripe directory at most, otherwise it's too slow
27818         # We are being very defensive. Although Autotest uses 4 MDTs.
27819         # We make sure stripe_max does not go over 4.
27820         (( stripe_max > 4 )) && stripe_max=4
27821         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27822         for stripe_count in $(seq 1 $stripe_max); do
27823                 testdir=$DIR/$tdir-s$stripe_count
27824                 mkdir $testdir || error "mkdir $testdir failed"
27825                 mkdir $testdir/rr || error "mkdir rr failed"
27826                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27827                         error "mkdir qos failed"
27828                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27829                         $testdir/rr || error "setdirstripe rr failed"
27830                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27831                         error "setdirstripe failed"
27832                 test_qos_mkdir "mkdir" $stripe_count
27833         done
27834 }
27835 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27836
27837 test_413c() {
27838         (( $MDSCOUNT >= 2 )) ||
27839                 skip "We need at least 2 MDTs for this test"
27840
27841         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27842                 skip "Need server version at least 2.14.51"
27843
27844         local testdir
27845         local inherit
27846         local inherit_rr
27847         local lmv_qos_maxage
27848         local lod_qos_maxage
27849
27850         # let caller set maxage for latest result
27851         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27852         $LCTL set_param lmv.*.qos_maxage=1
27853         stack_trap "$LCTL set_param \
27854                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27855         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27856                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27857         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27858                 lod.*.mdt_qos_maxage=1
27859         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27860                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27861
27862         # fill MDT unevenly
27863         generate_uneven_mdts 120
27864
27865         testdir=$DIR/${tdir}-s1
27866         mkdir $testdir || error "mkdir $testdir failed"
27867         mkdir $testdir/rr || error "mkdir rr failed"
27868         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27869         # default max_inherit is -1, default max_inherit_rr is 0
27870         $LFS setdirstripe -D -c 1 $testdir/rr ||
27871                 error "setdirstripe rr failed"
27872         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27873                 error "setdirstripe qos failed"
27874         test_qos_mkdir "mkdir" 1
27875
27876         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27877         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27878         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27879         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27880         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27881
27882         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27883         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27884         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27885         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27886         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27887         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27888         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27889                 error "level2 shouldn't have default LMV" || true
27890 }
27891 run_test 413c "mkdir with default LMV max inherit rr"
27892
27893 test_413d() {
27894         (( MDSCOUNT >= 2 )) ||
27895                 skip "We need at least 2 MDTs for this test"
27896
27897         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27898                 skip "Need server version at least 2.14.51"
27899
27900         local lmv_qos_threshold_rr
27901
27902         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27903                 head -n1)
27904         stack_trap "$LCTL set_param \
27905                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27906
27907         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27908         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27909         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27910                 error "$tdir shouldn't have default LMV"
27911         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27912                 error "mkdir sub failed"
27913
27914         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27915
27916         (( count == 100 )) || error "$count subdirs on MDT0"
27917 }
27918 run_test 413d "inherit ROOT default LMV"
27919
27920 test_413e() {
27921         (( MDSCOUNT >= 2 )) ||
27922                 skip "We need at least 2 MDTs for this test"
27923         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27924                 skip "Need server version at least 2.14.55"
27925
27926         local testdir=$DIR/$tdir
27927         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27928         local max_inherit
27929         local sub_max_inherit
27930
27931         mkdir -p $testdir || error "failed to create $testdir"
27932
27933         # set default max-inherit to -1 if stripe count is 0 or 1
27934         $LFS setdirstripe -D -c 1 $testdir ||
27935                 error "failed to set default LMV"
27936         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27937         (( max_inherit == -1 )) ||
27938                 error "wrong max_inherit value $max_inherit"
27939
27940         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27941         $LFS setdirstripe -D -c -1 $testdir ||
27942                 error "failed to set default LMV"
27943         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27944         (( max_inherit > 0 )) ||
27945                 error "wrong max_inherit value $max_inherit"
27946
27947         # and the subdir will decrease the max_inherit by 1
27948         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27949         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27950         (( sub_max_inherit == max_inherit - 1)) ||
27951                 error "wrong max-inherit of subdir $sub_max_inherit"
27952
27953         # check specified --max-inherit and warning message
27954         stack_trap "rm -f $tmpfile"
27955         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27956                 error "failed to set default LMV"
27957         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27958         (( max_inherit == -1 )) ||
27959                 error "wrong max_inherit value $max_inherit"
27960
27961         # check the warning messages
27962         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27963                 error "failed to detect warning string"
27964         fi
27965 }
27966 run_test 413e "check default max-inherit value"
27967
27968 test_fs_dmv_inherit()
27969 {
27970         local testdir=$DIR/$tdir
27971
27972         local count
27973         local inherit
27974         local inherit_rr
27975
27976         for i in 1 2; do
27977                 mkdir $testdir || error "mkdir $testdir failed"
27978                 count=$($LFS getdirstripe -D -c $testdir)
27979                 (( count == 1 )) ||
27980                         error "$testdir default LMV count mismatch $count != 1"
27981                 inherit=$($LFS getdirstripe -D -X $testdir)
27982                 (( inherit == 3 - i )) ||
27983                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27984                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27985                 (( inherit_rr == 3 - i )) ||
27986                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27987                 testdir=$testdir/sub
27988         done
27989
27990         mkdir $testdir || error "mkdir $testdir failed"
27991         count=$($LFS getdirstripe -D -c $testdir)
27992         (( count == 0 )) ||
27993                 error "$testdir default LMV count not zero: $count"
27994 }
27995
27996 test_413f() {
27997         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27998
27999         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28000                 skip "Need server version at least 2.14.55"
28001
28002         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28003                 error "dump $DIR default LMV failed"
28004         stack_trap "setfattr --restore=$TMP/dmv.ea"
28005
28006         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28007                 error "set $DIR default LMV failed"
28008
28009         test_fs_dmv_inherit
28010 }
28011 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28012
28013 test_413g() {
28014         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28015
28016         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28017         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28018                 error "dump $DIR default LMV failed"
28019         stack_trap "setfattr --restore=$TMP/dmv.ea"
28020
28021         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28022                 error "set $DIR default LMV failed"
28023
28024         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28025                 error "mount $MOUNT2 failed"
28026         stack_trap "umount_client $MOUNT2"
28027
28028         local saved_DIR=$DIR
28029
28030         export DIR=$MOUNT2
28031
28032         stack_trap "export DIR=$saved_DIR"
28033
28034         # first check filesystem-wide default LMV inheritance
28035         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28036
28037         # then check subdirs are spread to all MDTs
28038         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28039
28040         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28041
28042         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28043 }
28044 run_test 413g "enforce ROOT default LMV on subdir mount"
28045
28046 test_413h() {
28047         (( MDSCOUNT >= 2 )) ||
28048                 skip "We need at least 2 MDTs for this test"
28049
28050         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28051                 skip "Need server version at least 2.15.50.6"
28052
28053         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28054
28055         stack_trap "$LCTL set_param \
28056                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28057         $LCTL set_param lmv.*.qos_maxage=1
28058
28059         local depth=5
28060         local rr_depth=4
28061         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28062         local count=$((MDSCOUNT * 20))
28063
28064         generate_uneven_mdts 50
28065
28066         mkdir -p $dir || error "mkdir $dir failed"
28067         stack_trap "rm -rf $dir"
28068         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28069                 --max-inherit-rr=$rr_depth $dir
28070
28071         for ((d=0; d < depth + 2; d++)); do
28072                 log "dir=$dir:"
28073                 for ((sub=0; sub < count; sub++)); do
28074                         mkdir $dir/d$sub
28075                 done
28076                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28077                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28078                 # subdirs within $rr_depth should be created round-robin
28079                 if (( d < rr_depth )); then
28080                         (( ${num[0]} != count )) ||
28081                                 error "all objects created on MDT ${num[1]}"
28082                 fi
28083
28084                 dir=$dir/d0
28085         done
28086 }
28087 run_test 413h "don't stick to parent for round-robin dirs"
28088
28089 test_413i() {
28090         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28091
28092         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28093                 skip "Need server version at least 2.14.55"
28094
28095         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28096                 error "dump $DIR default LMV failed"
28097         stack_trap "setfattr --restore=$TMP/dmv.ea"
28098
28099         local testdir=$DIR/$tdir
28100         local def_max_rr=1
28101         local def_max=3
28102         local count
28103
28104         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28105                 --max-inherit-rr=$def_max_rr $DIR ||
28106                 error "set $DIR default LMV failed"
28107
28108         for i in $(seq 2 3); do
28109                 def_max=$((def_max - 1))
28110                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28111
28112                 mkdir $testdir
28113                 # RR is decremented and keeps zeroed once exhausted
28114                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28115                 (( count == def_max_rr )) ||
28116                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28117
28118                 # max-inherit is decremented
28119                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28120                 (( count == def_max )) ||
28121                         error_noexit "$testdir: max-inherit $count != $def_max"
28122
28123                 testdir=$testdir/d$i
28124         done
28125
28126         # d3 is the last inherited from ROOT, no inheritance anymore
28127         # i.e. no the default layout anymore
28128         mkdir -p $testdir/d4/d5
28129         count=$($LFS getdirstripe -D --max-inherit $testdir)
28130         (( count == -1 )) ||
28131                 error_noexit "$testdir: max-inherit $count != -1"
28132
28133         local p_count=$($LFS getdirstripe -i $testdir)
28134
28135         for i in $(seq 4 5); do
28136                 testdir=$testdir/d$i
28137
28138                 # the root default layout is not applied once exhausted
28139                 count=$($LFS getdirstripe -i $testdir)
28140                 (( count == p_count )) ||
28141                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28142         done
28143
28144         $LFS setdirstripe -i 0 $DIR/d2
28145         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28146         (( count == -1 )) ||
28147                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28148 }
28149 run_test 413i "check default layout inheritance"
28150
28151 test_413z() {
28152         local pids=""
28153         local subdir
28154         local pid
28155
28156         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28157                 unlinkmany $subdir/f. $TEST413_COUNT &
28158                 pids="$pids $!"
28159         done
28160
28161         for pid in $pids; do
28162                 wait $pid
28163         done
28164
28165         true
28166 }
28167 run_test 413z "413 test cleanup"
28168
28169 test_414() {
28170 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28171         $LCTL set_param fail_loc=0x80000521
28172         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28173         rm -f $DIR/$tfile
28174 }
28175 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28176
28177 test_415() {
28178         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28179         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28180                 skip "Need server version at least 2.11.52"
28181
28182         # LU-11102
28183         local total=500
28184         local max=120
28185
28186         # this test may be slow on ZFS
28187         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28188
28189         # though this test is designed for striped directory, let's test normal
28190         # directory too since lock is always saved as CoS lock.
28191         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28192         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28193         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28194         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28195         wait_delete_completed_mds
28196
28197         # run a loop without concurrent touch to measure rename duration.
28198         # only for test debug/robustness, NOT part of COS functional test.
28199         local start_time=$SECONDS
28200         for ((i = 0; i < total; i++)); do
28201                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28202                         > /dev/null
28203         done
28204         local baseline=$((SECONDS - start_time))
28205         echo "rename $total files without 'touch' took $baseline sec"
28206
28207         (
28208                 while true; do
28209                         touch $DIR/$tdir
28210                 done
28211         ) &
28212         local setattr_pid=$!
28213
28214         # rename files back to original name so unlinkmany works
28215         start_time=$SECONDS
28216         for ((i = 0; i < total; i++)); do
28217                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28218                         > /dev/null
28219         done
28220         local duration=$((SECONDS - start_time))
28221
28222         kill -9 $setattr_pid
28223
28224         echo "rename $total files with 'touch' took $duration sec"
28225         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28226         (( duration <= max )) ||
28227                 error_not_in_vm "rename took $duration > $max sec"
28228 }
28229 run_test 415 "lock revoke is not missing"
28230
28231 test_416() {
28232         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28233                 skip "Need server version at least 2.11.55"
28234
28235         # define OBD_FAIL_OSD_TXN_START    0x19a
28236         do_facet mds1 lctl set_param fail_loc=0x19a
28237
28238         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28239
28240         true
28241 }
28242 run_test 416 "transaction start failure won't cause system hung"
28243
28244 cleanup_417() {
28245         trap 0
28246         do_nodes $(comma_list $(mdts_nodes)) \
28247                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28248         do_nodes $(comma_list $(mdts_nodes)) \
28249                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28250         do_nodes $(comma_list $(mdts_nodes)) \
28251                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28252 }
28253
28254 test_417() {
28255         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28256         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28257                 skip "Need MDS version at least 2.11.56"
28258
28259         trap cleanup_417 RETURN EXIT
28260
28261         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28262         do_nodes $(comma_list $(mdts_nodes)) \
28263                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28264         $LFS migrate -m 0 $DIR/$tdir.1 &&
28265                 error "migrate dir $tdir.1 should fail"
28266
28267         do_nodes $(comma_list $(mdts_nodes)) \
28268                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28269         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28270                 error "create remote dir $tdir.2 should fail"
28271
28272         do_nodes $(comma_list $(mdts_nodes)) \
28273                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28274         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28275                 error "create striped dir $tdir.3 should fail"
28276         true
28277 }
28278 run_test 417 "disable remote dir, striped dir and dir migration"
28279
28280 # Checks that the outputs of df [-i] and lfs df [-i] match
28281 #
28282 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28283 check_lfs_df() {
28284         local dir=$2
28285         local inodes
28286         local df_out
28287         local lfs_df_out
28288         local count
28289         local passed=false
28290
28291         # blocks or inodes
28292         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28293
28294         for count in {1..100}; do
28295                 do_nodes "$CLIENTS" \
28296                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28297                 sync; sleep 0.2
28298
28299                 # read the lines of interest
28300                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28301                         error "df $inodes $dir | tail -n +2 failed"
28302                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28303                         error "lfs df $inodes $dir | grep summary: failed"
28304
28305                 # skip first substrings of each output as they are different
28306                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28307                 # compare the two outputs
28308                 passed=true
28309                 #  skip "available" on MDT until LU-13997 is fixed.
28310                 #for i in {1..5}; do
28311                 for i in 1 2 4 5; do
28312                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28313                 done
28314                 $passed && break
28315         done
28316
28317         if ! $passed; then
28318                 df -P $inodes $dir
28319                 echo
28320                 lfs df $inodes $dir
28321                 error "df and lfs df $1 output mismatch: "      \
28322                       "df ${inodes}: ${df_out[*]}, "            \
28323                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28324         fi
28325 }
28326
28327 test_418() {
28328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28329
28330         local dir=$DIR/$tdir
28331         local numfiles=$((RANDOM % 4096 + 2))
28332         local numblocks=$((RANDOM % 256 + 1))
28333
28334         wait_delete_completed
28335         test_mkdir $dir
28336
28337         # check block output
28338         check_lfs_df blocks $dir
28339         # check inode output
28340         check_lfs_df inodes $dir
28341
28342         # create a single file and retest
28343         echo "Creating a single file and testing"
28344         createmany -o $dir/$tfile- 1 &>/dev/null ||
28345                 error "creating 1 file in $dir failed"
28346         check_lfs_df blocks $dir
28347         check_lfs_df inodes $dir
28348
28349         # create a random number of files
28350         echo "Creating $((numfiles - 1)) files and testing"
28351         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28352                 error "creating $((numfiles - 1)) files in $dir failed"
28353
28354         # write a random number of blocks to the first test file
28355         echo "Writing $numblocks 4K blocks and testing"
28356         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28357                 count=$numblocks &>/dev/null ||
28358                 error "dd to $dir/${tfile}-0 failed"
28359
28360         # retest
28361         check_lfs_df blocks $dir
28362         check_lfs_df inodes $dir
28363
28364         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28365                 error "unlinking $numfiles files in $dir failed"
28366 }
28367 run_test 418 "df and lfs df outputs match"
28368
28369 test_419()
28370 {
28371         local dir=$DIR/$tdir
28372
28373         mkdir -p $dir
28374         touch $dir/file
28375
28376         cancel_lru_locks mdc
28377
28378         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28379         $LCTL set_param fail_loc=0x1410
28380         cat $dir/file
28381         $LCTL set_param fail_loc=0
28382         rm -rf $dir
28383 }
28384 run_test 419 "Verify open file by name doesn't crash kernel"
28385
28386 test_420()
28387 {
28388         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28389                 skip "Need MDS version at least 2.12.53"
28390
28391         local SAVE_UMASK=$(umask)
28392         local dir=$DIR/$tdir
28393         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28394
28395         mkdir -p $dir
28396         umask 0000
28397         mkdir -m03777 $dir/testdir
28398         ls -dn $dir/testdir
28399         # Need to remove trailing '.' when SELinux is enabled
28400         local dirperms=$(ls -dn $dir/testdir |
28401                          awk '{ sub(/\.$/, "", $1); print $1}')
28402         [ $dirperms == "drwxrwsrwt" ] ||
28403                 error "incorrect perms on $dir/testdir"
28404
28405         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28406                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28407         ls -n $dir/testdir/testfile
28408         local fileperms=$(ls -n $dir/testdir/testfile |
28409                           awk '{ sub(/\.$/, "", $1); print $1}')
28410         [ $fileperms == "-rwxr-xr-x" ] ||
28411                 error "incorrect perms on $dir/testdir/testfile"
28412
28413         umask $SAVE_UMASK
28414 }
28415 run_test 420 "clear SGID bit on non-directories for non-members"
28416
28417 test_421a() {
28418         local cnt
28419         local fid1
28420         local fid2
28421
28422         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28423                 skip "Need MDS version at least 2.12.54"
28424
28425         test_mkdir $DIR/$tdir
28426         createmany -o $DIR/$tdir/f 3
28427         cnt=$(ls -1 $DIR/$tdir | wc -l)
28428         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28429
28430         fid1=$(lfs path2fid $DIR/$tdir/f1)
28431         fid2=$(lfs path2fid $DIR/$tdir/f2)
28432         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28433
28434         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28435         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28436
28437         cnt=$(ls -1 $DIR/$tdir | wc -l)
28438         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28439
28440         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28441         createmany -o $DIR/$tdir/f 3
28442         cnt=$(ls -1 $DIR/$tdir | wc -l)
28443         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28444
28445         fid1=$(lfs path2fid $DIR/$tdir/f1)
28446         fid2=$(lfs path2fid $DIR/$tdir/f2)
28447         echo "remove using fsname $FSNAME"
28448         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28449
28450         cnt=$(ls -1 $DIR/$tdir | wc -l)
28451         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28452 }
28453 run_test 421a "simple rm by fid"
28454
28455 test_421b() {
28456         local cnt
28457         local FID1
28458         local FID2
28459
28460         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28461                 skip "Need MDS version at least 2.12.54"
28462
28463         test_mkdir $DIR/$tdir
28464         createmany -o $DIR/$tdir/f 3
28465         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28466         MULTIPID=$!
28467
28468         FID1=$(lfs path2fid $DIR/$tdir/f1)
28469         FID2=$(lfs path2fid $DIR/$tdir/f2)
28470         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28471
28472         kill -USR1 $MULTIPID
28473         wait
28474
28475         cnt=$(ls $DIR/$tdir | wc -l)
28476         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28477 }
28478 run_test 421b "rm by fid on open file"
28479
28480 test_421c() {
28481         local cnt
28482         local FIDS
28483
28484         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28485                 skip "Need MDS version at least 2.12.54"
28486
28487         test_mkdir $DIR/$tdir
28488         createmany -o $DIR/$tdir/f 3
28489         touch $DIR/$tdir/$tfile
28490         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28491         cnt=$(ls -1 $DIR/$tdir | wc -l)
28492         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28493
28494         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28495         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28496
28497         cnt=$(ls $DIR/$tdir | wc -l)
28498         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28499 }
28500 run_test 421c "rm by fid against hardlinked files"
28501
28502 test_421d() {
28503         local cnt
28504         local FIDS
28505
28506         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28507                 skip "Need MDS version at least 2.12.54"
28508
28509         test_mkdir $DIR/$tdir
28510         createmany -o $DIR/$tdir/f 4097
28511         cnt=$(ls -1 $DIR/$tdir | wc -l)
28512         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28513
28514         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28515         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28516
28517         cnt=$(ls $DIR/$tdir | wc -l)
28518         rm -rf $DIR/$tdir
28519         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28520 }
28521 run_test 421d "rmfid en masse"
28522
28523 test_421e() {
28524         local cnt
28525         local FID
28526
28527         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28528         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28529                 skip "Need MDS version at least 2.12.54"
28530
28531         mkdir -p $DIR/$tdir
28532         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28533         createmany -o $DIR/$tdir/striped_dir/f 512
28534         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28535         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28536
28537         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28538                 sed "s/[/][^:]*://g")
28539         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28540
28541         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28542         rm -rf $DIR/$tdir
28543         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28544 }
28545 run_test 421e "rmfid in DNE"
28546
28547 test_421f() {
28548         local cnt
28549         local FID
28550
28551         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28552                 skip "Need MDS version at least 2.12.54"
28553
28554         test_mkdir $DIR/$tdir
28555         touch $DIR/$tdir/f
28556         cnt=$(ls -1 $DIR/$tdir | wc -l)
28557         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28558
28559         FID=$(lfs path2fid $DIR/$tdir/f)
28560         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28561         # rmfid should fail
28562         cnt=$(ls -1 $DIR/$tdir | wc -l)
28563         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28564
28565         chmod a+rw $DIR/$tdir
28566         ls -la $DIR/$tdir
28567         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28568         # rmfid should fail
28569         cnt=$(ls -1 $DIR/$tdir | wc -l)
28570         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28571
28572         rm -f $DIR/$tdir/f
28573         $RUNAS touch $DIR/$tdir/f
28574         FID=$(lfs path2fid $DIR/$tdir/f)
28575         echo "rmfid as root"
28576         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28577         cnt=$(ls -1 $DIR/$tdir | wc -l)
28578         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28579
28580         rm -f $DIR/$tdir/f
28581         $RUNAS touch $DIR/$tdir/f
28582         cnt=$(ls -1 $DIR/$tdir | wc -l)
28583         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28584         FID=$(lfs path2fid $DIR/$tdir/f)
28585         # rmfid w/o user_fid2path mount option should fail
28586         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28587         cnt=$(ls -1 $DIR/$tdir | wc -l)
28588         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28589
28590         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28591         stack_trap "rmdir $tmpdir"
28592         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28593                 error "failed to mount client'"
28594         stack_trap "umount_client $tmpdir"
28595
28596         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28597         # rmfid should succeed
28598         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28599         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28600
28601         # rmfid shouldn't allow to remove files due to dir's permission
28602         chmod a+rwx $tmpdir/$tdir
28603         touch $tmpdir/$tdir/f
28604         ls -la $tmpdir/$tdir
28605         FID=$(lfs path2fid $tmpdir/$tdir/f)
28606         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28607         return 0
28608 }
28609 run_test 421f "rmfid checks permissions"
28610
28611 test_421g() {
28612         local cnt
28613         local FIDS
28614
28615         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28616         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28617                 skip "Need MDS version at least 2.12.54"
28618
28619         mkdir -p $DIR/$tdir
28620         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28621         createmany -o $DIR/$tdir/striped_dir/f 512
28622         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28623         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28624
28625         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28626                 sed "s/[/][^:]*://g")
28627
28628         rm -f $DIR/$tdir/striped_dir/f1*
28629         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28630         removed=$((512 - cnt))
28631
28632         # few files have been just removed, so we expect
28633         # rmfid to fail on their fids
28634         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28635         [ $removed != $errors ] && error "$errors != $removed"
28636
28637         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28638         rm -rf $DIR/$tdir
28639         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28640 }
28641 run_test 421g "rmfid to return errors properly"
28642
28643 test_421h() {
28644         local mount_other
28645         local mount_ret
28646         local rmfid_ret
28647         local old_fid
28648         local fidA
28649         local fidB
28650         local fidC
28651         local fidD
28652
28653         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28654                 skip "Need MDS version at least 2.15.53"
28655
28656         test_mkdir $DIR/$tdir
28657         test_mkdir $DIR/$tdir/subdir
28658         touch $DIR/$tdir/subdir/file0
28659         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28660         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28661         rm -f $DIR/$tdir/subdir/file0
28662         touch $DIR/$tdir/subdir/fileA
28663         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28664         echo File $DIR/$tdir/subdir/fileA FID $fidA
28665         touch $DIR/$tdir/subdir/fileB
28666         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28667         echo File $DIR/$tdir/subdir/fileB FID $fidB
28668         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28669         touch $DIR/$tdir/subdir/fileC
28670         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28671         echo File $DIR/$tdir/subdir/fileC FID $fidC
28672         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28673         touch $DIR/$tdir/fileD
28674         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28675         echo File $DIR/$tdir/fileD FID $fidD
28676
28677         # mount another client mount point with subdirectory mount
28678         export FILESET=/$tdir/subdir
28679         mount_other=${MOUNT}_other
28680         mount_client $mount_other ${MOUNT_OPTS}
28681         mount_ret=$?
28682         export FILESET=""
28683         (( mount_ret == 0 )) || error "mount $mount_other failed"
28684
28685         echo Removing FIDs:
28686         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28687         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28688         rmfid_ret=$?
28689
28690         umount_client $mount_other || error "umount $mount_other failed"
28691
28692         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28693
28694         # fileA should have been deleted
28695         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28696
28697         # fileB should have been deleted
28698         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28699
28700         # fileC should not have been deleted, fid also exists outside of fileset
28701         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28702
28703         # fileD should not have been deleted, it exists outside of fileset
28704         stat $DIR/$tdir/fileD || error "fileD deleted"
28705 }
28706 run_test 421h "rmfid with fileset mount"
28707
28708 test_422() {
28709         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28710         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28711         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28712         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28713         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28714
28715         local amc=$(at_max_get client)
28716         local amo=$(at_max_get mds1)
28717         local timeout=`lctl get_param -n timeout`
28718
28719         at_max_set 0 client
28720         at_max_set 0 mds1
28721
28722 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28723         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28724                         fail_val=$(((2*timeout + 10)*1000))
28725         touch $DIR/$tdir/d3/file &
28726         sleep 2
28727 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28728         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28729                         fail_val=$((2*timeout + 5))
28730         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28731         local pid=$!
28732         sleep 1
28733         kill -9 $pid
28734         sleep $((2 * timeout))
28735         echo kill $pid
28736         kill -9 $pid
28737         lctl mark touch
28738         touch $DIR/$tdir/d2/file3
28739         touch $DIR/$tdir/d2/file4
28740         touch $DIR/$tdir/d2/file5
28741
28742         wait
28743         at_max_set $amc client
28744         at_max_set $amo mds1
28745
28746         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28747         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28748                 error "Watchdog is always throttled"
28749 }
28750 run_test 422 "kill a process with RPC in progress"
28751
28752 stat_test() {
28753     df -h $MOUNT &
28754     df -h $MOUNT &
28755     df -h $MOUNT &
28756     df -h $MOUNT &
28757     df -h $MOUNT &
28758     df -h $MOUNT &
28759 }
28760
28761 test_423() {
28762     local _stats
28763     # ensure statfs cache is expired
28764     sleep 2;
28765
28766     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28767     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28768
28769     return 0
28770 }
28771 run_test 423 "statfs should return a right data"
28772
28773 test_424() {
28774 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28775         $LCTL set_param fail_loc=0x80000522
28776         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28777         rm -f $DIR/$tfile
28778 }
28779 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28780
28781 test_425() {
28782         test_mkdir -c -1 $DIR/$tdir
28783         $LFS setstripe -c -1 $DIR/$tdir
28784
28785         lru_resize_disable "" 100
28786         stack_trap "lru_resize_enable" EXIT
28787
28788         sleep 5
28789
28790         for i in $(seq $((MDSCOUNT * 125))); do
28791                 local t=$DIR/$tdir/$tfile_$i
28792
28793                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28794                         error_noexit "Create file $t"
28795         done
28796         stack_trap "rm -rf $DIR/$tdir" EXIT
28797
28798         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28799                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28800                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28801
28802                 [ $lock_count -le $lru_size ] ||
28803                         error "osc lock count $lock_count > lru size $lru_size"
28804         done
28805
28806         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28807                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28808                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28809
28810                 [ $lock_count -le $lru_size ] ||
28811                         error "mdc lock count $lock_count > lru size $lru_size"
28812         done
28813 }
28814 run_test 425 "lock count should not exceed lru size"
28815
28816 test_426() {
28817         splice-test -r $DIR/$tfile
28818         splice-test -rd $DIR/$tfile
28819         splice-test $DIR/$tfile
28820         splice-test -d $DIR/$tfile
28821 }
28822 run_test 426 "splice test on Lustre"
28823
28824 test_427() {
28825         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28826         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28827                 skip "Need MDS version at least 2.12.4"
28828         local log
28829
28830         mkdir $DIR/$tdir
28831         mkdir $DIR/$tdir/1
28832         mkdir $DIR/$tdir/2
28833         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28834         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28835
28836         $LFS getdirstripe $DIR/$tdir/1/dir
28837
28838         #first setfattr for creating updatelog
28839         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28840
28841 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28842         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28843         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28844         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28845
28846         sleep 2
28847         fail mds2
28848         wait_recovery_complete mds2 $((2*TIMEOUT))
28849
28850         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28851         echo $log | grep "get update log failed" &&
28852                 error "update log corruption is detected" || true
28853 }
28854 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28855
28856 test_428() {
28857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28858         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
28859                               awk '/^max_cached_mb/ { print $2 }')
28860         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
28861
28862         $LCTL set_param -n llite.*.max_cached_mb=64
28863
28864         mkdir $DIR/$tdir
28865         $LFS setstripe -c 1 $DIR/$tdir
28866         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28867         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28868         #test write
28869         for f in $(seq 4); do
28870                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28871         done
28872         wait
28873
28874         cancel_lru_locks osc
28875         # Test read
28876         for f in $(seq 4); do
28877                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28878         done
28879         wait
28880 }
28881 run_test 428 "large block size IO should not hang"
28882
28883 test_429() { # LU-7915 / LU-10948
28884         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28885         local testfile=$DIR/$tfile
28886         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28887         local new_flag=1
28888         local first_rpc
28889         local second_rpc
28890         local third_rpc
28891
28892         $LCTL get_param $ll_opencache_threshold_count ||
28893                 skip "client does not have opencache parameter"
28894
28895         set_opencache $new_flag
28896         stack_trap "restore_opencache"
28897         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28898                 error "enable opencache failed"
28899         touch $testfile
28900         # drop MDC DLM locks
28901         cancel_lru_locks mdc
28902         # clear MDC RPC stats counters
28903         $LCTL set_param $mdc_rpcstats=clear
28904
28905         # According to the current implementation, we need to run 3 times
28906         # open & close file to verify if opencache is enabled correctly.
28907         # 1st, RPCs are sent for lookup/open and open handle is released on
28908         #      close finally.
28909         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28910         #      so open handle won't be released thereafter.
28911         # 3rd, No RPC is sent out.
28912         $MULTIOP $testfile oc || error "multiop failed"
28913         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28914         echo "1st: $first_rpc RPCs in flight"
28915
28916         $MULTIOP $testfile oc || error "multiop failed"
28917         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28918         echo "2nd: $second_rpc RPCs in flight"
28919
28920         $MULTIOP $testfile oc || error "multiop failed"
28921         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28922         echo "3rd: $third_rpc RPCs in flight"
28923
28924         #verify no MDC RPC is sent
28925         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28926 }
28927 run_test 429 "verify if opencache flag on client side does work"
28928
28929 lseek_test_430() {
28930         local offset
28931         local file=$1
28932
28933         # data at [200K, 400K)
28934         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28935                 error "256K->512K dd fails"
28936         # data at [2M, 3M)
28937         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28938                 error "2M->3M dd fails"
28939         # data at [4M, 5M)
28940         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28941                 error "4M->5M dd fails"
28942         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28943         # start at first component hole #1
28944         printf "Seeking hole from 1000 ... "
28945         offset=$(lseek_test -l 1000 $file)
28946         echo $offset
28947         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28948         printf "Seeking data from 1000 ... "
28949         offset=$(lseek_test -d 1000 $file)
28950         echo $offset
28951         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28952
28953         # start at first component data block
28954         printf "Seeking hole from 300000 ... "
28955         offset=$(lseek_test -l 300000 $file)
28956         echo $offset
28957         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28958         printf "Seeking data from 300000 ... "
28959         offset=$(lseek_test -d 300000 $file)
28960         echo $offset
28961         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28962
28963         # start at the first component but beyond end of object size
28964         printf "Seeking hole from 1000000 ... "
28965         offset=$(lseek_test -l 1000000 $file)
28966         echo $offset
28967         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28968         printf "Seeking data from 1000000 ... "
28969         offset=$(lseek_test -d 1000000 $file)
28970         echo $offset
28971         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28972
28973         # start at second component stripe 2 (empty file)
28974         printf "Seeking hole from 1500000 ... "
28975         offset=$(lseek_test -l 1500000 $file)
28976         echo $offset
28977         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28978         printf "Seeking data from 1500000 ... "
28979         offset=$(lseek_test -d 1500000 $file)
28980         echo $offset
28981         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28982
28983         # start at second component stripe 1 (all data)
28984         printf "Seeking hole from 3000000 ... "
28985         offset=$(lseek_test -l 3000000 $file)
28986         echo $offset
28987         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28988         printf "Seeking data from 3000000 ... "
28989         offset=$(lseek_test -d 3000000 $file)
28990         echo $offset
28991         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28992
28993         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28994                 error "2nd dd fails"
28995         echo "Add data block at 640K...1280K"
28996
28997         # start at before new data block, in hole
28998         printf "Seeking hole from 600000 ... "
28999         offset=$(lseek_test -l 600000 $file)
29000         echo $offset
29001         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29002         printf "Seeking data from 600000 ... "
29003         offset=$(lseek_test -d 600000 $file)
29004         echo $offset
29005         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29006
29007         # start at the first component new data block
29008         printf "Seeking hole from 1000000 ... "
29009         offset=$(lseek_test -l 1000000 $file)
29010         echo $offset
29011         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29012         printf "Seeking data from 1000000 ... "
29013         offset=$(lseek_test -d 1000000 $file)
29014         echo $offset
29015         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29016
29017         # start at second component stripe 2, new data
29018         printf "Seeking hole from 1200000 ... "
29019         offset=$(lseek_test -l 1200000 $file)
29020         echo $offset
29021         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29022         printf "Seeking data from 1200000 ... "
29023         offset=$(lseek_test -d 1200000 $file)
29024         echo $offset
29025         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29026
29027         # start beyond file end
29028         printf "Using offset > filesize ... "
29029         lseek_test -l 4000000 $file && error "lseek should fail"
29030         printf "Using offset > filesize ... "
29031         lseek_test -d 4000000 $file && error "lseek should fail"
29032
29033         printf "Done\n\n"
29034 }
29035
29036 test_430a() {
29037         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29038                 skip "MDT does not support SEEK_HOLE"
29039
29040         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29041                 skip "OST does not support SEEK_HOLE"
29042
29043         local file=$DIR/$tdir/$tfile
29044
29045         mkdir -p $DIR/$tdir
29046
29047         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29048         # OST stripe #1 will have continuous data at [1M, 3M)
29049         # OST stripe #2 is empty
29050         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29051         lseek_test_430 $file
29052         rm $file
29053         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29054         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29055         lseek_test_430 $file
29056         rm $file
29057         $LFS setstripe -c2 -S 512K $file
29058         echo "Two stripes, stripe size 512K"
29059         lseek_test_430 $file
29060         rm $file
29061         # FLR with stale mirror
29062         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29063                        -N -c2 -S 1M $file
29064         echo "Mirrored file:"
29065         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29066         echo "Plain 2 stripes 1M"
29067         lseek_test_430 $file
29068         rm $file
29069 }
29070 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29071
29072 test_430b() {
29073         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29074                 skip "OST does not support SEEK_HOLE"
29075
29076         local offset
29077         local file=$DIR/$tdir/$tfile
29078
29079         mkdir -p $DIR/$tdir
29080         # Empty layout lseek should fail
29081         $MCREATE $file
29082         # seek from 0
29083         printf "Seeking hole from 0 ... "
29084         lseek_test -l 0 $file && error "lseek should fail"
29085         printf "Seeking data from 0 ... "
29086         lseek_test -d 0 $file && error "lseek should fail"
29087         rm $file
29088
29089         # 1M-hole file
29090         $LFS setstripe -E 1M -c2 -E eof $file
29091         $TRUNCATE $file 1048576
29092         printf "Seeking hole from 1000000 ... "
29093         offset=$(lseek_test -l 1000000 $file)
29094         echo $offset
29095         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29096         printf "Seeking data from 1000000 ... "
29097         lseek_test -d 1000000 $file && error "lseek should fail"
29098         rm $file
29099
29100         # full component followed by non-inited one
29101         $LFS setstripe -E 1M -c2 -E eof $file
29102         dd if=/dev/urandom of=$file bs=1M count=1
29103         printf "Seeking hole from 1000000 ... "
29104         offset=$(lseek_test -l 1000000 $file)
29105         echo $offset
29106         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29107         printf "Seeking hole from 1048576 ... "
29108         lseek_test -l 1048576 $file && error "lseek should fail"
29109         # init second component and truncate back
29110         echo "123" >> $file
29111         $TRUNCATE $file 1048576
29112         printf "Seeking hole from 1000000 ... "
29113         offset=$(lseek_test -l 1000000 $file)
29114         echo $offset
29115         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29116         printf "Seeking hole from 1048576 ... "
29117         lseek_test -l 1048576 $file && error "lseek should fail"
29118         # boundary checks for big values
29119         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29120         offset=$(lseek_test -d 0 $file.10g)
29121         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29122         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29123         offset=$(lseek_test -d 0 $file.100g)
29124         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29125         return 0
29126 }
29127 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29128
29129 test_430c() {
29130         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29131                 skip "OST does not support SEEK_HOLE"
29132
29133         local file=$DIR/$tdir/$tfile
29134         local start
29135
29136         mkdir -p $DIR/$tdir
29137         stack_trap "rm -f $file $file.tmp"
29138         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29139
29140         # cp version 8.33+ prefers lseek over fiemap
29141         local ver=$(cp --version | awk '{ print $4; exit; }')
29142
29143         echo "cp $ver installed"
29144         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29145                 start=$SECONDS
29146                 time cp -v $file $file.tmp || error "cp $file failed"
29147                 (( SECONDS - start < 5 )) || {
29148                         strace cp $file $file.tmp |&
29149                                 grep -E "open|read|seek|FIEMAP" |
29150                                 grep -A 100 $file
29151                         error "cp: too long runtime $((SECONDS - start))"
29152                 }
29153         else
29154                 echo "cp test skipped due to $ver < 8.33"
29155         fi
29156
29157         # tar version 1.29+ supports SEEK_HOLE/DATA
29158         ver=$(tar --version | awk '{ print $4; exit; }')
29159         echo "tar $ver installed"
29160         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29161                 start=$SECONDS
29162                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29163                 (( SECONDS - start < 5 )) || {
29164                         strace tar cf $file.tmp --sparse $file |&
29165                                 grep -E "open|read|seek|FIEMAP" |
29166                                 grep -A 100 $file
29167                         error "tar: too long runtime $((SECONDS - start))"
29168                 }
29169         else
29170                 echo "tar test skipped due to $ver < 1.29"
29171         fi
29172 }
29173 run_test 430c "lseek: external tools check"
29174
29175 test_431() { # LU-14187
29176         local file=$DIR/$tdir/$tfile
29177
29178         mkdir -p $DIR/$tdir
29179         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29180         dd if=/dev/urandom of=$file bs=4k count=1
29181         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29182         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29183         #define OBD_FAIL_OST_RESTART_IO 0x251
29184         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29185         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29186         cp $file $file.0
29187         cancel_lru_locks
29188         sync_all_data
29189         echo 3 > /proc/sys/vm/drop_caches
29190         diff  $file $file.0 || error "data diff"
29191 }
29192 run_test 431 "Restart transaction for IO"
29193
29194 cleanup_test_432() {
29195         do_facet mgs $LCTL nodemap_activate 0
29196         wait_nm_sync active
29197 }
29198
29199 test_432() {
29200         local tmpdir=$TMP/dir432
29201
29202         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29203                 skip "Need MDS version at least 2.14.52"
29204
29205         stack_trap cleanup_test_432 EXIT
29206         mkdir $DIR/$tdir
29207         mkdir $tmpdir
29208
29209         do_facet mgs $LCTL nodemap_activate 1
29210         wait_nm_sync active
29211         do_facet mgs $LCTL nodemap_modify --name default \
29212                 --property admin --value 1
29213         do_facet mgs $LCTL nodemap_modify --name default \
29214                 --property trusted --value 1
29215         cancel_lru_locks mdc
29216         wait_nm_sync default admin_nodemap
29217         wait_nm_sync default trusted_nodemap
29218
29219         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29220                grep -ci "Operation not permitted") -ne 0 ]; then
29221                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29222         fi
29223 }
29224 run_test 432 "mv dir from outside Lustre"
29225
29226 test_433() {
29227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29228
29229         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29230                 skip "inode cache not supported"
29231
29232         $LCTL set_param llite.*.inode_cache=0
29233         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29234
29235         local count=256
29236         local before
29237         local after
29238
29239         cancel_lru_locks mdc
29240         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29241         createmany -m $DIR/$tdir/f $count
29242         createmany -d $DIR/$tdir/d $count
29243         ls -l $DIR/$tdir > /dev/null
29244         stack_trap "rm -rf $DIR/$tdir"
29245
29246         before=$(num_objects)
29247         cancel_lru_locks mdc
29248         after=$(num_objects)
29249
29250         # sometimes even @before is less than 2 * count
29251         while (( before - after < count )); do
29252                 sleep 1
29253                 after=$(num_objects)
29254                 wait=$((wait + 1))
29255                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29256                 if (( wait > 60 )); then
29257                         error "inode slab grew from $before to $after"
29258                 fi
29259         done
29260
29261         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29262 }
29263 run_test 433 "ldlm lock cancel releases dentries and inodes"
29264
29265 test_434() {
29266         local file
29267         local getxattr_count
29268         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29269         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29270
29271         [[ $(getenforce) == "Disabled" ]] ||
29272                 skip "lsm selinux module have to be disabled for this test"
29273
29274         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29275                 error "fail to create $DIR/$tdir/ on MDT0000"
29276
29277         touch $DIR/$tdir/$tfile-{001..100}
29278
29279         # disable the xattr cache
29280         save_lustre_params client "llite.*.xattr_cache" > $p
29281         lctl set_param llite.*.xattr_cache=0
29282         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29283
29284         # clear clients mdc stats
29285         clear_stats $mdc_stat_param ||
29286                 error "fail to clear stats on mdc MDT0000"
29287
29288         for file in $DIR/$tdir/$tfile-{001..100}; do
29289                 getfattr -n security.selinux $file |&
29290                         grep -q "Operation not supported" ||
29291                         error "getxattr on security.selinux should return EOPNOTSUPP"
29292         done
29293
29294         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29295         (( getxattr_count < 100 )) ||
29296                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29297 }
29298 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29299
29300 test_440() {
29301         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29302                 source $LUSTRE/scripts/bash-completion/lustre
29303         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29304                 source /usr/share/bash-completion/completions/lustre
29305         else
29306                 skip "bash completion scripts not found"
29307         fi
29308
29309         local lctl_completions
29310         local lfs_completions
29311
29312         lctl_completions=$(_lustre_cmds lctl)
29313         if [[ ! $lctl_completions =~ "get_param" ]]; then
29314                 error "lctl bash completion failed"
29315         fi
29316
29317         lfs_completions=$(_lustre_cmds lfs)
29318         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29319                 error "lfs bash completion failed"
29320         fi
29321 }
29322 run_test 440 "bash completion for lfs, lctl"
29323
29324 prep_801() {
29325         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29326         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29327                 skip "Need server version at least 2.9.55"
29328
29329         start_full_debug_logging
29330 }
29331
29332 post_801() {
29333         stop_full_debug_logging
29334 }
29335
29336 barrier_stat() {
29337         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29338                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29339                            awk '/The barrier for/ { print $7 }')
29340                 echo $st
29341         else
29342                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29343                 echo \'$st\'
29344         fi
29345 }
29346
29347 barrier_expired() {
29348         local expired
29349
29350         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29351                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29352                           awk '/will be expired/ { print $7 }')
29353         else
29354                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29355         fi
29356
29357         echo $expired
29358 }
29359
29360 test_801a() {
29361         prep_801
29362
29363         echo "Start barrier_freeze at: $(date)"
29364         #define OBD_FAIL_BARRIER_DELAY          0x2202
29365         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29366         # Do not reduce barrier time - See LU-11873
29367         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29368
29369         sleep 2
29370         local b_status=$(barrier_stat)
29371         echo "Got barrier status at: $(date)"
29372         [ "$b_status" = "'freezing_p1'" ] ||
29373                 error "(1) unexpected barrier status $b_status"
29374
29375         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29376         wait
29377         b_status=$(barrier_stat)
29378         [ "$b_status" = "'frozen'" ] ||
29379                 error "(2) unexpected barrier status $b_status"
29380
29381         local expired=$(barrier_expired)
29382         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29383         sleep $((expired + 3))
29384
29385         b_status=$(barrier_stat)
29386         [ "$b_status" = "'expired'" ] ||
29387                 error "(3) unexpected barrier status $b_status"
29388
29389         # Do not reduce barrier time - See LU-11873
29390         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29391                 error "(4) fail to freeze barrier"
29392
29393         b_status=$(barrier_stat)
29394         [ "$b_status" = "'frozen'" ] ||
29395                 error "(5) unexpected barrier status $b_status"
29396
29397         echo "Start barrier_thaw at: $(date)"
29398         #define OBD_FAIL_BARRIER_DELAY          0x2202
29399         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29400         do_facet mgs $LCTL barrier_thaw $FSNAME &
29401
29402         sleep 2
29403         b_status=$(barrier_stat)
29404         echo "Got barrier status at: $(date)"
29405         [ "$b_status" = "'thawing'" ] ||
29406                 error "(6) unexpected barrier status $b_status"
29407
29408         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29409         wait
29410         b_status=$(barrier_stat)
29411         [ "$b_status" = "'thawed'" ] ||
29412                 error "(7) unexpected barrier status $b_status"
29413
29414         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29415         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29416         do_facet mgs $LCTL barrier_freeze $FSNAME
29417
29418         b_status=$(barrier_stat)
29419         [ "$b_status" = "'failed'" ] ||
29420                 error "(8) unexpected barrier status $b_status"
29421
29422         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29423         do_facet mgs $LCTL barrier_thaw $FSNAME
29424
29425         post_801
29426 }
29427 run_test 801a "write barrier user interfaces and stat machine"
29428
29429 test_801b() {
29430         prep_801
29431
29432         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29433         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29434         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29435         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29436         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29437
29438         cancel_lru_locks mdc
29439
29440         # 180 seconds should be long enough
29441         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29442
29443         local b_status=$(barrier_stat)
29444         [ "$b_status" = "'frozen'" ] ||
29445                 error "(6) unexpected barrier status $b_status"
29446
29447         mkdir $DIR/$tdir/d0/d10 &
29448         mkdir_pid=$!
29449
29450         touch $DIR/$tdir/d1/f13 &
29451         touch_pid=$!
29452
29453         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29454         ln_pid=$!
29455
29456         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29457         mv_pid=$!
29458
29459         rm -f $DIR/$tdir/d4/f12 &
29460         rm_pid=$!
29461
29462         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29463
29464         # To guarantee taht the 'stat' is not blocked
29465         b_status=$(barrier_stat)
29466         [ "$b_status" = "'frozen'" ] ||
29467                 error "(8) unexpected barrier status $b_status"
29468
29469         # let above commands to run at background
29470         sleep 5
29471
29472         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29473         ps -p $touch_pid || error "(10) touch should be blocked"
29474         ps -p $ln_pid || error "(11) link should be blocked"
29475         ps -p $mv_pid || error "(12) rename should be blocked"
29476         ps -p $rm_pid || error "(13) unlink should be blocked"
29477
29478         b_status=$(barrier_stat)
29479         [ "$b_status" = "'frozen'" ] ||
29480                 error "(14) unexpected barrier status $b_status"
29481
29482         do_facet mgs $LCTL barrier_thaw $FSNAME
29483         b_status=$(barrier_stat)
29484         [ "$b_status" = "'thawed'" ] ||
29485                 error "(15) unexpected barrier status $b_status"
29486
29487         wait $mkdir_pid || error "(16) mkdir should succeed"
29488         wait $touch_pid || error "(17) touch should succeed"
29489         wait $ln_pid || error "(18) link should succeed"
29490         wait $mv_pid || error "(19) rename should succeed"
29491         wait $rm_pid || error "(20) unlink should succeed"
29492
29493         post_801
29494 }
29495 run_test 801b "modification will be blocked by write barrier"
29496
29497 test_801c() {
29498         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29499
29500         prep_801
29501
29502         stop mds2 || error "(1) Fail to stop mds2"
29503
29504         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29505
29506         local b_status=$(barrier_stat)
29507         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29508                 do_facet mgs $LCTL barrier_thaw $FSNAME
29509                 error "(2) unexpected barrier status $b_status"
29510         }
29511
29512         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29513                 error "(3) Fail to rescan barrier bitmap"
29514
29515         # Do not reduce barrier time - See LU-11873
29516         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29517
29518         b_status=$(barrier_stat)
29519         [ "$b_status" = "'frozen'" ] ||
29520                 error "(4) unexpected barrier status $b_status"
29521
29522         do_facet mgs $LCTL barrier_thaw $FSNAME
29523         b_status=$(barrier_stat)
29524         [ "$b_status" = "'thawed'" ] ||
29525                 error "(5) unexpected barrier status $b_status"
29526
29527         local devname=$(mdsdevname 2)
29528
29529         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29530
29531         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29532                 error "(7) Fail to rescan barrier bitmap"
29533
29534         post_801
29535 }
29536 run_test 801c "rescan barrier bitmap"
29537
29538 test_802b() {
29539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29540         remote_mds_nodsh && skip "remote MDS with nodsh"
29541
29542         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29543                 skip "readonly option not available"
29544
29545         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29546
29547         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29548                 error "(2) Fail to copy"
29549
29550         # write back all cached data before setting MDT to readonly
29551         cancel_lru_locks
29552         sync_all_data
29553
29554         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29555         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29556
29557         echo "Modify should be refused"
29558         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29559
29560         echo "Read should be allowed"
29561         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29562                 error "(7) Read should succeed under ro mode"
29563
29564         # disable readonly
29565         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29566 }
29567 run_test 802b "be able to set MDTs to readonly"
29568
29569 test_803a() {
29570         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29571         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29572                 skip "MDS needs to be newer than 2.10.54"
29573
29574         mkdir_on_mdt0 $DIR/$tdir
29575         # Create some objects on all MDTs to trigger related logs objects
29576         for idx in $(seq $MDSCOUNT); do
29577                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29578                         $DIR/$tdir/dir${idx} ||
29579                         error "Fail to create $DIR/$tdir/dir${idx}"
29580         done
29581
29582         wait_delete_completed # ensure old test cleanups are finished
29583         sleep 3
29584         echo "before create:"
29585         $LFS df -i $MOUNT
29586         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29587
29588         for i in {1..10}; do
29589                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29590                         error "Fail to create $DIR/$tdir/foo$i"
29591         done
29592
29593         # sync ZFS-on-MDS to refresh statfs data
29594         wait_zfs_commit mds1
29595         sleep 3
29596         echo "after create:"
29597         $LFS df -i $MOUNT
29598         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29599
29600         # allow for an llog to be cleaned up during the test
29601         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29602                 error "before ($before_used) + 10 > after ($after_used)"
29603
29604         for i in {1..10}; do
29605                 rm -rf $DIR/$tdir/foo$i ||
29606                         error "Fail to remove $DIR/$tdir/foo$i"
29607         done
29608
29609         # sync ZFS-on-MDS to refresh statfs data
29610         wait_zfs_commit mds1
29611         wait_delete_completed
29612         sleep 3 # avoid MDT return cached statfs
29613         echo "after unlink:"
29614         $LFS df -i $MOUNT
29615         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29616
29617         # allow for an llog to be created during the test
29618         [ $after_used -le $((before_used + 1)) ] ||
29619                 error "after ($after_used) > before ($before_used) + 1"
29620 }
29621 run_test 803a "verify agent object for remote object"
29622
29623 test_803b() {
29624         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29625         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29626                 skip "MDS needs to be newer than 2.13.56"
29627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29628
29629         for i in $(seq 0 $((MDSCOUNT - 1))); do
29630                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29631         done
29632
29633         local before=0
29634         local after=0
29635
29636         local tmp
29637
29638         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29639         for i in $(seq 0 $((MDSCOUNT - 1))); do
29640                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29641                         awk '/getattr/ { print $2 }')
29642                 before=$((before + tmp))
29643         done
29644         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29645         for i in $(seq 0 $((MDSCOUNT - 1))); do
29646                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29647                         awk '/getattr/ { print $2 }')
29648                 after=$((after + tmp))
29649         done
29650
29651         [ $before -eq $after ] || error "getattr count $before != $after"
29652 }
29653 run_test 803b "remote object can getattr from cache"
29654
29655 test_804() {
29656         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29657         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29658                 skip "MDS needs to be newer than 2.10.54"
29659         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29660
29661         mkdir -p $DIR/$tdir
29662         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29663                 error "Fail to create $DIR/$tdir/dir0"
29664
29665         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29666         local dev=$(mdsdevname 2)
29667
29668         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29669                 grep ${fid} || error "NOT found agent entry for dir0"
29670
29671         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29672                 error "Fail to create $DIR/$tdir/dir1"
29673
29674         touch $DIR/$tdir/dir1/foo0 ||
29675                 error "Fail to create $DIR/$tdir/dir1/foo0"
29676         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29677         local rc=0
29678
29679         for idx in $(seq $MDSCOUNT); do
29680                 dev=$(mdsdevname $idx)
29681                 do_facet mds${idx} \
29682                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29683                         grep ${fid} && rc=$idx
29684         done
29685
29686         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29687                 error "Fail to rename foo0 to foo1"
29688         if [ $rc -eq 0 ]; then
29689                 for idx in $(seq $MDSCOUNT); do
29690                         dev=$(mdsdevname $idx)
29691                         do_facet mds${idx} \
29692                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29693                         grep ${fid} && rc=$idx
29694                 done
29695         fi
29696
29697         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29698                 error "Fail to rename foo1 to foo2"
29699         if [ $rc -eq 0 ]; then
29700                 for idx in $(seq $MDSCOUNT); do
29701                         dev=$(mdsdevname $idx)
29702                         do_facet mds${idx} \
29703                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29704                         grep ${fid} && rc=$idx
29705                 done
29706         fi
29707
29708         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29709
29710         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29711                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29712         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29713                 error "Fail to rename foo2 to foo0"
29714         unlink $DIR/$tdir/dir1/foo0 ||
29715                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29716         rm -rf $DIR/$tdir/dir0 ||
29717                 error "Fail to rm $DIR/$tdir/dir0"
29718
29719         for idx in $(seq $MDSCOUNT); do
29720                 rc=0
29721
29722                 stop mds${idx}
29723                 dev=$(mdsdevname $idx)
29724                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29725                         rc=$?
29726                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29727                         error "mount mds$idx failed"
29728                 df $MOUNT > /dev/null 2>&1
29729
29730                 # e2fsck should not return error
29731                 [ $rc -eq 0 ] ||
29732                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29733         done
29734 }
29735 run_test 804 "verify agent entry for remote entry"
29736
29737 cleanup_805() {
29738         do_facet $SINGLEMDS zfs set quota=$old $fsset
29739         unlinkmany $DIR/$tdir/f- 1000000
29740         trap 0
29741 }
29742
29743 test_805() {
29744         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29745         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29746         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29747                 skip "netfree not implemented before 0.7"
29748         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29749                 skip "Need MDS version at least 2.10.57"
29750
29751         local fsset
29752         local freekb
29753         local usedkb
29754         local old
29755         local quota
29756         local pref="osd-zfs.$FSNAME-MDT0000."
29757
29758         # limit available space on MDS dataset to meet nospace issue
29759         # quickly. then ZFS 0.7.2 can use reserved space if asked
29760         # properly (using netfree flag in osd_declare_destroy()
29761         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29762         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29763                 gawk '{print $3}')
29764         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29765         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29766         let "usedkb=usedkb-freekb"
29767         let "freekb=freekb/2"
29768         if let "freekb > 5000"; then
29769                 let "freekb=5000"
29770         fi
29771         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29772         trap cleanup_805 EXIT
29773         mkdir_on_mdt0 $DIR/$tdir
29774         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29775                 error "Can't set PFL layout"
29776         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29777         rm -rf $DIR/$tdir || error "not able to remove"
29778         do_facet $SINGLEMDS zfs set quota=$old $fsset
29779         trap 0
29780 }
29781 run_test 805 "ZFS can remove from full fs"
29782
29783 # Size-on-MDS test
29784 check_lsom_data()
29785 {
29786         local file=$1
29787         local expect=$(stat -c %s $file)
29788
29789         check_lsom_size $1 $expect
29790
29791         local blocks=$($LFS getsom -b $file)
29792         expect=$(stat -c %b $file)
29793         [[ $blocks == $expect ]] ||
29794                 error "$file expected blocks: $expect, got: $blocks"
29795 }
29796
29797 check_lsom_size()
29798 {
29799         local size
29800         local expect=$2
29801
29802         cancel_lru_locks mdc
29803
29804         size=$($LFS getsom -s $1)
29805         [[ $size == $expect ]] ||
29806                 error "$file expected size: $expect, got: $size"
29807 }
29808
29809 test_806() {
29810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29811                 skip "Need MDS version at least 2.11.52"
29812
29813         local bs=1048576
29814
29815         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29816
29817         disable_opencache
29818         stack_trap "restore_opencache"
29819
29820         # single-threaded write
29821         echo "Test SOM for single-threaded write"
29822         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29823                 error "write $tfile failed"
29824         check_lsom_size $DIR/$tfile $bs
29825
29826         local num=32
29827         local size=$(($num * $bs))
29828         local offset=0
29829         local i
29830
29831         echo "Test SOM for single client multi-threaded($num) write"
29832         $TRUNCATE $DIR/$tfile 0
29833         for ((i = 0; i < $num; i++)); do
29834                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29835                 local pids[$i]=$!
29836                 offset=$((offset + $bs))
29837         done
29838         for (( i=0; i < $num; i++ )); do
29839                 wait ${pids[$i]}
29840         done
29841         check_lsom_size $DIR/$tfile $size
29842
29843         $TRUNCATE $DIR/$tfile 0
29844         for ((i = 0; i < $num; i++)); do
29845                 offset=$((offset - $bs))
29846                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29847                 local pids[$i]=$!
29848         done
29849         for (( i=0; i < $num; i++ )); do
29850                 wait ${pids[$i]}
29851         done
29852         check_lsom_size $DIR/$tfile $size
29853
29854         # multi-client writes
29855         num=$(get_node_count ${CLIENTS//,/ })
29856         size=$(($num * $bs))
29857         offset=0
29858         i=0
29859
29860         echo "Test SOM for multi-client ($num) writes"
29861         $TRUNCATE $DIR/$tfile 0
29862         for client in ${CLIENTS//,/ }; do
29863                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29864                 local pids[$i]=$!
29865                 i=$((i + 1))
29866                 offset=$((offset + $bs))
29867         done
29868         for (( i=0; i < $num; i++ )); do
29869                 wait ${pids[$i]}
29870         done
29871         check_lsom_size $DIR/$tfile $offset
29872
29873         i=0
29874         $TRUNCATE $DIR/$tfile 0
29875         for client in ${CLIENTS//,/ }; do
29876                 offset=$((offset - $bs))
29877                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29878                 local pids[$i]=$!
29879                 i=$((i + 1))
29880         done
29881         for (( i=0; i < $num; i++ )); do
29882                 wait ${pids[$i]}
29883         done
29884         check_lsom_size $DIR/$tfile $size
29885
29886         # verify SOM blocks count
29887         echo "Verify SOM block count"
29888         $TRUNCATE $DIR/$tfile 0
29889         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29890                 error "failed to write file $tfile with fdatasync and fstat"
29891         check_lsom_data $DIR/$tfile
29892
29893         $TRUNCATE $DIR/$tfile 0
29894         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29895                 error "failed to write file $tfile with fdatasync"
29896         check_lsom_data $DIR/$tfile
29897
29898         $TRUNCATE $DIR/$tfile 0
29899         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29900                 error "failed to write file $tfile with sync IO"
29901         check_lsom_data $DIR/$tfile
29902
29903         # verify truncate
29904         echo "Test SOM for truncate"
29905         # use ftruncate to sync blocks on close request
29906         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29907         check_lsom_size $DIR/$tfile 16384
29908         check_lsom_data $DIR/$tfile
29909
29910         $TRUNCATE $DIR/$tfile 1234
29911         check_lsom_size $DIR/$tfile 1234
29912         # sync blocks on the MDT
29913         $MULTIOP $DIR/$tfile oc
29914         check_lsom_data $DIR/$tfile
29915 }
29916 run_test 806 "Verify Lazy Size on MDS"
29917
29918 test_807() {
29919         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29920         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29921                 skip "Need MDS version at least 2.11.52"
29922
29923         # Registration step
29924         changelog_register || error "changelog_register failed"
29925         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29926         changelog_users $SINGLEMDS | grep -q $cl_user ||
29927                 error "User $cl_user not found in changelog_users"
29928
29929         rm -rf $DIR/$tdir || error "rm $tdir failed"
29930         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29931         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29932         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29933         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29934                 error "truncate $tdir/trunc failed"
29935
29936         local bs=1048576
29937         echo "Test SOM for single-threaded write with fsync"
29938         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29939                 error "write $tfile failed"
29940         sync;sync;sync
29941
29942         # multi-client wirtes
29943         local num=$(get_node_count ${CLIENTS//,/ })
29944         local offset=0
29945         local i=0
29946
29947         echo "Test SOM for multi-client ($num) writes"
29948         touch $DIR/$tfile || error "touch $tfile failed"
29949         $TRUNCATE $DIR/$tfile 0
29950         for client in ${CLIENTS//,/ }; do
29951                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29952                 local pids[$i]=$!
29953                 i=$((i + 1))
29954                 offset=$((offset + $bs))
29955         done
29956         for (( i=0; i < $num; i++ )); do
29957                 wait ${pids[$i]}
29958         done
29959
29960         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29961         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29962         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29963         check_lsom_data $DIR/$tdir/trunc
29964         check_lsom_data $DIR/$tdir/single_dd
29965         check_lsom_data $DIR/$tfile
29966
29967         rm -rf $DIR/$tdir
29968         # Deregistration step
29969         changelog_deregister || error "changelog_deregister failed"
29970 }
29971 run_test 807 "verify LSOM syncing tool"
29972
29973 check_som_nologged()
29974 {
29975         local lines=$($LFS changelog $FSNAME-MDT0000 |
29976                 grep 'x=trusted.som' | wc -l)
29977         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29978 }
29979
29980 test_808() {
29981         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29982                 skip "Need MDS version at least 2.11.55"
29983
29984         # Registration step
29985         changelog_register || error "changelog_register failed"
29986
29987         touch $DIR/$tfile || error "touch $tfile failed"
29988         check_som_nologged
29989
29990         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29991                 error "write $tfile failed"
29992         check_som_nologged
29993
29994         $TRUNCATE $DIR/$tfile 1234
29995         check_som_nologged
29996
29997         $TRUNCATE $DIR/$tfile 1048576
29998         check_som_nologged
29999
30000         # Deregistration step
30001         changelog_deregister || error "changelog_deregister failed"
30002 }
30003 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30004
30005 check_som_nodata()
30006 {
30007         $LFS getsom $1
30008         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30009 }
30010
30011 test_809() {
30012         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30013                 skip "Need MDS version at least 2.11.56"
30014
30015         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30016                 error "failed to create DoM-only file $DIR/$tfile"
30017         touch $DIR/$tfile || error "touch $tfile failed"
30018         check_som_nodata $DIR/$tfile
30019
30020         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30021                 error "write $tfile failed"
30022         check_som_nodata $DIR/$tfile
30023
30024         $TRUNCATE $DIR/$tfile 1234
30025         check_som_nodata $DIR/$tfile
30026
30027         $TRUNCATE $DIR/$tfile 4097
30028         check_som_nodata $DIR/$file
30029 }
30030 run_test 809 "Verify no SOM xattr store for DoM-only files"
30031
30032 test_810() {
30033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30034         $GSS && skip_env "could not run with gss"
30035         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30036                 skip "OST < 2.12.58 doesn't align checksum"
30037
30038         set_checksums 1
30039         stack_trap "set_checksums $ORIG_CSUM" EXIT
30040         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30041
30042         local csum
30043         local before
30044         local after
30045         for csum in $CKSUM_TYPES; do
30046                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30047                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30048                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30049                         eval set -- $i
30050                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30051                         before=$(md5sum $DIR/$tfile)
30052                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30053                         after=$(md5sum $DIR/$tfile)
30054                         [ "$before" == "$after" ] ||
30055                                 error "$csum: $before != $after bs=$1 seek=$2"
30056                 done
30057         done
30058 }
30059 run_test 810 "partial page writes on ZFS (LU-11663)"
30060
30061 test_812a() {
30062         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30063                 skip "OST < 2.12.51 doesn't support this fail_loc"
30064
30065         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30066         # ensure ost1 is connected
30067         stat $DIR/$tfile >/dev/null || error "can't stat"
30068         wait_osc_import_state client ost1 FULL
30069         # no locks, no reqs to let the connection idle
30070         cancel_lru_locks osc
30071
30072         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30073 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30074         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30075         wait_osc_import_state client ost1 CONNECTING
30076         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30077
30078         stat $DIR/$tfile >/dev/null || error "can't stat file"
30079 }
30080 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30081
30082 test_812b() { # LU-12378
30083         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30084                 skip "OST < 2.12.51 doesn't support this fail_loc"
30085
30086         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30087         # ensure ost1 is connected
30088         stat $DIR/$tfile >/dev/null || error "can't stat"
30089         wait_osc_import_state client ost1 FULL
30090         # no locks, no reqs to let the connection idle
30091         cancel_lru_locks osc
30092
30093         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30094 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30095         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30096         wait_osc_import_state client ost1 CONNECTING
30097         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30098
30099         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30100         wait_osc_import_state client ost1 IDLE
30101 }
30102 run_test 812b "do not drop no resend request for idle connect"
30103
30104 test_812c() {
30105         local old
30106
30107         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30108
30109         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30110         $LFS getstripe $DIR/$tfile
30111         $LCTL set_param osc.*.idle_timeout=10
30112         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30113         # ensure ost1 is connected
30114         stat $DIR/$tfile >/dev/null || error "can't stat"
30115         wait_osc_import_state client ost1 FULL
30116         # no locks, no reqs to let the connection idle
30117         cancel_lru_locks osc
30118
30119 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30120         $LCTL set_param fail_loc=0x80000533
30121         sleep 15
30122         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30123 }
30124 run_test 812c "idle import vs lock enqueue race"
30125
30126 test_813() {
30127         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30128         [ -z "$file_heat_sav" ] && skip "no file heat support"
30129
30130         local readsample
30131         local writesample
30132         local readbyte
30133         local writebyte
30134         local readsample1
30135         local writesample1
30136         local readbyte1
30137         local writebyte1
30138
30139         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30140         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30141
30142         $LCTL set_param -n llite.*.file_heat=1
30143         echo "Turn on file heat"
30144         echo "Period second: $period_second, Decay percentage: $decay_pct"
30145
30146         echo "QQQQ" > $DIR/$tfile
30147         echo "QQQQ" > $DIR/$tfile
30148         echo "QQQQ" > $DIR/$tfile
30149         cat $DIR/$tfile > /dev/null
30150         cat $DIR/$tfile > /dev/null
30151         cat $DIR/$tfile > /dev/null
30152         cat $DIR/$tfile > /dev/null
30153
30154         local out=$($LFS heat_get $DIR/$tfile)
30155
30156         $LFS heat_get $DIR/$tfile
30157         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30158         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30159         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30160         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30161
30162         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30163         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30164         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30165         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30166
30167         sleep $((period_second + 3))
30168         echo "Sleep $((period_second + 3)) seconds..."
30169         # The recursion formula to calculate the heat of the file f is as
30170         # follow:
30171         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30172         # Where Hi is the heat value in the period between time points i*I and
30173         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30174         # to the weight of Ci.
30175         out=$($LFS heat_get $DIR/$tfile)
30176         $LFS heat_get $DIR/$tfile
30177         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30178         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30179         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30180         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30181
30182         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30183                 error "read sample ($readsample) is wrong"
30184         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30185                 error "write sample ($writesample) is wrong"
30186         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30187                 error "read bytes ($readbyte) is wrong"
30188         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30189                 error "write bytes ($writebyte) is wrong"
30190
30191         echo "QQQQ" > $DIR/$tfile
30192         echo "QQQQ" > $DIR/$tfile
30193         echo "QQQQ" > $DIR/$tfile
30194         cat $DIR/$tfile > /dev/null
30195         cat $DIR/$tfile > /dev/null
30196         cat $DIR/$tfile > /dev/null
30197         cat $DIR/$tfile > /dev/null
30198
30199         sleep $((period_second + 3))
30200         echo "Sleep $((period_second + 3)) seconds..."
30201
30202         out=$($LFS heat_get $DIR/$tfile)
30203         $LFS heat_get $DIR/$tfile
30204         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30205         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30206         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30207         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30208
30209         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30210                 4 * $decay_pct) / 100") -eq 1 ] ||
30211                 error "read sample ($readsample1) is wrong"
30212         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30213                 3 * $decay_pct) / 100") -eq 1 ] ||
30214                 error "write sample ($writesample1) is wrong"
30215         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30216                 20 * $decay_pct) / 100") -eq 1 ] ||
30217                 error "read bytes ($readbyte1) is wrong"
30218         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30219                 15 * $decay_pct) / 100") -eq 1 ] ||
30220                 error "write bytes ($writebyte1) is wrong"
30221
30222         echo "Turn off file heat for the file $DIR/$tfile"
30223         $LFS heat_set -o $DIR/$tfile
30224
30225         echo "QQQQ" > $DIR/$tfile
30226         echo "QQQQ" > $DIR/$tfile
30227         echo "QQQQ" > $DIR/$tfile
30228         cat $DIR/$tfile > /dev/null
30229         cat $DIR/$tfile > /dev/null
30230         cat $DIR/$tfile > /dev/null
30231         cat $DIR/$tfile > /dev/null
30232
30233         out=$($LFS heat_get $DIR/$tfile)
30234         $LFS heat_get $DIR/$tfile
30235         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30236         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30237         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30238         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30239
30240         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30241         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30242         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30243         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30244
30245         echo "Trun on file heat for the file $DIR/$tfile"
30246         $LFS heat_set -O $DIR/$tfile
30247
30248         echo "QQQQ" > $DIR/$tfile
30249         echo "QQQQ" > $DIR/$tfile
30250         echo "QQQQ" > $DIR/$tfile
30251         cat $DIR/$tfile > /dev/null
30252         cat $DIR/$tfile > /dev/null
30253         cat $DIR/$tfile > /dev/null
30254         cat $DIR/$tfile > /dev/null
30255
30256         out=$($LFS heat_get $DIR/$tfile)
30257         $LFS heat_get $DIR/$tfile
30258         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30259         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30260         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30261         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30262
30263         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30264         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30265         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30266         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30267
30268         $LFS heat_set -c $DIR/$tfile
30269         $LCTL set_param -n llite.*.file_heat=0
30270         echo "Turn off file heat support for the Lustre filesystem"
30271
30272         echo "QQQQ" > $DIR/$tfile
30273         echo "QQQQ" > $DIR/$tfile
30274         echo "QQQQ" > $DIR/$tfile
30275         cat $DIR/$tfile > /dev/null
30276         cat $DIR/$tfile > /dev/null
30277         cat $DIR/$tfile > /dev/null
30278         cat $DIR/$tfile > /dev/null
30279
30280         out=$($LFS heat_get $DIR/$tfile)
30281         $LFS heat_get $DIR/$tfile
30282         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30283         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30284         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30285         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30286
30287         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30288         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30289         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30290         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30291
30292         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30293         rm -f $DIR/$tfile
30294 }
30295 run_test 813 "File heat verfication"
30296
30297 test_814()
30298 {
30299         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30300         echo -n y >> $DIR/$tfile
30301         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30302         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30303 }
30304 run_test 814 "sparse cp works as expected (LU-12361)"
30305
30306 test_815()
30307 {
30308         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30309         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30310 }
30311 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30312
30313 test_816() {
30314         local ost1_imp=$(get_osc_import_name client ost1)
30315         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30316                          cut -d'.' -f2)
30317
30318         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30319         # ensure ost1 is connected
30320
30321         stat $DIR/$tfile >/dev/null || error "can't stat"
30322         wait_osc_import_state client ost1 FULL
30323         # no locks, no reqs to let the connection idle
30324         cancel_lru_locks osc
30325         lru_resize_disable osc
30326         local before
30327         local now
30328         before=$($LCTL get_param -n \
30329                  ldlm.namespaces.$imp_name.lru_size)
30330
30331         wait_osc_import_state client ost1 IDLE
30332         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30333         now=$($LCTL get_param -n \
30334               ldlm.namespaces.$imp_name.lru_size)
30335         [ $before == $now ] || error "lru_size changed $before != $now"
30336 }
30337 run_test 816 "do not reset lru_resize on idle reconnect"
30338
30339 cleanup_817() {
30340         umount $tmpdir
30341         exportfs -u localhost:$DIR/nfsexp
30342         rm -rf $DIR/nfsexp
30343 }
30344
30345 test_817() {
30346         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30347
30348         mkdir -p $DIR/nfsexp
30349         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30350                 error "failed to export nfs"
30351
30352         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30353         stack_trap cleanup_817 EXIT
30354
30355         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30356                 error "failed to mount nfs to $tmpdir"
30357
30358         cp /bin/true $tmpdir
30359         $DIR/nfsexp/true || error "failed to execute 'true' command"
30360 }
30361 run_test 817 "nfsd won't cache write lock for exec file"
30362
30363 test_818() {
30364         test_mkdir -i0 -c1 $DIR/$tdir
30365         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30366         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30367         stop $SINGLEMDS
30368
30369         # restore osp-syn threads
30370         stack_trap "fail $SINGLEMDS"
30371
30372         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30373         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30374         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30375                 error "start $SINGLEMDS failed"
30376         rm -rf $DIR/$tdir
30377
30378         local testid=$(echo $TESTNAME | tr '_' ' ')
30379
30380         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30381                 grep "run LFSCK" || error "run LFSCK is not suggested"
30382 }
30383 run_test 818 "unlink with failed llog"
30384
30385 test_819a() {
30386         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30387         cancel_lru_locks osc
30388         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30389         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30390         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30391         rm -f $TDIR/$tfile
30392 }
30393 run_test 819a "too big niobuf in read"
30394
30395 test_819b() {
30396         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30397         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30398         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30399         cancel_lru_locks osc
30400         sleep 1
30401         rm -f $TDIR/$tfile
30402 }
30403 run_test 819b "too big niobuf in write"
30404
30405
30406 function test_820_start_ost() {
30407         sleep 5
30408
30409         for num in $(seq $OSTCOUNT); do
30410                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30411         done
30412 }
30413
30414 test_820() {
30415         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30416
30417         mkdir $DIR/$tdir
30418         umount_client $MOUNT || error "umount failed"
30419         for num in $(seq $OSTCOUNT); do
30420                 stop ost$num
30421         done
30422
30423         # mount client with no active OSTs
30424         # so that the client can't initialize max LOV EA size
30425         # from OSC notifications
30426         mount_client $MOUNT || error "mount failed"
30427         # delay OST starting to keep this 0 max EA size for a while
30428         test_820_start_ost &
30429
30430         # create a directory on MDS2
30431         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30432                 error "Failed to create directory"
30433         # open intent should update default EA size
30434         # see mdc_update_max_ea_from_body()
30435         # notice this is the very first RPC to MDS2
30436         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30437         ret=$?
30438         echo $out
30439         # With SSK, this situation can lead to -EPERM being returned.
30440         # In that case, simply retry.
30441         if [ $ret -ne 0 ] && $SHARED_KEY; then
30442                 if echo "$out" | grep -q "not permitted"; then
30443                         cp /etc/services $DIR/$tdir/mds2
30444                         ret=$?
30445                 fi
30446         fi
30447         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30448 }
30449 run_test 820 "update max EA from open intent"
30450
30451 test_823() {
30452         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30453         local OST_MAX_PRECREATE=20000
30454
30455         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30456                 skip "Need MDS version at least 2.14.56"
30457
30458         save_lustre_params mds1 \
30459                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30460         do_facet $SINGLEMDS "$LCTL set_param -n \
30461                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30462         do_facet $SINGLEMDS "$LCTL set_param -n \
30463                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30464
30465         stack_trap "restore_lustre_params < $p; rm $p"
30466
30467         do_facet $SINGLEMDS "$LCTL set_param -n \
30468                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30469
30470         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30471                       osp.$FSNAME-OST0000*MDT0000.create_count")
30472         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30473                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30474         local expect_count=$(((($max/2)/256) * 256))
30475
30476         log "setting create_count to 100200:"
30477         log " -result- count: $count with max: $max, expecting: $expect_count"
30478
30479         [[ $count -eq expect_count ]] ||
30480                 error "Create count not set to max precreate."
30481 }
30482 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30483
30484 test_831() {
30485         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30486                 skip "Need MDS version 2.14.56"
30487
30488         local sync_changes=$(do_facet $SINGLEMDS \
30489                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30490
30491         [ "$sync_changes" -gt 100 ] &&
30492                 skip "Sync changes $sync_changes > 100 already"
30493
30494         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30495
30496         $LFS mkdir -i 0 $DIR/$tdir
30497         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30498
30499         save_lustre_params mds1 \
30500                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30501         save_lustre_params mds1 \
30502                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30503
30504         do_facet mds1 "$LCTL set_param -n \
30505                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30506                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30507         stack_trap "restore_lustre_params < $p" EXIT
30508
30509         createmany -o $DIR/$tdir/f- 1000
30510         unlinkmany $DIR/$tdir/f- 1000 &
30511         local UNLINK_PID=$!
30512
30513         while sleep 1; do
30514                 sync_changes=$(do_facet mds1 \
30515                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30516                 # the check in the code is racy, fail the test
30517                 # if the value above the limit by 10.
30518                 [ $sync_changes -gt 110 ] && {
30519                         kill -2 $UNLINK_PID
30520                         wait
30521                         error "osp changes throttling failed, $sync_changes>110"
30522                 }
30523                 kill -0 $UNLINK_PID 2> /dev/null || break
30524         done
30525         wait
30526 }
30527 run_test 831 "throttling unlink/setattr queuing on OSP"
30528
30529 test_832() {
30530         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30531         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30532                 skip "Need MDS version 2.15.52+"
30533         is_rmentry_supported || skip "rm_entry not supported"
30534
30535         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30536         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30537         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30538                 error "mkdir remote_dir failed"
30539         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30540                 error "mkdir striped_dir failed"
30541         touch $DIR/$tdir/file || error "touch file failed"
30542         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30543         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30544 }
30545 run_test 832 "lfs rm_entry"
30546
30547 test_833() {
30548         local file=$DIR/$tfile
30549
30550         stack_trap "rm -f $file" EXIT
30551         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30552
30553         local wpid
30554         local rpid
30555         local rpid2
30556
30557         # Buffered I/O write
30558         (
30559                 while [ ! -e $DIR/sanity.833.lck ]; do
30560                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30561                                 error "failed to write $file"
30562                         sleep 0.$((RANDOM % 4 + 1))
30563                 done
30564         )&
30565         wpid=$!
30566
30567         # Buffered I/O read
30568         (
30569                 while [ ! -e $DIR/sanity.833.lck ]; do
30570                         dd if=$file of=/dev/null bs=1M count=50 ||
30571                                 error "failed to read $file"
30572                         sleep 0.$((RANDOM % 4 + 1))
30573                 done
30574         )&
30575         rpid=$!
30576
30577         # Direct I/O read
30578         (
30579                 while [ ! -e $DIR/sanity.833.lck ]; do
30580                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30581                                 error "failed to read $file in direct I/O mode"
30582                         sleep 0.$((RANDOM % 4 + 1))
30583                 done
30584         )&
30585         rpid2=$!
30586
30587         sleep 30
30588         touch $DIR/sanity.833.lck
30589         wait $wpid || error "$?: buffered write failed"
30590         wait $rpid || error "$?: buffered read failed"
30591         wait $rpid2 || error "$?: direct read failed"
30592 }
30593 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30594
30595 #
30596 # tests that do cleanup/setup should be run at the end
30597 #
30598
30599 test_900() {
30600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30601         local ls
30602
30603         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30604         $LCTL set_param fail_loc=0x903
30605
30606         cancel_lru_locks MGC
30607
30608         FAIL_ON_ERROR=true cleanup
30609         FAIL_ON_ERROR=true setup
30610 }
30611 run_test 900 "umount should not race with any mgc requeue thread"
30612
30613 # LUS-6253/LU-11185
30614 test_901() {
30615         local old
30616         local count
30617         local oldc
30618         local newc
30619         local olds
30620         local news
30621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30622
30623         # some get_param have a bug to handle dot in param name
30624         cancel_lru_locks MGC
30625         old=$(mount -t lustre | wc -l)
30626         # 1 config+sptlrpc
30627         # 2 params
30628         # 3 nodemap
30629         # 4 IR
30630         old=$((old * 4))
30631         oldc=0
30632         count=0
30633         while [ $old -ne $oldc ]; do
30634                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30635                 sleep 1
30636                 ((count++))
30637                 if [ $count -ge $TIMEOUT ]; then
30638                         error "too large timeout"
30639                 fi
30640         done
30641         umount_client $MOUNT || error "umount failed"
30642         mount_client $MOUNT || error "mount failed"
30643         cancel_lru_locks MGC
30644         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30645
30646         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30647
30648         return 0
30649 }
30650 run_test 901 "don't leak a mgc lock on client umount"
30651
30652 # LU-13377
30653 test_902() {
30654         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30655                 skip "client does not have LU-13377 fix"
30656         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30657         $LCTL set_param fail_loc=0x1415
30658         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30659         cancel_lru_locks osc
30660         rm -f $DIR/$tfile
30661 }
30662 run_test 902 "test short write doesn't hang lustre"
30663
30664 # LU-14711
30665 test_903() {
30666         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30667         echo "blah" > $DIR/${tfile}-2
30668         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30669         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30670         $LCTL set_param fail_loc=0x417 fail_val=20
30671
30672         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30673         sleep 1 # To start the destroy
30674         wait_destroy_complete 150 || error "Destroy taking too long"
30675         cat $DIR/$tfile > /dev/null || error "Evicted"
30676 }
30677 run_test 903 "Test long page discard does not cause evictions"
30678
30679 test_904() {
30680         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30681         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30682                 grep -q project || skip "skip project quota not supported"
30683
30684         local testfile="$DIR/$tdir/$tfile"
30685         local xattr="trusted.projid"
30686         local projid
30687         local mdts=$(comma_list $(mdts_nodes))
30688         local saved=$(do_facet mds1 $LCTL get_param -n \
30689                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30690
30691         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30692         stack_trap "do_nodes $mdts $LCTL set_param \
30693                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30694
30695         mkdir -p $DIR/$tdir
30696         touch $testfile
30697         #hide projid xattr on server
30698         $LFS project -p 1 $testfile ||
30699                 error "set $testfile project id failed"
30700         getfattr -m - $testfile | grep $xattr &&
30701                 error "do not show trusted.projid when disabled on server"
30702         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30703         #should be hidden when projid is 0
30704         $LFS project -p 0 $testfile ||
30705                 error "set $testfile project id failed"
30706         getfattr -m - $testfile | grep $xattr &&
30707                 error "do not show trusted.projid with project ID 0"
30708
30709         #still can getxattr explicitly
30710         projid=$(getfattr -n $xattr $testfile |
30711                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30712         [ $projid == "0" ] ||
30713                 error "projid expected 0 not $projid"
30714
30715         #set the projid via setxattr
30716         setfattr -n $xattr -v "1000" $testfile ||
30717                 error "setattr failed with $?"
30718         projid=($($LFS project $testfile))
30719         [ ${projid[0]} == "1000" ] ||
30720                 error "projid expected 1000 not $projid"
30721
30722         #check the new projid via getxattr
30723         $LFS project -p 1001 $testfile ||
30724                 error "set $testfile project id failed"
30725         getfattr -m - $testfile | grep $xattr ||
30726                 error "should show trusted.projid when project ID != 0"
30727         projid=$(getfattr -n $xattr $testfile |
30728                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30729         [ $projid == "1001" ] ||
30730                 error "projid expected 1001 not $projid"
30731
30732         #try to set invalid projid
30733         setfattr -n $xattr -v "4294967295" $testfile &&
30734                 error "set invalid projid should fail"
30735
30736         #remove the xattr means setting projid to 0
30737         setfattr -x $xattr $testfile ||
30738                 error "setfattr failed with $?"
30739         projid=($($LFS project $testfile))
30740         [ ${projid[0]} == "0" ] ||
30741                 error "projid expected 0 not $projid"
30742
30743         #should be hidden when parent has inherit flag and same projid
30744         $LFS project -srp 1002 $DIR/$tdir ||
30745                 error "set $tdir project id failed"
30746         getfattr -m - $testfile | grep $xattr &&
30747                 error "do not show trusted.projid with inherit flag"
30748
30749         #still can getxattr explicitly
30750         projid=$(getfattr -n $xattr $testfile |
30751                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30752         [ $projid == "1002" ] ||
30753                 error "projid expected 1002 not $projid"
30754 }
30755 run_test 904 "virtual project ID xattr"
30756
30757 # LU-8582
30758 test_905() {
30759         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30760                 skip "need OST version >= 2.15.50.220 for fail_loc"
30761
30762         remote_ost_nodsh && skip "remote OST with nodsh"
30763         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30764
30765         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30766
30767         #define OBD_FAIL_OST_OPCODE 0x253
30768         # OST_LADVISE = 21
30769         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30770         $LFS ladvise -a willread $DIR/$tfile &&
30771                 error "unexpected success of ladvise with fault injection"
30772         $LFS ladvise -a willread $DIR/$tfile |&
30773                 grep -q "Operation not supported"
30774         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30775 }
30776 run_test 905 "bad or new opcode should not stuck client"
30777
30778 test_906() {
30779         grep -q io_uring_setup /proc/kallsyms ||
30780                 skip "Client OS does not support io_uring I/O engine"
30781         io_uring_probe || skip "kernel does not support io_uring fully"
30782         which fio || skip_env "no fio installed"
30783         fio --enghelp | grep -q io_uring ||
30784                 skip_env "fio does not support io_uring I/O engine"
30785
30786         local file=$DIR/$tfile
30787         local ioengine="io_uring"
30788         local numjobs=2
30789         local size=50M
30790
30791         fio --name=seqwrite --ioengine=$ioengine        \
30792                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30793                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30794                 error "fio seqwrite $file failed"
30795
30796         fio --name=seqread --ioengine=$ioengine \
30797                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30798                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30799                 error "fio seqread $file failed"
30800
30801         rm -f $file || error "rm -f $file failed"
30802 }
30803 run_test 906 "Simple test for io_uring I/O engine via fio"
30804
30805 complete_test $SECONDS
30806 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30807 check_and_cleanup_lustre
30808 if [ "$I_MOUNTED" != "yes" ]; then
30809         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30810 fi
30811 exit_status