Whamcloud - gitweb
LU-16838 tests: use import name in 398a
[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         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3729         return 0
3730 }
3731 run_test 31j "link for directory"
3732
3733 test_31k() {
3734         test_mkdir -c1 -p $DIR/$tdir
3735         touch $DIR/$tdir/s
3736         touch $DIR/$tdir/exist
3737         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3738         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3739         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3740         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3741         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3742         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3743         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3744         return 0
3745 }
3746 run_test 31k "link to file: the same, non-existing, dir"
3747
3748 test_31l() {
3749         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3750
3751         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3752         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3753                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3754
3755         touch $DIR/$tfile || error "create failed"
3756         mkdir $DIR/$tdir || error "mkdir failed"
3757         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3758 }
3759 run_test 31l "link to file: target dir has trailing slash"
3760
3761 test_31m() {
3762         mkdir $DIR/d31m
3763         touch $DIR/d31m/s
3764         mkdir $DIR/d31m2
3765         touch $DIR/d31m2/exist
3766         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3767         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3768         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3769         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3770         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3771         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3772         return 0
3773 }
3774 run_test 31m "link to file: the same, non-existing, dir"
3775
3776 test_31n() {
3777         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3778         nlink=$(stat --format=%h $DIR/$tfile)
3779         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3780         local fd=$(free_fd)
3781         local cmd="exec $fd<$DIR/$tfile"
3782         eval $cmd
3783         cmd="exec $fd<&-"
3784         trap "eval $cmd" EXIT
3785         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3786         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3787         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3788         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3789         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3790         eval $cmd
3791 }
3792 run_test 31n "check link count of unlinked file"
3793
3794 link_one() {
3795         local tempfile=$(mktemp $1_XXXXXX)
3796         link $tempfile $1 2> /dev/null &&
3797                 echo "$BASHPID: link $tempfile to $1 succeeded"
3798         unlink $tempfile
3799 }
3800
3801 test_31o() { # LU-2901
3802         test_mkdir $DIR/$tdir
3803         for LOOP in $(seq 100); do
3804                 rm -f $DIR/$tdir/$tfile*
3805                 for THREAD in $(seq 8); do
3806                         link_one $DIR/$tdir/$tfile.$LOOP &
3807                 done
3808                 wait
3809                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3810                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3811                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3812                         break || true
3813         done
3814 }
3815 run_test 31o "duplicate hard links with same filename"
3816
3817 test_31p() {
3818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3819
3820         test_mkdir $DIR/$tdir
3821         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3822         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3823
3824         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3825                 error "open unlink test1 failed"
3826         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3827                 error "open unlink test2 failed"
3828
3829         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3830                 error "test1 still exists"
3831         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3832                 error "test2 still exists"
3833 }
3834 run_test 31p "remove of open striped directory"
3835
3836 test_31q() {
3837         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3838
3839         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3840         index=$($LFS getdirstripe -i $DIR/$tdir)
3841         [ $index -eq 3 ] || error "first stripe index $index != 3"
3842         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3843         [ $index -eq 1 ] || error "second stripe index $index != 1"
3844
3845         # when "-c <stripe_count>" is set, the number of MDTs specified after
3846         # "-i" should equal to the stripe count
3847         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3848 }
3849 run_test 31q "create striped directory on specific MDTs"
3850
3851 #LU-14949
3852 test_31r() {
3853         touch $DIR/$tfile.target
3854         touch $DIR/$tfile.source
3855
3856         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3857         $LCTL set_param fail_loc=0x1419 fail_val=3
3858         cat $DIR/$tfile.target &
3859         CATPID=$!
3860
3861         # Guarantee open is waiting before we get here
3862         sleep 1
3863         mv $DIR/$tfile.source $DIR/$tfile.target
3864
3865         wait $CATPID
3866         RC=$?
3867         if [[ $RC -ne 0 ]]; then
3868                 error "open with cat failed, rc=$RC"
3869         fi
3870 }
3871 run_test 31r "open-rename(replace) race"
3872
3873 cleanup_test32_mount() {
3874         local rc=0
3875         trap 0
3876         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3877         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3878         losetup -d $loopdev || true
3879         rm -rf $DIR/$tdir
3880         return $rc
3881 }
3882
3883 test_32a() {
3884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3885
3886         echo "== more mountpoints and symlinks ================="
3887         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3888         trap cleanup_test32_mount EXIT
3889         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3890         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3891                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3892         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3893                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3894         cleanup_test32_mount
3895 }
3896 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3897
3898 test_32b() {
3899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3900
3901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3902         trap cleanup_test32_mount EXIT
3903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3904         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3905                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3906         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3907                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3908         cleanup_test32_mount
3909 }
3910 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3911
3912 test_32c() {
3913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3914
3915         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3916         trap cleanup_test32_mount EXIT
3917         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3918         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3919                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3920         test_mkdir -p $DIR/$tdir/d2/test_dir
3921         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3922                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3923         cleanup_test32_mount
3924 }
3925 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3926
3927 test_32d() {
3928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3929
3930         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3931         trap cleanup_test32_mount EXIT
3932         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3933         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3934                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3935         test_mkdir -p $DIR/$tdir/d2/test_dir
3936         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3937                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3938         cleanup_test32_mount
3939 }
3940 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3941
3942 test_32e() {
3943         rm -fr $DIR/$tdir
3944         test_mkdir -p $DIR/$tdir/tmp
3945         local tmp_dir=$DIR/$tdir/tmp
3946         ln -s $DIR/$tdir $tmp_dir/symlink11
3947         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3948         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3949         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3950 }
3951 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3952
3953 test_32f() {
3954         rm -fr $DIR/$tdir
3955         test_mkdir -p $DIR/$tdir/tmp
3956         local tmp_dir=$DIR/$tdir/tmp
3957         ln -s $DIR/$tdir $tmp_dir/symlink11
3958         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3959         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3960         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3961 }
3962 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3963
3964 test_32g() {
3965         local tmp_dir=$DIR/$tdir/tmp
3966         test_mkdir -p $tmp_dir
3967         test_mkdir $DIR/${tdir}2
3968         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3969         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3970         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3971         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3972         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3973         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3974 }
3975 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3976
3977 test_32h() {
3978         rm -fr $DIR/$tdir $DIR/${tdir}2
3979         tmp_dir=$DIR/$tdir/tmp
3980         test_mkdir -p $tmp_dir
3981         test_mkdir $DIR/${tdir}2
3982         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3983         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3984         ls $tmp_dir/symlink12 || error "listing symlink12"
3985         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3986 }
3987 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3988
3989 test_32i() {
3990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3991
3992         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3993         trap cleanup_test32_mount EXIT
3994         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3995         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3996                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3997         touch $DIR/$tdir/test_file
3998         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3999                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4000         cleanup_test32_mount
4001 }
4002 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4003
4004 test_32j() {
4005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4006
4007         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4008         trap cleanup_test32_mount EXIT
4009         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4010         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4011                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4012         touch $DIR/$tdir/test_file
4013         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4014                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4015         cleanup_test32_mount
4016 }
4017 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4018
4019 test_32k() {
4020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4021
4022         rm -fr $DIR/$tdir
4023         trap cleanup_test32_mount EXIT
4024         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4025         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4026                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4027         test_mkdir -p $DIR/$tdir/d2
4028         touch $DIR/$tdir/d2/test_file || error "touch failed"
4029         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4030                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4031         cleanup_test32_mount
4032 }
4033 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4034
4035 test_32l() {
4036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4037
4038         rm -fr $DIR/$tdir
4039         trap cleanup_test32_mount EXIT
4040         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4041         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4042                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4043         test_mkdir -p $DIR/$tdir/d2
4044         touch $DIR/$tdir/d2/test_file || error "touch failed"
4045         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4046                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4047         cleanup_test32_mount
4048 }
4049 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4050
4051 test_32m() {
4052         rm -fr $DIR/d32m
4053         test_mkdir -p $DIR/d32m/tmp
4054         TMP_DIR=$DIR/d32m/tmp
4055         ln -s $DIR $TMP_DIR/symlink11
4056         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4057         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4058                 error "symlink11 not a link"
4059         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4060                 error "symlink01 not a link"
4061 }
4062 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4063
4064 test_32n() {
4065         rm -fr $DIR/d32n
4066         test_mkdir -p $DIR/d32n/tmp
4067         TMP_DIR=$DIR/d32n/tmp
4068         ln -s $DIR $TMP_DIR/symlink11
4069         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4070         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4071         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4072 }
4073 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4074
4075 test_32o() {
4076         touch $DIR/$tfile
4077         test_mkdir -p $DIR/d32o/tmp
4078         TMP_DIR=$DIR/d32o/tmp
4079         ln -s $DIR/$tfile $TMP_DIR/symlink12
4080         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4081         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4082                 error "symlink12 not a link"
4083         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4084         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4085                 error "$DIR/d32o/tmp/symlink12 not file type"
4086         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4087                 error "$DIR/d32o/symlink02 not file type"
4088 }
4089 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4090
4091 test_32p() {
4092         log 32p_1
4093         rm -fr $DIR/d32p
4094         log 32p_2
4095         rm -f $DIR/$tfile
4096         log 32p_3
4097         touch $DIR/$tfile
4098         log 32p_4
4099         test_mkdir -p $DIR/d32p/tmp
4100         log 32p_5
4101         TMP_DIR=$DIR/d32p/tmp
4102         log 32p_6
4103         ln -s $DIR/$tfile $TMP_DIR/symlink12
4104         log 32p_7
4105         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4106         log 32p_8
4107         cat $DIR/d32p/tmp/symlink12 ||
4108                 error "Can't open $DIR/d32p/tmp/symlink12"
4109         log 32p_9
4110         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4111         log 32p_10
4112 }
4113 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4114
4115 test_32q() {
4116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4117
4118         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4119         trap cleanup_test32_mount EXIT
4120         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4121         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4122         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4123                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4124         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4125         cleanup_test32_mount
4126 }
4127 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4128
4129 test_32r() {
4130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4131
4132         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4133         trap cleanup_test32_mount EXIT
4134         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4135         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4136         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4137                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4138         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4139         cleanup_test32_mount
4140 }
4141 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4142
4143 test_33aa() {
4144         rm -f $DIR/$tfile
4145         touch $DIR/$tfile
4146         chmod 444 $DIR/$tfile
4147         chown $RUNAS_ID $DIR/$tfile
4148         log 33_1
4149         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4150         log 33_2
4151 }
4152 run_test 33aa "write file with mode 444 (should return error)"
4153
4154 test_33a() {
4155         rm -fr $DIR/$tdir
4156         test_mkdir $DIR/$tdir
4157         chown $RUNAS_ID $DIR/$tdir
4158         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4159                 error "$RUNAS create $tdir/$tfile failed"
4160         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4161                 error "open RDWR" || true
4162 }
4163 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4164
4165 test_33b() {
4166         rm -fr $DIR/$tdir
4167         test_mkdir $DIR/$tdir
4168         chown $RUNAS_ID $DIR/$tdir
4169         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4170 }
4171 run_test 33b "test open file with malformed flags (No panic)"
4172
4173 test_33c() {
4174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4175         remote_ost_nodsh && skip "remote OST with nodsh"
4176
4177         local ostnum
4178         local ostname
4179         local write_bytes
4180         local all_zeros
4181
4182         all_zeros=true
4183         test_mkdir $DIR/$tdir
4184         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4185
4186         sync
4187         for ostnum in $(seq $OSTCOUNT); do
4188                 # test-framework's OST numbering is one-based, while Lustre's
4189                 # is zero-based
4190                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4191                 # check if at least some write_bytes stats are counted
4192                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4193                               obdfilter.$ostname.stats |
4194                               awk '/^write_bytes/ {print $7}' )
4195                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4196                 if (( ${write_bytes:-0} > 0 )); then
4197                         all_zeros=false
4198                         break
4199                 fi
4200         done
4201
4202         $all_zeros || return 0
4203
4204         # Write four bytes
4205         echo foo > $DIR/$tdir/bar
4206         # Really write them
4207         sync
4208
4209         # Total up write_bytes after writing.  We'd better find non-zeros.
4210         for ostnum in $(seq $OSTCOUNT); do
4211                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4212                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4213                               obdfilter/$ostname/stats |
4214                               awk '/^write_bytes/ {print $7}' )
4215                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4216                 if (( ${write_bytes:-0} > 0 )); then
4217                         all_zeros=false
4218                         break
4219                 fi
4220         done
4221
4222         if $all_zeros; then
4223                 for ostnum in $(seq $OSTCOUNT); do
4224                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4225                         echo "Check write_bytes is in obdfilter.*.stats:"
4226                         do_facet ost$ostnum lctl get_param -n \
4227                                 obdfilter.$ostname.stats
4228                 done
4229                 error "OST not keeping write_bytes stats (b=22312)"
4230         fi
4231 }
4232 run_test 33c "test write_bytes stats"
4233
4234 test_33d() {
4235         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4237
4238         local MDTIDX=1
4239         local remote_dir=$DIR/$tdir/remote_dir
4240
4241         test_mkdir $DIR/$tdir
4242         $LFS mkdir -i $MDTIDX $remote_dir ||
4243                 error "create remote directory failed"
4244
4245         touch $remote_dir/$tfile
4246         chmod 444 $remote_dir/$tfile
4247         chown $RUNAS_ID $remote_dir/$tfile
4248
4249         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4250
4251         chown $RUNAS_ID $remote_dir
4252         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4253                                         error "create" || true
4254         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4255                                     error "open RDWR" || true
4256         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4257 }
4258 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4259
4260 test_33e() {
4261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4262
4263         mkdir $DIR/$tdir
4264
4265         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4266         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4267         mkdir $DIR/$tdir/local_dir
4268
4269         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4270         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4271         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4272
4273         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4274                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4275
4276         rmdir $DIR/$tdir/* || error "rmdir failed"
4277
4278         umask 777
4279         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4280         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4281         mkdir $DIR/$tdir/local_dir
4282
4283         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4284         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4285         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4286
4287         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4288                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4289
4290         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4291
4292         umask 000
4293         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4294         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4295         mkdir $DIR/$tdir/local_dir
4296
4297         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4298         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4299         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4300
4301         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4302                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4303 }
4304 run_test 33e "mkdir and striped directory should have same mode"
4305
4306 cleanup_33f() {
4307         trap 0
4308         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4309 }
4310
4311 test_33f() {
4312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4313         remote_mds_nodsh && skip "remote MDS with nodsh"
4314
4315         mkdir $DIR/$tdir
4316         chmod go+rwx $DIR/$tdir
4317         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4318         trap cleanup_33f EXIT
4319
4320         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4321                 error "cannot create striped directory"
4322
4323         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4324                 error "cannot create files in striped directory"
4325
4326         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4327                 error "cannot remove files in striped directory"
4328
4329         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4330                 error "cannot remove striped directory"
4331
4332         cleanup_33f
4333 }
4334 run_test 33f "nonroot user can create, access, and remove a striped directory"
4335
4336 test_33g() {
4337         mkdir -p $DIR/$tdir/dir2
4338
4339         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4340         echo $err
4341         [[ $err =~ "exists" ]] || error "Not exists error"
4342 }
4343 run_test 33g "nonroot user create already existing root created file"
4344
4345 sub_33h() {
4346         local hash_type=$1
4347         local count=250
4348
4349         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4350                 error "lfs mkdir -H $hash_type $tdir failed"
4351         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4352
4353         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4354         local index2
4355         local fname
4356
4357         for fname in $DIR/$tdir/$tfile.bak \
4358                      $DIR/$tdir/$tfile.SAV \
4359                      $DIR/$tdir/$tfile.orig \
4360                      $DIR/$tdir/$tfile~; do
4361                 touch $fname || error "touch $fname failed"
4362                 index2=$($LFS getstripe -m $fname)
4363                 (( $index == $index2 )) ||
4364                         error "$fname MDT index mismatch $index != $index2"
4365         done
4366
4367         local failed=0
4368         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4369         local pattern
4370
4371         for pattern in ${patterns[*]}; do
4372                 echo "pattern $pattern"
4373                 fname=$DIR/$tdir/$pattern
4374                 for (( i = 0; i < $count; i++ )); do
4375                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4376                                 error "mktemp $DIR/$tdir/$pattern failed"
4377                         index2=$($LFS getstripe -m $fname)
4378                         (( $index == $index2 )) && continue
4379
4380                         failed=$((failed + 1))
4381                         echo "$fname MDT index mismatch $index != $index2"
4382                 done
4383         done
4384
4385         echo "$failed/$count MDT index mismatches, expect ~2-4"
4386         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4387
4388         local same=0
4389         local expect
4390
4391         # verify that "crush" is still broken with all files on same MDT,
4392         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4393         [[ "$hash_type" == "crush" ]] && expect=$count ||
4394                 expect=$((count / MDSCOUNT))
4395
4396         # crush2 doesn't put all-numeric suffixes on the same MDT,
4397         # filename like $tfile.12345678 should *not* be considered temp
4398         for pattern in ${patterns[*]}; do
4399                 local base=${pattern%%X*}
4400                 local suff=${pattern#$base}
4401
4402                 echo "pattern $pattern"
4403                 for (( i = 0; i < $count; i++ )); do
4404                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4405                         touch $fname || error "touch $fname failed"
4406                         index2=$($LFS getstripe -m $fname)
4407                         (( $index != $index2 )) && continue
4408
4409                         same=$((same + 1))
4410                 done
4411         done
4412
4413         # the number of "bad" hashes is random, as it depends on the random
4414         # filenames generated by "mktemp".  Allow some margin in the results.
4415         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4416         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4417            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4418                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4419         same=0
4420
4421         # crush2 doesn't put suffixes with special characters on the same MDT
4422         # filename like $tfile.txt.1234 should *not* be considered temp
4423         for pattern in ${patterns[*]}; do
4424                 local base=${pattern%%X*}
4425                 local suff=${pattern#$base}
4426
4427                 pattern=$base...${suff/XXX}
4428                 echo "pattern=$pattern"
4429                 for (( i = 0; i < $count; i++ )); do
4430                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4431                                 error "touch $fname failed"
4432                         index2=$($LFS getstripe -m $fname)
4433                         (( $index != $index2 )) && continue
4434
4435                         same=$((same + 1))
4436                 done
4437         done
4438
4439         # the number of "bad" hashes is random, as it depends on the random
4440         # filenames generated by "mktemp".  Allow some margin in the results.
4441         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4442         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4443            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4444                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4445 }
4446
4447 test_33h() {
4448         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4449         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4450                 skip "Need MDS version at least 2.13.50"
4451
4452         sub_33h crush
4453 }
4454 run_test 33h "temp file is located on the same MDT as target (crush)"
4455
4456 test_33hh() {
4457         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4458         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4459         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4460                 skip "Need MDS version at least 2.15.0 for crush2"
4461
4462         sub_33h crush2
4463 }
4464 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4465
4466 test_33i()
4467 {
4468         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4469
4470         local FNAME=$(str_repeat 'f' 250)
4471
4472         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4473         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4474
4475         local count
4476         local total
4477
4478         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4479
4480         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4481
4482         lctl --device %$MDC deactivate
4483         stack_trap "lctl --device %$MDC activate"
4484         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4485         total=$(\ls -l $DIR/$tdir | wc -l)
4486         # "ls -l" will list total in the first line
4487         total=$((total - 1))
4488         (( total + count == 1000 )) ||
4489                 error "ls list $total files, $count files on MDT1"
4490 }
4491 run_test 33i "striped directory can be accessed when one MDT is down"
4492
4493 test_33j() {
4494         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4495
4496         mkdir -p $DIR/$tdir/
4497
4498         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4499                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4500
4501         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4502                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4503
4504         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4505                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4506
4507         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4508                 error "-D was not specified, but still failed"
4509 }
4510 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4511
4512 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4513 test_34a() {
4514         rm -f $DIR/f34
4515         $MCREATE $DIR/f34 || error "mcreate failed"
4516         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4517                 error "getstripe failed"
4518         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4519         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4520                 error "getstripe failed"
4521         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4522                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4523 }
4524 run_test 34a "truncate file that has not been opened ==========="
4525
4526 test_34b() {
4527         [ ! -f $DIR/f34 ] && test_34a
4528         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4529                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4530         $OPENFILE -f O_RDONLY $DIR/f34
4531         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4532                 error "getstripe failed"
4533         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4534                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4535 }
4536 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4537
4538 test_34c() {
4539         [ ! -f $DIR/f34 ] && test_34a
4540         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4541                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4542         $OPENFILE -f O_RDWR $DIR/f34
4543         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4544                 error "$LFS getstripe failed"
4545         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4546                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4547 }
4548 run_test 34c "O_RDWR opening file-with-size works =============="
4549
4550 test_34d() {
4551         [ ! -f $DIR/f34 ] && test_34a
4552         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4553                 error "dd failed"
4554         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4555                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4556         rm $DIR/f34
4557 }
4558 run_test 34d "write to sparse file ============================="
4559
4560 test_34e() {
4561         rm -f $DIR/f34e
4562         $MCREATE $DIR/f34e || error "mcreate failed"
4563         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4564         $CHECKSTAT -s 1000 $DIR/f34e ||
4565                 error "Size of $DIR/f34e not equal to 1000 bytes"
4566         $OPENFILE -f O_RDWR $DIR/f34e
4567         $CHECKSTAT -s 1000 $DIR/f34e ||
4568                 error "Size of $DIR/f34e not equal to 1000 bytes"
4569 }
4570 run_test 34e "create objects, some with size and some without =="
4571
4572 test_34f() { # bug 6242, 6243
4573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4574
4575         SIZE34F=48000
4576         rm -f $DIR/f34f
4577         $MCREATE $DIR/f34f || error "mcreate failed"
4578         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4579         dd if=$DIR/f34f of=$TMP/f34f
4580         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4581         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4582         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4583         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4584         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4585 }
4586 run_test 34f "read from a file with no objects until EOF ======="
4587
4588 test_34g() {
4589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4590
4591         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4592                 error "dd failed"
4593         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4594         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4595                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4596         cancel_lru_locks osc
4597         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4598                 error "wrong size after lock cancel"
4599
4600         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4602                 error "expanding truncate failed"
4603         cancel_lru_locks osc
4604         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4605                 error "wrong expanded size after lock cancel"
4606 }
4607 run_test 34g "truncate long file ==============================="
4608
4609 test_34h() {
4610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4611
4612         local gid=10
4613         local sz=1000
4614
4615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4616         sync # Flush the cache so that multiop below does not block on cache
4617              # flush when getting the group lock
4618         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4619         MULTIPID=$!
4620
4621         # Since just timed wait is not good enough, let's do a sync write
4622         # that way we are sure enough time for a roundtrip + processing
4623         # passed + 2 seconds of extra margin.
4624         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4625         rm $DIR/${tfile}-1
4626         sleep 2
4627
4628         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4629                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4630                 kill -9 $MULTIPID
4631         fi
4632         wait $MULTIPID
4633         local nsz=`stat -c %s $DIR/$tfile`
4634         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4635 }
4636 run_test 34h "ftruncate file under grouplock should not block"
4637
4638 test_35a() {
4639         cp /bin/sh $DIR/f35a
4640         chmod 444 $DIR/f35a
4641         chown $RUNAS_ID $DIR/f35a
4642         $RUNAS $DIR/f35a && error || true
4643         rm $DIR/f35a
4644 }
4645 run_test 35a "exec file with mode 444 (should return and not leak)"
4646
4647 test_36a() {
4648         rm -f $DIR/f36
4649         utime $DIR/f36 || error "utime failed for MDS"
4650 }
4651 run_test 36a "MDS utime check (mknod, utime)"
4652
4653 test_36b() {
4654         echo "" > $DIR/f36
4655         utime $DIR/f36 || error "utime failed for OST"
4656 }
4657 run_test 36b "OST utime check (open, utime)"
4658
4659 test_36c() {
4660         rm -f $DIR/d36/f36
4661         test_mkdir $DIR/d36
4662         chown $RUNAS_ID $DIR/d36
4663         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4664 }
4665 run_test 36c "non-root MDS utime check (mknod, utime)"
4666
4667 test_36d() {
4668         [ ! -d $DIR/d36 ] && test_36c
4669         echo "" > $DIR/d36/f36
4670         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4671 }
4672 run_test 36d "non-root OST utime check (open, utime)"
4673
4674 test_36e() {
4675         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4676
4677         test_mkdir $DIR/$tdir
4678         touch $DIR/$tdir/$tfile
4679         $RUNAS utime $DIR/$tdir/$tfile &&
4680                 error "utime worked, expected failure" || true
4681 }
4682 run_test 36e "utime on non-owned file (should return error)"
4683
4684 subr_36fh() {
4685         local fl="$1"
4686         local LANG_SAVE=$LANG
4687         local LC_LANG_SAVE=$LC_LANG
4688         export LANG=C LC_LANG=C # for date language
4689
4690         DATESTR="Dec 20  2000"
4691         test_mkdir $DIR/$tdir
4692         lctl set_param fail_loc=$fl
4693         date; date +%s
4694         cp /etc/hosts $DIR/$tdir/$tfile
4695         sync & # write RPC generated with "current" inode timestamp, but delayed
4696         sleep 1
4697         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4698         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4699         cancel_lru_locks $OSC
4700         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4701         date; date +%s
4702         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4703                 echo "BEFORE: $LS_BEFORE" && \
4704                 echo "AFTER : $LS_AFTER" && \
4705                 echo "WANT  : $DATESTR" && \
4706                 error "$DIR/$tdir/$tfile timestamps changed" || true
4707
4708         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4709 }
4710
4711 test_36f() {
4712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4713
4714         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4715         subr_36fh "0x80000214"
4716 }
4717 run_test 36f "utime on file racing with OST BRW write =========="
4718
4719 test_36g() {
4720         remote_ost_nodsh && skip "remote OST with nodsh"
4721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4722         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4723                 skip "Need MDS version at least 2.12.51"
4724
4725         local fmd_max_age
4726         local fmd
4727         local facet="ost1"
4728         local tgt="obdfilter"
4729
4730         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4731
4732         test_mkdir $DIR/$tdir
4733         fmd_max_age=$(do_facet $facet \
4734                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4735                 head -n 1")
4736
4737         echo "FMD max age: ${fmd_max_age}s"
4738         touch $DIR/$tdir/$tfile
4739         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4740                 gawk '{cnt=cnt+$1}  END{print cnt}')
4741         echo "FMD before: $fmd"
4742         [[ $fmd == 0 ]] &&
4743                 error "FMD wasn't create by touch"
4744         sleep $((fmd_max_age + 12))
4745         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4746                 gawk '{cnt=cnt+$1}  END{print cnt}')
4747         echo "FMD after: $fmd"
4748         [[ $fmd == 0 ]] ||
4749                 error "FMD wasn't expired by ping"
4750 }
4751 run_test 36g "FMD cache expiry ====================="
4752
4753 test_36h() {
4754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4755
4756         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4757         subr_36fh "0x80000227"
4758 }
4759 run_test 36h "utime on file racing with OST BRW write =========="
4760
4761 test_36i() {
4762         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4763
4764         test_mkdir $DIR/$tdir
4765         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4766
4767         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4768         local new_mtime=$((mtime + 200))
4769
4770         #change Modify time of striped dir
4771         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4772                         error "change mtime failed"
4773
4774         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4775
4776         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4777 }
4778 run_test 36i "change mtime on striped directory"
4779
4780 # test_37 - duplicate with tests 32q 32r
4781
4782 test_38() {
4783         local file=$DIR/$tfile
4784         touch $file
4785         openfile -f O_DIRECTORY $file
4786         local RC=$?
4787         local ENOTDIR=20
4788         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4789         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4790 }
4791 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4792
4793 test_39a() { # was test_39
4794         touch $DIR/$tfile
4795         touch $DIR/${tfile}2
4796 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4797 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4798 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4799         sleep 2
4800         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4801         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4802                 echo "mtime"
4803                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4804                 echo "atime"
4805                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4806                 echo "ctime"
4807                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4808                 error "O_TRUNC didn't change timestamps"
4809         fi
4810 }
4811 run_test 39a "mtime changed on create"
4812
4813 test_39b() {
4814         test_mkdir -c1 $DIR/$tdir
4815         cp -p /etc/passwd $DIR/$tdir/fopen
4816         cp -p /etc/passwd $DIR/$tdir/flink
4817         cp -p /etc/passwd $DIR/$tdir/funlink
4818         cp -p /etc/passwd $DIR/$tdir/frename
4819         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4820
4821         sleep 1
4822         echo "aaaaaa" >> $DIR/$tdir/fopen
4823         echo "aaaaaa" >> $DIR/$tdir/flink
4824         echo "aaaaaa" >> $DIR/$tdir/funlink
4825         echo "aaaaaa" >> $DIR/$tdir/frename
4826
4827         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4828         local link_new=`stat -c %Y $DIR/$tdir/flink`
4829         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4830         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4831
4832         cat $DIR/$tdir/fopen > /dev/null
4833         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4834         rm -f $DIR/$tdir/funlink2
4835         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4836
4837         for (( i=0; i < 2; i++ )) ; do
4838                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4839                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4840                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4841                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4842
4843                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4844                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4845                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4846                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4847
4848                 cancel_lru_locks $OSC
4849                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4850         done
4851 }
4852 run_test 39b "mtime change on open, link, unlink, rename  ======"
4853
4854 # this should be set to past
4855 TEST_39_MTIME=`date -d "1 year ago" +%s`
4856
4857 # bug 11063
4858 test_39c() {
4859         touch $DIR1/$tfile
4860         sleep 2
4861         local mtime0=`stat -c %Y $DIR1/$tfile`
4862
4863         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4864         local mtime1=`stat -c %Y $DIR1/$tfile`
4865         [ "$mtime1" = $TEST_39_MTIME ] || \
4866                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4867
4868         local d1=`date +%s`
4869         echo hello >> $DIR1/$tfile
4870         local d2=`date +%s`
4871         local mtime2=`stat -c %Y $DIR1/$tfile`
4872         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4873                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4874
4875         mv $DIR1/$tfile $DIR1/$tfile-1
4876
4877         for (( i=0; i < 2; i++ )) ; do
4878                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4879                 [ "$mtime2" = "$mtime3" ] || \
4880                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4881
4882                 cancel_lru_locks $OSC
4883                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4884         done
4885 }
4886 run_test 39c "mtime change on rename ==========================="
4887
4888 # bug 21114
4889 test_39d() {
4890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4891
4892         touch $DIR1/$tfile
4893         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4894
4895         for (( i=0; i < 2; i++ )) ; do
4896                 local mtime=`stat -c %Y $DIR1/$tfile`
4897                 [ $mtime = $TEST_39_MTIME ] || \
4898                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4899
4900                 cancel_lru_locks $OSC
4901                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4902         done
4903 }
4904 run_test 39d "create, utime, stat =============================="
4905
4906 # bug 21114
4907 test_39e() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         touch $DIR1/$tfile
4911         local mtime1=`stat -c %Y $DIR1/$tfile`
4912
4913         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4914
4915         for (( i=0; i < 2; i++ )) ; do
4916                 local mtime2=`stat -c %Y $DIR1/$tfile`
4917                 [ $mtime2 = $TEST_39_MTIME ] || \
4918                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4919
4920                 cancel_lru_locks $OSC
4921                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4922         done
4923 }
4924 run_test 39e "create, stat, utime, stat ========================"
4925
4926 # bug 21114
4927 test_39f() {
4928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4929
4930         touch $DIR1/$tfile
4931         mtime1=`stat -c %Y $DIR1/$tfile`
4932
4933         sleep 2
4934         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local mtime2=`stat -c %Y $DIR1/$tfile`
4938                 [ $mtime2 = $TEST_39_MTIME ] || \
4939                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4940
4941                 cancel_lru_locks $OSC
4942                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4943         done
4944 }
4945 run_test 39f "create, stat, sleep, utime, stat ================="
4946
4947 # bug 11063
4948 test_39g() {
4949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4950
4951         echo hello >> $DIR1/$tfile
4952         local mtime1=`stat -c %Y $DIR1/$tfile`
4953
4954         sleep 2
4955         chmod o+r $DIR1/$tfile
4956
4957         for (( i=0; i < 2; i++ )) ; do
4958                 local mtime2=`stat -c %Y $DIR1/$tfile`
4959                 [ "$mtime1" = "$mtime2" ] || \
4960                         error "lost mtime: $mtime2, should be $mtime1"
4961
4962                 cancel_lru_locks $OSC
4963                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4964         done
4965 }
4966 run_test 39g "write, chmod, stat ==============================="
4967
4968 # bug 11063
4969 test_39h() {
4970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4971
4972         touch $DIR1/$tfile
4973         sleep 1
4974
4975         local d1=`date`
4976         echo hello >> $DIR1/$tfile
4977         local mtime1=`stat -c %Y $DIR1/$tfile`
4978
4979         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4980         local d2=`date`
4981         if [ "$d1" != "$d2" ]; then
4982                 echo "write and touch not within one second"
4983         else
4984                 for (( i=0; i < 2; i++ )) ; do
4985                         local mtime2=`stat -c %Y $DIR1/$tfile`
4986                         [ "$mtime2" = $TEST_39_MTIME ] || \
4987                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4988
4989                         cancel_lru_locks $OSC
4990                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4991                 done
4992         fi
4993 }
4994 run_test 39h "write, utime within one second, stat ============="
4995
4996 test_39i() {
4997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4998
4999         touch $DIR1/$tfile
5000         sleep 1
5001
5002         echo hello >> $DIR1/$tfile
5003         local mtime1=`stat -c %Y $DIR1/$tfile`
5004
5005         mv $DIR1/$tfile $DIR1/$tfile-1
5006
5007         for (( i=0; i < 2; i++ )) ; do
5008                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5009
5010                 [ "$mtime1" = "$mtime2" ] || \
5011                         error "lost mtime: $mtime2, should be $mtime1"
5012
5013                 cancel_lru_locks $OSC
5014                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5015         done
5016 }
5017 run_test 39i "write, rename, stat =============================="
5018
5019 test_39j() {
5020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5021
5022         start_full_debug_logging
5023         touch $DIR1/$tfile
5024         sleep 1
5025
5026         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5027         lctl set_param fail_loc=0x80000412
5028         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5029                 error "multiop failed"
5030         local multipid=$!
5031         local mtime1=`stat -c %Y $DIR1/$tfile`
5032
5033         mv $DIR1/$tfile $DIR1/$tfile-1
5034
5035         kill -USR1 $multipid
5036         wait $multipid || error "multiop close failed"
5037
5038         for (( i=0; i < 2; i++ )) ; do
5039                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5040                 [ "$mtime1" = "$mtime2" ] ||
5041                         error "mtime is lost on close: $mtime2, " \
5042                               "should be $mtime1"
5043
5044                 cancel_lru_locks
5045                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5046         done
5047         lctl set_param fail_loc=0
5048         stop_full_debug_logging
5049 }
5050 run_test 39j "write, rename, close, stat ======================="
5051
5052 test_39k() {
5053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5054
5055         touch $DIR1/$tfile
5056         sleep 1
5057
5058         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5059         local multipid=$!
5060         local mtime1=`stat -c %Y $DIR1/$tfile`
5061
5062         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5063
5064         kill -USR1 $multipid
5065         wait $multipid || error "multiop close failed"
5066
5067         for (( i=0; i < 2; i++ )) ; do
5068                 local mtime2=`stat -c %Y $DIR1/$tfile`
5069
5070                 [ "$mtime2" = $TEST_39_MTIME ] || \
5071                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5072
5073                 cancel_lru_locks
5074                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5075         done
5076 }
5077 run_test 39k "write, utime, close, stat ========================"
5078
5079 # this should be set to future
5080 TEST_39_ATIME=`date -d "1 year" +%s`
5081
5082 test_39l() {
5083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5084         remote_mds_nodsh && skip "remote MDS with nodsh"
5085
5086         local atime_diff=$(do_facet $SINGLEMDS \
5087                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5088         rm -rf $DIR/$tdir
5089         mkdir_on_mdt0 $DIR/$tdir
5090
5091         # test setting directory atime to future
5092         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5093         local atime=$(stat -c %X $DIR/$tdir)
5094         [ "$atime" = $TEST_39_ATIME ] ||
5095                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5096
5097         # test setting directory atime from future to now
5098         local now=$(date +%s)
5099         touch -a -d @$now $DIR/$tdir
5100
5101         atime=$(stat -c %X $DIR/$tdir)
5102         [ "$atime" -eq "$now"  ] ||
5103                 error "atime is not updated from future: $atime, $now"
5104
5105         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5106         sleep 3
5107
5108         # test setting directory atime when now > dir atime + atime_diff
5109         local d1=$(date +%s)
5110         ls $DIR/$tdir
5111         local d2=$(date +%s)
5112         cancel_lru_locks mdc
5113         atime=$(stat -c %X $DIR/$tdir)
5114         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5115                 error "atime is not updated  : $atime, should be $d2"
5116
5117         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5118         sleep 3
5119
5120         # test not setting directory atime when now < dir atime + atime_diff
5121         ls $DIR/$tdir
5122         cancel_lru_locks mdc
5123         atime=$(stat -c %X $DIR/$tdir)
5124         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5125                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5126
5127         do_facet $SINGLEMDS \
5128                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5129 }
5130 run_test 39l "directory atime update ==========================="
5131
5132 test_39m() {
5133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5134
5135         touch $DIR1/$tfile
5136         sleep 2
5137         local far_past_mtime=$(date -d "May 29 1953" +%s)
5138         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5139
5140         touch -m -d @$far_past_mtime $DIR1/$tfile
5141         touch -a -d @$far_past_atime $DIR1/$tfile
5142
5143         for (( i=0; i < 2; i++ )) ; do
5144                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5145                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5146                         error "atime or mtime set incorrectly"
5147
5148                 cancel_lru_locks $OSC
5149                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5150         done
5151 }
5152 run_test 39m "test atime and mtime before 1970"
5153
5154 test_39n() { # LU-3832
5155         remote_mds_nodsh && skip "remote MDS with nodsh"
5156
5157         local atime_diff=$(do_facet $SINGLEMDS \
5158                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5159         local atime0
5160         local atime1
5161         local atime2
5162
5163         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5164
5165         rm -rf $DIR/$tfile
5166         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5167         atime0=$(stat -c %X $DIR/$tfile)
5168
5169         sleep 5
5170         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5171         atime1=$(stat -c %X $DIR/$tfile)
5172
5173         sleep 5
5174         cancel_lru_locks mdc
5175         cancel_lru_locks osc
5176         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5177         atime2=$(stat -c %X $DIR/$tfile)
5178
5179         do_facet $SINGLEMDS \
5180                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5181
5182         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5183         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5184 }
5185 run_test 39n "check that O_NOATIME is honored"
5186
5187 test_39o() {
5188         TESTDIR=$DIR/$tdir/$tfile
5189         [ -e $TESTDIR ] && rm -rf $TESTDIR
5190         mkdir -p $TESTDIR
5191         cd $TESTDIR
5192         links1=2
5193         ls
5194         mkdir a b
5195         ls
5196         links2=$(stat -c %h .)
5197         [ $(($links1 + 2)) != $links2 ] &&
5198                 error "wrong links count $(($links1 + 2)) != $links2"
5199         rmdir b
5200         links3=$(stat -c %h .)
5201         [ $(($links1 + 1)) != $links3 ] &&
5202                 error "wrong links count $links1 != $links3"
5203         return 0
5204 }
5205 run_test 39o "directory cached attributes updated after create"
5206
5207 test_39p() {
5208         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5209
5210         local MDTIDX=1
5211         TESTDIR=$DIR/$tdir/$tdir
5212         [ -e $TESTDIR ] && rm -rf $TESTDIR
5213         test_mkdir -p $TESTDIR
5214         cd $TESTDIR
5215         links1=2
5216         ls
5217         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5218         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5219         ls
5220         links2=$(stat -c %h .)
5221         [ $(($links1 + 2)) != $links2 ] &&
5222                 error "wrong links count $(($links1 + 2)) != $links2"
5223         rmdir remote_dir2
5224         links3=$(stat -c %h .)
5225         [ $(($links1 + 1)) != $links3 ] &&
5226                 error "wrong links count $links1 != $links3"
5227         return 0
5228 }
5229 run_test 39p "remote directory cached attributes updated after create ========"
5230
5231 test_39r() {
5232         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5233                 skip "no atime update on old OST"
5234         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5235                 skip_env "ldiskfs only test"
5236         fi
5237
5238         local saved_adiff
5239         saved_adiff=$(do_facet ost1 \
5240                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5241         stack_trap "do_facet ost1 \
5242                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5243
5244         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5245
5246         $LFS setstripe -i 0 $DIR/$tfile
5247         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5248                 error "can't write initial file"
5249         cancel_lru_locks osc
5250
5251         # exceed atime_diff and access file
5252         sleep 10
5253         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5254                 error "can't udpate atime"
5255
5256         local atime_cli=$(stat -c %X $DIR/$tfile)
5257         echo "client atime: $atime_cli"
5258         # allow atime update to be written to device
5259         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5260         sleep 5
5261
5262         local ostdev=$(ostdevname 1)
5263         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5264         local seq=${fid[3]#0x}
5265         local oid=${fid[1]}
5266         local oid_hex
5267
5268         if [ $seq == 0 ]; then
5269                 oid_hex=${fid[1]}
5270         else
5271                 oid_hex=${fid[2]#0x}
5272         fi
5273         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5274         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5275
5276         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5277         local atime_ost=$(do_facet ost1 "$cmd" |&
5278                           awk -F'[: ]' '/atime:/ { print $4 }')
5279         (( atime_cli == atime_ost )) ||
5280                 error "atime on client $atime_cli != ost $atime_ost"
5281 }
5282 run_test 39r "lazy atime update on OST"
5283
5284 test_39q() { # LU-8041
5285         local testdir=$DIR/$tdir
5286         mkdir -p $testdir
5287         multiop_bg_pause $testdir D_c || error "multiop failed"
5288         local multipid=$!
5289         cancel_lru_locks mdc
5290         kill -USR1 $multipid
5291         local atime=$(stat -c %X $testdir)
5292         [ "$atime" -ne 0 ] || error "atime is zero"
5293 }
5294 run_test 39q "close won't zero out atime"
5295
5296 test_39s() {
5297         local atime0
5298         local atime1
5299         local atime2
5300         local atime3
5301         local atime4
5302
5303         umount_client $MOUNT
5304         mount_client $MOUNT relatime
5305
5306         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5307         atime0=$(stat -c %X $DIR/$tfile)
5308
5309         # First read updates atime
5310         sleep 1
5311         cat $DIR/$tfile >/dev/null
5312         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5313
5314         # Next reads do not update atime
5315         sleep 1
5316         cat $DIR/$tfile >/dev/null
5317         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5318
5319         # If mtime is greater than atime, atime is updated
5320         sleep 1
5321         touch -m $DIR/$tfile # (mtime = now)
5322         sleep 1
5323         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5324         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5325
5326         # Next reads do not update atime
5327         sleep 1
5328         cat $DIR/$tfile >/dev/null
5329         atime4=$(stat -c %X $DIR/$tfile)
5330
5331         # Remount the client to clear 'relatime' option
5332         remount_client $MOUNT
5333
5334         (( atime0 < atime1 )) ||
5335                 error "atime $atime0 should be smaller than $atime1"
5336         (( atime1 == atime2 )) ||
5337                 error "atime $atime1 was updated to $atime2"
5338         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5339         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5340 }
5341 run_test 39s "relatime is supported"
5342
5343 test_40() {
5344         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5345         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5346                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5347         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5348                 error "$tfile is not 4096 bytes in size"
5349 }
5350 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5351
5352 test_41() {
5353         # bug 1553
5354         small_write $DIR/f41 18
5355 }
5356 run_test 41 "test small file write + fstat ====================="
5357
5358 count_ost_writes() {
5359         lctl get_param -n ${OSC}.*.stats |
5360                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5361                         END { printf("%0.0f", writes) }'
5362 }
5363
5364 # decent default
5365 WRITEBACK_SAVE=500
5366 DIRTY_RATIO_SAVE=40
5367 MAX_DIRTY_RATIO=50
5368 BG_DIRTY_RATIO_SAVE=10
5369 MAX_BG_DIRTY_RATIO=25
5370
5371 start_writeback() {
5372         trap 0
5373         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5374         # dirty_ratio, dirty_background_ratio
5375         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5376                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5377                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5378                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5379         else
5380                 # if file not here, we are a 2.4 kernel
5381                 kill -CONT `pidof kupdated`
5382         fi
5383 }
5384
5385 stop_writeback() {
5386         # setup the trap first, so someone cannot exit the test at the
5387         # exact wrong time and mess up a machine
5388         trap start_writeback EXIT
5389         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5390         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5391                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5392                 sysctl -w vm.dirty_writeback_centisecs=0
5393                 sysctl -w vm.dirty_writeback_centisecs=0
5394                 # save and increase /proc/sys/vm/dirty_ratio
5395                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5396                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5397                 # save and increase /proc/sys/vm/dirty_background_ratio
5398                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5399                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5400         else
5401                 # if file not here, we are a 2.4 kernel
5402                 kill -STOP `pidof kupdated`
5403         fi
5404 }
5405
5406 # ensure that all stripes have some grant before we test client-side cache
5407 setup_test42() {
5408         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5409                 dd if=/dev/zero of=$i bs=4k count=1
5410                 rm $i
5411         done
5412 }
5413
5414 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5415 # file truncation, and file removal.
5416 test_42a() {
5417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5418
5419         setup_test42
5420         cancel_lru_locks $OSC
5421         stop_writeback
5422         sync; sleep 1; sync # just to be safe
5423         BEFOREWRITES=`count_ost_writes`
5424         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5425         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5426         AFTERWRITES=`count_ost_writes`
5427         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5428                 error "$BEFOREWRITES < $AFTERWRITES"
5429         start_writeback
5430 }
5431 run_test 42a "ensure that we don't flush on close"
5432
5433 test_42b() {
5434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5435
5436         setup_test42
5437         cancel_lru_locks $OSC
5438         stop_writeback
5439         sync
5440         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5441         BEFOREWRITES=$(count_ost_writes)
5442         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5443         AFTERWRITES=$(count_ost_writes)
5444         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5445                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5446         fi
5447         BEFOREWRITES=$(count_ost_writes)
5448         sync || error "sync: $?"
5449         AFTERWRITES=$(count_ost_writes)
5450         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5451                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5452         fi
5453         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5454         start_writeback
5455         return 0
5456 }
5457 run_test 42b "test destroy of file with cached dirty data ======"
5458
5459 # if these tests just want to test the effect of truncation,
5460 # they have to be very careful.  consider:
5461 # - the first open gets a {0,EOF}PR lock
5462 # - the first write conflicts and gets a {0, count-1}PW
5463 # - the rest of the writes are under {count,EOF}PW
5464 # - the open for truncate tries to match a {0,EOF}PR
5465 #   for the filesize and cancels the PWs.
5466 # any number of fixes (don't get {0,EOF} on open, match
5467 # composite locks, do smarter file size management) fix
5468 # this, but for now we want these tests to verify that
5469 # the cancellation with truncate intent works, so we
5470 # start the file with a full-file pw lock to match against
5471 # until the truncate.
5472 trunc_test() {
5473         test=$1
5474         file=$DIR/$test
5475         offset=$2
5476         cancel_lru_locks $OSC
5477         stop_writeback
5478         # prime the file with 0,EOF PW to match
5479         touch $file
5480         $TRUNCATE $file 0
5481         sync; sync
5482         # now the real test..
5483         dd if=/dev/zero of=$file bs=1024 count=100
5484         BEFOREWRITES=`count_ost_writes`
5485         $TRUNCATE $file $offset
5486         cancel_lru_locks $OSC
5487         AFTERWRITES=`count_ost_writes`
5488         start_writeback
5489 }
5490
5491 test_42c() {
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493
5494         trunc_test 42c 1024
5495         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5496                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5497         rm $file
5498 }
5499 run_test 42c "test partial truncate of file with cached dirty data"
5500
5501 test_42d() {
5502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5503
5504         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5505         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5506         $LCTL set_param debug=+cache
5507
5508         trunc_test 42d 0
5509         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5510                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5511         rm $file
5512 }
5513 run_test 42d "test complete truncate of file with cached dirty data"
5514
5515 test_42e() { # bug22074
5516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5517
5518         local TDIR=$DIR/${tdir}e
5519         local pages=16 # hardcoded 16 pages, don't change it.
5520         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5521         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5522         local max_dirty_mb
5523         local warmup_files
5524
5525         test_mkdir $DIR/${tdir}e
5526         $LFS setstripe -c 1 $TDIR
5527         createmany -o $TDIR/f $files
5528
5529         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5530
5531         # we assume that with $OSTCOUNT files, at least one of them will
5532         # be allocated on OST0.
5533         warmup_files=$((OSTCOUNT * max_dirty_mb))
5534         createmany -o $TDIR/w $warmup_files
5535
5536         # write a large amount of data into one file and sync, to get good
5537         # avail_grant number from OST.
5538         for ((i=0; i<$warmup_files; i++)); do
5539                 idx=$($LFS getstripe -i $TDIR/w$i)
5540                 [ $idx -ne 0 ] && continue
5541                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5542                 break
5543         done
5544         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5545         sync
5546         $LCTL get_param $proc_osc0/cur_dirty_bytes
5547         $LCTL get_param $proc_osc0/cur_grant_bytes
5548
5549         # create as much dirty pages as we can while not to trigger the actual
5550         # RPCs directly. but depends on the env, VFS may trigger flush during this
5551         # period, hopefully we are good.
5552         for ((i=0; i<$warmup_files; i++)); do
5553                 idx=$($LFS getstripe -i $TDIR/w$i)
5554                 [ $idx -ne 0 ] && continue
5555                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5556         done
5557         $LCTL get_param $proc_osc0/cur_dirty_bytes
5558         $LCTL get_param $proc_osc0/cur_grant_bytes
5559
5560         # perform the real test
5561         $LCTL set_param $proc_osc0/rpc_stats 0
5562         for ((;i<$files; i++)); do
5563                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5564                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5565         done
5566         sync
5567         $LCTL get_param $proc_osc0/rpc_stats
5568
5569         local percent=0
5570         local have_ppr=false
5571         $LCTL get_param $proc_osc0/rpc_stats |
5572                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5573                         # skip lines until we are at the RPC histogram data
5574                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5575                         $have_ppr || continue
5576
5577                         # we only want the percent stat for < 16 pages
5578                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5579
5580                         percent=$((percent + WPCT))
5581                         if [[ $percent -gt 15 ]]; then
5582                                 error "less than 16-pages write RPCs" \
5583                                       "$percent% > 15%"
5584                                 break
5585                         fi
5586                 done
5587         rm -rf $TDIR
5588 }
5589 run_test 42e "verify sub-RPC writes are not done synchronously"
5590
5591 test_43A() { # was test_43
5592         test_mkdir $DIR/$tdir
5593         cp -p /bin/ls $DIR/$tdir/$tfile
5594         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5595         pid=$!
5596         # give multiop a chance to open
5597         sleep 1
5598
5599         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5600         kill -USR1 $pid
5601         # Wait for multiop to exit
5602         wait $pid
5603 }
5604 run_test 43A "execution of file opened for write should return -ETXTBSY"
5605
5606 test_43a() {
5607         test_mkdir $DIR/$tdir
5608         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5609         $DIR/$tdir/sleep 60 &
5610         SLEEP_PID=$!
5611         # Make sure exec of $tdir/sleep wins race with truncate
5612         sleep 1
5613         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5614         kill $SLEEP_PID
5615 }
5616 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5617
5618 test_43b() {
5619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5620
5621         test_mkdir $DIR/$tdir
5622         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5623         $DIR/$tdir/sleep 60 &
5624         SLEEP_PID=$!
5625         # Make sure exec of $tdir/sleep wins race with truncate
5626         sleep 1
5627         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5628         kill $SLEEP_PID
5629 }
5630 run_test 43b "truncate of file being executed should return -ETXTBSY"
5631
5632 test_43c() {
5633         local testdir="$DIR/$tdir"
5634         test_mkdir $testdir
5635         cp $SHELL $testdir/
5636         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5637                 ( cd $testdir && md5sum -c )
5638 }
5639 run_test 43c "md5sum of copy into lustre"
5640
5641 test_44A() { # was test_44
5642         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5643
5644         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5645         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5646 }
5647 run_test 44A "zero length read from a sparse stripe"
5648
5649 test_44a() {
5650         local nstripe=$($LFS getstripe -c -d $DIR)
5651         [ -z "$nstripe" ] && skip "can't get stripe info"
5652         [[ $nstripe -gt $OSTCOUNT ]] &&
5653                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5654
5655         local stride=$($LFS getstripe -S -d $DIR)
5656         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5657                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5658         fi
5659
5660         OFFSETS="0 $((stride/2)) $((stride-1))"
5661         for offset in $OFFSETS; do
5662                 for i in $(seq 0 $((nstripe-1))); do
5663                         local GLOBALOFFSETS=""
5664                         # size in Bytes
5665                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5666                         local myfn=$DIR/d44a-$size
5667                         echo "--------writing $myfn at $size"
5668                         ll_sparseness_write $myfn $size ||
5669                                 error "ll_sparseness_write"
5670                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5671                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5672                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5673
5674                         for j in $(seq 0 $((nstripe-1))); do
5675                                 # size in Bytes
5676                                 size=$((((j + $nstripe )*$stride + $offset)))
5677                                 ll_sparseness_write $myfn $size ||
5678                                         error "ll_sparseness_write"
5679                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5680                         done
5681                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5682                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5683                         rm -f $myfn
5684                 done
5685         done
5686 }
5687 run_test 44a "test sparse pwrite ==============================="
5688
5689 dirty_osc_total() {
5690         tot=0
5691         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5692                 tot=$(($tot + $d))
5693         done
5694         echo $tot
5695 }
5696 do_dirty_record() {
5697         before=`dirty_osc_total`
5698         echo executing "\"$*\""
5699         eval $*
5700         after=`dirty_osc_total`
5701         echo before $before, after $after
5702 }
5703 test_45() {
5704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5705
5706         f="$DIR/f45"
5707         # Obtain grants from OST if it supports it
5708         echo blah > ${f}_grant
5709         stop_writeback
5710         sync
5711         do_dirty_record "echo blah > $f"
5712         [[ $before -eq $after ]] && error "write wasn't cached"
5713         do_dirty_record "> $f"
5714         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5715         do_dirty_record "echo blah > $f"
5716         [[ $before -eq $after ]] && error "write wasn't cached"
5717         do_dirty_record "sync"
5718         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5719         do_dirty_record "echo blah > $f"
5720         [[ $before -eq $after ]] && error "write wasn't cached"
5721         do_dirty_record "cancel_lru_locks osc"
5722         [[ $before -gt $after ]] ||
5723                 error "lock cancellation didn't lower dirty count"
5724         start_writeback
5725 }
5726 run_test 45 "osc io page accounting ============================"
5727
5728 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5729 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5730 # objects offset and an assert hit when an rpc was built with 1023's mapped
5731 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5732 test_46() {
5733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5734
5735         f="$DIR/f46"
5736         stop_writeback
5737         sync
5738         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5739         sync
5740         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5741         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5742         sync
5743         start_writeback
5744 }
5745 run_test 46 "dirtying a previously written page ================"
5746
5747 # test_47 is removed "Device nodes check" is moved to test_28
5748
5749 test_48a() { # bug 2399
5750         [ "$mds1_FSTYPE" = "zfs" ] &&
5751         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5752                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5753
5754         test_mkdir $DIR/$tdir
5755         cd $DIR/$tdir
5756         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5757         test_mkdir $DIR/$tdir
5758         touch foo || error "'touch foo' failed after recreating cwd"
5759         test_mkdir bar
5760         touch .foo || error "'touch .foo' failed after recreating cwd"
5761         test_mkdir .bar
5762         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5763         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5764         cd . || error "'cd .' failed after recreating cwd"
5765         mkdir . && error "'mkdir .' worked after recreating cwd"
5766         rmdir . && error "'rmdir .' worked after recreating cwd"
5767         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5768         cd .. || error "'cd ..' failed after recreating cwd"
5769 }
5770 run_test 48a "Access renamed working dir (should return errors)="
5771
5772 test_48b() { # bug 2399
5773         rm -rf $DIR/$tdir
5774         test_mkdir $DIR/$tdir
5775         cd $DIR/$tdir
5776         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5777         touch foo && error "'touch foo' worked after removing cwd"
5778         mkdir foo && error "'mkdir foo' worked after removing cwd"
5779         touch .foo && error "'touch .foo' worked after removing cwd"
5780         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5781         ls . > /dev/null && error "'ls .' worked after removing cwd"
5782         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5783         mkdir . && error "'mkdir .' worked after removing cwd"
5784         rmdir . && error "'rmdir .' worked after removing cwd"
5785         ln -s . foo && error "'ln -s .' worked after removing cwd"
5786         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5787 }
5788 run_test 48b "Access removed working dir (should return errors)="
5789
5790 test_48c() { # bug 2350
5791         #lctl set_param debug=-1
5792         #set -vx
5793         rm -rf $DIR/$tdir
5794         test_mkdir -p $DIR/$tdir/dir
5795         cd $DIR/$tdir/dir
5796         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5797         $TRACE touch foo && error "touch foo worked after removing cwd"
5798         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5799         touch .foo && error "touch .foo worked after removing cwd"
5800         mkdir .foo && error "mkdir .foo worked after removing cwd"
5801         $TRACE ls . && error "'ls .' worked after removing cwd"
5802         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5803         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5804         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5805         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5806         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5807 }
5808 run_test 48c "Access removed working subdir (should return errors)"
5809
5810 test_48d() { # bug 2350
5811         #lctl set_param debug=-1
5812         #set -vx
5813         rm -rf $DIR/$tdir
5814         test_mkdir -p $DIR/$tdir/dir
5815         cd $DIR/$tdir/dir
5816         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5817         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5818         $TRACE touch foo && error "'touch foo' worked after removing parent"
5819         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5820         touch .foo && error "'touch .foo' worked after removing parent"
5821         mkdir .foo && error "mkdir .foo worked after removing parent"
5822         $TRACE ls . && error "'ls .' worked after removing parent"
5823         $TRACE ls .. && error "'ls ..' worked after removing parent"
5824         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5825         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5826         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5827         true
5828 }
5829 run_test 48d "Access removed parent subdir (should return errors)"
5830
5831 test_48e() { # bug 4134
5832         #lctl set_param debug=-1
5833         #set -vx
5834         rm -rf $DIR/$tdir
5835         test_mkdir -p $DIR/$tdir/dir
5836         cd $DIR/$tdir/dir
5837         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5838         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5839         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5840         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5841         # On a buggy kernel addition of "touch foo" after cd .. will
5842         # produce kernel oops in lookup_hash_it
5843         touch ../foo && error "'cd ..' worked after recreate parent"
5844         cd $DIR
5845         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5846 }
5847 run_test 48e "Access to recreated parent subdir (should return errors)"
5848
5849 test_48f() {
5850         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5851                 skip "need MDS >= 2.13.55"
5852         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5853         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5854                 skip "needs different host for mdt1 mdt2"
5855         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5856
5857         $LFS mkdir -i0 $DIR/$tdir
5858         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5859
5860         for d in sub1 sub2 sub3; do
5861                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5862                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5863                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5864         done
5865
5866         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5867 }
5868 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5869
5870 test_49() { # LU-1030
5871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5872         remote_ost_nodsh && skip "remote OST with nodsh"
5873
5874         # get ost1 size - $FSNAME-OST0000
5875         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5876                 awk '{ print $4 }')
5877         # write 800M at maximum
5878         [[ $ost1_size -lt 2 ]] && ost1_size=2
5879         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5880
5881         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5882         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5883         local dd_pid=$!
5884
5885         # change max_pages_per_rpc while writing the file
5886         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5887         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5888         # loop until dd process exits
5889         while ps ax -opid | grep -wq $dd_pid; do
5890                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5891                 sleep $((RANDOM % 5 + 1))
5892         done
5893         # restore original max_pages_per_rpc
5894         $LCTL set_param $osc1_mppc=$orig_mppc
5895         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5896 }
5897 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5898
5899 test_50() {
5900         # bug 1485
5901         test_mkdir $DIR/$tdir
5902         cd $DIR/$tdir
5903         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5904 }
5905 run_test 50 "special situations: /proc symlinks  ==============="
5906
5907 test_51a() {    # was test_51
5908         # bug 1516 - create an empty entry right after ".." then split dir
5909         test_mkdir -c1 $DIR/$tdir
5910         touch $DIR/$tdir/foo
5911         $MCREATE $DIR/$tdir/bar
5912         rm $DIR/$tdir/foo
5913         createmany -m $DIR/$tdir/longfile 201
5914         FNUM=202
5915         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5916                 $MCREATE $DIR/$tdir/longfile$FNUM
5917                 FNUM=$(($FNUM + 1))
5918                 echo -n "+"
5919         done
5920         echo
5921         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5922 }
5923 run_test 51a "special situations: split htree with empty entry =="
5924
5925 cleanup_print_lfs_df () {
5926         trap 0
5927         $LFS df
5928         $LFS df -i
5929 }
5930
5931 test_51b() {
5932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5933
5934         local dir=$DIR/$tdir
5935         local nrdirs=$((65536 + 100))
5936
5937         # cleanup the directory
5938         rm -fr $dir
5939
5940         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5941
5942         $LFS df
5943         $LFS df -i
5944         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5945         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5946         [[ $numfree -lt $nrdirs ]] &&
5947                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5948
5949         # need to check free space for the directories as well
5950         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5951         numfree=$(( blkfree / $(fs_inode_ksize) ))
5952         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5953
5954         trap cleanup_print_lfs_df EXIT
5955
5956         # create files
5957         createmany -d $dir/d $nrdirs || {
5958                 unlinkmany $dir/d $nrdirs
5959                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5960         }
5961
5962         # really created :
5963         nrdirs=$(ls -U $dir | wc -l)
5964
5965         # unlink all but 100 subdirectories, then check it still works
5966         local left=100
5967         local delete=$((nrdirs - left))
5968
5969         $LFS df
5970         $LFS df -i
5971
5972         # for ldiskfs the nlink count should be 1, but this is OSD specific
5973         # and so this is listed for informational purposes only
5974         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5975         unlinkmany -d $dir/d $delete ||
5976                 error "unlink of first $delete subdirs failed"
5977
5978         echo "nlink between: $(stat -c %h $dir)"
5979         local found=$(ls -U $dir | wc -l)
5980         [ $found -ne $left ] &&
5981                 error "can't find subdirs: found only $found, expected $left"
5982
5983         unlinkmany -d $dir/d $delete $left ||
5984                 error "unlink of second $left subdirs failed"
5985         # regardless of whether the backing filesystem tracks nlink accurately
5986         # or not, the nlink count shouldn't be more than "." and ".." here
5987         local after=$(stat -c %h $dir)
5988         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5989                 echo "nlink after: $after"
5990
5991         cleanup_print_lfs_df
5992 }
5993 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5994
5995 test_51d_sub() {
5996         local stripecount=$1
5997         local nfiles=$2
5998
5999         log "create files with stripecount=$stripecount"
6000         $LFS setstripe -C $stripecount $DIR/$tdir
6001         createmany -o $DIR/$tdir/t- $nfiles
6002         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6003         for ((n = 0; n < $OSTCOUNT; n++)); do
6004                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6005                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6006                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6007                             '($1 == '$n') { objs += 1 } \
6008                             END { printf("%0.0f", objs) }')
6009                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6010         done
6011         unlinkmany $DIR/$tdir/t- $nfiles
6012         rm  -f $TMP/$tfile
6013
6014         local nlast
6015         local min=4
6016         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6017
6018         # For some combinations of stripecount and OSTCOUNT current code
6019         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6020         # than others. Rather than skipping this test entirely, check that
6021         # and keep testing to ensure imbalance does not get worse. LU-15282
6022         (( (OSTCOUNT == 6 && stripecount == 4) ||
6023            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6024            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6025         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6026                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6027                         { $LFS df && $LFS df -i &&
6028                         error "stripecount=$stripecount: " \
6029                               "OST $n has fewer objects vs. OST $nlast " \
6030                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6031                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6032                         { $LFS df && $LFS df -i &&
6033                         error "stripecount=$stripecount: " \
6034                               "OST $n has more objects vs. OST $nlast " \
6035                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6036
6037                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6038                         { $LFS df && $LFS df -i &&
6039                         error "stripecount=$stripecount: " \
6040                               "OST $n has fewer #0 objects vs. OST $nlast " \
6041                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6042                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6043                         { $LFS df && $LFS df -i &&
6044                         error "stripecount=$stripecount: " \
6045                               "OST $n has more #0 objects vs. OST $nlast " \
6046                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6047         done
6048 }
6049
6050 test_51d() {
6051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6052         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6053
6054         local stripecount
6055         local per_ost=100
6056         local nfiles=$((per_ost * OSTCOUNT))
6057         local mdts=$(comma_list $(mdts_nodes))
6058         local param="osp.*.create_count"
6059         local qos_old=$(do_facet mds1 \
6060                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6061
6062         do_nodes $mdts \
6063                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6064         stack_trap "do_nodes $mdts \
6065                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6066
6067         test_mkdir $DIR/$tdir
6068         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6069         (( dirstripes > 0 )) || dirstripes=1
6070
6071         # Ensure enough OST objects precreated for tests to pass without
6072         # running out of objects.  This is an LOV r-r OST algorithm test,
6073         # not an OST object precreation test.
6074         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6075         (( old >= nfiles )) ||
6076         {
6077                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6078
6079                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6080                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6081
6082                 # trigger precreation from all MDTs for all OSTs
6083                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6084                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6085                 done
6086         }
6087
6088         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6089                 sleep 8  # allow object precreation to catch up
6090                 test_51d_sub $stripecount $nfiles
6091         done
6092 }
6093 run_test 51d "check LOV round-robin OST object distribution"
6094
6095 test_51e() {
6096         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6097                 skip_env "ldiskfs only test"
6098         fi
6099
6100         test_mkdir -c1 $DIR/$tdir
6101         test_mkdir -c1 $DIR/$tdir/d0
6102
6103         touch $DIR/$tdir/d0/foo
6104         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6105                 error "file exceed 65000 nlink limit!"
6106         unlinkmany $DIR/$tdir/d0/f- 65001
6107         return 0
6108 }
6109 run_test 51e "check file nlink limit"
6110
6111 test_51f() {
6112         test_mkdir $DIR/$tdir
6113
6114         local max=100000
6115         local ulimit_old=$(ulimit -n)
6116         local spare=20 # number of spare fd's for scripts/libraries, etc.
6117         local mdt=$($LFS getstripe -m $DIR/$tdir)
6118         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6119
6120         echo "MDT$mdt numfree=$numfree, max=$max"
6121         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6122         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6123                 while ! ulimit -n $((numfree + spare)); do
6124                         numfree=$((numfree * 3 / 4))
6125                 done
6126                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6127         else
6128                 echo "left ulimit at $ulimit_old"
6129         fi
6130
6131         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6132                 unlinkmany $DIR/$tdir/f $numfree
6133                 error "create+open $numfree files in $DIR/$tdir failed"
6134         }
6135         ulimit -n $ulimit_old
6136
6137         # if createmany exits at 120s there will be fewer than $numfree files
6138         unlinkmany $DIR/$tdir/f $numfree || true
6139 }
6140 run_test 51f "check many open files limit"
6141
6142 test_52a() {
6143         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6144         test_mkdir $DIR/$tdir
6145         touch $DIR/$tdir/foo
6146         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6147         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6148         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6149         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6150         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6151                                         error "link worked"
6152         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6153         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6154         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6155                                                      error "lsattr"
6156         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6157         cp -r $DIR/$tdir $TMP/
6158         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6159 }
6160 run_test 52a "append-only flag test (should return errors)"
6161
6162 test_52b() {
6163         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6164         test_mkdir $DIR/$tdir
6165         touch $DIR/$tdir/foo
6166         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6167         cat test > $DIR/$tdir/foo && error "cat test worked"
6168         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6169         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6170         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6171                                         error "link worked"
6172         echo foo >> $DIR/$tdir/foo && error "echo worked"
6173         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6174         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6175         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6176         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6177                                                         error "lsattr"
6178         chattr -i $DIR/$tdir/foo || error "chattr failed"
6179
6180         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6181 }
6182 run_test 52b "immutable flag test (should return errors) ======="
6183
6184 test_53() {
6185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6186         remote_mds_nodsh && skip "remote MDS with nodsh"
6187         remote_ost_nodsh && skip "remote OST with nodsh"
6188
6189         local param
6190         local param_seq
6191         local ostname
6192         local mds_last
6193         local mds_last_seq
6194         local ost_last
6195         local ost_last_seq
6196         local ost_last_id
6197         local ostnum
6198         local node
6199         local found=false
6200         local support_last_seq=true
6201
6202         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6203                 support_last_seq=false
6204
6205         # only test MDT0000
6206         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6207         local value
6208         for value in $(do_facet $SINGLEMDS \
6209                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6210                 param=$(echo ${value[0]} | cut -d "=" -f1)
6211                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6212
6213                 if $support_last_seq; then
6214                         param_seq=$(echo $param |
6215                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6216                         mds_last_seq=$(do_facet $SINGLEMDS \
6217                                        $LCTL get_param -n $param_seq)
6218                 fi
6219                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6220
6221                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6222                 node=$(facet_active_host ost$((ostnum+1)))
6223                 param="obdfilter.$ostname.last_id"
6224                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6225                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6226                         ost_last_id=$ost_last
6227
6228                         if $support_last_seq; then
6229                                 ost_last_id=$(echo $ost_last |
6230                                               awk -F':' '{print $2}' |
6231                                               sed -e "s/^0x//g")
6232                                 ost_last_seq=$(echo $ost_last |
6233                                                awk -F':' '{print $1}')
6234                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6235                         fi
6236
6237                         if [[ $ost_last_id != $mds_last ]]; then
6238                                 error "$ost_last_id != $mds_last"
6239                         else
6240                                 found=true
6241                                 break
6242                         fi
6243                 done
6244         done
6245         $found || error "can not match last_seq/last_id for $mdtosc"
6246         return 0
6247 }
6248 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6249
6250 test_54a() {
6251         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6252
6253         LANG=C $SOCKETSERVER $DIR/socket ||
6254                 error "$SOCKETSERVER $DIR/socket failed: $?"
6255         LANG=C $SOCKETCLIENT $DIR/socket ||
6256                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6257         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6258 }
6259 run_test 54a "unix domain socket test =========================="
6260
6261 test_54b() {
6262         f="$DIR/f54b"
6263         mknod $f c 1 3
6264         chmod 0666 $f
6265         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6266 }
6267 run_test 54b "char device works in lustre ======================"
6268
6269 find_loop_dev() {
6270         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6271         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6272         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6273
6274         for i in $(seq 3 7); do
6275                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6276                 LOOPDEV=$LOOPBASE$i
6277                 LOOPNUM=$i
6278                 break
6279         done
6280 }
6281
6282 cleanup_54c() {
6283         local rc=0
6284         loopdev="$DIR/loop54c"
6285
6286         trap 0
6287         $UMOUNT $DIR/$tdir || rc=$?
6288         losetup -d $loopdev || true
6289         losetup -d $LOOPDEV || true
6290         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6291         return $rc
6292 }
6293
6294 test_54c() {
6295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6296
6297         loopdev="$DIR/loop54c"
6298
6299         find_loop_dev
6300         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6301         trap cleanup_54c EXIT
6302         mknod $loopdev b 7 $LOOPNUM
6303         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6304         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6305         losetup $loopdev $DIR/$tfile ||
6306                 error "can't set up $loopdev for $DIR/$tfile"
6307         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6308         test_mkdir $DIR/$tdir
6309         mount -t ext2 $loopdev $DIR/$tdir ||
6310                 error "error mounting $loopdev on $DIR/$tdir"
6311         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6312                 error "dd write"
6313         df $DIR/$tdir
6314         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6315                 error "dd read"
6316         cleanup_54c
6317 }
6318 run_test 54c "block device works in lustre ====================="
6319
6320 test_54d() {
6321         local pipe="$DIR/$tfile.pipe"
6322         local string="aaaaaa"
6323
6324         mknod $pipe p
6325         echo -n "$string" > $pipe &
6326         local result=$(cat $pipe)
6327         [[ "$result" == "$string" ]] || error "$result != $string"
6328 }
6329 run_test 54d "fifo device works in lustre ======================"
6330
6331 test_54e() {
6332         f="$DIR/f54e"
6333         string="aaaaaa"
6334         cp -aL /dev/console $f
6335         echo $string > $f || error "echo $string to $f failed"
6336 }
6337 run_test 54e "console/tty device works in lustre ======================"
6338
6339 test_55a() {
6340         local dev_path="/sys/kernel/debug/lustre/devices"
6341
6342         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6343
6344         # This must be run in iteractive mode, since attach and setup
6345         # are stateful
6346         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6347                 attach obd_test obd_name obd_uuid
6348                 setup obd_test
6349         EOF"
6350
6351         echo "Devices:"
6352         cat "$dev_path" | tail -n 10
6353
6354         $LCTL --device "obd_name" cleanup
6355         $LCTL --device "obd_name" detach
6356
6357         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6358                 error "OBD unit test failed"
6359
6360         rmmod -v obd_test ||
6361                 error "rmmod failed (may trigger a failure in a later test)"
6362 }
6363 run_test 55a "OBD device life cycle unit tests"
6364
6365 test_55b() {
6366         local dev_path="/sys/kernel/debug/lustre/devices"
6367         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6368         local num_dev_to_create="$((8192 - $dev_count))"
6369
6370         load_module obdclass/obd_test || error "load_module failed"
6371
6372         local start=$SECONDS
6373
6374         # This must be run in iteractive mode, since attach and setup
6375         # are stateful
6376         for ((i = 1; i <= num_dev_to_create; i++)); do
6377                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6378                 echo "setup obd_test_$i"
6379         done | $LCTL || error "OBD device creation failed"
6380
6381         echo "Load time: $((SECONDS - start))"
6382         echo "Devices:"
6383         cat "$dev_path" | tail -n 10
6384
6385         for ((i = 1; i <= num_dev_to_create; i++)); do
6386                 echo "--device obd_name_$i cleanup"
6387                 echo "--device obd_name_$i detach"
6388         done | $LCTL || error "OBD device cleanup failed"
6389
6390         echo "Unload time: $((SECONDS - start))"
6391
6392         rmmod -v obd_test ||
6393                 error "rmmod failed (may trigger a failure in a later test)"
6394 }
6395 run_test 55b "Load and unload max OBD devices"
6396
6397 test_56a() {
6398         local numfiles=3
6399         local numdirs=2
6400         local dir=$DIR/$tdir
6401
6402         rm -rf $dir
6403         test_mkdir -p $dir/dir
6404         for i in $(seq $numfiles); do
6405                 touch $dir/file$i
6406                 touch $dir/dir/file$i
6407         done
6408
6409         local numcomp=$($LFS getstripe --component-count $dir)
6410
6411         [[ $numcomp == 0 ]] && numcomp=1
6412
6413         # test lfs getstripe with --recursive
6414         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6415
6416         [[ $filenum -eq $((numfiles * 2)) ]] ||
6417                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6418         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6419         [[ $filenum -eq $numfiles ]] ||
6420                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6421         echo "$LFS getstripe showed obdidx or l_ost_idx"
6422
6423         # test lfs getstripe with file instead of dir
6424         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6425         [[ $filenum -eq 1 ]] ||
6426                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6427         echo "$LFS getstripe file1 passed"
6428
6429         #test lfs getstripe with --verbose
6430         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6431         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6432                 error "$LFS getstripe --verbose $dir: "\
6433                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6434         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6435                 error "$LFS getstripe $dir: showed lmm_magic"
6436
6437         #test lfs getstripe with -v prints lmm_fid
6438         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6439         local countfids=$((numdirs + numfiles * numcomp))
6440         [[ $filenum -eq $countfids ]] ||
6441                 error "$LFS getstripe -v $dir: "\
6442                       "got $filenum want $countfids lmm_fid"
6443         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6444                 error "$LFS getstripe $dir: showed lmm_fid by default"
6445         echo "$LFS getstripe --verbose passed"
6446
6447         #check for FID information
6448         local fid1=$($LFS getstripe --fid $dir/file1)
6449         local fid2=$($LFS getstripe --verbose $dir/file1 |
6450                      awk '/lmm_fid: / { print $2; exit; }')
6451         local fid3=$($LFS path2fid $dir/file1)
6452
6453         [ "$fid1" != "$fid2" ] &&
6454                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6455         [ "$fid1" != "$fid3" ] &&
6456                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6457         echo "$LFS getstripe --fid passed"
6458
6459         #test lfs getstripe with --obd
6460         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6461                 error "$LFS getstripe --obd wrong_uuid: should return error"
6462
6463         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6464
6465         local ostidx=1
6466         local obduuid=$(ostuuid_from_index $ostidx)
6467         local found=$($LFS getstripe -r --obd $obduuid $dir |
6468                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6469
6470         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6471         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6472                 ((filenum--))
6473         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6474                 ((filenum--))
6475
6476         [[ $found -eq $filenum ]] ||
6477                 error "$LFS getstripe --obd: found $found expect $filenum"
6478         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6479                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6480                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6481                 error "$LFS getstripe --obd: should not show file on other obd"
6482         echo "$LFS getstripe --obd passed"
6483 }
6484 run_test 56a "check $LFS getstripe"
6485
6486 test_56b() {
6487         local dir=$DIR/$tdir
6488         local numdirs=3
6489
6490         test_mkdir $dir
6491         for i in $(seq $numdirs); do
6492                 test_mkdir $dir/dir$i
6493         done
6494
6495         # test lfs getdirstripe default mode is non-recursion, which is
6496         # different from lfs getstripe
6497         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6498
6499         [[ $dircnt -eq 1 ]] ||
6500                 error "$LFS getdirstripe: found $dircnt, not 1"
6501         dircnt=$($LFS getdirstripe --recursive $dir |
6502                 grep -c lmv_stripe_count)
6503         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6504                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6505 }
6506 run_test 56b "check $LFS getdirstripe"
6507
6508 test_56bb() {
6509         verify_yaml_available || skip_env "YAML verification not installed"
6510         local output_file=$DIR/$tfile.out
6511
6512         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6513
6514         cat $output_file
6515         cat $output_file | verify_yaml || error "layout is not valid YAML"
6516 }
6517 run_test 56bb "check $LFS getdirstripe layout is YAML"
6518
6519 test_56c() {
6520         remote_ost_nodsh && skip "remote OST with nodsh"
6521
6522         local ost_idx=0
6523         local ost_name=$(ostname_from_index $ost_idx)
6524         local old_status=$(ost_dev_status $ost_idx)
6525         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6526
6527         [[ -z "$old_status" ]] ||
6528                 skip_env "OST $ost_name is in $old_status status"
6529
6530         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6531         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6532                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6533         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6534                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6535                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6536         fi
6537
6538         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6539                 error "$LFS df -v showing inactive devices"
6540         sleep_maxage
6541
6542         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6543
6544         [[ "$new_status" =~ "D" ]] ||
6545                 error "$ost_name status is '$new_status', missing 'D'"
6546         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6547                 [[ "$new_status" =~ "N" ]] ||
6548                         error "$ost_name status is '$new_status', missing 'N'"
6549         fi
6550         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6551                 [[ "$new_status" =~ "f" ]] ||
6552                         error "$ost_name status is '$new_status', missing 'f'"
6553         fi
6554
6555         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6556         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6557                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6558         [[ -z "$p" ]] && restore_lustre_params < $p || true
6559         sleep_maxage
6560
6561         new_status=$(ost_dev_status $ost_idx)
6562         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6563                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6564         # can't check 'f' as devices may actually be on flash
6565 }
6566 run_test 56c "check 'lfs df' showing device status"
6567
6568 test_56d() {
6569         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6570         local osts=$($LFS df -v $MOUNT | grep -c OST)
6571
6572         $LFS df $MOUNT
6573
6574         (( mdts == MDSCOUNT )) ||
6575                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6576         (( osts == OSTCOUNT )) ||
6577                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6578 }
6579 run_test 56d "'lfs df -v' prints only configured devices"
6580
6581 test_56e() {
6582         err_enoent=2 # No such file or directory
6583         err_eopnotsupp=95 # Operation not supported
6584
6585         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6586         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6587
6588         # Check for handling of path not exists
6589         output=$($LFS df $enoent_mnt 2>&1)
6590         ret=$?
6591
6592         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6593         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6594                 error "expect failure $err_enoent, not $ret"
6595
6596         # Check for handling of non-Lustre FS
6597         output=$($LFS df $notsup_mnt)
6598         ret=$?
6599
6600         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6601         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6602                 error "expect success $err_eopnotsupp, not $ret"
6603
6604         # Check for multiple LustreFS argument
6605         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6606         ret=$?
6607
6608         [[ $output -eq 3 && $ret -eq 0 ]] ||
6609                 error "expect success 3, not $output, rc = $ret"
6610
6611         # Check for correct non-Lustre FS handling among multiple
6612         # LustreFS argument
6613         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6614                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6615         ret=$?
6616
6617         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6618                 error "expect success 2, not $output, rc = $ret"
6619 }
6620 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6621
6622 NUMFILES=3
6623 NUMDIRS=3
6624 setup_56() {
6625         local local_tdir="$1"
6626         local local_numfiles="$2"
6627         local local_numdirs="$3"
6628         local dir_params="$4"
6629         local dir_stripe_params="$5"
6630
6631         if [ ! -d "$local_tdir" ] ; then
6632                 test_mkdir -p $dir_stripe_params $local_tdir
6633                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6634                 for i in $(seq $local_numfiles) ; do
6635                         touch $local_tdir/file$i
6636                 done
6637                 for i in $(seq $local_numdirs) ; do
6638                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6639                         for j in $(seq $local_numfiles) ; do
6640                                 touch $local_tdir/dir$i/file$j
6641                         done
6642                 done
6643         fi
6644 }
6645
6646 setup_56_special() {
6647         local local_tdir=$1
6648         local local_numfiles=$2
6649         local local_numdirs=$3
6650
6651         setup_56 $local_tdir $local_numfiles $local_numdirs
6652
6653         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6654                 for i in $(seq $local_numfiles) ; do
6655                         mknod $local_tdir/loop${i}b b 7 $i
6656                         mknod $local_tdir/null${i}c c 1 3
6657                         ln -s $local_tdir/file1 $local_tdir/link${i}
6658                 done
6659                 for i in $(seq $local_numdirs) ; do
6660                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6661                         mknod $local_tdir/dir$i/null${i}c c 1 3
6662                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6663                 done
6664         fi
6665 }
6666
6667 test_56g() {
6668         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6669         local expected=$(($NUMDIRS + 2))
6670
6671         setup_56 $dir $NUMFILES $NUMDIRS
6672
6673         # test lfs find with -name
6674         for i in $(seq $NUMFILES) ; do
6675                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6676
6677                 [ $nums -eq $expected ] ||
6678                         error "lfs find -name '*$i' $dir wrong: "\
6679                               "found $nums, expected $expected"
6680         done
6681 }
6682 run_test 56g "check lfs find -name"
6683
6684 test_56h() {
6685         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6686         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6687
6688         setup_56 $dir $NUMFILES $NUMDIRS
6689
6690         # test lfs find with ! -name
6691         for i in $(seq $NUMFILES) ; do
6692                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6693
6694                 [ $nums -eq $expected ] ||
6695                         error "lfs find ! -name '*$i' $dir wrong: "\
6696                               "found $nums, expected $expected"
6697         done
6698 }
6699 run_test 56h "check lfs find ! -name"
6700
6701 test_56i() {
6702         local dir=$DIR/$tdir
6703
6704         test_mkdir $dir
6705
6706         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6707         local out=$($cmd)
6708
6709         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6710 }
6711 run_test 56i "check 'lfs find -ost UUID' skips directories"
6712
6713 test_56j() {
6714         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6715
6716         setup_56_special $dir $NUMFILES $NUMDIRS
6717
6718         local expected=$((NUMDIRS + 1))
6719         local cmd="$LFS find -type d $dir"
6720         local nums=$($cmd | wc -l)
6721
6722         [ $nums -eq $expected ] ||
6723                 error "'$cmd' wrong: found $nums, expected $expected"
6724 }
6725 run_test 56j "check lfs find -type d"
6726
6727 test_56k() {
6728         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6729
6730         setup_56_special $dir $NUMFILES $NUMDIRS
6731
6732         local expected=$(((NUMDIRS + 1) * NUMFILES))
6733         local cmd="$LFS find -type f $dir"
6734         local nums=$($cmd | wc -l)
6735
6736         [ $nums -eq $expected ] ||
6737                 error "'$cmd' wrong: found $nums, expected $expected"
6738 }
6739 run_test 56k "check lfs find -type f"
6740
6741 test_56l() {
6742         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6743
6744         setup_56_special $dir $NUMFILES $NUMDIRS
6745
6746         local expected=$((NUMDIRS + NUMFILES))
6747         local cmd="$LFS find -type b $dir"
6748         local nums=$($cmd | wc -l)
6749
6750         [ $nums -eq $expected ] ||
6751                 error "'$cmd' wrong: found $nums, expected $expected"
6752 }
6753 run_test 56l "check lfs find -type b"
6754
6755 test_56m() {
6756         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6757
6758         setup_56_special $dir $NUMFILES $NUMDIRS
6759
6760         local expected=$((NUMDIRS + NUMFILES))
6761         local cmd="$LFS find -type c $dir"
6762         local nums=$($cmd | wc -l)
6763         [ $nums -eq $expected ] ||
6764                 error "'$cmd' wrong: found $nums, expected $expected"
6765 }
6766 run_test 56m "check lfs find -type c"
6767
6768 test_56n() {
6769         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6770         setup_56_special $dir $NUMFILES $NUMDIRS
6771
6772         local expected=$((NUMDIRS + NUMFILES))
6773         local cmd="$LFS find -type l $dir"
6774         local nums=$($cmd | wc -l)
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778 }
6779 run_test 56n "check lfs find -type l"
6780
6781 test_56o() {
6782         local dir=$DIR/$tdir
6783
6784         setup_56 $dir $NUMFILES $NUMDIRS
6785         utime $dir/file1 > /dev/null || error "utime (1)"
6786         utime $dir/file2 > /dev/null || error "utime (2)"
6787         utime $dir/dir1 > /dev/null || error "utime (3)"
6788         utime $dir/dir2 > /dev/null || error "utime (4)"
6789         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6790         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6791
6792         local expected=4
6793         local nums=$($LFS find -mtime +0 $dir | wc -l)
6794
6795         [ $nums -eq $expected ] ||
6796                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6797
6798         expected=12
6799         cmd="$LFS find -mtime 0 $dir"
6800         nums=$($cmd | wc -l)
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803 }
6804 run_test 56o "check lfs find -mtime for old files"
6805
6806 test_56ob() {
6807         local dir=$DIR/$tdir
6808         local expected=1
6809         local count=0
6810
6811         # just to make sure there is something that won't be found
6812         test_mkdir $dir
6813         touch $dir/$tfile.now
6814
6815         for age in year week day hour min; do
6816                 count=$((count + 1))
6817
6818                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6819                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6820                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6821
6822                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6823                 local nums=$($cmd | wc -l)
6824                 [ $nums -eq $expected ] ||
6825                         error "'$cmd' wrong: found $nums, expected $expected"
6826
6827                 cmd="$LFS find $dir -atime $count${age:0:1}"
6828                 nums=$($cmd | wc -l)
6829                 [ $nums -eq $expected ] ||
6830                         error "'$cmd' wrong: found $nums, expected $expected"
6831         done
6832
6833         sleep 2
6834         cmd="$LFS find $dir -ctime +1s -type f"
6835         nums=$($cmd | wc -l)
6836         (( $nums == $count * 2 + 1)) ||
6837                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6838 }
6839 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6840
6841 test_newerXY_base() {
6842         local x=$1
6843         local y=$2
6844         local dir=$DIR/$tdir
6845         local ref
6846         local negref
6847
6848         if [ $y == "t" ]; then
6849                 if [ $x == "b" ]; then
6850                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6851                 else
6852                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6853                 fi
6854         else
6855                 ref=$DIR/$tfile.newer.$x$y
6856                 touch $ref || error "touch $ref failed"
6857         fi
6858
6859         echo "before = $ref"
6860         sleep 2
6861         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6862         sleep 2
6863         if [ $y == "t" ]; then
6864                 if [ $x == "b" ]; then
6865                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6866                 else
6867                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6868                 fi
6869         else
6870                 negref=$DIR/$tfile.negnewer.$x$y
6871                 touch $negref || error "touch $negref failed"
6872         fi
6873
6874         echo "after = $negref"
6875         local cmd="$LFS find $dir -newer$x$y $ref"
6876         local nums=$(eval $cmd | wc -l)
6877         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6878
6879         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6880                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6881
6882         cmd="$LFS find $dir ! -newer$x$y $negref"
6883         nums=$(eval $cmd | wc -l)
6884         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6885                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6886
6887         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6888         nums=$(eval $cmd | wc -l)
6889         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6890                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6891
6892         rm -rf $DIR/*
6893 }
6894
6895 test_56oc() {
6896         test_newerXY_base "a" "a"
6897         test_newerXY_base "a" "m"
6898         test_newerXY_base "a" "c"
6899         test_newerXY_base "m" "a"
6900         test_newerXY_base "m" "m"
6901         test_newerXY_base "m" "c"
6902         test_newerXY_base "c" "a"
6903         test_newerXY_base "c" "m"
6904         test_newerXY_base "c" "c"
6905
6906         test_newerXY_base "a" "t"
6907         test_newerXY_base "m" "t"
6908         test_newerXY_base "c" "t"
6909
6910         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6911            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6912                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6913
6914         test_newerXY_base "b" "b"
6915         test_newerXY_base "b" "t"
6916 }
6917 run_test 56oc "check lfs find -newerXY work"
6918
6919 test_56od() {
6920         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6921                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6922
6923         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6924                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6925
6926         local dir=$DIR/$tdir
6927         local ref=$DIR/$tfile.ref
6928         local negref=$DIR/$tfile.negref
6929
6930         mkdir $dir || error "mkdir $dir failed"
6931         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6932         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6933         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6934         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6935         touch $ref || error "touch $ref failed"
6936         # sleep 3 seconds at least
6937         sleep 3
6938
6939         local before=$(do_facet mds1 date +%s)
6940         local skew=$(($(date +%s) - before + 1))
6941
6942         if (( skew < 0 && skew > -5 )); then
6943                 sleep $((0 - skew + 1))
6944                 skew=0
6945         fi
6946
6947         # Set the dir stripe params to limit files all on MDT0,
6948         # otherwise we need to calc the max clock skew between
6949         # the client and MDTs.
6950         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6951         sleep 2
6952         touch $negref || error "touch $negref failed"
6953
6954         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6955         local nums=$($cmd | wc -l)
6956         local expected=$(((NUMFILES + 1) * NUMDIRS))
6957
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6962         nums=$($cmd | wc -l)
6963         expected=$((NUMFILES + 1))
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         [ $skew -lt 0 ] && return
6968
6969         local after=$(do_facet mds1 date +%s)
6970         local age=$((after - before + 1 + skew))
6971
6972         cmd="$LFS find $dir -btime -${age}s -type f"
6973         nums=$($cmd | wc -l)
6974         expected=$(((NUMFILES + 1) * NUMDIRS))
6975
6976         echo "Clock skew between client and server: $skew, age:$age"
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=$(($NUMDIRS + 1))
6981         cmd="$LFS find $dir -btime -${age}s -type d"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985         rm -f $ref $negref || error "Failed to remove $ref $negref"
6986 }
6987 run_test 56od "check lfs find -btime with units"
6988
6989 test_56p() {
6990         [ $RUNAS_ID -eq $UID ] &&
6991                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6992
6993         local dir=$DIR/$tdir
6994
6995         setup_56 $dir $NUMFILES $NUMDIRS
6996         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6997
6998         local expected=$NUMFILES
6999         local cmd="$LFS find -uid $RUNAS_ID $dir"
7000         local nums=$($cmd | wc -l)
7001
7002         [ $nums -eq $expected ] ||
7003                 error "'$cmd' wrong: found $nums, expected $expected"
7004
7005         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7006         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7007         nums=$($cmd | wc -l)
7008         [ $nums -eq $expected ] ||
7009                 error "'$cmd' wrong: found $nums, expected $expected"
7010 }
7011 run_test 56p "check lfs find -uid and ! -uid"
7012
7013 test_56q() {
7014         [ $RUNAS_ID -eq $UID ] &&
7015                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7016
7017         local dir=$DIR/$tdir
7018
7019         setup_56 $dir $NUMFILES $NUMDIRS
7020         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7021
7022         local expected=$NUMFILES
7023         local cmd="$LFS find -gid $RUNAS_GID $dir"
7024         local nums=$($cmd | wc -l)
7025
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7030         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034 }
7035 run_test 56q "check lfs find -gid and ! -gid"
7036
7037 test_56r() {
7038         local dir=$DIR/$tdir
7039
7040         setup_56 $dir $NUMFILES $NUMDIRS
7041
7042         local expected=12
7043         local cmd="$LFS find -size 0 -type f -lazy $dir"
7044         local nums=$($cmd | wc -l)
7045
7046         [ $nums -eq $expected ] ||
7047                 error "'$cmd' wrong: found $nums, expected $expected"
7048         cmd="$LFS find -size 0 -type f $dir"
7049         nums=$($cmd | wc -l)
7050         [ $nums -eq $expected ] ||
7051                 error "'$cmd' wrong: found $nums, expected $expected"
7052
7053         expected=0
7054         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7055         nums=$($cmd | wc -l)
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058         cmd="$LFS find ! -size 0 -type f $dir"
7059         nums=$($cmd | wc -l)
7060         [ $nums -eq $expected ] ||
7061                 error "'$cmd' wrong: found $nums, expected $expected"
7062
7063         echo "test" > $dir/$tfile
7064         echo "test2" > $dir/$tfile.2 && sync
7065         expected=1
7066         cmd="$LFS find -size 5 -type f -lazy $dir"
7067         nums=$($cmd | wc -l)
7068         [ $nums -eq $expected ] ||
7069                 error "'$cmd' wrong: found $nums, expected $expected"
7070         cmd="$LFS find -size 5 -type f $dir"
7071         nums=$($cmd | wc -l)
7072         [ $nums -eq $expected ] ||
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074
7075         expected=1
7076         cmd="$LFS find -size +5 -type f -lazy $dir"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         cmd="$LFS find -size +5 -type f $dir"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] ||
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084
7085         expected=2
7086         cmd="$LFS find -size +0 -type f -lazy $dir"
7087         nums=$($cmd | wc -l)
7088         [ $nums -eq $expected ] ||
7089                 error "'$cmd' wrong: found $nums, expected $expected"
7090         cmd="$LFS find -size +0 -type f $dir"
7091         nums=$($cmd | wc -l)
7092         [ $nums -eq $expected ] ||
7093                 error "'$cmd' wrong: found $nums, expected $expected"
7094
7095         expected=2
7096         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7097         nums=$($cmd | wc -l)
7098         [ $nums -eq $expected ] ||
7099                 error "'$cmd' wrong: found $nums, expected $expected"
7100         cmd="$LFS find ! -size -5 -type f $dir"
7101         nums=$($cmd | wc -l)
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         expected=12
7106         cmd="$LFS find -size -5 -type f -lazy $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110         cmd="$LFS find -size -5 -type f $dir"
7111         nums=$($cmd | wc -l)
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114 }
7115 run_test 56r "check lfs find -size works"
7116
7117 test_56ra_sub() {
7118         local expected=$1
7119         local glimpses=$2
7120         local cmd="$3"
7121
7122         cancel_lru_locks $OSC
7123
7124         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7125         local nums=$($cmd | wc -l)
7126
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129
7130         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7131
7132         if (( rpcs_before + glimpses != rpcs_after )); then
7133                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7134                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7135
7136                 if [[ $glimpses == 0 ]]; then
7137                         error "'$cmd' should not send glimpse RPCs to OST"
7138                 else
7139                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7140                 fi
7141         fi
7142 }
7143
7144 test_56ra() {
7145         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7146                 skip "MDS < 2.12.58 doesn't return LSOM data"
7147         local dir=$DIR/$tdir
7148         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7149
7150         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7151
7152         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7153         $LCTL set_param -n llite.*.statahead_agl=0
7154         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7155
7156         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7157         # open and close all files to ensure LSOM is updated
7158         cancel_lru_locks $OSC
7159         find $dir -type f | xargs cat > /dev/null
7160
7161         #   expect_found  glimpse_rpcs  command_to_run
7162         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7163         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7164         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7165         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7166
7167         echo "test" > $dir/$tfile
7168         echo "test2" > $dir/$tfile.2 && sync
7169         cancel_lru_locks $OSC
7170         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7171
7172         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7173         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7174         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7175         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7176
7177         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7178         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7179         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7180         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7181         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7182         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7183 }
7184 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7185
7186 test_56rb() {
7187         local dir=$DIR/$tdir
7188         local tmp=$TMP/$tfile.log
7189         local mdt_idx;
7190
7191         test_mkdir -p $dir || error "failed to mkdir $dir"
7192         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7193                 error "failed to setstripe $dir/$tfile"
7194         mdt_idx=$($LFS getdirstripe -i $dir)
7195         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7196
7197         stack_trap "rm -f $tmp" EXIT
7198         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7199         ! grep -q obd_uuid $tmp ||
7200                 error "failed to find --size +100K --ost 0 $dir"
7201         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7202         ! grep -q obd_uuid $tmp ||
7203                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7204 }
7205 run_test 56rb "check lfs find --size --ost/--mdt works"
7206
7207 test_56rc() {
7208         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7209         local dir=$DIR/$tdir
7210         local found
7211
7212         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7213         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7214         (( $MDSCOUNT > 2 )) &&
7215                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7216         mkdir $dir/$tdir-{1..10}
7217         touch $dir/$tfile-{1..10}
7218
7219         found=$($LFS find $dir --mdt-count 2 | wc -l)
7220         expect=11
7221         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7222
7223         found=$($LFS find $dir -T +1 | wc -l)
7224         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7225         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7226
7227         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7228         expect=11
7229         (( $found == $expect )) || error "found $found all_char, expect $expect"
7230
7231         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7232         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7233         (( $found == $expect )) || error "found $found all_char, expect $expect"
7234 }
7235 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7236
7237 test_56rd() {
7238         local dir=$DIR/$tdir
7239
7240         test_mkdir $dir
7241         rm -f $dir/*
7242
7243         mkfifo $dir/fifo || error "failed to create fifo file"
7244         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7245                 error "should not fail even cannot get projid from pipe file"
7246         found=$($LFS find $dir -t p --printf "%y")
7247         [[ "p" == $found ]] || error "found $found, expect p"
7248
7249         mknod $dir/chardev c 1 5 ||
7250                 error "failed to create character device file"
7251         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7252                 error "should not fail even cannot get projid from chardev file"
7253         found=$($LFS find $dir -t c --printf "%y")
7254         [[ "c" == $found ]] || error "found $found, expect c"
7255
7256         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7257         (( found == 2 )) || error "unable to list all files"
7258 }
7259 run_test 56rd "check lfs find --printf special files"
7260
7261 test_56s() { # LU-611 #LU-9369
7262         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7263
7264         local dir=$DIR/$tdir
7265         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7266
7267         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7268         for i in $(seq $NUMDIRS); do
7269                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7270         done
7271
7272         local expected=$NUMDIRS
7273         local cmd="$LFS find -c $OSTCOUNT $dir"
7274         local nums=$($cmd | wc -l)
7275
7276         [ $nums -eq $expected ] || {
7277                 $LFS getstripe -R $dir
7278                 error "'$cmd' wrong: found $nums, expected $expected"
7279         }
7280
7281         expected=$((NUMDIRS + onestripe))
7282         cmd="$LFS find -stripe-count +0 -type f $dir"
7283         nums=$($cmd | wc -l)
7284         [ $nums -eq $expected ] || {
7285                 $LFS getstripe -R $dir
7286                 error "'$cmd' wrong: found $nums, expected $expected"
7287         }
7288
7289         expected=$onestripe
7290         cmd="$LFS find -stripe-count 1 -type f $dir"
7291         nums=$($cmd | wc -l)
7292         [ $nums -eq $expected ] || {
7293                 $LFS getstripe -R $dir
7294                 error "'$cmd' wrong: found $nums, expected $expected"
7295         }
7296
7297         cmd="$LFS find -stripe-count -2 -type f $dir"
7298         nums=$($cmd | wc -l)
7299         [ $nums -eq $expected ] || {
7300                 $LFS getstripe -R $dir
7301                 error "'$cmd' wrong: found $nums, expected $expected"
7302         }
7303
7304         expected=0
7305         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7306         nums=$($cmd | wc -l)
7307         [ $nums -eq $expected ] || {
7308                 $LFS getstripe -R $dir
7309                 error "'$cmd' wrong: found $nums, expected $expected"
7310         }
7311 }
7312 run_test 56s "check lfs find -stripe-count works"
7313
7314 test_56t() { # LU-611 #LU-9369
7315         local dir=$DIR/$tdir
7316
7317         setup_56 $dir 0 $NUMDIRS
7318         for i in $(seq $NUMDIRS); do
7319                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7320         done
7321
7322         local expected=$NUMDIRS
7323         local cmd="$LFS find -S 8M $dir"
7324         local nums=$($cmd | wc -l)
7325
7326         [ $nums -eq $expected ] || {
7327                 $LFS getstripe -R $dir
7328                 error "'$cmd' wrong: found $nums, expected $expected"
7329         }
7330         rm -rf $dir
7331
7332         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7333
7334         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7335
7336         expected=$(((NUMDIRS + 1) * NUMFILES))
7337         cmd="$LFS find -stripe-size 512k -type f $dir"
7338         nums=$($cmd | wc -l)
7339         [ $nums -eq $expected ] ||
7340                 error "'$cmd' wrong: found $nums, expected $expected"
7341
7342         cmd="$LFS find -stripe-size +320k -type f $dir"
7343         nums=$($cmd | wc -l)
7344         [ $nums -eq $expected ] ||
7345                 error "'$cmd' wrong: found $nums, expected $expected"
7346
7347         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7348         cmd="$LFS find -stripe-size +200k -type f $dir"
7349         nums=$($cmd | wc -l)
7350         [ $nums -eq $expected ] ||
7351                 error "'$cmd' wrong: found $nums, expected $expected"
7352
7353         cmd="$LFS find -stripe-size -640k -type f $dir"
7354         nums=$($cmd | wc -l)
7355         [ $nums -eq $expected ] ||
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357
7358         expected=4
7359         cmd="$LFS find -stripe-size 256k -type f $dir"
7360         nums=$($cmd | wc -l)
7361         [ $nums -eq $expected ] ||
7362                 error "'$cmd' wrong: found $nums, expected $expected"
7363
7364         cmd="$LFS find -stripe-size -320k -type f $dir"
7365         nums=$($cmd | wc -l)
7366         [ $nums -eq $expected ] ||
7367                 error "'$cmd' wrong: found $nums, expected $expected"
7368
7369         expected=0
7370         cmd="$LFS find -stripe-size 1024k -type f $dir"
7371         nums=$($cmd | wc -l)
7372         [ $nums -eq $expected ] ||
7373                 error "'$cmd' wrong: found $nums, expected $expected"
7374 }
7375 run_test 56t "check lfs find -stripe-size works"
7376
7377 test_56u() { # LU-611
7378         local dir=$DIR/$tdir
7379
7380         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7381
7382         if [[ $OSTCOUNT -gt 1 ]]; then
7383                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7384                 onestripe=4
7385         else
7386                 onestripe=0
7387         fi
7388
7389         local expected=$(((NUMDIRS + 1) * NUMFILES))
7390         local cmd="$LFS find -stripe-index 0 -type f $dir"
7391         local nums=$($cmd | wc -l)
7392
7393         [ $nums -eq $expected ] ||
7394                 error "'$cmd' wrong: found $nums, expected $expected"
7395
7396         expected=$onestripe
7397         cmd="$LFS find -stripe-index 1 -type f $dir"
7398         nums=$($cmd | wc -l)
7399         [ $nums -eq $expected ] ||
7400                 error "'$cmd' wrong: found $nums, expected $expected"
7401
7402         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7403         nums=$($cmd | wc -l)
7404         [ $nums -eq $expected ] ||
7405                 error "'$cmd' wrong: found $nums, expected $expected"
7406
7407         expected=0
7408         # This should produce an error and not return any files
7409         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7410         nums=$($cmd 2>/dev/null | wc -l)
7411         [ $nums -eq $expected ] ||
7412                 error "'$cmd' wrong: found $nums, expected $expected"
7413
7414         if [[ $OSTCOUNT -gt 1 ]]; then
7415                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7416                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7417                 nums=$($cmd | wc -l)
7418                 [ $nums -eq $expected ] ||
7419                         error "'$cmd' wrong: found $nums, expected $expected"
7420         fi
7421 }
7422 run_test 56u "check lfs find -stripe-index works"
7423
7424 test_56v() {
7425         local mdt_idx=0
7426         local dir=$DIR/$tdir
7427
7428         setup_56 $dir $NUMFILES $NUMDIRS
7429
7430         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7431         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7432
7433         for file in $($LFS find -m $UUID $dir); do
7434                 file_midx=$($LFS getstripe -m $file)
7435                 [ $file_midx -eq $mdt_idx ] ||
7436                         error "lfs find -m $UUID != getstripe -m $file_midx"
7437         done
7438 }
7439 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7440
7441 test_56wa() {
7442         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7444
7445         local dir=$DIR/$tdir
7446
7447         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7448         stack_trap "rm -rf $dir"
7449
7450         local stripe_size=$($LFS getstripe -S -d $dir) ||
7451                 error "$LFS getstripe -S -d $dir failed"
7452         stripe_size=${stripe_size%% *}
7453
7454         local file_size=$((stripe_size * OSTCOUNT))
7455         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7456         local required_space=$((file_num * file_size))
7457         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7458                            head -n1)
7459         (( free_space >= required_space / 1024 )) ||
7460                 skip_env "need $required_space, have $free_space kbytes"
7461
7462         local dd_bs=65536
7463         local dd_count=$((file_size / dd_bs))
7464
7465         # write data into the files
7466         local i
7467         local j
7468         local file
7469
7470         for ((i = 1; i <= NUMFILES; i++ )); do
7471                 file=$dir/file$i
7472                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7473                         error "write data into $file failed"
7474         done
7475         for ((i = 1; i <= NUMDIRS; i++ )); do
7476                 for ((j = 1; j <= NUMFILES; j++ )); do
7477                         file=$dir/dir$i/file$j
7478                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7479                                 error "write data into $file failed"
7480                 done
7481         done
7482
7483         # $LFS_MIGRATE will fail if hard link migration is unsupported
7484         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7485                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7486                         error "creating links to $dir/dir1/file1 failed"
7487         fi
7488
7489         local expected=-1
7490
7491         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7492
7493         # lfs_migrate file
7494         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7495
7496         echo "$cmd"
7497         eval $cmd || error "$cmd failed"
7498
7499         check_stripe_count $dir/file1 $expected
7500
7501         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7502                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7503                 # OST 1 if it is on OST 0. This file is small enough to
7504                 # be on only one stripe.
7505                 file=$dir/migr_1_ost
7506                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7507                         error "write data into $file failed"
7508                 local obdidx=$($LFS getstripe -i $file)
7509                 local oldmd5=$(md5sum $file)
7510                 local newobdidx=0
7511
7512                 (( obdidx != 0 )) || newobdidx=1
7513                 cmd="$LFS migrate -i $newobdidx $file"
7514                 echo $cmd
7515                 eval $cmd || error "$cmd failed"
7516
7517                 local realobdix=$($LFS getstripe -i $file)
7518                 local newmd5=$(md5sum $file)
7519
7520                 (( $newobdidx == $realobdix )) ||
7521                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7522                 [[ "$oldmd5" == "$newmd5" ]] ||
7523                         error "md5sum differ: $oldmd5, $newmd5"
7524         fi
7525
7526         # lfs_migrate dir
7527         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7528         echo "$cmd"
7529         eval $cmd || error "$cmd failed"
7530
7531         for (( j = 1; j <= NUMFILES; j++ )); do
7532                 check_stripe_count $dir/dir1/file$j $expected
7533         done
7534
7535         # lfs_migrate works with lfs find
7536         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7537              $LFS_MIGRATE -y -c $expected"
7538         echo "$cmd"
7539         eval $cmd || error "$cmd failed"
7540
7541         for (( i = 2; i <= NUMFILES; i++ )); do
7542                 check_stripe_count $dir/file$i $expected
7543         done
7544         for (( i = 2; i <= NUMDIRS; i++ )); do
7545                 for (( j = 1; j <= NUMFILES; j++ )); do
7546                         check_stripe_count $dir/dir$i/file$j $expected
7547                 done
7548         done
7549 }
7550 run_test 56wa "check lfs_migrate -c stripe_count works"
7551
7552 test_56wb() {
7553         local file1=$DIR/$tdir/file1
7554         local create_pool=false
7555         local initial_pool=$($LFS getstripe -p $DIR)
7556         local pool_list=()
7557         local pool=""
7558
7559         echo -n "Creating test dir..."
7560         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7561         echo "done."
7562
7563         echo -n "Creating test file..."
7564         touch $file1 || error "cannot create file"
7565         echo "done."
7566
7567         echo -n "Detecting existing pools..."
7568         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7569
7570         if [ ${#pool_list[@]} -gt 0 ]; then
7571                 echo "${pool_list[@]}"
7572                 for thispool in "${pool_list[@]}"; do
7573                         if [[ -z "$initial_pool" ||
7574                               "$initial_pool" != "$thispool" ]]; then
7575                                 pool="$thispool"
7576                                 echo "Using existing pool '$pool'"
7577                                 break
7578                         fi
7579                 done
7580         else
7581                 echo "none detected."
7582         fi
7583         if [ -z "$pool" ]; then
7584                 pool=${POOL:-testpool}
7585                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7586                 echo -n "Creating pool '$pool'..."
7587                 create_pool=true
7588                 pool_add $pool &> /dev/null ||
7589                         error "pool_add failed"
7590                 echo "done."
7591
7592                 echo -n "Adding target to pool..."
7593                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7594                         error "pool_add_targets failed"
7595                 echo "done."
7596         fi
7597
7598         echo -n "Setting pool using -p option..."
7599         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7600                 error "migrate failed rc = $?"
7601         echo "done."
7602
7603         echo -n "Verifying test file is in pool after migrating..."
7604         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7605                 error "file was not migrated to pool $pool"
7606         echo "done."
7607
7608         echo -n "Removing test file from pool '$pool'..."
7609         # "lfs migrate $file" won't remove the file from the pool
7610         # until some striping information is changed.
7611         $LFS migrate -c 1 $file1 &> /dev/null ||
7612                 error "cannot remove from pool"
7613         [ "$($LFS getstripe -p $file1)" ] &&
7614                 error "pool still set"
7615         echo "done."
7616
7617         echo -n "Setting pool using --pool option..."
7618         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7619                 error "migrate failed rc = $?"
7620         echo "done."
7621
7622         # Clean up
7623         rm -f $file1
7624         if $create_pool; then
7625                 destroy_test_pools 2> /dev/null ||
7626                         error "destroy test pools failed"
7627         fi
7628 }
7629 run_test 56wb "check lfs_migrate pool support"
7630
7631 test_56wc() {
7632         local file1="$DIR/$tdir/$tfile"
7633         local md5
7634         local parent_ssize
7635         local parent_scount
7636         local cur_ssize
7637         local cur_scount
7638         local orig_ssize
7639         local new_scount
7640         local cur_comp
7641
7642         echo -n "Creating test dir..."
7643         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7644         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7645                 error "cannot set stripe by '-S 1M -c 1'"
7646         echo "done"
7647
7648         echo -n "Setting initial stripe for test file..."
7649         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7650                 error "cannot set stripe"
7651         cur_ssize=$($LFS getstripe -S "$file1")
7652         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7653         echo "done."
7654
7655         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7656         stack_trap "rm -f $file1"
7657         md5="$(md5sum $file1)"
7658
7659         # File currently set to -S 512K -c 1
7660
7661         # Ensure -c and -S options are rejected when -R is set
7662         echo -n "Verifying incompatible options are detected..."
7663         $LFS_MIGRATE -R -c 1 "$file1" &&
7664                 error "incompatible -R and -c options not detected"
7665         $LFS_MIGRATE -R -S 1M "$file1" &&
7666                 error "incompatible -R and -S options not detected"
7667         $LFS_MIGRATE -R -p pool "$file1" &&
7668                 error "incompatible -R and -p options not detected"
7669         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7670                 error "incompatible -R and -E options not detected"
7671         $LFS_MIGRATE -R -A "$file1" &&
7672                 error "incompatible -R and -A options not detected"
7673         $LFS_MIGRATE -A -c 1 "$file1" &&
7674                 error "incompatible -A and -c options not detected"
7675         $LFS_MIGRATE -A -S 1M "$file1" &&
7676                 error "incompatible -A and -S options not detected"
7677         $LFS_MIGRATE -A -p pool "$file1" &&
7678                 error "incompatible -A and -p options not detected"
7679         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7680                 error "incompatible -A and -E options not detected"
7681         echo "done."
7682
7683         # Ensure unrecognized options are passed through to 'lfs migrate'
7684         echo -n "Verifying -S option is passed through to lfs migrate..."
7685         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7686         cur_ssize=$($LFS getstripe -S "$file1")
7687         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7688         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7689         echo "done."
7690
7691         # File currently set to -S 1M -c 1
7692
7693         # Ensure long options are supported
7694         echo -n "Verifying long options supported..."
7695         $LFS_MIGRATE --non-block "$file1" ||
7696                 error "long option without argument not supported"
7697         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7698                 error "long option with argument not supported"
7699         cur_ssize=$($LFS getstripe -S "$file1")
7700         (( cur_ssize == 524288 )) ||
7701                 error "migrate --stripe-size $cur_ssize != 524288"
7702         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7703         echo "done."
7704
7705         # File currently set to -S 512K -c 1
7706
7707         if (( OSTCOUNT > 1 )); then
7708                 echo -n "Verifying explicit stripe count can be set..."
7709                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7710                 cur_scount=$($LFS getstripe -c "$file1")
7711                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7712                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7713                         error "file data has changed (3)"
7714                 echo "done."
7715         fi
7716
7717         # File currently set to -S 512K -c 1 or -S 512K -c 2
7718
7719         # Ensure parent striping is used if -R is set, and no stripe
7720         # count or size is specified
7721         echo -n "Setting stripe for parent directory..."
7722         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7723                 error "cannot set stripe '-S 2M -c 1'"
7724         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7725         echo "done."
7726
7727         echo -n "Verifying restripe option uses parent stripe settings..."
7728         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7729         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7730         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7731         cur_ssize=$($LFS getstripe -S "$file1")
7732         (( cur_ssize == parent_ssize )) ||
7733                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7734         cur_scount=$($LFS getstripe -c "$file1")
7735         (( cur_scount == parent_scount )) ||
7736                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7737         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7738         echo "done."
7739
7740         # File currently set to -S 1M -c 1
7741
7742         # Ensure striping is preserved if -R is not set, and no stripe
7743         # count or size is specified
7744         echo -n "Verifying striping size preserved when not specified..."
7745         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7746         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7747                 error "cannot set stripe on parent directory"
7748         $LFS_MIGRATE "$file1" || error "migrate failed"
7749         cur_ssize=$($LFS getstripe -S "$file1")
7750         (( cur_ssize == orig_ssize )) ||
7751                 error "migrate by default $cur_ssize != $orig_ssize"
7752         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7753         echo "done."
7754
7755         # Ensure file name properly detected when final option has no argument
7756         echo -n "Verifying file name properly detected..."
7757         $LFS_MIGRATE "$file1" ||
7758                 error "file name interpreted as option argument"
7759         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7760         echo "done."
7761
7762         # Ensure PFL arguments are passed through properly
7763         echo -n "Verifying PFL options passed through..."
7764         new_scount=$(((OSTCOUNT + 1) / 2))
7765         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7766                 error "migrate PFL arguments failed"
7767         cur_comp=$($LFS getstripe --comp-count $file1)
7768         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7769         cur_scount=$($LFS getstripe --stripe-count $file1)
7770         (( cur_scount == new_scount)) ||
7771                 error "PFL stripe count $cur_scount != $new_scount"
7772         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7773         echo "done."
7774 }
7775 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7776
7777 test_56wd() {
7778         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7779
7780         local file1=$DIR/$tdir/$tfile
7781
7782         echo -n "Creating test dir..."
7783         test_mkdir $DIR/$tdir || error "cannot create dir"
7784         echo "done."
7785
7786         echo -n "Creating test file..."
7787         echo "$tfile" > $file1
7788         echo "done."
7789
7790         # Ensure 'lfs migrate' will fail by using a non-existent option,
7791         # and make sure rsync is not called to recover
7792         echo -n "Make sure --no-rsync option works..."
7793         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7794                 grep -q 'refusing to fall back to rsync' ||
7795                 error "rsync was called with --no-rsync set"
7796         echo "done."
7797
7798         # Ensure rsync is called without trying 'lfs migrate' first
7799         echo -n "Make sure --rsync option works..."
7800         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7801                 grep -q 'falling back to rsync' &&
7802                 error "lfs migrate was called with --rsync set"
7803         echo "done."
7804 }
7805 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7806
7807 test_56we() {
7808         local td=$DIR/$tdir
7809         local tf=$td/$tfile
7810
7811         test_mkdir $td || error "cannot create $td"
7812         touch $tf || error "cannot touch $tf"
7813
7814         echo -n "Make sure --non-direct|-D works..."
7815         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7816                 grep -q "lfs migrate --non-direct" ||
7817                 error "--non-direct option cannot work correctly"
7818         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7819                 grep -q "lfs migrate -D" ||
7820                 error "-D option cannot work correctly"
7821         echo "done."
7822 }
7823 run_test 56we "check lfs_migrate --non-direct|-D support"
7824
7825 test_56x() {
7826         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7827         check_swap_layouts_support
7828
7829         local dir=$DIR/$tdir
7830         local ref1=/etc/passwd
7831         local file1=$dir/file1
7832
7833         test_mkdir $dir || error "creating dir $dir"
7834         $LFS setstripe -c 2 $file1
7835         cp $ref1 $file1
7836         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7837         stripe=$($LFS getstripe -c $file1)
7838         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7839         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7840
7841         # clean up
7842         rm -f $file1
7843 }
7844 run_test 56x "lfs migration support"
7845
7846 test_56xa() {
7847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7848         check_swap_layouts_support
7849
7850         local dir=$DIR/$tdir/$testnum
7851
7852         test_mkdir -p $dir
7853
7854         local ref1=/etc/passwd
7855         local file1=$dir/file1
7856
7857         $LFS setstripe -c 2 $file1
7858         cp $ref1 $file1
7859         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7860
7861         local stripe=$($LFS getstripe -c $file1)
7862
7863         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7864         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7865
7866         # clean up
7867         rm -f $file1
7868 }
7869 run_test 56xa "lfs migration --block support"
7870
7871 check_migrate_links() {
7872         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7873         local dir="$1"
7874         local file1="$dir/file1"
7875         local begin="$2"
7876         local count="$3"
7877         local runas="$4"
7878         local total_count=$(($begin + $count - 1))
7879         local symlink_count=10
7880         local uniq_count=10
7881
7882         if [ ! -f "$file1" ]; then
7883                 echo -n "creating initial file..."
7884                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7885                         error "cannot setstripe initial file"
7886                 echo "done"
7887
7888                 echo -n "creating symlinks..."
7889                 for s in $(seq 1 $symlink_count); do
7890                         ln -s "$file1" "$dir/slink$s" ||
7891                                 error "cannot create symlinks"
7892                 done
7893                 echo "done"
7894
7895                 echo -n "creating nonlinked files..."
7896                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7897                         error "cannot create nonlinked files"
7898                 echo "done"
7899         fi
7900
7901         # create hard links
7902         if [ ! -f "$dir/file$total_count" ]; then
7903                 echo -n "creating hard links $begin:$total_count..."
7904                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7905                         /dev/null || error "cannot create hard links"
7906                 echo "done"
7907         fi
7908
7909         echo -n "checking number of hard links listed in xattrs..."
7910         local fid=$($LFS getstripe -F "$file1")
7911         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7912
7913         echo "${#paths[*]}"
7914         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7915                         skip "hard link list has unexpected size, skipping test"
7916         fi
7917         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7918                         error "link names should exceed xattrs size"
7919         fi
7920
7921         echo -n "migrating files..."
7922         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7923         local rc=$?
7924         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7925         echo "done"
7926
7927         # make sure all links have been properly migrated
7928         echo -n "verifying files..."
7929         fid=$($LFS getstripe -F "$file1") ||
7930                 error "cannot get fid for file $file1"
7931         for i in $(seq 2 $total_count); do
7932                 local fid2=$($LFS getstripe -F $dir/file$i)
7933
7934                 [ "$fid2" == "$fid" ] ||
7935                         error "migrated hard link has mismatched FID"
7936         done
7937
7938         # make sure hard links were properly detected, and migration was
7939         # performed only once for the entire link set; nonlinked files should
7940         # also be migrated
7941         local actual=$(grep -c 'done' <<< "$migrate_out")
7942         local expected=$(($uniq_count + 1))
7943
7944         [ "$actual" -eq  "$expected" ] ||
7945                 error "hard links individually migrated ($actual != $expected)"
7946
7947         # make sure the correct number of hard links are present
7948         local hardlinks=$(stat -c '%h' "$file1")
7949
7950         [ $hardlinks -eq $total_count ] ||
7951                 error "num hard links $hardlinks != $total_count"
7952         echo "done"
7953
7954         return 0
7955 }
7956
7957 test_56xb() {
7958         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7959                 skip "Need MDS version at least 2.10.55"
7960
7961         local dir="$DIR/$tdir"
7962
7963         test_mkdir "$dir" || error "cannot create dir $dir"
7964
7965         echo "testing lfs migrate mode when all links fit within xattrs"
7966         check_migrate_links "$dir" 2 99
7967
7968         echo "testing rsync mode when all links fit within xattrs"
7969         check_migrate_links --rsync "$dir" 2 99
7970
7971         echo "testing lfs migrate mode when all links do not fit within xattrs"
7972         check_migrate_links "$dir" 101 100
7973
7974         echo "testing rsync mode when all links do not fit within xattrs"
7975         check_migrate_links --rsync "$dir" 101 100
7976
7977         chown -R $RUNAS_ID $dir
7978         echo "testing non-root lfs migrate mode when not all links are in xattr"
7979         check_migrate_links "$dir" 101 100 "$RUNAS"
7980
7981         # clean up
7982         rm -rf $dir
7983 }
7984 run_test 56xb "lfs migration hard link support"
7985
7986 test_56xc() {
7987         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7988
7989         local dir="$DIR/$tdir"
7990
7991         test_mkdir "$dir" || error "cannot create dir $dir"
7992
7993         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7994         echo -n "Setting initial stripe for 20MB test file..."
7995         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7996                 error "cannot setstripe 20MB file"
7997         echo "done"
7998         echo -n "Sizing 20MB test file..."
7999         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8000         echo "done"
8001         echo -n "Verifying small file autostripe count is 1..."
8002         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8003                 error "cannot migrate 20MB file"
8004         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8005                 error "cannot get stripe for $dir/20mb"
8006         [ $stripe_count -eq 1 ] ||
8007                 error "unexpected stripe count $stripe_count for 20MB file"
8008         rm -f "$dir/20mb"
8009         echo "done"
8010
8011         # Test 2: File is small enough to fit within the available space on
8012         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8013         # have at least an additional 1KB for each desired stripe for test 3
8014         echo -n "Setting stripe for 1GB test file..."
8015         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8016         echo "done"
8017         echo -n "Sizing 1GB test file..."
8018         # File size is 1GB + 3KB
8019         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8020         echo "done"
8021
8022         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8023         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8024         if (( avail > 524288 * OSTCOUNT )); then
8025                 echo -n "Migrating 1GB file..."
8026                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8027                         error "cannot migrate 1GB file"
8028                 echo "done"
8029                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8030                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8031                         error "cannot getstripe for 1GB file"
8032                 [ $stripe_count -eq 2 ] ||
8033                         error "unexpected stripe count $stripe_count != 2"
8034                 echo "done"
8035         fi
8036
8037         # Test 3: File is too large to fit within the available space on
8038         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8039         if [ $OSTCOUNT -ge 3 ]; then
8040                 # The required available space is calculated as
8041                 # file size (1GB + 3KB) / OST count (3).
8042                 local kb_per_ost=349526
8043
8044                 echo -n "Migrating 1GB file with limit..."
8045                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8046                         error "cannot migrate 1GB file with limit"
8047                 echo "done"
8048
8049                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8050                 echo -n "Verifying 1GB autostripe count with limited space..."
8051                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8052                         error "unexpected stripe count $stripe_count (min 3)"
8053                 echo "done"
8054         fi
8055
8056         # clean up
8057         rm -rf $dir
8058 }
8059 run_test 56xc "lfs migration autostripe"
8060
8061 test_56xd() {
8062         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8063
8064         local dir=$DIR/$tdir
8065         local f_mgrt=$dir/$tfile.mgrt
8066         local f_yaml=$dir/$tfile.yaml
8067         local f_copy=$dir/$tfile.copy
8068         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8069         local layout_copy="-c 2 -S 2M -i 1"
8070         local yamlfile=$dir/yamlfile
8071         local layout_before;
8072         local layout_after;
8073
8074         test_mkdir "$dir" || error "cannot create dir $dir"
8075         stack_trap "rm -rf $dir"
8076         $LFS setstripe $layout_yaml $f_yaml ||
8077                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8078         $LFS getstripe --yaml $f_yaml > $yamlfile
8079         $LFS setstripe $layout_copy $f_copy ||
8080                 error "cannot setstripe $f_copy with layout $layout_copy"
8081         touch $f_mgrt
8082         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8083
8084         # 1. test option --yaml
8085         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8086                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8087         layout_before=$(get_layout_param $f_yaml)
8088         layout_after=$(get_layout_param $f_mgrt)
8089         [ "$layout_after" == "$layout_before" ] ||
8090                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8091
8092         # 2. test option --copy
8093         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8094                 error "cannot migrate $f_mgrt with --copy $f_copy"
8095         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8096         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8097         [ "$layout_after" == "$layout_before" ] ||
8098                 error "lfs_migrate --copy: $layout_after != $layout_before"
8099 }
8100 run_test 56xd "check lfs_migrate --yaml and --copy support"
8101
8102 test_56xe() {
8103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8104
8105         local dir=$DIR/$tdir
8106         local f_comp=$dir/$tfile
8107         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8108         local layout_before=""
8109         local layout_after=""
8110
8111         test_mkdir "$dir" || error "cannot create dir $dir"
8112         stack_trap "rm -rf $dir"
8113         $LFS setstripe $layout $f_comp ||
8114                 error "cannot setstripe $f_comp with layout $layout"
8115         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8116         dd if=/dev/zero of=$f_comp bs=1M count=4
8117
8118         # 1. migrate a comp layout file by lfs_migrate
8119         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8120         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8121         [ "$layout_before" == "$layout_after" ] ||
8122                 error "lfs_migrate: $layout_before != $layout_after"
8123
8124         # 2. migrate a comp layout file by lfs migrate
8125         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8126         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8127         [ "$layout_before" == "$layout_after" ] ||
8128                 error "lfs migrate: $layout_before != $layout_after"
8129 }
8130 run_test 56xe "migrate a composite layout file"
8131
8132 test_56xf() {
8133         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8134
8135         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8136                 skip "Need server version at least 2.13.53"
8137
8138         local dir=$DIR/$tdir
8139         local f_comp=$dir/$tfile
8140         local layout="-E 1M -c1 -E -1 -c2"
8141         local fid_before=""
8142         local fid_after=""
8143
8144         test_mkdir "$dir" || error "cannot create dir $dir"
8145         stack_trap "rm -rf $dir"
8146         $LFS setstripe $layout $f_comp ||
8147                 error "cannot setstripe $f_comp with layout $layout"
8148         fid_before=$($LFS getstripe --fid $f_comp)
8149         dd if=/dev/zero of=$f_comp bs=1M count=4
8150
8151         # 1. migrate a comp layout file to a comp layout
8152         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8153         fid_after=$($LFS getstripe --fid $f_comp)
8154         [ "$fid_before" == "$fid_after" ] ||
8155                 error "comp-to-comp migrate: $fid_before != $fid_after"
8156
8157         # 2. migrate a comp layout file to a plain layout
8158         $LFS migrate -c2 $f_comp ||
8159                 error "cannot migrate $f_comp by lfs migrate"
8160         fid_after=$($LFS getstripe --fid $f_comp)
8161         [ "$fid_before" == "$fid_after" ] ||
8162                 error "comp-to-plain migrate: $fid_before != $fid_after"
8163
8164         # 3. migrate a plain layout file to a comp layout
8165         $LFS migrate $layout $f_comp ||
8166                 error "cannot migrate $f_comp by lfs migrate"
8167         fid_after=$($LFS getstripe --fid $f_comp)
8168         [ "$fid_before" == "$fid_after" ] ||
8169                 error "plain-to-comp migrate: $fid_before != $fid_after"
8170 }
8171 run_test 56xf "FID is not lost during migration of a composite layout file"
8172
8173 check_file_ost_range() {
8174         local file="$1"
8175         shift
8176         local range="$*"
8177         local -a file_range
8178         local idx
8179
8180         file_range=($($LFS getstripe -y "$file" |
8181                 awk '/l_ost_idx:/ { print $NF }'))
8182
8183         if [[ "${#file_range[@]}" = 0 ]]; then
8184                 echo "No osts found for $file"
8185                 return 1
8186         fi
8187
8188         for idx in "${file_range[@]}"; do
8189                 [[ " $range " =~ " $idx " ]] ||
8190                         return 1
8191         done
8192
8193         return 0
8194 }
8195
8196 sub_test_56xg() {
8197         local stripe_opt="$1"
8198         local pool="$2"
8199         shift 2
8200         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8201
8202         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8203                 error "Fail to migrate $tfile on $pool"
8204         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8205                 error "$tfile is not in pool $pool"
8206         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8207                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8208 }
8209
8210 test_56xg() {
8211         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8212         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8213         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8214                 skip "Need MDS version newer than 2.14.52"
8215
8216         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8217         local -a pool_ranges=("0 0" "1 1" "0 1")
8218
8219         # init pools
8220         for i in "${!pool_names[@]}"; do
8221                 pool_add ${pool_names[$i]} ||
8222                         error "pool_add failed (pool: ${pool_names[$i]})"
8223                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8224                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8225         done
8226
8227         # init the file to migrate
8228         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8229                 error "Unable to create $tfile on OST1"
8230         stack_trap "rm -f $DIR/$tfile"
8231         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8232                 error "Unable to write on $tfile"
8233
8234         echo "1. migrate $tfile on pool ${pool_names[0]}"
8235         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8236
8237         echo "2. migrate $tfile on pool ${pool_names[2]}"
8238         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8239
8240         echo "3. migrate $tfile on pool ${pool_names[1]}"
8241         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8242
8243         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8244         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8245         echo
8246
8247         # Clean pools
8248         destroy_test_pools ||
8249                 error "pool_destroy failed"
8250 }
8251 run_test 56xg "lfs migrate pool support"
8252
8253 test_56xh() {
8254         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8255
8256         local size_mb=25
8257         local file1=$DIR/$tfile
8258         local tmp1=$TMP/$tfile.tmp
8259
8260         $LFS setstripe -c 2 $file1
8261
8262         stack_trap "rm -f $file1 $tmp1"
8263         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8264                         error "error creating $tmp1"
8265         ls -lsh $tmp1
8266         cp $tmp1 $file1
8267
8268         local start=$SECONDS
8269
8270         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8271                 error "migrate failed rc = $?"
8272
8273         local elapsed=$((SECONDS - start))
8274
8275         # with 1MB/s, elapsed should equal size_mb
8276         (( elapsed >= size_mb * 95 / 100 )) ||
8277                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8278
8279         (( elapsed <= size_mb * 120 / 100 )) ||
8280                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8281
8282         (( elapsed <= size_mb * 350 / 100 )) ||
8283                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8284
8285         stripe=$($LFS getstripe -c $file1)
8286         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8287         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8288
8289         # Clean up file (since it is multiple MB)
8290         rm -f $file1 $tmp1
8291 }
8292 run_test 56xh "lfs migrate bandwidth limitation support"
8293
8294 test_56xi() {
8295         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8296         verify_yaml_available || skip_env "YAML verification not installed"
8297
8298         local size_mb=5
8299         local file1=$DIR/$tfile.1
8300         local file2=$DIR/$tfile.2
8301         local file3=$DIR/$tfile.3
8302         local output_file=$DIR/$tfile.out
8303         local tmp1=$TMP/$tfile.tmp
8304
8305         $LFS setstripe -c 2 $file1
8306         $LFS setstripe -c 2 $file2
8307         $LFS setstripe -c 2 $file3
8308
8309         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8310         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8311                         error "error creating $tmp1"
8312         ls -lsh $tmp1
8313         cp $tmp1 $file1
8314         cp $tmp1 $file2
8315         cp $tmp1 $file3
8316
8317         $LFS migrate --stats --stats-interval=1 \
8318                 -c 1 $file1 $file2 $file3 1> $output_file ||
8319                 error "migrate failed rc = $?"
8320
8321         cat $output_file
8322         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8323
8324         # Clean up file (since it is multiple MB)
8325         rm -f $file1 $file2 $file3 $tmp1 $output_file
8326 }
8327 run_test 56xi "lfs migrate stats support"
8328
8329 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8330         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8331
8332         local file=$DIR/$tfile
8333         local linkdir=$DIR/$tdir
8334
8335         test_mkdir $linkdir || error "fail to create $linkdir"
8336         $LFS setstripe -i 0 -c 1 -S1M $file
8337         stack_trap "rm -rf $file $linkdir"
8338         dd if=/dev/urandom of=$file bs=1M count=10 ||
8339                 error "fail to create $file"
8340
8341         # Create file links
8342         local cpts
8343         local threads_max
8344         local nlinks
8345
8346         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8347         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8348         (( nlinks = thread_max * 3 / 2 / cpts))
8349
8350         echo "create $nlinks hard links of $file"
8351         createmany -l $file $linkdir/link $nlinks
8352
8353         # Parallel migrates (should not block)
8354         local i
8355         for ((i = 0; i < nlinks; i++)); do
8356                 echo $linkdir/link$i
8357         done | xargs -n1 -P $nlinks $LFS migrate -c2
8358
8359         local stripe_count
8360         stripe_count=$($LFS getstripe -c $file) ||
8361                 error "fail to get stripe count on $file"
8362
8363         ((stripe_count == 2)) ||
8364                 error "fail to migrate $file (stripe_count = $stripe_count)"
8365 }
8366 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8367
8368 test_56xk() {
8369         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8370
8371         local size_mb=5
8372         local file1=$DIR/$tfile
8373
8374         stack_trap "rm -f $file1"
8375         $LFS setstripe -c 1 $file1
8376         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8377                 error "error creating $file1"
8378         $LFS mirror extend -N $file1 || error "can't mirror"
8379         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8380                 error "can't dd"
8381         $LFS getstripe $file1 | grep stale ||
8382                 error "one component must be stale"
8383
8384         local start=$SECONDS
8385         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8386                 error "migrate failed rc = $?"
8387         local elapsed=$((SECONDS - start))
8388         $LFS getstripe $file1 | grep stale &&
8389                 error "all components must be sync"
8390
8391         # with 1MB/s, elapsed should equal size_mb
8392         (( elapsed >= size_mb * 95 / 100 )) ||
8393                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8394
8395         (( elapsed <= size_mb * 120 / 100 )) ||
8396                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8397
8398         (( elapsed <= size_mb * 350 / 100 )) ||
8399                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8400 }
8401 run_test 56xk "lfs mirror resync bandwidth limitation support"
8402
8403 test_56xl() {
8404         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8405         verify_yaml_available || skip_env "YAML verification not installed"
8406
8407         local size_mb=5
8408         local file1=$DIR/$tfile.1
8409         local output_file=$DIR/$tfile.out
8410
8411         stack_trap "rm -f $file1"
8412         $LFS setstripe -c 1 $file1
8413         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8414                 error "error creating $file1"
8415         $LFS mirror extend -N $file1 || error "can't mirror"
8416         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8417                 error "can't dd"
8418         $LFS getstripe $file1 | grep stale ||
8419                 error "one component must be stale"
8420         $LFS getstripe $file1
8421
8422         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8423                 error "resync failed rc = $?"
8424         $LFS getstripe $file1 | grep stale &&
8425                 error "all components must be sync"
8426
8427         cat $output_file
8428         cat $output_file | verify_yaml || error "stats is not valid YAML"
8429 }
8430 run_test 56xl "lfs mirror resync stats support"
8431
8432 test_56y() {
8433         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8434                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8435
8436         local res=""
8437         local dir=$DIR/$tdir
8438         local f1=$dir/file1
8439         local f2=$dir/file2
8440
8441         test_mkdir -p $dir || error "creating dir $dir"
8442         touch $f1 || error "creating std file $f1"
8443         $MULTIOP $f2 H2c || error "creating released file $f2"
8444
8445         # a directory can be raid0, so ask only for files
8446         res=$($LFS find $dir -L raid0 -type f | wc -l)
8447         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8448
8449         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8450         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8451
8452         # only files can be released, so no need to force file search
8453         res=$($LFS find $dir -L released)
8454         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8455
8456         res=$($LFS find $dir -type f \! -L released)
8457         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8458 }
8459 run_test 56y "lfs find -L raid0|released"
8460
8461 test_56z() { # LU-4824
8462         # This checks to make sure 'lfs find' continues after errors
8463         # There are two classes of errors that should be caught:
8464         # - If multiple paths are provided, all should be searched even if one
8465         #   errors out
8466         # - If errors are encountered during the search, it should not terminate
8467         #   early
8468         local dir=$DIR/$tdir
8469         local i
8470
8471         test_mkdir $dir
8472         for i in d{0..9}; do
8473                 test_mkdir $dir/$i
8474                 touch $dir/$i/$tfile
8475         done
8476         $LFS find $DIR/non_existent_dir $dir &&
8477                 error "$LFS find did not return an error"
8478         # Make a directory unsearchable. This should NOT be the last entry in
8479         # directory order.  Arbitrarily pick the 6th entry
8480         chmod 700 $($LFS find $dir -type d | sed '6!d')
8481
8482         $RUNAS $LFS find $DIR/non_existent $dir
8483         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8484
8485         # The user should be able to see 10 directories and 9 files
8486         (( count == 19 )) ||
8487                 error "$LFS find found $count != 19 entries after error"
8488 }
8489 run_test 56z "lfs find should continue after an error"
8490
8491 test_56aa() { # LU-5937
8492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8493
8494         local dir=$DIR/$tdir
8495
8496         mkdir $dir
8497         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8498
8499         createmany -o $dir/striped_dir/${tfile}- 1024
8500         local dirs=$($LFS find --size +8k $dir/)
8501
8502         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8503 }
8504 run_test 56aa "lfs find --size under striped dir"
8505
8506 test_56ab() { # LU-10705
8507         test_mkdir $DIR/$tdir
8508         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8509         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8510         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8511         # Flush writes to ensure valid blocks.  Need to be more thorough for
8512         # ZFS, since blocks are not allocated/returned to client immediately.
8513         sync_all_data
8514         wait_zfs_commit ost1 2
8515         cancel_lru_locks osc
8516         ls -ls $DIR/$tdir
8517
8518         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8519
8520         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8521
8522         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8523         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8524
8525         rm -f $DIR/$tdir/$tfile.[123]
8526 }
8527 run_test 56ab "lfs find --blocks"
8528
8529 # LU-11188
8530 test_56aca() {
8531         local dir="$DIR/$tdir"
8532         local perms=(001 002 003 004 005 006 007
8533                      010 020 030 040 050 060 070
8534                      100 200 300 400 500 600 700
8535                      111 222 333 444 555 666 777)
8536         local perm_minus=(8 8 4 8 4 4 2
8537                           8 8 4 8 4 4 2
8538                           8 8 4 8 4 4 2
8539                           4 4 2 4 2 2 1)
8540         local perm_slash=(8  8 12  8 12 12 14
8541                           8  8 12  8 12 12 14
8542                           8  8 12  8 12 12 14
8543                          16 16 24 16 24 24 28)
8544
8545         test_mkdir "$dir"
8546         for perm in ${perms[*]}; do
8547                 touch "$dir/$tfile.$perm"
8548                 chmod $perm "$dir/$tfile.$perm"
8549         done
8550
8551         for ((i = 0; i < ${#perms[*]}; i++)); do
8552                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8553                 (( $num == 1 )) ||
8554                         error "lfs find -perm ${perms[i]}:"\
8555                               "$num != 1"
8556
8557                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8558                 (( $num == ${perm_minus[i]} )) ||
8559                         error "lfs find -perm -${perms[i]}:"\
8560                               "$num != ${perm_minus[i]}"
8561
8562                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8563                 (( $num == ${perm_slash[i]} )) ||
8564                         error "lfs find -perm /${perms[i]}:"\
8565                               "$num != ${perm_slash[i]}"
8566         done
8567 }
8568 run_test 56aca "check lfs find -perm with octal representation"
8569
8570 test_56acb() {
8571         local dir=$DIR/$tdir
8572         # p is the permission of write and execute for user, group and other
8573         # without the umask. It is used to test +wx.
8574         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8575         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8576         local symbolic=(+t  a+t u+t g+t o+t
8577                         g+s u+s o+s +s o+sr
8578                         o=r,ug+o,u+w
8579                         u+ g+ o+ a+ ugo+
8580                         u- g- o- a- ugo-
8581                         u= g= o= a= ugo=
8582                         o=r,ug+o,u+w u=r,a+u,u+w
8583                         g=r,ugo=g,u+w u+x,+X +X
8584                         u+x,u+X u+X u+x,g+X o+r,+X
8585                         u+x,go+X +wx +rwx)
8586
8587         test_mkdir $dir
8588         for perm in ${perms[*]}; do
8589                 touch "$dir/$tfile.$perm"
8590                 chmod $perm "$dir/$tfile.$perm"
8591         done
8592
8593         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8594                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8595
8596                 (( $num == 1 )) ||
8597                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8598         done
8599 }
8600 run_test 56acb "check lfs find -perm with symbolic representation"
8601
8602 test_56acc() {
8603         local dir=$DIR/$tdir
8604         local tests="17777 787 789 abcd
8605                 ug=uu ug=a ug=gu uo=ou urw
8606                 u+xg+x a=r,u+x,"
8607
8608         test_mkdir $dir
8609         for err in $tests; do
8610                 if $LFS find $dir -perm $err 2>/dev/null; then
8611                         error "lfs find -perm $err: parsing should have failed"
8612                 fi
8613         done
8614 }
8615 run_test 56acc "check parsing error for lfs find -perm"
8616
8617 test_56ba() {
8618         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8619                 skip "Need MDS version at least 2.10.50"
8620
8621         # Create composite files with one component
8622         local dir=$DIR/$tdir
8623
8624         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8625         # Create composite files with three components
8626         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8627         # LU-16904 Create plain layout files
8628         lfs setstripe -c 1 $dir/$tfile-{1..10}
8629
8630         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8631
8632         [[ $nfiles == 10 ]] ||
8633                 error "lfs find -E 1M found $nfiles != 10 files"
8634
8635         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8636         [[ $nfiles == 25 ]] ||
8637                 error "lfs find ! -E 1M found $nfiles != 25 files"
8638
8639         # All files have a component that starts at 0
8640         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8641         [[ $nfiles == 35 ]] ||
8642                 error "lfs find --component-start 0 - $nfiles != 35 files"
8643
8644         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8645         [[ $nfiles == 15 ]] ||
8646                 error "lfs find --component-start 2M - $nfiles != 15 files"
8647
8648         # All files created here have a componenet that does not starts at 2M
8649         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8650         [[ $nfiles == 35 ]] ||
8651                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8652
8653         # Find files with a specified number of components
8654         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8655         [[ $nfiles == 15 ]] ||
8656                 error "lfs find --component-count 3 - $nfiles != 15 files"
8657
8658         # Remember non-composite files have a component count of zero
8659         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8660         [[ $nfiles == 10 ]] ||
8661                 error "lfs find --component-count 0 - $nfiles != 10 files"
8662
8663         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8664         [[ $nfiles == 20 ]] ||
8665                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8666
8667         # All files have a flag called "init"
8668         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8669         [[ $nfiles == 35 ]] ||
8670                 error "lfs find --component-flags init - $nfiles != 35 files"
8671
8672         # Multi-component files will have a component not initialized
8673         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8674         [[ $nfiles == 15 ]] ||
8675                 error "lfs find !--component-flags init - $nfiles != 15 files"
8676
8677         rm -rf $dir
8678
8679 }
8680 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8681
8682 test_56ca() {
8683         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8684                 skip "Need MDS version at least 2.10.57"
8685
8686         local td=$DIR/$tdir
8687         local tf=$td/$tfile
8688         local dir
8689         local nfiles
8690         local cmd
8691         local i
8692         local j
8693
8694         # create mirrored directories and mirrored files
8695         mkdir $td || error "mkdir $td failed"
8696         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8697         createmany -o $tf- 10 || error "create $tf- failed"
8698
8699         for i in $(seq 2); do
8700                 dir=$td/dir$i
8701                 mkdir $dir || error "mkdir $dir failed"
8702                 $LFS mirror create -N$((3 + i)) $dir ||
8703                         error "create mirrored dir $dir failed"
8704                 createmany -o $dir/$tfile- 10 ||
8705                         error "create $dir/$tfile- failed"
8706         done
8707
8708         # change the states of some mirrored files
8709         echo foo > $tf-6
8710         for i in $(seq 2); do
8711                 dir=$td/dir$i
8712                 for j in $(seq 4 9); do
8713                         echo foo > $dir/$tfile-$j
8714                 done
8715         done
8716
8717         # find mirrored files with specific mirror count
8718         cmd="$LFS find --mirror-count 3 --type f $td"
8719         nfiles=$($cmd | wc -l)
8720         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8721
8722         cmd="$LFS find ! --mirror-count 3 --type f $td"
8723         nfiles=$($cmd | wc -l)
8724         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8725
8726         cmd="$LFS find --mirror-count +2 --type f $td"
8727         nfiles=$($cmd | wc -l)
8728         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8729
8730         cmd="$LFS find --mirror-count -6 --type f $td"
8731         nfiles=$($cmd | wc -l)
8732         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8733
8734         # find mirrored files with specific file state
8735         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8736         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8737
8738         cmd="$LFS find --mirror-state=ro --type f $td"
8739         nfiles=$($cmd | wc -l)
8740         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8741
8742         cmd="$LFS find ! --mirror-state=ro --type f $td"
8743         nfiles=$($cmd | wc -l)
8744         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8745
8746         cmd="$LFS find --mirror-state=wp --type f $td"
8747         nfiles=$($cmd | wc -l)
8748         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8749
8750         cmd="$LFS find ! --mirror-state=sp --type f $td"
8751         nfiles=$($cmd | wc -l)
8752         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8753 }
8754 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8755
8756 test_56da() { # LU-14179
8757         local path=$DIR/$tdir
8758
8759         test_mkdir $path
8760         cd $path
8761
8762         local longdir=$(str_repeat 'a' 255)
8763
8764         for i in {1..15}; do
8765                 path=$path/$longdir
8766                 test_mkdir $longdir
8767                 cd $longdir
8768         done
8769
8770         local len=${#path}
8771         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8772
8773         test_mkdir $lastdir
8774         cd $lastdir
8775         # PATH_MAX-1
8776         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8777
8778         # NAME_MAX
8779         touch $(str_repeat 'f' 255)
8780
8781         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8782                 error "lfs find reported an error"
8783
8784         rm -rf $DIR/$tdir
8785 }
8786 run_test 56da "test lfs find with long paths"
8787
8788 test_56ea() { #LU-10378
8789         local path=$DIR/$tdir
8790         local pool=$TESTNAME
8791
8792         # Create ost pool
8793         pool_add $pool || error "pool_add $pool failed"
8794         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8795                 error "adding targets to $pool failed"
8796
8797         # Set default pool on directory before creating file
8798         mkdir $path || error "mkdir $path failed"
8799         $LFS setstripe -p $pool $path ||
8800                 error "set OST pool on $pool failed"
8801         touch $path/$tfile || error "touch $path/$tfile failed"
8802
8803         # Compare basic file attributes from -printf and stat
8804         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8805         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8806
8807         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8808                 error "Attrs from lfs find and stat don't match"
8809
8810         # Compare Lustre attributes from lfs find and lfs getstripe
8811         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8812         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8813         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8814         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8815         local fpool=$($LFS getstripe --pool $path/$tfile)
8816         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8817
8818         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8819                 error "Attrs from lfs find and lfs getstripe don't match"
8820
8821         # Verify behavior for unknown escape/format sequences
8822         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8823
8824         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8825                 error "Escape/format codes don't match"
8826 }
8827 run_test 56ea "test lfs find -printf option"
8828
8829 test_56eb() {
8830         local dir=$DIR/$tdir
8831         local subdir_1=$dir/subdir_1
8832
8833         test_mkdir -p $subdir_1
8834         ln -s subdir_1 $dir/link_1
8835
8836         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8837                 error "symlink is not followed"
8838
8839         $LFS getstripe --no-follow $dir |
8840                 grep "^$dir/link_1 has no stripe info$" ||
8841                 error "symlink should not have stripe info"
8842
8843         touch $dir/testfile
8844         ln -s testfile $dir/file_link_2
8845
8846         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8847                 error "symlink is not followed"
8848
8849         $LFS getstripe --no-follow $dir |
8850                 grep "^$dir/file_link_2 has no stripe info$" ||
8851                 error "symlink should not have stripe info"
8852 }
8853 run_test 56eb "check lfs getstripe on symlink"
8854
8855 test_56ec() {
8856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8857         local dir=$DIR/$tdir
8858         local srcfile=$dir/srcfile
8859         local srcyaml=$dir/srcyaml
8860         local destfile=$dir/destfile
8861
8862         test_mkdir -p $dir
8863
8864         $LFS setstripe -i 1 $srcfile
8865         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8866         # if the setstripe yaml parsing fails for any reason, the command can
8867         # randomly assign the correct OST index, leading to an erroneous
8868         # success. but the chance of false success is low enough that a
8869         # regression should still be quickly caught.
8870         $LFS setstripe --yaml=$srcyaml $destfile
8871
8872         local srcindex=$($LFS getstripe -i $srcfile)
8873         local destindex=$($LFS getstripe -i $destfile)
8874
8875         if [[ ! $srcindex -eq $destindex ]]; then
8876                 error "setstripe did not set OST index correctly"
8877         fi
8878 }
8879 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8880
8881 test_56eda() {
8882         local dir=$DIR/$tdir
8883         local subdir=$dir/subdir
8884         local file1=$dir/$tfile
8885         local file2=$dir/$tfile\2
8886         local link=$dir/$tfile-link
8887         local nfiles
8888
8889         test_mkdir -p $dir
8890         $LFS setdirstripe -c1 $subdir
8891         touch $file1
8892         touch $file2
8893         ln $file2 $link
8894
8895         nfiles=$($LFS find --links 1 $dir | wc -l)
8896         (( $nfiles == 1 )) ||
8897                 error "lfs find --links expected 1 file, got $nfiles"
8898
8899         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8900         (( $nfiles == 2 )) ||
8901                 error "lfs find --links expected 2 files, got $nfiles"
8902
8903         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8904         (( $nfiles == 1 )) ||
8905                 error "lfs find --links expected 1 directory, got $nfiles"
8906 }
8907 run_test 56eda "check lfs find --links"
8908
8909 test_56edb() {
8910         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8911
8912         local dir=$DIR/$tdir
8913         local stripedir=$dir/stripedir
8914         local nfiles
8915
8916         test_mkdir -p $dir
8917
8918         $LFS setdirstripe -c2 $stripedir
8919
8920         $LFS getdirstripe $stripedir
8921
8922         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8923         (( $nfiles == 1 )) ||
8924                 error "lfs find --links expected 1 directory, got $nfiles"
8925 }
8926 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8927
8928 test_56ef() {
8929         local dir=$DIR/$tdir
8930         local dir1=$dir/d1
8931         local dir2=$dir/d2
8932         local nfiles
8933
8934         test_mkdir -p $dir
8935
8936         mkdir $dir1
8937         mkdir $dir2
8938
8939         touch $dir1/f
8940         touch $dir2/f
8941
8942         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8943         (( $nfiles == 2 )) ||
8944                 error "(1) lfs find expected 2 files, got $nfiles"
8945
8946         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8947         (( $nfiles == 2 )) ||
8948                 error "(2) lfs find expected 2 files, got $nfiles"
8949
8950         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8951         (( $nfiles == 2 )) ||
8952                 error "(3) lfs find expected 2 files, got $nfiles"
8953 }
8954 run_test 56ef "lfs find with multiple paths"
8955
8956 test_57a() {
8957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8958         # note test will not do anything if MDS is not local
8959         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8960                 skip_env "ldiskfs only test"
8961         fi
8962         remote_mds_nodsh && skip "remote MDS with nodsh"
8963
8964         local MNTDEV="osd*.*MDT*.mntdev"
8965         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8966         [ -z "$DEV" ] && error "can't access $MNTDEV"
8967         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8968                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8969                         error "can't access $DEV"
8970                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8971                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8972                 rm $TMP/t57a.dump
8973         done
8974 }
8975 run_test 57a "verify MDS filesystem created with large inodes =="
8976
8977 test_57b() {
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8980                 skip_env "ldiskfs only test"
8981         fi
8982         remote_mds_nodsh && skip "remote MDS with nodsh"
8983
8984         local dir=$DIR/$tdir
8985         local filecount=100
8986         local file1=$dir/f1
8987         local fileN=$dir/f$filecount
8988
8989         rm -rf $dir || error "removing $dir"
8990         test_mkdir -c1 $dir
8991         local mdtidx=$($LFS getstripe -m $dir)
8992         local mdtname=MDT$(printf %04x $mdtidx)
8993         local facet=mds$((mdtidx + 1))
8994
8995         echo "mcreating $filecount files"
8996         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8997
8998         # verify that files do not have EAs yet
8999         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9000                 error "$file1 has an EA"
9001         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9002                 error "$fileN has an EA"
9003
9004         sync
9005         sleep 1
9006         df $dir  #make sure we get new statfs data
9007         local mdsfree=$(do_facet $facet \
9008                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9009         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9010         local file
9011
9012         echo "opening files to create objects/EAs"
9013         for file in $(seq -f $dir/f%g 1 $filecount); do
9014                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9015                         error "opening $file"
9016         done
9017
9018         # verify that files have EAs now
9019         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9020                 error "$file1 missing EA"
9021         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9022                 error "$fileN missing EA"
9023
9024         sleep 1  #make sure we get new statfs data
9025         df $dir
9026         local mdsfree2=$(do_facet $facet \
9027                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9028         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9029
9030         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9031                 if [ "$mdsfree" != "$mdsfree2" ]; then
9032                         error "MDC before $mdcfree != after $mdcfree2"
9033                 else
9034                         echo "MDC before $mdcfree != after $mdcfree2"
9035                         echo "unable to confirm if MDS has large inodes"
9036                 fi
9037         fi
9038         rm -rf $dir
9039 }
9040 run_test 57b "default LOV EAs are stored inside large inodes ==="
9041
9042 test_58() {
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044         [ -z "$(which wiretest 2>/dev/null)" ] &&
9045                         skip_env "could not find wiretest"
9046
9047         wiretest
9048 }
9049 run_test 58 "verify cross-platform wire constants =============="
9050
9051 test_59() {
9052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9053
9054         echo "touch 130 files"
9055         createmany -o $DIR/f59- 130
9056         echo "rm 130 files"
9057         unlinkmany $DIR/f59- 130
9058         sync
9059         # wait for commitment of removal
9060         wait_delete_completed
9061 }
9062 run_test 59 "verify cancellation of llog records async ========="
9063
9064 TEST60_HEAD="test_60 run $RANDOM"
9065 test_60a() {
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         remote_mgs_nodsh && skip "remote MGS with nodsh"
9068         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9069                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9070                         skip_env "missing subtest run-llog.sh"
9071
9072         log "$TEST60_HEAD - from kernel mode"
9073         do_facet mgs "$LCTL dk > /dev/null"
9074         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9075         do_facet mgs $LCTL dk > $TMP/$tfile
9076
9077         # LU-6388: test llog_reader
9078         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9079         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9080         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9081                         skip_env "missing llog_reader"
9082         local fstype=$(facet_fstype mgs)
9083         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9084                 skip_env "Only for ldiskfs or zfs type mgs"
9085
9086         local mntpt=$(facet_mntpt mgs)
9087         local mgsdev=$(mgsdevname 1)
9088         local fid_list
9089         local fid
9090         local rec_list
9091         local rec
9092         local rec_type
9093         local obj_file
9094         local path
9095         local seq
9096         local oid
9097         local pass=true
9098
9099         #get fid and record list
9100         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9101                 tail -n 4))
9102         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9103                 tail -n 4))
9104         #remount mgs as ldiskfs or zfs type
9105         stop mgs || error "stop mgs failed"
9106         mount_fstype mgs || error "remount mgs failed"
9107         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9108                 fid=${fid_list[i]}
9109                 rec=${rec_list[i]}
9110                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9111                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9112                 oid=$((16#$oid))
9113
9114                 case $fstype in
9115                         ldiskfs )
9116                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9117                         zfs )
9118                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9119                 esac
9120                 echo "obj_file is $obj_file"
9121                 do_facet mgs $llog_reader $obj_file
9122
9123                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9124                         awk '{ print $3 }' | sed -e "s/^type=//g")
9125                 if [ $rec_type != $rec ]; then
9126                         echo "FAILED test_60a wrong record type $rec_type," \
9127                               "should be $rec"
9128                         pass=false
9129                         break
9130                 fi
9131
9132                 #check obj path if record type is LLOG_LOGID_MAGIC
9133                 if [ "$rec" == "1064553b" ]; then
9134                         path=$(do_facet mgs $llog_reader $obj_file |
9135                                 grep "path=" | awk '{ print $NF }' |
9136                                 sed -e "s/^path=//g")
9137                         if [ $obj_file != $mntpt/$path ]; then
9138                                 echo "FAILED test_60a wrong obj path" \
9139                                       "$montpt/$path, should be $obj_file"
9140                                 pass=false
9141                                 break
9142                         fi
9143                 fi
9144         done
9145         rm -f $TMP/$tfile
9146         #restart mgs before "error", otherwise it will block the next test
9147         stop mgs || error "stop mgs failed"
9148         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9149         $pass || error "test failed, see FAILED test_60a messages for specifics"
9150 }
9151 run_test 60a "llog_test run from kernel module and test llog_reader"
9152
9153 test_60b() { # bug 6411
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155
9156         dmesg > $DIR/$tfile
9157         LLOG_COUNT=$(do_facet mgs dmesg |
9158                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9159                           /llog_[a-z]*.c:[0-9]/ {
9160                                 if (marker)
9161                                         from_marker++
9162                                 from_begin++
9163                           }
9164                           END {
9165                                 if (marker)
9166                                         print from_marker
9167                                 else
9168                                         print from_begin
9169                           }")
9170
9171         [[ $LLOG_COUNT -gt 120 ]] &&
9172                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9173 }
9174 run_test 60b "limit repeated messages from CERROR/CWARN"
9175
9176 test_60c() {
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178
9179         echo "create 5000 files"
9180         createmany -o $DIR/f60c- 5000
9181 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9182         lctl set_param fail_loc=0x80000137
9183         unlinkmany $DIR/f60c- 5000
9184         lctl set_param fail_loc=0
9185 }
9186 run_test 60c "unlink file when mds full"
9187
9188 test_60d() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190
9191         SAVEPRINTK=$(lctl get_param -n printk)
9192         # verify "lctl mark" is even working"
9193         MESSAGE="test message ID $RANDOM $$"
9194         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9195         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9196
9197         lctl set_param printk=0 || error "set lnet.printk failed"
9198         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9199         MESSAGE="new test message ID $RANDOM $$"
9200         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9201         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9202         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9203
9204         lctl set_param -n printk="$SAVEPRINTK"
9205 }
9206 run_test 60d "test printk console message masking"
9207
9208 test_60e() {
9209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9210         remote_mds_nodsh && skip "remote MDS with nodsh"
9211
9212         touch $DIR/$tfile
9213 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9214         do_facet mds1 lctl set_param fail_loc=0x15b
9215         rm $DIR/$tfile
9216 }
9217 run_test 60e "no space while new llog is being created"
9218
9219 test_60f() {
9220         local old_path=$($LCTL get_param -n debug_path)
9221
9222         stack_trap "$LCTL set_param debug_path=$old_path"
9223         stack_trap "rm -f $TMP/$tfile*"
9224         rm -f $TMP/$tfile* 2> /dev/null
9225         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9226         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9227         test_mkdir $DIR/$tdir
9228         # retry in case the open is cached and not released
9229         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9230                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9231                 sleep 0.1
9232         done
9233         ls $TMP/$tfile*
9234         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9235 }
9236 run_test 60f "change debug_path works"
9237
9238 test_60g() {
9239         local pid
9240         local i
9241
9242         test_mkdir -c $MDSCOUNT $DIR/$tdir
9243
9244         (
9245                 local index=0
9246                 while true; do
9247                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9248                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9249                                 2>/dev/null
9250                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9251                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9252                         index=$((index + 1))
9253                 done
9254         ) &
9255
9256         pid=$!
9257
9258         for i in {0..100}; do
9259                 # define OBD_FAIL_OSD_TXN_START    0x19a
9260                 local index=$((i % MDSCOUNT + 1))
9261
9262                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9263                         > /dev/null
9264                 sleep 0.01
9265         done
9266
9267         kill -9 $pid
9268
9269         for i in $(seq $MDSCOUNT); do
9270                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9271         done
9272
9273         mkdir $DIR/$tdir/new || error "mkdir failed"
9274         rmdir $DIR/$tdir/new || error "rmdir failed"
9275
9276         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9277                 -t namespace
9278         for i in $(seq $MDSCOUNT); do
9279                 wait_update_facet mds$i "$LCTL get_param -n \
9280                         mdd.$(facet_svc mds$i).lfsck_namespace |
9281                         awk '/^status/ { print \\\$2 }'" "completed"
9282         done
9283
9284         ls -R $DIR/$tdir
9285         rm -rf $DIR/$tdir || error "rmdir failed"
9286 }
9287 run_test 60g "transaction abort won't cause MDT hung"
9288
9289 test_60h() {
9290         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9291                 skip "Need MDS version at least 2.12.52"
9292         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9293
9294         local f
9295
9296         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9297         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9298         for fail_loc in 0x80000188 0x80000189; do
9299                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9300                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9301                         error "mkdir $dir-$fail_loc failed"
9302                 for i in {0..10}; do
9303                         # create may fail on missing stripe
9304                         echo $i > $DIR/$tdir-$fail_loc/$i
9305                 done
9306                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9307                         error "getdirstripe $tdir-$fail_loc failed"
9308                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9309                         error "migrate $tdir-$fail_loc failed"
9310                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9311                         error "getdirstripe $tdir-$fail_loc failed"
9312                 pushd $DIR/$tdir-$fail_loc
9313                 for f in *; do
9314                         echo $f | cmp $f - || error "$f data mismatch"
9315                 done
9316                 popd
9317                 rm -rf $DIR/$tdir-$fail_loc
9318         done
9319 }
9320 run_test 60h "striped directory with missing stripes can be accessed"
9321
9322 function t60i_load() {
9323         mkdir $DIR/$tdir
9324         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9325         $LCTL set_param fail_loc=0x131c fail_val=1
9326         for ((i=0; i<5000; i++)); do
9327                 touch $DIR/$tdir/f$i
9328         done
9329 }
9330
9331 test_60i() {
9332         changelog_register || error "changelog_register failed"
9333         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9334         changelog_users $SINGLEMDS | grep -q $cl_user ||
9335                 error "User $cl_user not found in changelog_users"
9336         changelog_chmask "ALL"
9337         t60i_load &
9338         local PID=$!
9339         for((i=0; i<100; i++)); do
9340                 changelog_dump >/dev/null ||
9341                         error "can't read changelog"
9342         done
9343         kill $PID
9344         wait $PID
9345         changelog_deregister || error "changelog_deregister failed"
9346         $LCTL set_param fail_loc=0
9347 }
9348 run_test 60i "llog: new record vs reader race"
9349
9350 test_60j() {
9351         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9352                 skip "need MDS version at least 2.15.50"
9353         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9354         remote_mds_nodsh && skip "remote MDS with nodsh"
9355         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9356
9357         changelog_users $SINGLEMDS | grep "^cl" &&
9358                 skip "active changelog user"
9359
9360         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9361
9362         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9363                 skip_env "missing llog_reader"
9364
9365         mkdir_on_mdt0 $DIR/$tdir
9366
9367         local f=$DIR/$tdir/$tfile
9368         local mdt_dev
9369         local tmpfile
9370         local plain
9371
9372         changelog_register || error "cannot register changelog user"
9373
9374         # set changelog_mask to ALL
9375         changelog_chmask "ALL"
9376         changelog_clear
9377
9378         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9379         unlinkmany ${f}- 100 || error "unlinkmany failed"
9380
9381         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9382         mdt_dev=$(facet_device $SINGLEMDS)
9383
9384         do_facet $SINGLEMDS sync
9385         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9386                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9387                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9388
9389         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9390
9391         # if $tmpfile is not on EXT3 filesystem for some reason
9392         [[ ${plain:0:1} == 'O' ]] ||
9393                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9394
9395         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9396                 $mdt_dev; stat -c %s $tmpfile")
9397         echo "Truncate llog from $size to $((size - size % 8192))"
9398         size=$((size - size % 8192))
9399         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9400         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9401                 grep -c 'in bitmap only')
9402         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9403
9404         size=$((size - 9000))
9405         echo "Corrupt llog in the middle at $size"
9406         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9407                 count=333 conv=notrunc
9408         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9409                 grep -c 'next chunk')
9410         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9411 }
9412 run_test 60j "llog_reader reports corruptions"
9413
9414 test_61a() {
9415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9416
9417         f="$DIR/f61"
9418         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9419         cancel_lru_locks osc
9420         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9421         sync
9422 }
9423 run_test 61a "mmap() writes don't make sync hang ================"
9424
9425 test_61b() {
9426         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9427 }
9428 run_test 61b "mmap() of unstriped file is successful"
9429
9430 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9431 # Though this test is irrelevant anymore, it helped to reveal some
9432 # other grant bugs (LU-4482), let's keep it.
9433 test_63a() {   # was test_63
9434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9435
9436         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9437
9438         for i in `seq 10` ; do
9439                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9440                 sleep 5
9441                 kill $!
9442                 sleep 1
9443         done
9444
9445         rm -f $DIR/f63 || true
9446 }
9447 run_test 63a "Verify oig_wait interruption does not crash ======="
9448
9449 # bug 2248 - async write errors didn't return to application on sync
9450 # bug 3677 - async write errors left page locked
9451 test_63b() {
9452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9453
9454         debugsave
9455         lctl set_param debug=-1
9456
9457         # ensure we have a grant to do async writes
9458         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9459         rm $DIR/$tfile
9460
9461         sync    # sync lest earlier test intercept the fail_loc
9462
9463         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9464         lctl set_param fail_loc=0x80000406
9465         $MULTIOP $DIR/$tfile Owy && \
9466                 error "sync didn't return ENOMEM"
9467         sync; sleep 2; sync     # do a real sync this time to flush page
9468         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9469                 error "locked page left in cache after async error" || true
9470         debugrestore
9471 }
9472 run_test 63b "async write errors should be returned to fsync ==="
9473
9474 test_64a () {
9475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9476
9477         lfs df $DIR
9478         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9479 }
9480 run_test 64a "verify filter grant calculations (in kernel) ====="
9481
9482 test_64b () {
9483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9484
9485         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9486 }
9487 run_test 64b "check out-of-space detection on client"
9488
9489 test_64c() {
9490         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9491 }
9492 run_test 64c "verify grant shrink"
9493
9494 import_param() {
9495         local tgt=$1
9496         local param=$2
9497
9498         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9499 }
9500
9501 # this does exactly what osc_request.c:osc_announce_cached() does in
9502 # order to calculate max amount of grants to ask from server
9503 want_grant() {
9504         local tgt=$1
9505
9506         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9507         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9508
9509         ((rpc_in_flight++));
9510         nrpages=$((nrpages * rpc_in_flight))
9511
9512         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9513
9514         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9515
9516         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9517         local undirty=$((nrpages * PAGE_SIZE))
9518
9519         local max_extent_pages
9520         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9521         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9522         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9523         local grant_extent_tax
9524         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9525
9526         undirty=$((undirty + nrextents * grant_extent_tax))
9527
9528         echo $undirty
9529 }
9530
9531 # this is size of unit for grant allocation. It should be equal to
9532 # what tgt_grant.c:tgt_grant_chunk() calculates
9533 grant_chunk() {
9534         local tgt=$1
9535         local max_brw_size
9536         local grant_extent_tax
9537
9538         max_brw_size=$(import_param $tgt max_brw_size)
9539
9540         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9541
9542         echo $(((max_brw_size + grant_extent_tax) * 2))
9543 }
9544
9545 test_64d() {
9546         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9547                 skip "OST < 2.10.55 doesn't limit grants enough"
9548
9549         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9550
9551         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9552                 skip "no grant_param connect flag"
9553
9554         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9555
9556         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9557         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9558
9559
9560         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9561         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9562
9563         $LFS setstripe $DIR/$tfile -i 0 -c 1
9564         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9565         ddpid=$!
9566
9567         while kill -0 $ddpid; do
9568                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9569
9570                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9571                         kill $ddpid
9572                         error "cur_grant $cur_grant > $max_cur_granted"
9573                 fi
9574
9575                 sleep 1
9576         done
9577 }
9578 run_test 64d "check grant limit exceed"
9579
9580 check_grants() {
9581         local tgt=$1
9582         local expected=$2
9583         local msg=$3
9584         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9585
9586         ((cur_grants == expected)) ||
9587                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9588 }
9589
9590 round_up_p2() {
9591         echo $((($1 + $2 - 1) & ~($2 - 1)))
9592 }
9593
9594 test_64e() {
9595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9596         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9597                 skip "Need OSS version at least 2.11.56"
9598
9599         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9600         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9601         $LCTL set_param debug=+cache
9602
9603         # Remount client to reset grant
9604         remount_client $MOUNT || error "failed to remount client"
9605         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9606
9607         local init_grants=$(import_param $osc_tgt initial_grant)
9608
9609         check_grants $osc_tgt $init_grants "init grants"
9610
9611         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9612         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9613         local gbs=$(import_param $osc_tgt grant_block_size)
9614
9615         # write random number of bytes from max_brw_size / 4 to max_brw_size
9616         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9617         # align for direct io
9618         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9619         # round to grant consumption unit
9620         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9621
9622         local grants=$((wb_round_up + extent_tax))
9623
9624         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9625         stack_trap "rm -f $DIR/$tfile"
9626
9627         # define OBD_FAIL_TGT_NO_GRANT 0x725
9628         # make the server not grant more back
9629         do_facet ost1 $LCTL set_param fail_loc=0x725
9630         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9631
9632         do_facet ost1 $LCTL set_param fail_loc=0
9633
9634         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9635
9636         rm -f $DIR/$tfile || error "rm failed"
9637
9638         # Remount client to reset grant
9639         remount_client $MOUNT || error "failed to remount client"
9640         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9641
9642         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9643
9644         # define OBD_FAIL_TGT_NO_GRANT 0x725
9645         # make the server not grant more back
9646         do_facet ost1 $LCTL set_param fail_loc=0x725
9647         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9648         do_facet ost1 $LCTL set_param fail_loc=0
9649
9650         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9651 }
9652 run_test 64e "check grant consumption (no grant allocation)"
9653
9654 test_64f() {
9655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9656
9657         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9658         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9659         $LCTL set_param debug=+cache
9660
9661         # Remount client to reset grant
9662         remount_client $MOUNT || error "failed to remount client"
9663         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9664
9665         local init_grants=$(import_param $osc_tgt initial_grant)
9666         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9667         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9668         local gbs=$(import_param $osc_tgt grant_block_size)
9669         local chunk=$(grant_chunk $osc_tgt)
9670
9671         # write random number of bytes from max_brw_size / 4 to max_brw_size
9672         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9673         # align for direct io
9674         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9675         # round to grant consumption unit
9676         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9677
9678         local grants=$((wb_round_up + extent_tax))
9679
9680         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9681         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9682                 error "error writing to $DIR/$tfile"
9683
9684         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9685                 "direct io with grant allocation"
9686
9687         rm -f $DIR/$tfile || error "rm failed"
9688
9689         # Remount client to reset grant
9690         remount_client $MOUNT || error "failed to remount client"
9691         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9692
9693         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9694
9695         # Testing that buffered IO consumes grant on the client
9696
9697         # Delay the RPC on the server so it's guaranteed to not complete even
9698         # if the RPC is sent from the client
9699         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9700         $LCTL set_param fail_loc=0x50a fail_val=3
9701         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9702                 error "error writing to $DIR/$tfile with buffered IO"
9703
9704         check_grants $osc_tgt $((init_grants - grants)) \
9705                 "buffered io, not write rpc"
9706
9707         # Clear the fail loc and do a sync on the client
9708         $LCTL set_param fail_loc=0 fail_val=0
9709         sync
9710
9711         # RPC is now known to have sent
9712         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9713                 "buffered io, one RPC"
9714 }
9715 run_test 64f "check grant consumption (with grant allocation)"
9716
9717 test_64g() {
9718         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9719                 skip "Need MDS version at least 2.14.56"
9720
9721         local mdts=$(comma_list $(mdts_nodes))
9722
9723         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9724                         tr '\n' ' ')
9725         stack_trap "$LCTL set_param $old"
9726
9727         # generate dirty pages and increase dirty granted on MDT
9728         stack_trap "rm -f $DIR/$tfile-*"
9729         for (( i = 0; i < 10; i++)); do
9730                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9731                         error "can't set stripe"
9732                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9733                         error "can't dd"
9734                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9735                         $LFS getstripe $DIR/$tfile-$i
9736                         error "not DoM file"
9737                 }
9738         done
9739
9740         # flush dirty pages
9741         sync
9742
9743         # wait until grant shrink reset grant dirty on MDTs
9744         for ((i = 0; i < 120; i++)); do
9745                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9746                         awk '{sum=sum+$1} END {print sum}')
9747                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9748                 echo "$grant_dirty grants, $vm_dirty pages"
9749                 (( grant_dirty + vm_dirty == 0 )) && break
9750                 (( i == 3 )) && sync &&
9751                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9752                 sleep 1
9753         done
9754
9755         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9756                 awk '{sum=sum+$1} END {print sum}')
9757         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9758 }
9759 run_test 64g "grant shrink on MDT"
9760
9761 test_64h() {
9762         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9763                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9764
9765         local instance=$($LFS getname -i $DIR)
9766         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9767         local num_exps=$(do_facet ost1 \
9768             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9769         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9770         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9771         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9772
9773         # 10MiB is for file to be written, max_brw_size * 16 *
9774         # num_exps is space reserve so that tgt_grant_shrink() decided
9775         # to not shrink
9776         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9777         (( avail * 1024 < expect )) &&
9778                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9779
9780         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9781         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9782         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9783         $LCTL set_param osc.*OST0000*.grant_shrink=1
9784         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9785
9786         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9787         stack_trap "rm -f $DIR/$tfile"
9788         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9789
9790         # drop cache so that coming read would do rpc
9791         cancel_lru_locks osc
9792
9793         # shrink interval is set to 10, pause for 7 seconds so that
9794         # grant thread did not wake up yet but coming read entered
9795         # shrink mode for rpc (osc_should_shrink_grant())
9796         sleep 7
9797
9798         declare -a cur_grant_bytes
9799         declare -a tot_granted
9800         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9801         tot_granted[0]=$(do_facet ost1 \
9802             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9803
9804         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9805
9806         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9807         tot_granted[1]=$(do_facet ost1 \
9808             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9809
9810         # grant change should be equal on both sides
9811         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9812                 tot_granted[0] - tot_granted[1])) ||
9813                 error "grant change mismatch, "                                \
9814                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9815                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9816 }
9817 run_test 64h "grant shrink on read"
9818
9819 test_64i() {
9820         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9821                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9822
9823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9824         remote_ost_nodsh && skip "remote OSTs with nodsh"
9825
9826         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9827         stack_trap "rm -f $DIR/$tfile"
9828
9829         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9830
9831         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9832         local instance=$($LFS getname -i $DIR)
9833
9834         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9835         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9836
9837         # shrink grants and simulate rpc loss
9838         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9839         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9840         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9841
9842         fail ost1
9843
9844         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9845
9846         local testid=$(echo $TESTNAME | tr '_' ' ')
9847
9848         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9849                 grep "GRANT, real grant" &&
9850                 error "client has more grants then it owns" || true
9851 }
9852 run_test 64i "shrink on reconnect"
9853
9854 # bug 1414 - set/get directories' stripe info
9855 test_65a() {
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857
9858         test_mkdir $DIR/$tdir
9859         touch $DIR/$tdir/f1
9860         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9861 }
9862 run_test 65a "directory with no stripe info"
9863
9864 test_65b() {
9865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9866
9867         test_mkdir $DIR/$tdir
9868         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9869
9870         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9871                                                 error "setstripe"
9872         touch $DIR/$tdir/f2
9873         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9874 }
9875 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9876
9877 test_65c() {
9878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9879         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9880
9881         test_mkdir $DIR/$tdir
9882         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9883
9884         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9885                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9886         touch $DIR/$tdir/f3
9887         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9888 }
9889 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9890
9891 test_65d() {
9892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9893
9894         test_mkdir $DIR/$tdir
9895         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9896         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9897
9898         if [[ $STRIPECOUNT -le 0 ]]; then
9899                 sc=1
9900         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9901                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9902                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9903         else
9904                 sc=$(($STRIPECOUNT - 1))
9905         fi
9906         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9907         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9908         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9909                 error "lverify failed"
9910 }
9911 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9912
9913 test_65e() {
9914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9915
9916         # LU-16904 delete layout when root is set as PFL layout
9917         save_layout_restore_at_exit $MOUNT
9918         $LFS setstripe -d $MOUNT || error "setstripe failed"
9919
9920         test_mkdir $DIR/$tdir
9921
9922         $LFS setstripe $DIR/$tdir || error "setstripe"
9923         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9924                                         error "no stripe info failed"
9925         touch $DIR/$tdir/f6
9926         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9927 }
9928 run_test 65e "directory setstripe defaults"
9929
9930 test_65f() {
9931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9932
9933         test_mkdir $DIR/${tdir}f
9934         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9935                 error "setstripe succeeded" || true
9936 }
9937 run_test 65f "dir setstripe permission (should return error) ==="
9938
9939 test_65g() {
9940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9941
9942         # LU-16904 delete layout when root is set as PFL layout
9943         save_layout_restore_at_exit $MOUNT
9944         $LFS setstripe -d $MOUNT || error "setstripe failed"
9945
9946         test_mkdir $DIR/$tdir
9947         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9948
9949         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9950                 error "setstripe -S failed"
9951         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9952         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9953                 error "delete default stripe failed"
9954 }
9955 run_test 65g "directory setstripe -d"
9956
9957 test_65h() {
9958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9959
9960         test_mkdir $DIR/$tdir
9961         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9962
9963         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9964                 error "setstripe -S failed"
9965         test_mkdir $DIR/$tdir/dd1
9966         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9967                 error "stripe info inherit failed"
9968 }
9969 run_test 65h "directory stripe info inherit ===================="
9970
9971 test_65i() {
9972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9973
9974         save_layout_restore_at_exit $MOUNT
9975
9976         # bug6367: set non-default striping on root directory
9977         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9978
9979         # bug12836: getstripe on -1 default directory striping
9980         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9981
9982         # bug12836: getstripe -v on -1 default directory striping
9983         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9984
9985         # bug12836: new find on -1 default directory striping
9986         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9987 }
9988 run_test 65i "various tests to set root directory striping"
9989
9990 test_65j() { # bug6367
9991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9992
9993         sync; sleep 1
9994
9995         # if we aren't already remounting for each test, do so for this test
9996         if [ "$I_MOUNTED" = "yes" ]; then
9997                 cleanup || error "failed to unmount"
9998                 setup
9999         fi
10000
10001         save_layout_restore_at_exit $MOUNT
10002
10003         $LFS setstripe -d $MOUNT || error "setstripe failed"
10004 }
10005 run_test 65j "set default striping on root directory (bug 6367)="
10006
10007 cleanup_65k() {
10008         rm -rf $DIR/$tdir
10009         wait_delete_completed
10010         do_facet $SINGLEMDS "lctl set_param -n \
10011                 osp.$ost*MDT0000.max_create_count=$max_count"
10012         do_facet $SINGLEMDS "lctl set_param -n \
10013                 osp.$ost*MDT0000.create_count=$count"
10014         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10015         echo $INACTIVE_OSC "is Activate"
10016
10017         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10018 }
10019
10020 test_65k() { # bug11679
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10023         remote_mds_nodsh && skip "remote MDS with nodsh"
10024
10025         local disable_precreate=true
10026         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10027                 disable_precreate=false
10028
10029         echo "Check OST status: "
10030         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10031                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10032
10033         for OSC in $MDS_OSCS; do
10034                 echo $OSC "is active"
10035                 do_facet $SINGLEMDS lctl --device %$OSC activate
10036         done
10037
10038         for INACTIVE_OSC in $MDS_OSCS; do
10039                 local ost=$(osc_to_ost $INACTIVE_OSC)
10040                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10041                                lov.*md*.target_obd |
10042                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10043
10044                 mkdir -p $DIR/$tdir
10045                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10046                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10047
10048                 echo "Deactivate: " $INACTIVE_OSC
10049                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10050
10051                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10052                               osp.$ost*MDT0000.create_count")
10053                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10054                                   osp.$ost*MDT0000.max_create_count")
10055                 $disable_precreate &&
10056                         do_facet $SINGLEMDS "lctl set_param -n \
10057                                 osp.$ost*MDT0000.max_create_count=0"
10058
10059                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10060                         [ -f $DIR/$tdir/$idx ] && continue
10061                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10062                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10063                                 { cleanup_65k;
10064                                   error "setstripe $idx should succeed"; }
10065                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10066                 done
10067                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10068                 rmdir $DIR/$tdir
10069
10070                 do_facet $SINGLEMDS "lctl set_param -n \
10071                         osp.$ost*MDT0000.max_create_count=$max_count"
10072                 do_facet $SINGLEMDS "lctl set_param -n \
10073                         osp.$ost*MDT0000.create_count=$count"
10074                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10075                 echo $INACTIVE_OSC "is Activate"
10076
10077                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10078         done
10079 }
10080 run_test 65k "validate manual striping works properly with deactivated OSCs"
10081
10082 test_65l() { # bug 12836
10083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10084
10085         test_mkdir -p $DIR/$tdir/test_dir
10086         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10087         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10088 }
10089 run_test 65l "lfs find on -1 stripe dir ========================"
10090
10091 test_65m() {
10092         local layout=$(save_layout $MOUNT)
10093         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10094                 restore_layout $MOUNT $layout
10095                 error "setstripe should fail by non-root users"
10096         }
10097         true
10098 }
10099 run_test 65m "normal user can't set filesystem default stripe"
10100
10101 test_65n() {
10102         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10103         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10104                 skip "Need MDS version at least 2.12.50"
10105         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10106
10107         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10108         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10109         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10110
10111         save_layout_restore_at_exit $MOUNT
10112
10113         # new subdirectory under root directory should not inherit
10114         # the default layout from root
10115         # LU-16904 check if the root is set as PFL layout
10116         local numcomp=$($LFS getstripe --component-count $MOUNT)
10117
10118         if [[ $numcomp -eq 0 ]]; then
10119                 local dir1=$MOUNT/$tdir-1
10120                 mkdir $dir1 || error "mkdir $dir1 failed"
10121                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10122                         error "$dir1 shouldn't have LOV EA"
10123         fi
10124
10125         # delete the default layout on root directory
10126         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10127
10128         local dir2=$MOUNT/$tdir-2
10129         mkdir $dir2 || error "mkdir $dir2 failed"
10130         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10131                 error "$dir2 shouldn't have LOV EA"
10132
10133         # set a new striping pattern on root directory
10134         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10135         local new_def_stripe_size=$((def_stripe_size * 2))
10136         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10137                 error "set stripe size on $MOUNT failed"
10138
10139         # new file created in $dir2 should inherit the new stripe size from
10140         # the filesystem default
10141         local file2=$dir2/$tfile-2
10142         touch $file2 || error "touch $file2 failed"
10143
10144         local file2_stripe_size=$($LFS getstripe -S $file2)
10145         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10146         {
10147                 echo "file2_stripe_size: '$file2_stripe_size'"
10148                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10149                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10150         }
10151
10152         local dir3=$MOUNT/$tdir-3
10153         mkdir $dir3 || error "mkdir $dir3 failed"
10154         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10155         # the root layout, which is the actual default layout that will be used
10156         # when new files are created in $dir3.
10157         local dir3_layout=$(get_layout_param $dir3)
10158         local root_dir_layout=$(get_layout_param $MOUNT)
10159         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10160         {
10161                 echo "dir3_layout: '$dir3_layout'"
10162                 echo "root_dir_layout: '$root_dir_layout'"
10163                 error "$dir3 should show the default layout from $MOUNT"
10164         }
10165
10166         # set OST pool on root directory
10167         local pool=$TESTNAME
10168         pool_add $pool || error "add $pool failed"
10169         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10170                 error "add targets to $pool failed"
10171
10172         $LFS setstripe -p $pool $MOUNT ||
10173                 error "set OST pool on $MOUNT failed"
10174
10175         # new file created in $dir3 should inherit the pool from
10176         # the filesystem default
10177         local file3=$dir3/$tfile-3
10178         touch $file3 || error "touch $file3 failed"
10179
10180         local file3_pool=$($LFS getstripe -p $file3)
10181         [[ "$file3_pool" = "$pool" ]] ||
10182                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10183
10184         local dir4=$MOUNT/$tdir-4
10185         mkdir $dir4 || error "mkdir $dir4 failed"
10186         local dir4_layout=$(get_layout_param $dir4)
10187         root_dir_layout=$(get_layout_param $MOUNT)
10188         echo "$LFS getstripe -d $dir4"
10189         $LFS getstripe -d $dir4
10190         echo "$LFS getstripe -d $MOUNT"
10191         $LFS getstripe -d $MOUNT
10192         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10193         {
10194                 echo "dir4_layout: '$dir4_layout'"
10195                 echo "root_dir_layout: '$root_dir_layout'"
10196                 error "$dir4 should show the default layout from $MOUNT"
10197         }
10198
10199         # new file created in $dir4 should inherit the pool from
10200         # the filesystem default
10201         local file4=$dir4/$tfile-4
10202         touch $file4 || error "touch $file4 failed"
10203
10204         local file4_pool=$($LFS getstripe -p $file4)
10205         [[ "$file4_pool" = "$pool" ]] ||
10206                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10207
10208         # new subdirectory under non-root directory should inherit
10209         # the default layout from its parent directory
10210         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10211                 error "set directory layout on $dir4 failed"
10212
10213         local dir5=$dir4/$tdir-5
10214         mkdir $dir5 || error "mkdir $dir5 failed"
10215
10216         dir4_layout=$(get_layout_param $dir4)
10217         local dir5_layout=$(get_layout_param $dir5)
10218         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10219         {
10220                 echo "dir4_layout: '$dir4_layout'"
10221                 echo "dir5_layout: '$dir5_layout'"
10222                 error "$dir5 should inherit the default layout from $dir4"
10223         }
10224
10225         # though subdir under ROOT doesn't inherit default layout, but
10226         # its sub dir/file should be created with default layout.
10227         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10228         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10229                 skip "Need MDS version at least 2.12.59"
10230
10231         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10232         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10233         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10234
10235         if [ $default_lmv_hash == "none" ]; then
10236                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10237         else
10238                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10239                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10240         fi
10241
10242         $LFS setdirstripe -D -c 2 $MOUNT ||
10243                 error "setdirstripe -D -c 2 failed"
10244         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10245         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10246         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10247
10248         # $dir4 layout includes pool
10249         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10250         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10251                 error "pool lost on setstripe"
10252         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10253         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10254                 error "pool lost on compound layout setstripe"
10255 }
10256 run_test 65n "don't inherit default layout from root for new subdirectories"
10257
10258 test_65o() {
10259         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10260                 skip "need MDS version at least 2.14.57"
10261
10262         # set OST pool on root directory
10263         local pool=$TESTNAME
10264
10265         pool_add $pool || error "add $pool failed"
10266         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10267                 error "add targets to $pool failed"
10268
10269         local dir1=$MOUNT/$tdir
10270
10271         mkdir $dir1 || error "mkdir $dir1 failed"
10272
10273         # set a new striping pattern on root directory
10274         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10275
10276         $LFS setstripe -p $pool $dir1 ||
10277                 error "set directory layout on $dir1 failed"
10278
10279         # $dir1 layout includes pool
10280         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10281         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10282                 error "pool lost on setstripe"
10283         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10284         $LFS getstripe $dir1
10285         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10286                 error "pool lost on compound layout setstripe"
10287
10288         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10289                 error "setdirstripe failed on sub-dir with inherited pool"
10290         $LFS getstripe $dir1/dir2
10291         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10292                 error "pool lost on compound layout setdirstripe"
10293
10294         $LFS setstripe -E -1 -c 1 $dir1
10295         $LFS getstripe -d $dir1
10296         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10297                 error "pool lost on setstripe"
10298 }
10299 run_test 65o "pool inheritance for mdt component"
10300
10301 test_65p () { # LU-16152
10302         local src_dir=$DIR/$tdir/src_dir
10303         local dst_dir=$DIR/$tdir/dst_dir
10304         local yaml_file=$DIR/$tdir/layout.yaml
10305         local border
10306
10307         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10308                 skip "Need at least version 2.15.51"
10309
10310         test_mkdir -p $src_dir
10311         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10312                 error "failed to setstripe"
10313         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10314                 error "failed to getstripe"
10315
10316         test_mkdir -p $dst_dir
10317         $LFS setstripe --yaml $yaml_file $dst_dir ||
10318                 error "failed to setstripe with yaml file"
10319         border=$($LFS getstripe -d $dst_dir |
10320                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10321                 error "failed to getstripe"
10322
10323         # 2048M is 0x80000000, or 2147483648
10324         (( $border == 2147483648 )) ||
10325                 error "failed to handle huge number in yaml layout"
10326 }
10327 run_test 65p "setstripe with yaml file and huge number"
10328
10329 # bug 2543 - update blocks count on client
10330 test_66() {
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332
10333         local COUNT=${COUNT:-8}
10334         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10335         sync; sync_all_data; sync; sync_all_data
10336         cancel_lru_locks osc
10337         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10338         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10339 }
10340 run_test 66 "update inode blocks count on client ==============="
10341
10342 meminfo() {
10343         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10344 }
10345
10346 swap_used() {
10347         swapon -s | awk '($1 == "'$1'") { print $4 }'
10348 }
10349
10350 # bug5265, obdfilter oa2dentry return -ENOENT
10351 # #define OBD_FAIL_SRV_ENOENT 0x217
10352 test_69() {
10353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10354         remote_ost_nodsh && skip "remote OST with nodsh"
10355
10356         f="$DIR/$tfile"
10357         $LFS setstripe -c 1 -i 0 $f
10358         stack_trap "rm -f $f ${f}.2"
10359
10360         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10361
10362         do_facet ost1 lctl set_param fail_loc=0x217
10363         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10364         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10365
10366         do_facet ost1 lctl set_param fail_loc=0
10367         $DIRECTIO write $f 0 2 || error "write error"
10368
10369         cancel_lru_locks osc
10370         $DIRECTIO read $f 0 1 || error "read error"
10371
10372         do_facet ost1 lctl set_param fail_loc=0x217
10373         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10374
10375         do_facet ost1 lctl set_param fail_loc=0
10376 }
10377 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10378
10379 test_71() {
10380         test_mkdir $DIR/$tdir
10381         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10382         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10383 }
10384 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10385
10386 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10388         [ "$RUNAS_ID" = "$UID" ] &&
10389                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10390         # Check that testing environment is properly set up. Skip if not
10391         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10392                 skip_env "User $RUNAS_ID does not exist - skipping"
10393
10394         touch $DIR/$tfile
10395         chmod 777 $DIR/$tfile
10396         chmod ug+s $DIR/$tfile
10397         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10398                 error "$RUNAS dd $DIR/$tfile failed"
10399         # See if we are still setuid/sgid
10400         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10401                 error "S/gid is not dropped on write"
10402         # Now test that MDS is updated too
10403         cancel_lru_locks mdc
10404         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10405                 error "S/gid is not dropped on MDS"
10406         rm -f $DIR/$tfile
10407 }
10408 run_test 72a "Test that remove suid works properly (bug5695) ===="
10409
10410 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10411         local perm
10412
10413         [ "$RUNAS_ID" = "$UID" ] &&
10414                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10415         [ "$RUNAS_ID" -eq 0 ] &&
10416                 skip_env "RUNAS_ID = 0 -- skipping"
10417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10418         # Check that testing environment is properly set up. Skip if not
10419         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10420                 skip_env "User $RUNAS_ID does not exist - skipping"
10421
10422         touch $DIR/${tfile}-f{g,u}
10423         test_mkdir $DIR/${tfile}-dg
10424         test_mkdir $DIR/${tfile}-du
10425         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10426         chmod g+s $DIR/${tfile}-{f,d}g
10427         chmod u+s $DIR/${tfile}-{f,d}u
10428         for perm in 777 2777 4777; do
10429                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10430                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10431                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10432                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10433         done
10434         true
10435 }
10436 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10437
10438 # bug 3462 - multiple simultaneous MDC requests
10439 test_73() {
10440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10441
10442         test_mkdir $DIR/d73-1
10443         test_mkdir $DIR/d73-2
10444         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10445         pid1=$!
10446
10447         lctl set_param fail_loc=0x80000129
10448         $MULTIOP $DIR/d73-1/f73-2 Oc &
10449         sleep 1
10450         lctl set_param fail_loc=0
10451
10452         $MULTIOP $DIR/d73-2/f73-3 Oc &
10453         pid3=$!
10454
10455         kill -USR1 $pid1
10456         wait $pid1 || return 1
10457
10458         sleep 25
10459
10460         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10461         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10462         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10463
10464         rm -rf $DIR/d73-*
10465 }
10466 run_test 73 "multiple MDC requests (should not deadlock)"
10467
10468 test_74a() { # bug 6149, 6184
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470
10471         touch $DIR/f74a
10472         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10473         #
10474         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10475         # will spin in a tight reconnection loop
10476         $LCTL set_param fail_loc=0x8000030e
10477         # get any lock that won't be difficult - lookup works.
10478         ls $DIR/f74a
10479         $LCTL set_param fail_loc=0
10480         rm -f $DIR/f74a
10481         true
10482 }
10483 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10484
10485 test_74b() { # bug 13310
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487
10488         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10489         #
10490         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10491         # will spin in a tight reconnection loop
10492         $LCTL set_param fail_loc=0x8000030e
10493         # get a "difficult" lock
10494         touch $DIR/f74b
10495         $LCTL set_param fail_loc=0
10496         rm -f $DIR/f74b
10497         true
10498 }
10499 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10500
10501 test_74c() {
10502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10503
10504         #define OBD_FAIL_LDLM_NEW_LOCK
10505         $LCTL set_param fail_loc=0x319
10506         touch $DIR/$tfile && error "touch successful"
10507         $LCTL set_param fail_loc=0
10508         true
10509 }
10510 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10511
10512 slab_lic=/sys/kernel/slab/lustre_inode_cache
10513 num_objects() {
10514         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10515         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10516                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10517 }
10518
10519 test_76a() { # Now for b=20433, added originally in b=1443
10520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10521
10522         cancel_lru_locks osc
10523         # there may be some slab objects cached per core
10524         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10525         local before=$(num_objects)
10526         local count=$((512 * cpus))
10527         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10528         local margin=$((count / 10))
10529         if [[ -f $slab_lic/aliases ]]; then
10530                 local aliases=$(cat $slab_lic/aliases)
10531                 (( aliases > 0 )) && margin=$((margin * aliases))
10532         fi
10533
10534         echo "before slab objects: $before"
10535         for i in $(seq $count); do
10536                 touch $DIR/$tfile
10537                 rm -f $DIR/$tfile
10538         done
10539         cancel_lru_locks osc
10540         local after=$(num_objects)
10541         echo "created: $count, after slab objects: $after"
10542         # shared slab counts are not very accurate, allow significant margin
10543         # the main goal is that the cache growth is not permanently > $count
10544         while (( after > before + margin )); do
10545                 sleep 1
10546                 after=$(num_objects)
10547                 wait=$((wait + 1))
10548                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10549                 if (( wait > 60 )); then
10550                         error "inode slab grew from $before+$margin to $after"
10551                 fi
10552         done
10553 }
10554 run_test 76a "confirm clients recycle inodes properly ===="
10555
10556 test_76b() {
10557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10558         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10559
10560         local count=512
10561         local before=$(num_objects)
10562
10563         for i in $(seq $count); do
10564                 mkdir $DIR/$tdir
10565                 rmdir $DIR/$tdir
10566         done
10567
10568         local after=$(num_objects)
10569         local wait=0
10570
10571         while (( after > before )); do
10572                 sleep 1
10573                 after=$(num_objects)
10574                 wait=$((wait + 1))
10575                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10576                 if (( wait > 60 )); then
10577                         error "inode slab grew from $before to $after"
10578                 fi
10579         done
10580
10581         echo "slab objects before: $before, after: $after"
10582 }
10583 run_test 76b "confirm clients recycle directory inodes properly ===="
10584
10585 export ORIG_CSUM=""
10586 set_checksums()
10587 {
10588         # Note: in sptlrpc modes which enable its own bulk checksum, the
10589         # original crc32_le bulk checksum will be automatically disabled,
10590         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10591         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10592         # In this case set_checksums() will not be no-op, because sptlrpc
10593         # bulk checksum will be enabled all through the test.
10594
10595         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10596         lctl set_param -n osc.*.checksums $1
10597         return 0
10598 }
10599
10600 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10601                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10602 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10603                              tr -d [] | head -n1)}
10604 set_checksum_type()
10605 {
10606         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10607         rc=$?
10608         log "set checksum type to $1, rc = $rc"
10609         return $rc
10610 }
10611
10612 get_osc_checksum_type()
10613 {
10614         # arugment 1: OST name, like OST0000
10615         ost=$1
10616         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10617                         sed 's/.*\[\(.*\)\].*/\1/g')
10618         rc=$?
10619         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10620         echo $checksum_type
10621 }
10622
10623 F77_TMP=$TMP/f77-temp
10624 F77SZ=8
10625 setup_f77() {
10626         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10627                 error "error writing to $F77_TMP"
10628 }
10629
10630 test_77a() { # bug 10889
10631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10632         $GSS && skip_env "could not run with gss"
10633
10634         [ ! -f $F77_TMP ] && setup_f77
10635         set_checksums 1
10636         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10637         set_checksums 0
10638         rm -f $DIR/$tfile
10639 }
10640 run_test 77a "normal checksum read/write operation"
10641
10642 test_77b() { # bug 10889
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644         $GSS && skip_env "could not run with gss"
10645
10646         [ ! -f $F77_TMP ] && setup_f77
10647         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10648         $LCTL set_param fail_loc=0x80000409
10649         set_checksums 1
10650
10651         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10652                 error "dd error: $?"
10653         $LCTL set_param fail_loc=0
10654
10655         for algo in $CKSUM_TYPES; do
10656                 cancel_lru_locks osc
10657                 set_checksum_type $algo
10658                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10659                 $LCTL set_param fail_loc=0x80000408
10660                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10661                 $LCTL set_param fail_loc=0
10662         done
10663         set_checksums 0
10664         set_checksum_type $ORIG_CSUM_TYPE
10665         rm -f $DIR/$tfile
10666 }
10667 run_test 77b "checksum error on client write, read"
10668
10669 cleanup_77c() {
10670         trap 0
10671         set_checksums 0
10672         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10673         $check_ost &&
10674                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10675         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10676         $check_ost && [ -n "$ost_file_prefix" ] &&
10677                 do_facet ost1 rm -f ${ost_file_prefix}\*
10678 }
10679
10680 test_77c() {
10681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10682         $GSS && skip_env "could not run with gss"
10683         remote_ost_nodsh && skip "remote OST with nodsh"
10684
10685         local bad1
10686         local osc_file_prefix
10687         local osc_file
10688         local check_ost=false
10689         local ost_file_prefix
10690         local ost_file
10691         local orig_cksum
10692         local dump_cksum
10693         local fid
10694
10695         # ensure corruption will occur on first OSS/OST
10696         $LFS setstripe -i 0 $DIR/$tfile
10697
10698         [ ! -f $F77_TMP ] && setup_f77
10699         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10700                 error "dd write error: $?"
10701         fid=$($LFS path2fid $DIR/$tfile)
10702
10703         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10704         then
10705                 check_ost=true
10706                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10707                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10708         else
10709                 echo "OSS do not support bulk pages dump upon error"
10710         fi
10711
10712         osc_file_prefix=$($LCTL get_param -n debug_path)
10713         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10714
10715         trap cleanup_77c EXIT
10716
10717         set_checksums 1
10718         # enable bulk pages dump upon error on Client
10719         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10720         # enable bulk pages dump upon error on OSS
10721         $check_ost &&
10722                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10723
10724         # flush Client cache to allow next read to reach OSS
10725         cancel_lru_locks osc
10726
10727         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10728         $LCTL set_param fail_loc=0x80000408
10729         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10730         $LCTL set_param fail_loc=0
10731
10732         rm -f $DIR/$tfile
10733
10734         # check cksum dump on Client
10735         osc_file=$(ls ${osc_file_prefix}*)
10736         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10737         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10738         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10739         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10740         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10741                      cksum)
10742         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10743         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10744                 error "dump content does not match on Client"
10745
10746         $check_ost || skip "No need to check cksum dump on OSS"
10747
10748         # check cksum dump on OSS
10749         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10750         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10751         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10752         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10753         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10754                 error "dump content does not match on OSS"
10755
10756         cleanup_77c
10757 }
10758 run_test 77c "checksum error on client read with debug"
10759
10760 test_77d() { # bug 10889
10761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10762         $GSS && skip_env "could not run with gss"
10763
10764         stack_trap "rm -f $DIR/$tfile"
10765         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10766         $LCTL set_param fail_loc=0x80000409
10767         set_checksums 1
10768         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10769                 error "direct write: rc=$?"
10770         $LCTL set_param fail_loc=0
10771         set_checksums 0
10772
10773         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10774         $LCTL set_param fail_loc=0x80000408
10775         set_checksums 1
10776         cancel_lru_locks osc
10777         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10778                 error "direct read: rc=$?"
10779         $LCTL set_param fail_loc=0
10780         set_checksums 0
10781 }
10782 run_test 77d "checksum error on OST direct write, read"
10783
10784 test_77f() { # bug 10889
10785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10786         $GSS && skip_env "could not run with gss"
10787
10788         set_checksums 1
10789         stack_trap "rm -f $DIR/$tfile"
10790         for algo in $CKSUM_TYPES; do
10791                 cancel_lru_locks osc
10792                 set_checksum_type $algo
10793                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10794                 $LCTL set_param fail_loc=0x409
10795                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10796                         error "direct write succeeded"
10797                 $LCTL set_param fail_loc=0
10798         done
10799         set_checksum_type $ORIG_CSUM_TYPE
10800         set_checksums 0
10801 }
10802 run_test 77f "repeat checksum error on write (expect error)"
10803
10804 test_77g() { # bug 10889
10805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10806         $GSS && skip_env "could not run with gss"
10807         remote_ost_nodsh && skip "remote OST with nodsh"
10808
10809         [ ! -f $F77_TMP ] && setup_f77
10810
10811         local file=$DIR/$tfile
10812         stack_trap "rm -f $file" EXIT
10813
10814         $LFS setstripe -c 1 -i 0 $file
10815         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10816         do_facet ost1 lctl set_param fail_loc=0x8000021a
10817         set_checksums 1
10818         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10819                 error "write error: rc=$?"
10820         do_facet ost1 lctl set_param fail_loc=0
10821         set_checksums 0
10822
10823         cancel_lru_locks osc
10824         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10825         do_facet ost1 lctl set_param fail_loc=0x8000021b
10826         set_checksums 1
10827         cmp $F77_TMP $file || error "file compare failed"
10828         do_facet ost1 lctl set_param fail_loc=0
10829         set_checksums 0
10830 }
10831 run_test 77g "checksum error on OST write, read"
10832
10833 test_77k() { # LU-10906
10834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10835         $GSS && skip_env "could not run with gss"
10836
10837         local cksum_param="osc.$FSNAME*.checksums"
10838         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10839         local checksum
10840         local i
10841
10842         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10843         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10844         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10845
10846         for i in 0 1; do
10847                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10848                         error "failed to set checksum=$i on MGS"
10849                 wait_update $HOSTNAME "$get_checksum" $i
10850                 #remount
10851                 echo "remount client, checksum should be $i"
10852                 remount_client $MOUNT || error "failed to remount client"
10853                 checksum=$(eval $get_checksum)
10854                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10855         done
10856         # remove persistent param to avoid races with checksum mountopt below
10857         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10858                 error "failed to delete checksum on MGS"
10859
10860         for opt in "checksum" "nochecksum"; do
10861                 #remount with mount option
10862                 echo "remount client with option $opt, checksum should be $i"
10863                 umount_client $MOUNT || error "failed to umount client"
10864                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10865                         error "failed to mount client with option '$opt'"
10866                 checksum=$(eval $get_checksum)
10867                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10868                 i=$((i - 1))
10869         done
10870
10871         remount_client $MOUNT || error "failed to remount client"
10872 }
10873 run_test 77k "enable/disable checksum correctly"
10874
10875 test_77l() {
10876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10877         $GSS && skip_env "could not run with gss"
10878
10879         set_checksums 1
10880         stack_trap "set_checksums $ORIG_CSUM" EXIT
10881         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10882
10883         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10884
10885         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10886         for algo in $CKSUM_TYPES; do
10887                 set_checksum_type $algo || error "fail to set checksum type $algo"
10888                 osc_algo=$(get_osc_checksum_type OST0000)
10889                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10890
10891                 # no locks, no reqs to let the connection idle
10892                 cancel_lru_locks osc
10893                 lru_resize_disable osc
10894                 wait_osc_import_state client ost1 IDLE
10895
10896                 # ensure ost1 is connected
10897                 stat $DIR/$tfile >/dev/null || error "can't stat"
10898                 wait_osc_import_state client ost1 FULL
10899
10900                 osc_algo=$(get_osc_checksum_type OST0000)
10901                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10902         done
10903         return 0
10904 }
10905 run_test 77l "preferred checksum type is remembered after reconnected"
10906
10907 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10908 rm -f $F77_TMP
10909 unset F77_TMP
10910
10911 test_77m() {
10912         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10913                 skip "Need at least version 2.14.52"
10914         local param=checksum_speed
10915
10916         $LCTL get_param $param || error "reading $param failed"
10917
10918         csum_speeds=$($LCTL get_param -n $param)
10919
10920         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10921                 error "known checksum types are missing"
10922 }
10923 run_test 77m "Verify checksum_speed is correctly read"
10924
10925 check_filefrag_77n() {
10926         local nr_ext=0
10927         local starts=()
10928         local ends=()
10929
10930         while read extidx a b start end rest; do
10931                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10932                         nr_ext=$(( $nr_ext + 1 ))
10933                         starts+=( ${start%..} )
10934                         ends+=( ${end%:} )
10935                 fi
10936         done < <( filefrag -sv $1 )
10937
10938         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10939         return 1
10940 }
10941
10942 test_77n() {
10943         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10944
10945         touch $DIR/$tfile
10946         $TRUNCATE $DIR/$tfile 0
10947         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10948         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10949         check_filefrag_77n $DIR/$tfile ||
10950                 skip "$tfile blocks not contiguous around hole"
10951
10952         set_checksums 1
10953         stack_trap "set_checksums $ORIG_CSUM" EXIT
10954         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10955         stack_trap "rm -f $DIR/$tfile"
10956
10957         for algo in $CKSUM_TYPES; do
10958                 if [[ "$algo" =~ ^t10 ]]; then
10959                         set_checksum_type $algo ||
10960                                 error "fail to set checksum type $algo"
10961                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10962                                 error "fail to read $tfile with $algo"
10963                 fi
10964         done
10965         rm -f $DIR/$tfile
10966         return 0
10967 }
10968 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10969
10970 test_77o() {
10971         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10972                 skip "Need MDS version at least 2.14.55"
10973         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10974                 skip "Need OST version at least 2.14.55"
10975         local ofd=obdfilter
10976         local mdt=mdt
10977
10978         # print OST checksum_type
10979         echo "$ofd.$FSNAME-*.checksum_type:"
10980         do_nodes $(comma_list $(osts_nodes)) \
10981                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10982
10983         # print MDT checksum_type
10984         echo "$mdt.$FSNAME-*.checksum_type:"
10985         do_nodes $(comma_list $(mdts_nodes)) \
10986                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10987
10988         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10989                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10990
10991         (( $o_count == $OSTCOUNT )) ||
10992                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10993
10994         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10995                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10996
10997         (( $m_count == $MDSCOUNT )) ||
10998                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10999 }
11000 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11001
11002 cleanup_test_78() {
11003         trap 0
11004         rm -f $DIR/$tfile
11005 }
11006
11007 test_78() { # bug 10901
11008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11009         remote_ost || skip_env "local OST"
11010
11011         NSEQ=5
11012         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11013         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11014         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11015         echo "MemTotal: $MEMTOTAL"
11016
11017         # reserve 256MB of memory for the kernel and other running processes,
11018         # and then take 1/2 of the remaining memory for the read/write buffers.
11019         if [ $MEMTOTAL -gt 512 ] ;then
11020                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11021         else
11022                 # for those poor memory-starved high-end clusters...
11023                 MEMTOTAL=$((MEMTOTAL / 2))
11024         fi
11025         echo "Mem to use for directio: $MEMTOTAL"
11026
11027         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11028         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11029         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11030         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11031                 head -n1)
11032         echo "Smallest OST: $SMALLESTOST"
11033         [[ $SMALLESTOST -lt 10240 ]] &&
11034                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11035
11036         trap cleanup_test_78 EXIT
11037
11038         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11039                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11040
11041         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11042         echo "File size: $F78SIZE"
11043         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11044         for i in $(seq 1 $NSEQ); do
11045                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11046                 echo directIO rdwr round $i of $NSEQ
11047                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11048         done
11049
11050         cleanup_test_78
11051 }
11052 run_test 78 "handle large O_DIRECT writes correctly ============"
11053
11054 test_79() { # bug 12743
11055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11056
11057         wait_delete_completed
11058
11059         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11060         BKFREE=$(calc_osc_kbytes kbytesfree)
11061         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11062
11063         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11064         DFTOTAL=`echo $STRING | cut -d, -f1`
11065         DFUSED=`echo $STRING  | cut -d, -f2`
11066         DFAVAIL=`echo $STRING | cut -d, -f3`
11067         DFFREE=$(($DFTOTAL - $DFUSED))
11068
11069         ALLOWANCE=$((64 * $OSTCOUNT))
11070
11071         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11072            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11073                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11074         fi
11075         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11076            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11077                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11078         fi
11079         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11080            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11081                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11082         fi
11083 }
11084 run_test 79 "df report consistency check ======================="
11085
11086 test_80() { # bug 10718
11087         remote_ost_nodsh && skip "remote OST with nodsh"
11088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11089
11090         # relax strong synchronous semantics for slow backends like ZFS
11091         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11092                 local soc="obdfilter.*.sync_lock_cancel"
11093                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11094
11095                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11096                 if [ -z "$save" ]; then
11097                         soc="obdfilter.*.sync_on_lock_cancel"
11098                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11099                 fi
11100
11101                 if [ "$save" != "never" ]; then
11102                         local hosts=$(comma_list $(osts_nodes))
11103
11104                         do_nodes $hosts $LCTL set_param $soc=never
11105                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11106                 fi
11107         fi
11108
11109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11110         sync; sleep 1; sync
11111         local before=$(date +%s)
11112         cancel_lru_locks osc
11113         local after=$(date +%s)
11114         local diff=$((after - before))
11115         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11116
11117         rm -f $DIR/$tfile
11118 }
11119 run_test 80 "Page eviction is equally fast at high offsets too"
11120
11121 test_81a() { # LU-456
11122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11123         remote_ost_nodsh && skip "remote OST with nodsh"
11124
11125         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11126         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11127         do_facet ost1 lctl set_param fail_loc=0x80000228
11128
11129         # write should trigger a retry and success
11130         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11132         RC=$?
11133         if [ $RC -ne 0 ] ; then
11134                 error "write should success, but failed for $RC"
11135         fi
11136 }
11137 run_test 81a "OST should retry write when get -ENOSPC ==============="
11138
11139 test_81b() { # LU-456
11140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11141         remote_ost_nodsh && skip "remote OST with nodsh"
11142
11143         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11144         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11145         do_facet ost1 lctl set_param fail_loc=0x228
11146
11147         # write should retry several times and return -ENOSPC finally
11148         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11150         RC=$?
11151         ENOSPC=28
11152         if [ $RC -ne $ENOSPC ] ; then
11153                 error "dd should fail for -ENOSPC, but succeed."
11154         fi
11155 }
11156 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11157
11158 test_99() {
11159         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11160
11161         test_mkdir $DIR/$tdir.cvsroot
11162         chown $RUNAS_ID $DIR/$tdir.cvsroot
11163
11164         cd $TMP
11165         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11166
11167         cd /etc/init.d
11168         # some versions of cvs import exit(1) when asked to import links or
11169         # files they can't read.  ignore those files.
11170         local toignore=$(find . -type l -printf '-I %f\n' -o \
11171                          ! -perm /4 -printf '-I %f\n')
11172         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11173                 $tdir.reposname vtag rtag
11174
11175         cd $DIR
11176         test_mkdir $DIR/$tdir.reposname
11177         chown $RUNAS_ID $DIR/$tdir.reposname
11178         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11179
11180         cd $DIR/$tdir.reposname
11181         $RUNAS touch foo99
11182         $RUNAS cvs add -m 'addmsg' foo99
11183         $RUNAS cvs update
11184         $RUNAS cvs commit -m 'nomsg' foo99
11185         rm -fr $DIR/$tdir.cvsroot
11186 }
11187 run_test 99 "cvs strange file/directory operations"
11188
11189 test_100() {
11190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11191         [[ "$NETTYPE" =~ tcp ]] ||
11192                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11193         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11194         remote_ost_nodsh && skip "remote OST with nodsh"
11195         remote_mds_nodsh && skip "remote MDS with nodsh"
11196         remote_servers || skip "useless for local single node setup"
11197
11198         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11199                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11200
11201                 rc=0
11202                 if (( ${LOCAL/*:/} >= 1024 )); then
11203                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11204                         ss -tna
11205                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11206                 fi
11207         done
11208         (( $rc == 0 )) || error "privileged port not found" )
11209 }
11210 run_test 100 "check local port using privileged port"
11211
11212 function get_named_value()
11213 {
11214     local tag=$1
11215
11216     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11217 }
11218
11219 test_101a() {
11220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11221
11222         local s
11223         local discard
11224         local nreads=10000
11225         local cache_limit=32
11226
11227         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11228         $LCTL set_param -n llite.*.read_ahead_stats=0
11229         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11230                               awk '/^max_cached_mb/ { print $2 }')
11231         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11232         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11233
11234         #
11235         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11236         #
11237         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11238         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11239
11240         discard=0
11241         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11242                    get_named_value 'read.but.discarded'); do
11243                         discard=$(($discard + $s))
11244         done
11245
11246         $LCTL get_param osc.*-osc*.rpc_stats
11247         $LCTL get_param llite.*.read_ahead_stats
11248
11249         # Discard is generally zero, but sometimes a few random reads line up
11250         # and trigger larger readahead, which is wasted & leads to discards.
11251         if [[ $(($discard)) -gt $nreads ]]; then
11252                 error "too many ($discard) discarded pages"
11253         fi
11254         rm -f $DIR/$tfile || true
11255 }
11256 run_test 101a "check read-ahead for random reads"
11257
11258 setup_test101bc() {
11259         test_mkdir $DIR/$tdir
11260         local ssize=$1
11261         local FILE_LENGTH=$2
11262         STRIPE_OFFSET=0
11263
11264         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11265
11266         local list=$(comma_list $(osts_nodes))
11267         set_osd_param $list '' read_cache_enable 0
11268         set_osd_param $list '' writethrough_cache_enable 0
11269
11270         trap cleanup_test101bc EXIT
11271         # prepare the read-ahead file
11272         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11273
11274         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11275                                 count=$FILE_SIZE_MB 2> /dev/null
11276
11277 }
11278
11279 cleanup_test101bc() {
11280         trap 0
11281         rm -rf $DIR/$tdir
11282         rm -f $DIR/$tfile
11283
11284         local list=$(comma_list $(osts_nodes))
11285         set_osd_param $list '' read_cache_enable 1
11286         set_osd_param $list '' writethrough_cache_enable 1
11287 }
11288
11289 calc_total() {
11290         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11291 }
11292
11293 ra_check_101() {
11294         local read_size=$1
11295         local stripe_size=$2
11296         local stride_length=$((stripe_size / read_size))
11297         local stride_width=$((stride_length * OSTCOUNT))
11298         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11299                                 (stride_width - stride_length) ))
11300         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11301                   get_named_value 'read.but.discarded' | calc_total)
11302
11303         if [[ $discard -gt $discard_limit ]]; then
11304                 $LCTL get_param llite.*.read_ahead_stats
11305                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11306         else
11307                 echo "Read-ahead success for size ${read_size}"
11308         fi
11309 }
11310
11311 test_101b() {
11312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11313         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11314
11315         local STRIPE_SIZE=1048576
11316         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11317
11318         if [ $SLOW == "yes" ]; then
11319                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11320         else
11321                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11322         fi
11323
11324         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11325
11326         # prepare the read-ahead file
11327         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11328         cancel_lru_locks osc
11329         for BIDX in 2 4 8 16 32 64 128 256
11330         do
11331                 local BSIZE=$((BIDX*4096))
11332                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11333                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11334                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11335                 $LCTL set_param -n llite.*.read_ahead_stats=0
11336                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11337                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11338                 cancel_lru_locks osc
11339                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11340         done
11341         cleanup_test101bc
11342         true
11343 }
11344 run_test 101b "check stride-io mode read-ahead ================="
11345
11346 test_101c() {
11347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11348
11349         local STRIPE_SIZE=1048576
11350         local FILE_LENGTH=$((STRIPE_SIZE*100))
11351         local nreads=10000
11352         local rsize=65536
11353         local osc_rpc_stats
11354
11355         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11356
11357         cancel_lru_locks osc
11358         $LCTL set_param osc.*.rpc_stats=0
11359         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11360         $LCTL get_param osc.*.rpc_stats
11361         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11362                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11363                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11364                 local size
11365
11366                 if [ $lines -le 20 ]; then
11367                         echo "continue debug"
11368                         continue
11369                 fi
11370                 for size in 1 2 4 8; do
11371                         local rpc=$(echo "$stats" |
11372                                     awk '($1 == "'$size':") {print $2; exit; }')
11373                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11374                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11375                 done
11376                 echo "$osc_rpc_stats check passed!"
11377         done
11378         cleanup_test101bc
11379         true
11380 }
11381 run_test 101c "check stripe_size aligned read-ahead"
11382
11383 test_101d() {
11384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11385
11386         local file=$DIR/$tfile
11387         local sz_MB=${FILESIZE_101d:-80}
11388         local ra_MB=${READAHEAD_MB:-40}
11389
11390         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11391         [ $free_MB -lt $sz_MB ] &&
11392                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11393
11394         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11395         $LFS setstripe -c -1 $file || error "setstripe failed"
11396
11397         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11398         echo Cancel LRU locks on lustre client to flush the client cache
11399         cancel_lru_locks osc
11400
11401         echo Disable read-ahead
11402         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11403         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11404         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11405         $LCTL get_param -n llite.*.max_read_ahead_mb
11406
11407         echo "Reading the test file $file with read-ahead disabled"
11408         local sz_KB=$((sz_MB * 1024 / 4))
11409         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11410         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11411         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11412                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11413
11414         echo "Cancel LRU locks on lustre client to flush the client cache"
11415         cancel_lru_locks osc
11416         echo Enable read-ahead with ${ra_MB}MB
11417         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11418
11419         echo "Reading the test file $file with read-ahead enabled"
11420         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11421                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11422
11423         echo "read-ahead disabled time read $raOFF"
11424         echo "read-ahead enabled time read $raON"
11425
11426         rm -f $file
11427         wait_delete_completed
11428
11429         # use awk for this check instead of bash because it handles decimals
11430         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11431                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11432 }
11433 run_test 101d "file read with and without read-ahead enabled"
11434
11435 test_101e() {
11436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11437
11438         local file=$DIR/$tfile
11439         local size_KB=500  #KB
11440         local count=100
11441         local bsize=1024
11442
11443         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11444         local need_KB=$((count * size_KB))
11445         [[ $free_KB -le $need_KB ]] &&
11446                 skip_env "Need free space $need_KB, have $free_KB"
11447
11448         echo "Creating $count ${size_KB}K test files"
11449         for ((i = 0; i < $count; i++)); do
11450                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11451         done
11452
11453         echo "Cancel LRU locks on lustre client to flush the client cache"
11454         cancel_lru_locks $OSC
11455
11456         echo "Reset readahead stats"
11457         $LCTL set_param -n llite.*.read_ahead_stats=0
11458
11459         for ((i = 0; i < $count; i++)); do
11460                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11461         done
11462
11463         $LCTL get_param llite.*.max_cached_mb
11464         $LCTL get_param llite.*.read_ahead_stats
11465         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11466                      get_named_value 'misses' | calc_total)
11467
11468         for ((i = 0; i < $count; i++)); do
11469                 rm -rf $file.$i 2>/dev/null
11470         done
11471
11472         #10000 means 20% reads are missing in readahead
11473         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11474 }
11475 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11476
11477 test_101f() {
11478         which iozone || skip_env "no iozone installed"
11479
11480         local old_debug=$($LCTL get_param debug)
11481         old_debug=${old_debug#*=}
11482         $LCTL set_param debug="reada mmap"
11483
11484         # create a test file
11485         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11486
11487         echo Cancel LRU locks on lustre client to flush the client cache
11488         cancel_lru_locks osc
11489
11490         echo Reset readahead stats
11491         $LCTL set_param -n llite.*.read_ahead_stats=0
11492
11493         echo mmap read the file with small block size
11494         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11495                 > /dev/null 2>&1
11496
11497         echo checking missing pages
11498         $LCTL get_param llite.*.read_ahead_stats
11499         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11500                         get_named_value 'misses' | calc_total)
11501
11502         $LCTL set_param debug="$old_debug"
11503         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11504         rm -f $DIR/$tfile
11505 }
11506 run_test 101f "check mmap read performance"
11507
11508 test_101g_brw_size_test() {
11509         local mb=$1
11510         local pages=$((mb * 1048576 / PAGE_SIZE))
11511         local file=$DIR/$tfile
11512
11513         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11514                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11515         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11516                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11517                         return 2
11518         done
11519
11520         stack_trap "rm -f $file" EXIT
11521         $LCTL set_param -n osc.*.rpc_stats=0
11522
11523         # 10 RPCs should be enough for the test
11524         local count=10
11525         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11526                 { error "dd write ${mb} MB blocks failed"; return 3; }
11527         cancel_lru_locks osc
11528         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11529                 { error "dd write ${mb} MB blocks failed"; return 4; }
11530
11531         # calculate number of full-sized read and write RPCs
11532         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11533                 sed -n '/pages per rpc/,/^$/p' |
11534                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11535                 END { print reads,writes }'))
11536         # allow one extra full-sized read RPC for async readahead
11537         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11538                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11539         [[ ${rpcs[1]} == $count ]] ||
11540                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11541 }
11542
11543 test_101g() {
11544         remote_ost_nodsh && skip "remote OST with nodsh"
11545
11546         local rpcs
11547         local osts=$(get_facets OST)
11548         local list=$(comma_list $(osts_nodes))
11549         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11550         local brw_size="obdfilter.*.brw_size"
11551
11552         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11553
11554         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11555
11556         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11557                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11558                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11559            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11560                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11561                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11562
11563                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11564                         suffix="M"
11565
11566                 if [[ $orig_mb -lt 16 ]]; then
11567                         save_lustre_params $osts "$brw_size" > $p
11568                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11569                                 error "set 16MB RPC size failed"
11570
11571                         echo "remount client to enable new RPC size"
11572                         remount_client $MOUNT || error "remount_client failed"
11573                 fi
11574
11575                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11576                 # should be able to set brw_size=12, but no rpc_stats for that
11577                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11578         fi
11579
11580         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11581
11582         if [[ $orig_mb -lt 16 ]]; then
11583                 restore_lustre_params < $p
11584                 remount_client $MOUNT || error "remount_client restore failed"
11585         fi
11586
11587         rm -f $p $DIR/$tfile
11588 }
11589 run_test 101g "Big bulk(4/16 MiB) readahead"
11590
11591 test_101h() {
11592         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11593
11594         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11595                 error "dd 70M file failed"
11596         echo Cancel LRU locks on lustre client to flush the client cache
11597         cancel_lru_locks osc
11598
11599         echo "Reset readahead stats"
11600         $LCTL set_param -n llite.*.read_ahead_stats 0
11601
11602         echo "Read 10M of data but cross 64M bundary"
11603         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11604         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11605                      get_named_value 'misses' | calc_total)
11606         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11607         rm -f $p $DIR/$tfile
11608 }
11609 run_test 101h "Readahead should cover current read window"
11610
11611 test_101i() {
11612         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11613                 error "dd 10M file failed"
11614
11615         local max_per_file_mb=$($LCTL get_param -n \
11616                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11617         cancel_lru_locks osc
11618         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11619         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11620                 error "set max_read_ahead_per_file_mb to 1 failed"
11621
11622         echo "Reset readahead stats"
11623         $LCTL set_param llite.*.read_ahead_stats=0
11624
11625         dd if=$DIR/$tfile of=/dev/null bs=2M
11626
11627         $LCTL get_param llite.*.read_ahead_stats
11628         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11629                      awk '/misses/ { print $2 }')
11630         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11631         rm -f $DIR/$tfile
11632 }
11633 run_test 101i "allow current readahead to exceed reservation"
11634
11635 test_101j() {
11636         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11637                 error "setstripe $DIR/$tfile failed"
11638         local file_size=$((1048576 * 16))
11639         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11640         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11641
11642         echo Disable read-ahead
11643         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11644
11645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11646         for blk in $PAGE_SIZE 1048576 $file_size; do
11647                 cancel_lru_locks osc
11648                 echo "Reset readahead stats"
11649                 $LCTL set_param -n llite.*.read_ahead_stats=0
11650                 local count=$(($file_size / $blk))
11651                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11652                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11653                              get_named_value 'failed.to.fast.read' | calc_total)
11654                 $LCTL get_param -n llite.*.read_ahead_stats
11655                 [ $miss -eq $count ] || error "expected $count got $miss"
11656         done
11657
11658         rm -f $p $DIR/$tfile
11659 }
11660 run_test 101j "A complete read block should be submitted when no RA"
11661
11662 test_readahead_base() {
11663         local file=$DIR/$tfile
11664         local size=$1
11665         local iosz
11666         local ramax
11667         local ranum
11668
11669         $LCTL set_param -n llite.*.read_ahead_stats=0
11670         # The first page is not accounted into readahead
11671         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11672         iosz=$(((size + 1048575) / 1048576 * 1048576))
11673         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11674
11675         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11676         fallocate -l $size $file || error "failed to fallocate $file"
11677         cancel_lru_locks osc
11678         $MULTIOP $file or${iosz}c || error "failed to read $file"
11679         $LCTL get_param -n llite.*.read_ahead_stats
11680         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11681                 awk '/readahead.pages/ { print $7 }' | calc_total)
11682         (( $ranum <= $ramax )) ||
11683                 error "read-ahead pages is $ranum more than $ramax"
11684         rm -rf $file || error "failed to remove $file"
11685 }
11686
11687 test_101m()
11688 {
11689         local file=$DIR/$tfile
11690         local ramax
11691         local ranum
11692         local size
11693         local iosz
11694
11695         check_set_fallocate_or_skip
11696         stack_trap "rm -f $file" EXIT
11697
11698         test_readahead_base 4096
11699
11700         # file size: 16K = 16384
11701         test_readahead_base 16384
11702         test_readahead_base 16385
11703         test_readahead_base 16383
11704
11705         # file size: 1M + 1 = 1048576 + 1
11706         test_readahead_base 1048577
11707         # file size: 1M + 16K
11708         test_readahead_base $((1048576 + 16384))
11709
11710         # file size: stripe_size * (stripe_count - 1) + 16K
11711         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11712         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11713         # file size: stripe_size * stripe_count + 16K
11714         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11715         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11716         # file size: 2 * stripe_size * stripe_count + 16K
11717         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11718         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11719 }
11720 run_test 101m "read ahead for small file and last stripe of the file"
11721
11722 setup_test102() {
11723         test_mkdir $DIR/$tdir
11724         chown $RUNAS_ID $DIR/$tdir
11725         STRIPE_SIZE=65536
11726         STRIPE_OFFSET=1
11727         STRIPE_COUNT=$OSTCOUNT
11728         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11729
11730         trap cleanup_test102 EXIT
11731         cd $DIR
11732         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11733         cd $DIR/$tdir
11734         for num in 1 2 3 4; do
11735                 for count in $(seq 1 $STRIPE_COUNT); do
11736                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11737                                 local size=`expr $STRIPE_SIZE \* $num`
11738                                 local file=file"$num-$idx-$count"
11739                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11740                         done
11741                 done
11742         done
11743
11744         cd $DIR
11745         $1 tar cf $TMP/f102.tar $tdir --xattrs
11746 }
11747
11748 cleanup_test102() {
11749         trap 0
11750         rm -f $TMP/f102.tar
11751         rm -rf $DIR/d0.sanity/d102
11752 }
11753
11754 test_102a() {
11755         [ "$UID" != 0 ] && skip "must run as root"
11756         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11757                 skip_env "must have user_xattr"
11758
11759         [ -z "$(which setfattr 2>/dev/null)" ] &&
11760                 skip_env "could not find setfattr"
11761
11762         local testfile=$DIR/$tfile
11763
11764         touch $testfile
11765         echo "set/get xattr..."
11766         setfattr -n trusted.name1 -v value1 $testfile ||
11767                 error "setfattr -n trusted.name1=value1 $testfile failed"
11768         getfattr -n trusted.name1 $testfile 2> /dev/null |
11769           grep "trusted.name1=.value1" ||
11770                 error "$testfile missing trusted.name1=value1"
11771
11772         setfattr -n user.author1 -v author1 $testfile ||
11773                 error "setfattr -n user.author1=author1 $testfile failed"
11774         getfattr -n user.author1 $testfile 2> /dev/null |
11775           grep "user.author1=.author1" ||
11776                 error "$testfile missing trusted.author1=author1"
11777
11778         echo "listxattr..."
11779         setfattr -n trusted.name2 -v value2 $testfile ||
11780                 error "$testfile unable to set trusted.name2"
11781         setfattr -n trusted.name3 -v value3 $testfile ||
11782                 error "$testfile unable to set trusted.name3"
11783         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11784             grep "trusted.name" | wc -l) -eq 3 ] ||
11785                 error "$testfile missing 3 trusted.name xattrs"
11786
11787         setfattr -n user.author2 -v author2 $testfile ||
11788                 error "$testfile unable to set user.author2"
11789         setfattr -n user.author3 -v author3 $testfile ||
11790                 error "$testfile unable to set user.author3"
11791         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11792             grep "user.author" | wc -l) -eq 3 ] ||
11793                 error "$testfile missing 3 user.author xattrs"
11794
11795         echo "remove xattr..."
11796         setfattr -x trusted.name1 $testfile ||
11797                 error "$testfile error deleting trusted.name1"
11798         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11799                 error "$testfile did not delete trusted.name1 xattr"
11800
11801         setfattr -x user.author1 $testfile ||
11802                 error "$testfile error deleting user.author1"
11803         echo "set lustre special xattr ..."
11804         $LFS setstripe -c1 $testfile
11805         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11806                 awk -F "=" '/trusted.lov/ { print $2 }' )
11807         setfattr -n "trusted.lov" -v $lovea $testfile ||
11808                 error "$testfile doesn't ignore setting trusted.lov again"
11809         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11810                 error "$testfile allow setting invalid trusted.lov"
11811         rm -f $testfile
11812 }
11813 run_test 102a "user xattr test =================================="
11814
11815 check_102b_layout() {
11816         local layout="$*"
11817         local testfile=$DIR/$tfile
11818
11819         echo "test layout '$layout'"
11820         $LFS setstripe $layout $testfile || error "setstripe failed"
11821         $LFS getstripe -y $testfile
11822
11823         echo "get/set/list trusted.lov xattr ..." # b=10930
11824         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11825         [[ "$value" =~ "trusted.lov" ]] ||
11826                 error "can't get trusted.lov from $testfile"
11827         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11828                 error "getstripe failed"
11829
11830         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11831
11832         value=$(cut -d= -f2 <<<$value)
11833         # LU-13168: truncated xattr should fail if short lov_user_md header
11834         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11835                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11836         for len in $lens; do
11837                 echo "setfattr $len $testfile.2"
11838                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11839                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11840         done
11841         local stripe_size=$($LFS getstripe -S $testfile.2)
11842         local stripe_count=$($LFS getstripe -c $testfile.2)
11843         [[ $stripe_size -eq 65536 ]] ||
11844                 error "stripe size $stripe_size != 65536"
11845         [[ $stripe_count -eq $stripe_count_orig ]] ||
11846                 error "stripe count $stripe_count != $stripe_count_orig"
11847         rm $testfile $testfile.2
11848 }
11849
11850 test_102b() {
11851         [ -z "$(which setfattr 2>/dev/null)" ] &&
11852                 skip_env "could not find setfattr"
11853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11854
11855         # check plain layout
11856         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11857
11858         # and also check composite layout
11859         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11860
11861 }
11862 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11863
11864 test_102c() {
11865         [ -z "$(which setfattr 2>/dev/null)" ] &&
11866                 skip_env "could not find setfattr"
11867         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11868
11869         # b10930: get/set/list lustre.lov xattr
11870         echo "get/set/list lustre.lov xattr ..."
11871         test_mkdir $DIR/$tdir
11872         chown $RUNAS_ID $DIR/$tdir
11873         local testfile=$DIR/$tdir/$tfile
11874         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11875                 error "setstripe failed"
11876         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11877                 error "getstripe failed"
11878         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11879         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11880
11881         local testfile2=${testfile}2
11882         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11883                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11884
11885         $RUNAS $MCREATE $testfile2
11886         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11887         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11888         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11889         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11890         [ $stripe_count -eq $STRIPECOUNT ] ||
11891                 error "stripe count $stripe_count != $STRIPECOUNT"
11892 }
11893 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11894
11895 compare_stripe_info1() {
11896         local stripe_index_all_zero=true
11897
11898         for num in 1 2 3 4; do
11899                 for count in $(seq 1 $STRIPE_COUNT); do
11900                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11901                                 local size=$((STRIPE_SIZE * num))
11902                                 local file=file"$num-$offset-$count"
11903                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11904                                 [[ $stripe_size -ne $size ]] &&
11905                                     error "$file: size $stripe_size != $size"
11906                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11907                                 # allow fewer stripes to be created, ORI-601
11908                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11909                                     error "$file: count $stripe_count != $count"
11910                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11911                                 [[ $stripe_index -ne 0 ]] &&
11912                                         stripe_index_all_zero=false
11913                         done
11914                 done
11915         done
11916         $stripe_index_all_zero &&
11917                 error "all files are being extracted starting from OST index 0"
11918         return 0
11919 }
11920
11921 have_xattrs_include() {
11922         tar --help | grep -q xattrs-include &&
11923                 echo --xattrs-include="lustre.*"
11924 }
11925
11926 test_102d() {
11927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11928         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11929
11930         XINC=$(have_xattrs_include)
11931         setup_test102
11932         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11933         cd $DIR/$tdir/$tdir
11934         compare_stripe_info1
11935 }
11936 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11937
11938 test_102f() {
11939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11941
11942         XINC=$(have_xattrs_include)
11943         setup_test102
11944         test_mkdir $DIR/$tdir.restore
11945         cd $DIR
11946         tar cf - --xattrs $tdir | tar xf - \
11947                 -C $DIR/$tdir.restore --xattrs $XINC
11948         cd $DIR/$tdir.restore/$tdir
11949         compare_stripe_info1
11950 }
11951 run_test 102f "tar copy files, not keep osts"
11952
11953 grow_xattr() {
11954         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11955                 skip "must have user_xattr"
11956         [ -z "$(which setfattr 2>/dev/null)" ] &&
11957                 skip_env "could not find setfattr"
11958         [ -z "$(which getfattr 2>/dev/null)" ] &&
11959                 skip_env "could not find getfattr"
11960
11961         local xsize=${1:-1024}  # in bytes
11962         local file=$DIR/$tfile
11963         local value="$(generate_string $xsize)"
11964         local xbig=trusted.big
11965         local toobig=$2
11966
11967         touch $file
11968         log "save $xbig on $file"
11969         if [ -z "$toobig" ]
11970         then
11971                 setfattr -n $xbig -v $value $file ||
11972                         error "saving $xbig on $file failed"
11973         else
11974                 setfattr -n $xbig -v $value $file &&
11975                         error "saving $xbig on $file succeeded"
11976                 return 0
11977         fi
11978
11979         local orig=$(get_xattr_value $xbig $file)
11980         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11981
11982         local xsml=trusted.sml
11983         log "save $xsml on $file"
11984         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11985
11986         local new=$(get_xattr_value $xbig $file)
11987         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11988
11989         log "grow $xsml on $file"
11990         setfattr -n $xsml -v "$value" $file ||
11991                 error "growing $xsml on $file failed"
11992
11993         new=$(get_xattr_value $xbig $file)
11994         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11995         log "$xbig still valid after growing $xsml"
11996
11997         rm -f $file
11998 }
11999
12000 test_102h() { # bug 15777
12001         grow_xattr 1024
12002 }
12003 run_test 102h "grow xattr from inside inode to external block"
12004
12005 test_102ha() {
12006         large_xattr_enabled || skip_env "ea_inode feature disabled"
12007
12008         echo "setting xattr of max xattr size: $(max_xattr_size)"
12009         grow_xattr $(max_xattr_size)
12010
12011         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12012         echo "This should fail:"
12013         grow_xattr $(($(max_xattr_size) + 10)) 1
12014 }
12015 run_test 102ha "grow xattr from inside inode to external inode"
12016
12017 test_102i() { # bug 17038
12018         [ -z "$(which getfattr 2>/dev/null)" ] &&
12019                 skip "could not find getfattr"
12020
12021         touch $DIR/$tfile
12022         ln -s $DIR/$tfile $DIR/${tfile}link
12023         getfattr -n trusted.lov $DIR/$tfile ||
12024                 error "lgetxattr on $DIR/$tfile failed"
12025         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12026                 grep -i "no such attr" ||
12027                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12028         rm -f $DIR/$tfile $DIR/${tfile}link
12029 }
12030 run_test 102i "lgetxattr test on symbolic link ============"
12031
12032 test_102j() {
12033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12034         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12035
12036         XINC=$(have_xattrs_include)
12037         setup_test102 "$RUNAS"
12038         chown $RUNAS_ID $DIR/$tdir
12039         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12040         cd $DIR/$tdir/$tdir
12041         compare_stripe_info1 "$RUNAS"
12042 }
12043 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12044
12045 test_102k() {
12046         [ -z "$(which setfattr 2>/dev/null)" ] &&
12047                 skip "could not find setfattr"
12048
12049         touch $DIR/$tfile
12050         # b22187 just check that does not crash for regular file.
12051         setfattr -n trusted.lov $DIR/$tfile
12052         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12053         local test_kdir=$DIR/$tdir
12054         test_mkdir $test_kdir
12055         local default_size=$($LFS getstripe -S $test_kdir)
12056         local default_count=$($LFS getstripe -c $test_kdir)
12057         local default_offset=$($LFS getstripe -i $test_kdir)
12058         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12059                 error 'dir setstripe failed'
12060         setfattr -n trusted.lov $test_kdir
12061         local stripe_size=$($LFS getstripe -S $test_kdir)
12062         local stripe_count=$($LFS getstripe -c $test_kdir)
12063         local stripe_offset=$($LFS getstripe -i $test_kdir)
12064         [ $stripe_size -eq $default_size ] ||
12065                 error "stripe size $stripe_size != $default_size"
12066         [ $stripe_count -eq $default_count ] ||
12067                 error "stripe count $stripe_count != $default_count"
12068         [ $stripe_offset -eq $default_offset ] ||
12069                 error "stripe offset $stripe_offset != $default_offset"
12070         rm -rf $DIR/$tfile $test_kdir
12071 }
12072 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12073
12074 test_102l() {
12075         [ -z "$(which getfattr 2>/dev/null)" ] &&
12076                 skip "could not find getfattr"
12077
12078         # LU-532 trusted. xattr is invisible to non-root
12079         local testfile=$DIR/$tfile
12080
12081         touch $testfile
12082
12083         echo "listxattr as user..."
12084         chown $RUNAS_ID $testfile
12085         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12086             grep -q "trusted" &&
12087                 error "$testfile trusted xattrs are user visible"
12088
12089         return 0;
12090 }
12091 run_test 102l "listxattr size test =================================="
12092
12093 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12094         local path=$DIR/$tfile
12095         touch $path
12096
12097         listxattr_size_check $path || error "listattr_size_check $path failed"
12098 }
12099 run_test 102m "Ensure listxattr fails on small bufffer ========"
12100
12101 cleanup_test102
12102
12103 getxattr() { # getxattr path name
12104         # Return the base64 encoding of the value of xattr name on path.
12105         local path=$1
12106         local name=$2
12107
12108         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12109         # file: $path
12110         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12111         #
12112         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12113
12114         getfattr --absolute-names --encoding=base64 --name=$name $path |
12115                 awk -F= -v name=$name '$1 == name {
12116                         print substr($0, index($0, "=") + 1);
12117         }'
12118 }
12119
12120 test_102n() { # LU-4101 mdt: protect internal xattrs
12121         [ -z "$(which setfattr 2>/dev/null)" ] &&
12122                 skip "could not find setfattr"
12123         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12124         then
12125                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12126         fi
12127
12128         local file0=$DIR/$tfile.0
12129         local file1=$DIR/$tfile.1
12130         local xattr0=$TMP/$tfile.0
12131         local xattr1=$TMP/$tfile.1
12132         local namelist="lov lma lmv link fid version som hsm"
12133         local name
12134         local value
12135
12136         rm -rf $file0 $file1 $xattr0 $xattr1
12137         touch $file0 $file1
12138
12139         # Get 'before' xattrs of $file1.
12140         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12141
12142         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12143                 namelist+=" lfsck_namespace"
12144         for name in $namelist; do
12145                 # Try to copy xattr from $file0 to $file1.
12146                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12147
12148                 setfattr --name=trusted.$name --value="$value" $file1 ||
12149                         error "setxattr 'trusted.$name' failed"
12150
12151                 # Try to set a garbage xattr.
12152                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12153
12154                 if [[ x$name == "xlov" ]]; then
12155                         setfattr --name=trusted.lov --value="$value" $file1 &&
12156                         error "setxattr invalid 'trusted.lov' success"
12157                 else
12158                         setfattr --name=trusted.$name --value="$value" $file1 ||
12159                                 error "setxattr invalid 'trusted.$name' failed"
12160                 fi
12161
12162                 # Try to remove the xattr from $file1. We don't care if this
12163                 # appears to succeed or fail, we just don't want there to be
12164                 # any changes or crashes.
12165                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12166         done
12167
12168         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12169         then
12170                 name="lfsck_ns"
12171                 # Try to copy xattr from $file0 to $file1.
12172                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12173
12174                 setfattr --name=trusted.$name --value="$value" $file1 ||
12175                         error "setxattr 'trusted.$name' failed"
12176
12177                 # Try to set a garbage xattr.
12178                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12179
12180                 setfattr --name=trusted.$name --value="$value" $file1 ||
12181                         error "setxattr 'trusted.$name' failed"
12182
12183                 # Try to remove the xattr from $file1. We don't care if this
12184                 # appears to succeed or fail, we just don't want there to be
12185                 # any changes or crashes.
12186                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12187         fi
12188
12189         # Get 'after' xattrs of file1.
12190         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12191
12192         if ! diff $xattr0 $xattr1; then
12193                 error "before and after xattrs of '$file1' differ"
12194         fi
12195
12196         rm -rf $file0 $file1 $xattr0 $xattr1
12197
12198         return 0
12199 }
12200 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12201
12202 test_102p() { # LU-4703 setxattr did not check ownership
12203         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12204                 skip "MDS needs to be at least 2.5.56"
12205
12206         local testfile=$DIR/$tfile
12207
12208         touch $testfile
12209
12210         echo "setfacl as user..."
12211         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12212         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12213
12214         echo "setfattr as user..."
12215         setfacl -m "u:$RUNAS_ID:---" $testfile
12216         $RUNAS setfattr -x system.posix_acl_access $testfile
12217         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12218 }
12219 run_test 102p "check setxattr(2) correctly fails without permission"
12220
12221 test_102q() {
12222         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12223                 skip "MDS needs to be at least 2.6.92"
12224
12225         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12226 }
12227 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12228
12229 test_102r() {
12230         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12231                 skip "MDS needs to be at least 2.6.93"
12232
12233         touch $DIR/$tfile || error "touch"
12234         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12235         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12236         rm $DIR/$tfile || error "rm"
12237
12238         #normal directory
12239         mkdir -p $DIR/$tdir || error "mkdir"
12240         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12241         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12242         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12243                 error "$testfile error deleting user.author1"
12244         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12245                 grep "user.$(basename $tdir)" &&
12246                 error "$tdir did not delete user.$(basename $tdir)"
12247         rmdir $DIR/$tdir || error "rmdir"
12248
12249         #striped directory
12250         test_mkdir $DIR/$tdir
12251         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12252         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12253         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12254                 error "$testfile error deleting user.author1"
12255         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12256                 grep "user.$(basename $tdir)" &&
12257                 error "$tdir did not delete user.$(basename $tdir)"
12258         rmdir $DIR/$tdir || error "rm striped dir"
12259 }
12260 run_test 102r "set EAs with empty values"
12261
12262 test_102s() {
12263         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12264                 skip "MDS needs to be at least 2.11.52"
12265
12266         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12267
12268         save_lustre_params client "llite.*.xattr_cache" > $save
12269
12270         for cache in 0 1; do
12271                 lctl set_param llite.*.xattr_cache=$cache
12272
12273                 rm -f $DIR/$tfile
12274                 touch $DIR/$tfile || error "touch"
12275                 for prefix in lustre security system trusted user; do
12276                         # Note getxattr() may fail with 'Operation not
12277                         # supported' or 'No such attribute' depending
12278                         # on prefix and cache.
12279                         getfattr -n $prefix.n102s $DIR/$tfile &&
12280                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12281                 done
12282         done
12283
12284         restore_lustre_params < $save
12285 }
12286 run_test 102s "getting nonexistent xattrs should fail"
12287
12288 test_102t() {
12289         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12290                 skip "MDS needs to be at least 2.11.52"
12291
12292         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12293
12294         save_lustre_params client "llite.*.xattr_cache" > $save
12295
12296         for cache in 0 1; do
12297                 lctl set_param llite.*.xattr_cache=$cache
12298
12299                 for buf_size in 0 256; do
12300                         rm -f $DIR/$tfile
12301                         touch $DIR/$tfile || error "touch"
12302                         setfattr -n user.multiop $DIR/$tfile
12303                         $MULTIOP $DIR/$tfile oa$buf_size ||
12304                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12305                 done
12306         done
12307
12308         restore_lustre_params < $save
12309 }
12310 run_test 102t "zero length xattr values handled correctly"
12311
12312 run_acl_subtest()
12313 {
12314         local test=$LUSTRE/tests/acl/$1.test
12315         local tmp=$(mktemp -t $1-XXXXXX).test
12316         local bin=$2
12317         local dmn=$3
12318         local grp=$4
12319         local nbd=$5
12320         export LANG=C
12321
12322
12323         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12324         local sedgroups="-e s/:users/:$grp/g"
12325         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12326
12327         sed $sedusers $sedgroups < $test > $tmp
12328         stack_trap "rm -f $tmp"
12329         [[ -s $tmp ]] || error "sed failed to create test script"
12330
12331         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12332         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12333 }
12334
12335 test_103a() {
12336         [ "$UID" != 0 ] && skip "must run as root"
12337         $GSS && skip_env "could not run under gss"
12338         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12339                 skip_env "must have acl enabled"
12340         which setfacl || skip_env "could not find setfacl"
12341         remote_mds_nodsh && skip "remote MDS with nodsh"
12342
12343         local mdts=$(comma_list $(mdts_nodes))
12344         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12345
12346         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12347         stack_trap "[[ -z \"$saved\" ]] || \
12348                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12349
12350         ACLBIN=${ACLBIN:-"bin"}
12351         ACLDMN=${ACLDMN:-"daemon"}
12352         ACLGRP=${ACLGRP:-"users"}
12353         ACLNBD=${ACLNBD:-"nobody"}
12354
12355         if ! id $ACLBIN ||
12356            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12357                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12358                 ACLBIN=$USER0
12359                 if ! id $ACLBIN ; then
12360                         cat /etc/passwd
12361                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12362                 fi
12363         fi
12364         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12365            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12366                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12367                 ACLDMN=$USER1
12368                 if ! id $ACLDMN ; then
12369                         cat /etc/passwd
12370                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12371                 fi
12372         fi
12373         if ! getent group $ACLGRP; then
12374                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12375                 ACLGRP="$TSTUSR"
12376                 if ! getent group $ACLGRP; then
12377                         echo "cannot find group '$ACLGRP', adding it"
12378                         cat /etc/group
12379                         add_group 60000 $ACLGRP
12380                 fi
12381         fi
12382
12383         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12384         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12385         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12386
12387         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12388                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12389                 ACLGRP="$TSTUSR"
12390                 if ! getent group $ACLGRP; then
12391                         echo "cannot find group '$ACLGRP', adding it"
12392                         cat /etc/group
12393                         add_group 60000 $ACLGRP
12394                 fi
12395                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12396                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12397                         cat /etc/group
12398                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12399                 fi
12400         fi
12401
12402         gpasswd -a $ACLDMN $ACLBIN ||
12403                 error "setting client group failed"             # LU-5641
12404         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12405                 error "setting MDS group failed"                # LU-5641
12406
12407         declare -a identity_old
12408
12409         for num in $(seq $MDSCOUNT); do
12410                 switch_identity $num true || identity_old[$num]=$?
12411         done
12412
12413         SAVE_UMASK=$(umask)
12414         umask 0022
12415         mkdir -p $DIR/$tdir
12416         cd $DIR/$tdir
12417
12418         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12419         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12420         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12421         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12422         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12423         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12424         if ! id -u $ACLNBD ||
12425            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12426                 ACLNBD="nfsnobody"
12427                 if ! id -u $ACLNBD; then
12428                         ACLNBD=""
12429                 fi
12430         fi
12431         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12432                 add_group $(id -u $ACLNBD) $ACLNBD
12433                 if ! getent group $ACLNBD; then
12434                         ACLNBD=""
12435                 fi
12436         fi
12437         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12438            [[ -n "$ACLNBD" ]] && which setfattr; then
12439                 run_acl_subtest permissions_xattr \
12440                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12441         elif [[ -z "$ACLNBD" ]]; then
12442                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12443         else
12444                 echo "skip 'permission_xattr' test - missing setfattr command"
12445         fi
12446         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12447
12448         # inheritance test got from HP
12449         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12450         chmod +x make-tree || error "chmod +x failed"
12451         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12452         rm -f make-tree
12453
12454         echo "LU-974 ignore umask when acl is enabled..."
12455         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12456         if [ $MDSCOUNT -ge 2 ]; then
12457                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12458         fi
12459
12460         echo "LU-2561 newly created file is same size as directory..."
12461         if [ "$mds1_FSTYPE" != "zfs" ]; then
12462                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12463         else
12464                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12465         fi
12466
12467         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12468
12469         cd $SAVE_PWD
12470         umask $SAVE_UMASK
12471
12472         for num in $(seq $MDSCOUNT); do
12473                 if [ "${identity_old[$num]}" = 1 ]; then
12474                         switch_identity $num false || identity_old[$num]=$?
12475                 fi
12476         done
12477 }
12478 run_test 103a "acl test"
12479
12480 test_103b() {
12481         declare -a pids
12482         local U
12483
12484         stack_trap "rm -f $DIR/$tfile.*"
12485         for U in {0..511}; do
12486                 {
12487                 local O=$(printf "%04o" $U)
12488
12489                 umask $(printf "%04o" $((511 ^ $O)))
12490                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12491                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12492
12493                 (( $S == ($O & 0666) )) ||
12494                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12495
12496                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12497                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12498                 (( $S == ($O & 0666) )) ||
12499                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12500
12501                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12502                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12503                 (( $S == ($O & 0666) )) ||
12504                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12505                 rm -f $DIR/$tfile.[smp]$0
12506                 } &
12507                 local pid=$!
12508
12509                 # limit the concurrently running threads to 64. LU-11878
12510                 local idx=$((U % 64))
12511                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12512                 pids[idx]=$pid
12513         done
12514         wait
12515 }
12516 run_test 103b "umask lfs setstripe"
12517
12518 test_103c() {
12519         mkdir -p $DIR/$tdir
12520         cp -rp $DIR/$tdir $DIR/$tdir.bak
12521
12522         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12523                 error "$DIR/$tdir shouldn't contain default ACL"
12524         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12525                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12526         true
12527 }
12528 run_test 103c "'cp -rp' won't set empty acl"
12529
12530 test_103e() {
12531         local numacl
12532         local fileacl
12533         local saved_debug=$($LCTL get_param -n debug)
12534
12535         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12536                 skip "MDS needs to be at least 2.14.52"
12537
12538         large_xattr_enabled || skip_env "ea_inode feature disabled"
12539
12540         mkdir -p $DIR/$tdir
12541         # add big LOV EA to cause reply buffer overflow earlier
12542         $LFS setstripe -C 1000 $DIR/$tdir
12543         lctl set_param mdc.*-mdc*.stats=clear
12544
12545         $LCTL set_param debug=0
12546         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12547         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12548
12549         # add a large number of default ACLs (expect 8000+ for 2.13+)
12550         for U in {2..7000}; do
12551                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12552                         error "Able to add just $U default ACLs"
12553         done
12554         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12555         echo "$numacl default ACLs created"
12556
12557         stat $DIR/$tdir || error "Cannot stat directory"
12558         # check file creation
12559         touch $DIR/$tdir/$tfile ||
12560                 error "failed to create $tfile with $numacl default ACLs"
12561         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12562         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12563         echo "$fileacl ACLs were inherited"
12564         (( $fileacl == $numacl )) ||
12565                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12566         # check that new ACLs creation adds new ACLs to inherited ACLs
12567         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12568                 error "Cannot set new ACL"
12569         numacl=$((numacl + 1))
12570         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12571         (( $fileacl == $numacl )) ||
12572                 error "failed to add new ACL: $fileacl != $numacl as expected"
12573         # adds more ACLs to a file to reach their maximum at 8000+
12574         numacl=0
12575         for U in {20000..25000}; do
12576                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12577                 numacl=$((numacl + 1))
12578         done
12579         echo "Added $numacl more ACLs to the file"
12580         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12581         echo "Total $fileacl ACLs in file"
12582         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12583         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12584         rmdir $DIR/$tdir || error "Cannot remove directory"
12585 }
12586 run_test 103e "inheritance of big amount of default ACLs"
12587
12588 test_103f() {
12589         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12590                 skip "MDS needs to be at least 2.14.51"
12591
12592         large_xattr_enabled || skip_env "ea_inode feature disabled"
12593
12594         # enable changelog to consume more internal MDD buffers
12595         changelog_register
12596
12597         mkdir -p $DIR/$tdir
12598         # add big LOV EA
12599         $LFS setstripe -C 1000 $DIR/$tdir
12600         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12601         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12602         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12603         rmdir $DIR/$tdir || error "Cannot remove directory"
12604 }
12605 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12606
12607 test_104a() {
12608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12609
12610         touch $DIR/$tfile
12611         lfs df || error "lfs df failed"
12612         lfs df -ih || error "lfs df -ih failed"
12613         lfs df -h $DIR || error "lfs df -h $DIR failed"
12614         lfs df -i $DIR || error "lfs df -i $DIR failed"
12615         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12616         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12617
12618         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12619         lctl --device %$OSC deactivate
12620         lfs df || error "lfs df with deactivated OSC failed"
12621         lctl --device %$OSC activate
12622         # wait the osc back to normal
12623         wait_osc_import_ready client ost
12624
12625         lfs df || error "lfs df with reactivated OSC failed"
12626         rm -f $DIR/$tfile
12627 }
12628 run_test 104a "lfs df [-ih] [path] test ========================="
12629
12630 test_104b() {
12631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12632         [ $RUNAS_ID -eq $UID ] &&
12633                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12634
12635         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12636                         grep "Permission denied" | wc -l)))
12637         if [ $denied_cnt -ne 0 ]; then
12638                 error "lfs check servers test failed"
12639         fi
12640 }
12641 run_test 104b "$RUNAS lfs check servers test ===================="
12642
12643 #
12644 # Verify $1 is within range of $2.
12645 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12646 # $1 is <= 2% of $2. Else Fail.
12647 #
12648 value_in_range() {
12649         # Strip all units (M, G, T)
12650         actual=$(echo $1 | tr -d A-Z)
12651         expect=$(echo $2 | tr -d A-Z)
12652
12653         expect_lo=$(($expect * 98 / 100)) # 2% below
12654         expect_hi=$(($expect * 102 / 100)) # 2% above
12655
12656         # permit 2% drift above and below
12657         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12658 }
12659
12660 test_104c() {
12661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12662         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12663
12664         local ost_param="osd-zfs.$FSNAME-OST0000."
12665         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12666         local ofacets=$(get_facets OST)
12667         local mfacets=$(get_facets MDS)
12668         local saved_ost_blocks=
12669         local saved_mdt_blocks=
12670
12671         echo "Before recordsize change"
12672         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12673         df=($(df -h | grep "$MOUNT"$))
12674
12675         # For checking.
12676         echo "lfs output : ${lfs_df[*]}"
12677         echo "df  output : ${df[*]}"
12678
12679         for facet in ${ofacets//,/ }; do
12680                 if [ -z $saved_ost_blocks ]; then
12681                         saved_ost_blocks=$(do_facet $facet \
12682                                 lctl get_param -n $ost_param.blocksize)
12683                         echo "OST Blocksize: $saved_ost_blocks"
12684                 fi
12685                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12686                 do_facet $facet zfs set recordsize=32768 $ost
12687         done
12688
12689         # BS too small. Sufficient for functional testing.
12690         for facet in ${mfacets//,/ }; do
12691                 if [ -z $saved_mdt_blocks ]; then
12692                         saved_mdt_blocks=$(do_facet $facet \
12693                                 lctl get_param -n $mdt_param.blocksize)
12694                         echo "MDT Blocksize: $saved_mdt_blocks"
12695                 fi
12696                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12697                 do_facet $facet zfs set recordsize=32768 $mdt
12698         done
12699
12700         # Give new values chance to reflect change
12701         sleep 2
12702
12703         echo "After recordsize change"
12704         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12705         df_after=($(df -h | grep "$MOUNT"$))
12706
12707         # For checking.
12708         echo "lfs output : ${lfs_df_after[*]}"
12709         echo "df  output : ${df_after[*]}"
12710
12711         # Verify lfs df
12712         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12713                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12714         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12715                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12716         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12717                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12718
12719         # Verify df
12720         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12721                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12722         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12723                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12724         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12725                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12726
12727         # Restore MDT recordize back to original
12728         for facet in ${mfacets//,/ }; do
12729                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12730                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12731         done
12732
12733         # Restore OST recordize back to original
12734         for facet in ${ofacets//,/ }; do
12735                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12736                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12737         done
12738
12739         return 0
12740 }
12741 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12742
12743 test_104d() {
12744         (( $RUNAS_ID != $UID )) ||
12745                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12746
12747         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12748                 skip "lustre version doesn't support lctl dl with non-root"
12749
12750         # debugfs only allows root users to access files, so the
12751         # previous move of the "devices" file to debugfs broke
12752         # "lctl dl" for non-root users. The LU-9680 Netlink
12753         # interface again allows non-root users to list devices.
12754         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12755                 error "lctl dl doesn't work for non root"
12756
12757         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12758         [ "$ost_count" -eq $OSTCOUNT ]  ||
12759                 error "lctl dl reports wrong number of OST devices"
12760
12761         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12762         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12763                 error "lctl dl reports wrong number of MDT devices"
12764 }
12765 run_test 104d "$RUNAS lctl dl test"
12766
12767 test_105a() {
12768         # doesn't work on 2.4 kernels
12769         touch $DIR/$tfile
12770         if $(flock_is_enabled); then
12771                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12772         else
12773                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12774         fi
12775         rm -f $DIR/$tfile
12776 }
12777 run_test 105a "flock when mounted without -o flock test ========"
12778
12779 test_105b() {
12780         touch $DIR/$tfile
12781         if $(flock_is_enabled); then
12782                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12783         else
12784                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12785         fi
12786         rm -f $DIR/$tfile
12787 }
12788 run_test 105b "fcntl when mounted without -o flock test ========"
12789
12790 test_105c() {
12791         touch $DIR/$tfile
12792         if $(flock_is_enabled); then
12793                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12794         else
12795                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12796         fi
12797         rm -f $DIR/$tfile
12798 }
12799 run_test 105c "lockf when mounted without -o flock test"
12800
12801 test_105d() { # bug 15924
12802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12803
12804         test_mkdir $DIR/$tdir
12805         flock_is_enabled || skip_env "mount w/o flock enabled"
12806         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12807         $LCTL set_param fail_loc=0x80000315
12808         flocks_test 2 $DIR/$tdir
12809 }
12810 run_test 105d "flock race (should not freeze) ========"
12811
12812 test_105e() { # bug 22660 && 22040
12813         flock_is_enabled || skip_env "mount w/o flock enabled"
12814
12815         touch $DIR/$tfile
12816         flocks_test 3 $DIR/$tfile
12817 }
12818 run_test 105e "Two conflicting flocks from same process"
12819
12820 test_106() { #bug 10921
12821         test_mkdir $DIR/$tdir
12822         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12823         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12824 }
12825 run_test 106 "attempt exec of dir followed by chown of that dir"
12826
12827 test_107() {
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829
12830         CDIR=`pwd`
12831         local file=core
12832
12833         cd $DIR
12834         rm -f $file
12835
12836         local save_pattern=$(sysctl -n kernel.core_pattern)
12837         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12838         sysctl -w kernel.core_pattern=$file
12839         sysctl -w kernel.core_uses_pid=0
12840
12841         ulimit -c unlimited
12842         sleep 60 &
12843         SLEEPPID=$!
12844
12845         sleep 1
12846
12847         kill -s 11 $SLEEPPID
12848         wait $SLEEPPID
12849         if [ -e $file ]; then
12850                 size=`stat -c%s $file`
12851                 [ $size -eq 0 ] && error "Fail to create core file $file"
12852         else
12853                 error "Fail to create core file $file"
12854         fi
12855         rm -f $file
12856         sysctl -w kernel.core_pattern=$save_pattern
12857         sysctl -w kernel.core_uses_pid=$save_uses_pid
12858         cd $CDIR
12859 }
12860 run_test 107 "Coredump on SIG"
12861
12862 test_110() {
12863         test_mkdir $DIR/$tdir
12864         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12865         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12866                 error "mkdir with 256 char should fail, but did not"
12867         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12868                 error "create with 255 char failed"
12869         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12870                 error "create with 256 char should fail, but did not"
12871
12872         ls -l $DIR/$tdir
12873         rm -rf $DIR/$tdir
12874 }
12875 run_test 110 "filename length checking"
12876
12877 test_116a() { # was previously test_116()
12878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12880         remote_mds_nodsh && skip "remote MDS with nodsh"
12881
12882         echo -n "Free space priority "
12883         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12884                 head -n1
12885         declare -a AVAIL
12886         free_min_max
12887
12888         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12889         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12890         stack_trap simple_cleanup_common
12891
12892         # Check if we need to generate uneven OSTs
12893         test_mkdir -p $DIR/$tdir/OST${MINI}
12894         local FILL=$((MINV / 4))
12895         local DIFF=$((MAXV - MINV))
12896         local DIFF2=$((DIFF * 100 / MINV))
12897
12898         local threshold=$(do_facet $SINGLEMDS \
12899                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12900         threshold=${threshold%%%}
12901         echo -n "Check for uneven OSTs: "
12902         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12903
12904         if [[ $DIFF2 -gt $threshold ]]; then
12905                 echo "ok"
12906                 echo "Don't need to fill OST$MINI"
12907         else
12908                 # generate uneven OSTs. Write 2% over the QOS threshold value
12909                 echo "no"
12910                 DIFF=$((threshold - DIFF2 + 2))
12911                 DIFF2=$((MINV * DIFF / 100))
12912                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12913                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12914                         error "setstripe failed"
12915                 DIFF=$((DIFF2 / 2048))
12916                 i=0
12917                 while [ $i -lt $DIFF ]; do
12918                         i=$((i + 1))
12919                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12920                                 bs=2M count=1 2>/dev/null
12921                         echo -n .
12922                 done
12923                 echo .
12924                 sync
12925                 sleep_maxage
12926                 free_min_max
12927         fi
12928
12929         DIFF=$((MAXV - MINV))
12930         DIFF2=$((DIFF * 100 / MINV))
12931         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12932         if [ $DIFF2 -gt $threshold ]; then
12933                 echo "ok"
12934         else
12935                 skip "QOS imbalance criteria not met"
12936         fi
12937
12938         MINI1=$MINI
12939         MINV1=$MINV
12940         MAXI1=$MAXI
12941         MAXV1=$MAXV
12942
12943         # now fill using QOS
12944         $LFS setstripe -c 1 $DIR/$tdir
12945         FILL=$((FILL / 200))
12946         if [ $FILL -gt 600 ]; then
12947                 FILL=600
12948         fi
12949         echo "writing $FILL files to QOS-assigned OSTs"
12950         i=0
12951         while [ $i -lt $FILL ]; do
12952                 i=$((i + 1))
12953                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12954                         count=1 2>/dev/null
12955                 echo -n .
12956         done
12957         echo "wrote $i 200k files"
12958         sync
12959         sleep_maxage
12960
12961         echo "Note: free space may not be updated, so measurements might be off"
12962         free_min_max
12963         DIFF2=$((MAXV - MINV))
12964         echo "free space delta: orig $DIFF final $DIFF2"
12965         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12966         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12967         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12968         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12969         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12970         if [[ $DIFF -gt 0 ]]; then
12971                 FILL=$((DIFF2 * 100 / DIFF - 100))
12972                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12973         fi
12974
12975         # Figure out which files were written where
12976         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12977                awk '/'$MINI1': / {print $2; exit}')
12978         echo $UUID
12979         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12980         echo "$MINC files created on smaller OST $MINI1"
12981         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12982                awk '/'$MAXI1': / {print $2; exit}')
12983         echo $UUID
12984         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12985         echo "$MAXC files created on larger OST $MAXI1"
12986         if [[ $MINC -gt 0 ]]; then
12987                 FILL=$((MAXC * 100 / MINC - 100))
12988                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12989         fi
12990         [[ $MAXC -gt $MINC ]] ||
12991                 error_ignore LU-9 "stripe QOS didn't balance free space"
12992 }
12993 run_test 116a "stripe QOS: free space balance ==================="
12994
12995 test_116b() { # LU-2093
12996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12997         remote_mds_nodsh && skip "remote MDS with nodsh"
12998
12999 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13000         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13001                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13002         [ -z "$old_rr" ] && skip "no QOS"
13003         do_facet $SINGLEMDS lctl set_param \
13004                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13005         mkdir -p $DIR/$tdir
13006         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13007         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13008         do_facet $SINGLEMDS lctl set_param fail_loc=0
13009         rm -rf $DIR/$tdir
13010         do_facet $SINGLEMDS lctl set_param \
13011                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13012 }
13013 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13014
13015 test_117() # bug 10891
13016 {
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018
13019         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13020         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13021         lctl set_param fail_loc=0x21e
13022         > $DIR/$tfile || error "truncate failed"
13023         lctl set_param fail_loc=0
13024         echo "Truncate succeeded."
13025         rm -f $DIR/$tfile
13026 }
13027 run_test 117 "verify osd extend =========="
13028
13029 NO_SLOW_RESENDCOUNT=4
13030 export OLD_RESENDCOUNT=""
13031 set_resend_count () {
13032         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13033         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13034         lctl set_param -n $PROC_RESENDCOUNT $1
13035         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13036 }
13037
13038 # for reduce test_118* time (b=14842)
13039 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13040
13041 # Reset async IO behavior after error case
13042 reset_async() {
13043         FILE=$DIR/reset_async
13044
13045         # Ensure all OSCs are cleared
13046         $LFS setstripe -c -1 $FILE
13047         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13048         sync
13049         rm $FILE
13050 }
13051
13052 test_118a() #bug 11710
13053 {
13054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13055
13056         reset_async
13057
13058         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13059         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13060         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13061
13062         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13063                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13064                 return 1;
13065         fi
13066         rm -f $DIR/$tfile
13067 }
13068 run_test 118a "verify O_SYNC works =========="
13069
13070 test_118b()
13071 {
13072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13073         remote_ost_nodsh && skip "remote OST with nodsh"
13074
13075         reset_async
13076
13077         #define OBD_FAIL_SRV_ENOENT 0x217
13078         set_nodes_failloc "$(osts_nodes)" 0x217
13079         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13080         RC=$?
13081         set_nodes_failloc "$(osts_nodes)" 0
13082         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13083         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13084                     grep -c writeback)
13085
13086         if [[ $RC -eq 0 ]]; then
13087                 error "Must return error due to dropped pages, rc=$RC"
13088                 return 1;
13089         fi
13090
13091         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13092                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13093                 return 1;
13094         fi
13095
13096         echo "Dirty pages not leaked on ENOENT"
13097
13098         # Due to the above error the OSC will issue all RPCs syncronously
13099         # until a subsequent RPC completes successfully without error.
13100         $MULTIOP $DIR/$tfile Ow4096yc
13101         rm -f $DIR/$tfile
13102
13103         return 0
13104 }
13105 run_test 118b "Reclaim dirty pages on fatal error =========="
13106
13107 test_118c()
13108 {
13109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13110
13111         # for 118c, restore the original resend count, LU-1940
13112         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13113                                 set_resend_count $OLD_RESENDCOUNT
13114         remote_ost_nodsh && skip "remote OST with nodsh"
13115
13116         reset_async
13117
13118         #define OBD_FAIL_OST_EROFS               0x216
13119         set_nodes_failloc "$(osts_nodes)" 0x216
13120
13121         # multiop should block due to fsync until pages are written
13122         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13123         MULTIPID=$!
13124         sleep 1
13125
13126         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13127                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13128         fi
13129
13130         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13131                     grep -c writeback)
13132         if [[ $WRITEBACK -eq 0 ]]; then
13133                 error "No page in writeback, writeback=$WRITEBACK"
13134         fi
13135
13136         set_nodes_failloc "$(osts_nodes)" 0
13137         wait $MULTIPID
13138         RC=$?
13139         if [[ $RC -ne 0 ]]; then
13140                 error "Multiop fsync failed, rc=$RC"
13141         fi
13142
13143         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13144         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13145                     grep -c writeback)
13146         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13147                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13148         fi
13149
13150         rm -f $DIR/$tfile
13151         echo "Dirty pages flushed via fsync on EROFS"
13152         return 0
13153 }
13154 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13155
13156 # continue to use small resend count to reduce test_118* time (b=14842)
13157 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13158
13159 test_118d()
13160 {
13161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13162         remote_ost_nodsh && skip "remote OST with nodsh"
13163
13164         reset_async
13165
13166         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13167         set_nodes_failloc "$(osts_nodes)" 0x214
13168         # multiop should block due to fsync until pages are written
13169         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13170         MULTIPID=$!
13171         sleep 1
13172
13173         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13174                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13175         fi
13176
13177         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13178                     grep -c writeback)
13179         if [[ $WRITEBACK -eq 0 ]]; then
13180                 error "No page in writeback, writeback=$WRITEBACK"
13181         fi
13182
13183         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13184         set_nodes_failloc "$(osts_nodes)" 0
13185
13186         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13187         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13188                     grep -c writeback)
13189         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13190                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13191         fi
13192
13193         rm -f $DIR/$tfile
13194         echo "Dirty pages gaurenteed flushed via fsync"
13195         return 0
13196 }
13197 run_test 118d "Fsync validation inject a delay of the bulk =========="
13198
13199 test_118f() {
13200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13201
13202         reset_async
13203
13204         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13205         lctl set_param fail_loc=0x8000040a
13206
13207         # Should simulate EINVAL error which is fatal
13208         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13209         RC=$?
13210         if [[ $RC -eq 0 ]]; then
13211                 error "Must return error due to dropped pages, rc=$RC"
13212         fi
13213
13214         lctl set_param fail_loc=0x0
13215
13216         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13217         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13218         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13219                     grep -c writeback)
13220         if [[ $LOCKED -ne 0 ]]; then
13221                 error "Locked pages remain in cache, locked=$LOCKED"
13222         fi
13223
13224         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13225                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13226         fi
13227
13228         rm -f $DIR/$tfile
13229         echo "No pages locked after fsync"
13230
13231         reset_async
13232         return 0
13233 }
13234 run_test 118f "Simulate unrecoverable OSC side error =========="
13235
13236 test_118g() {
13237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13238
13239         reset_async
13240
13241         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13242         lctl set_param fail_loc=0x406
13243
13244         # simulate local -ENOMEM
13245         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13246         RC=$?
13247
13248         lctl set_param fail_loc=0
13249         if [[ $RC -eq 0 ]]; then
13250                 error "Must return error due to dropped pages, rc=$RC"
13251         fi
13252
13253         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13254         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13255         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13256                         grep -c writeback)
13257         if [[ $LOCKED -ne 0 ]]; then
13258                 error "Locked pages remain in cache, locked=$LOCKED"
13259         fi
13260
13261         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13262                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13263         fi
13264
13265         rm -f $DIR/$tfile
13266         echo "No pages locked after fsync"
13267
13268         reset_async
13269         return 0
13270 }
13271 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13272
13273 test_118h() {
13274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13275         remote_ost_nodsh && skip "remote OST with nodsh"
13276
13277         reset_async
13278
13279         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13280         set_nodes_failloc "$(osts_nodes)" 0x20e
13281         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13282         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13283         RC=$?
13284
13285         set_nodes_failloc "$(osts_nodes)" 0
13286         if [[ $RC -eq 0 ]]; then
13287                 error "Must return error due to dropped pages, rc=$RC"
13288         fi
13289
13290         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13291         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13292         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13293                     grep -c writeback)
13294         if [[ $LOCKED -ne 0 ]]; then
13295                 error "Locked pages remain in cache, locked=$LOCKED"
13296         fi
13297
13298         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13299                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13300         fi
13301
13302         rm -f $DIR/$tfile
13303         echo "No pages locked after fsync"
13304
13305         return 0
13306 }
13307 run_test 118h "Verify timeout in handling recoverables errors  =========="
13308
13309 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13310
13311 test_118i() {
13312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13313         remote_ost_nodsh && skip "remote OST with nodsh"
13314
13315         reset_async
13316
13317         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13318         set_nodes_failloc "$(osts_nodes)" 0x20e
13319
13320         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13321         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13322         PID=$!
13323         sleep 5
13324         set_nodes_failloc "$(osts_nodes)" 0
13325
13326         wait $PID
13327         RC=$?
13328         if [[ $RC -ne 0 ]]; then
13329                 error "got error, but should be not, rc=$RC"
13330         fi
13331
13332         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13333         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13334         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13335         if [[ $LOCKED -ne 0 ]]; then
13336                 error "Locked pages remain in cache, locked=$LOCKED"
13337         fi
13338
13339         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13340                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13341         fi
13342
13343         rm -f $DIR/$tfile
13344         echo "No pages locked after fsync"
13345
13346         return 0
13347 }
13348 run_test 118i "Fix error before timeout in recoverable error  =========="
13349
13350 [ "$SLOW" = "no" ] && set_resend_count 4
13351
13352 test_118j() {
13353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13354         remote_ost_nodsh && skip "remote OST with nodsh"
13355
13356         reset_async
13357
13358         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13359         set_nodes_failloc "$(osts_nodes)" 0x220
13360
13361         # return -EIO from OST
13362         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13363         RC=$?
13364         set_nodes_failloc "$(osts_nodes)" 0x0
13365         if [[ $RC -eq 0 ]]; then
13366                 error "Must return error due to dropped pages, rc=$RC"
13367         fi
13368
13369         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13370         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13371         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13372         if [[ $LOCKED -ne 0 ]]; then
13373                 error "Locked pages remain in cache, locked=$LOCKED"
13374         fi
13375
13376         # in recoverable error on OST we want resend and stay until it finished
13377         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13378                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13379         fi
13380
13381         rm -f $DIR/$tfile
13382         echo "No pages locked after fsync"
13383
13384         return 0
13385 }
13386 run_test 118j "Simulate unrecoverable OST side error =========="
13387
13388 test_118k()
13389 {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         remote_ost_nodsh && skip "remote OSTs with nodsh"
13392
13393         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13394         set_nodes_failloc "$(osts_nodes)" 0x20e
13395         test_mkdir $DIR/$tdir
13396
13397         for ((i=0;i<10;i++)); do
13398                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13399                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13400                 SLEEPPID=$!
13401                 sleep 0.500s
13402                 kill $SLEEPPID
13403                 wait $SLEEPPID
13404         done
13405
13406         set_nodes_failloc "$(osts_nodes)" 0
13407         rm -rf $DIR/$tdir
13408 }
13409 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13410
13411 test_118l() # LU-646
13412 {
13413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13414
13415         test_mkdir $DIR/$tdir
13416         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13417         rm -rf $DIR/$tdir
13418 }
13419 run_test 118l "fsync dir"
13420
13421 test_118m() # LU-3066
13422 {
13423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13424
13425         test_mkdir $DIR/$tdir
13426         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13427         rm -rf $DIR/$tdir
13428 }
13429 run_test 118m "fdatasync dir ========="
13430
13431 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13432
13433 test_118n()
13434 {
13435         local begin
13436         local end
13437
13438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13439         remote_ost_nodsh && skip "remote OSTs with nodsh"
13440
13441         # Sleep to avoid a cached response.
13442         #define OBD_STATFS_CACHE_SECONDS 1
13443         sleep 2
13444
13445         # Inject a 10 second delay in the OST_STATFS handler.
13446         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13447         set_nodes_failloc "$(osts_nodes)" 0x242
13448
13449         begin=$SECONDS
13450         stat --file-system $MOUNT > /dev/null
13451         end=$SECONDS
13452
13453         set_nodes_failloc "$(osts_nodes)" 0
13454
13455         if ((end - begin > 20)); then
13456             error "statfs took $((end - begin)) seconds, expected 10"
13457         fi
13458 }
13459 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13460
13461 test_119a() # bug 11737
13462 {
13463         BSIZE=$((512 * 1024))
13464         directio write $DIR/$tfile 0 1 $BSIZE
13465         # We ask to read two blocks, which is more than a file size.
13466         # directio will indicate an error when requested and actual
13467         # sizes aren't equeal (a normal situation in this case) and
13468         # print actual read amount.
13469         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13470         if [ "$NOB" != "$BSIZE" ]; then
13471                 error "read $NOB bytes instead of $BSIZE"
13472         fi
13473         rm -f $DIR/$tfile
13474 }
13475 run_test 119a "Short directIO read must return actual read amount"
13476
13477 test_119b() # bug 11737
13478 {
13479         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13480
13481         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13482         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13483         sync
13484         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13485                 error "direct read failed"
13486         rm -f $DIR/$tfile
13487 }
13488 run_test 119b "Sparse directIO read must return actual read amount"
13489
13490 test_119c() # bug 13099
13491 {
13492         BSIZE=1048576
13493         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13494         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13495         rm -f $DIR/$tfile
13496 }
13497 run_test 119c "Testing for direct read hitting hole"
13498
13499 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13500 # Maloo test history
13501
13502 test_119e()
13503 {
13504         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13505
13506         local stripe_size=$((1024 * 1024)) #1 MiB
13507         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13508         local file_size=$((25 * stripe_size))
13509         local bsizes
13510
13511         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13512         stack_trap "rm -f $DIR/$tfile*"
13513
13514         # Just a bit bigger than the largest size in the test set below
13515         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13516                 error "buffered i/o to create file failed"
13517
13518         if zfs_or_rotational; then
13519                 # DIO on ZFS can take up to 2 seconds per IO
13520                 # rotational is better, but still slow.
13521                 # Limit testing on those media to larger sizes
13522                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13523         else
13524                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13525                         $((stripe_size * 4))"
13526         fi
13527
13528         for bs in $bsizes; do
13529                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13530                 echo "Read/write with DIO at size $bs"
13531                 # Read and write with DIO from source to dest
13532                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13533                         iflag=direct oflag=direct ||
13534                         error "dio failed"
13535
13536                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13537                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13538                         error "size incorrect, file copy read/write bsize: $bs"
13539                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13540                         error "files differ, bsize $bs"
13541                 rm -f $DIR/$tfile.2
13542         done
13543 }
13544 run_test 119e "Basic tests of dio read and write at various sizes"
13545
13546 test_119f()
13547 {
13548         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13549
13550         local stripe_size=$((1024 * 1024)) #1 MiB
13551         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13552         local file_size=$((25 * stripe_size))
13553         local bsizes
13554
13555         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13556         stack_trap "rm -f $DIR/$tfile*"
13557
13558         # Just a bit bigger than the largest size in the test set below
13559         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13560                 error "buffered i/o to create file failed"
13561
13562         if zfs_or_rotational; then
13563                 # DIO on ZFS can take up to 2 seconds per IO
13564                 # rotational is better, but still slow.
13565                 # Limit testing on those media to larger sizes
13566                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13567         else
13568                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13569                         $((stripe_size * 4))"
13570         fi
13571
13572         for bs in $bsizes; do
13573                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13574                 # Read and write with DIO from source to dest in two
13575                 # threads - should give correct copy of file
13576
13577                 echo "bs: $bs"
13578                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13579                         oflag=direct conv=notrunc &
13580                 pid_dio1=$!
13581                 # Note block size is different here for a more interesting race
13582                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13583                         iflag=direct oflag=direct conv=notrunc &
13584                 pid_dio2=$!
13585                 wait $pid_dio1
13586                 rc1=$?
13587                 wait $pid_dio2
13588                 rc2=$?
13589                 if (( rc1 != 0 )); then
13590                         error "dio copy 1 w/bsize $bs failed: $rc1"
13591                 fi
13592                 if (( rc2 != 0 )); then
13593                         error "dio copy 2 w/bsize $bs failed: $rc2"
13594                 fi
13595
13596
13597                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13598                         error "size incorrect, file copy read/write bsize: $bs"
13599                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13600                         error "files differ, bsize $bs"
13601                 rm -f $DIR/$tfile.2
13602         done
13603 }
13604 run_test 119f "dio vs dio race"
13605
13606 test_119g()
13607 {
13608         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13609
13610         local stripe_size=$((1024 * 1024)) #1 MiB
13611         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13612         local file_size=$((25 * stripe_size))
13613         local bsizes
13614
13615         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13616         stack_trap "rm -f $DIR/$tfile*"
13617
13618         # Just a bit bigger than the largest size in the test set below
13619         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13620                 error "buffered i/o to create file failed"
13621
13622         if zfs_or_rotational; then
13623                 # DIO on ZFS can take up to 2 seconds per IO
13624                 # rotational is better, but still slow.
13625                 # Limit testing on those media to larger sizes
13626                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13627         else
13628                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13629                         $((stripe_size * 4))"
13630         fi
13631
13632         for bs in $bsizes; do
13633                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13634                 echo "bs: $bs"
13635                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13636                         oflag=direct conv=notrunc &
13637                 pid_dio1=$!
13638                 # Buffered I/O with similar but not the same block size
13639                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13640                 pid_bio2=$!
13641                 wait $pid_dio1
13642                 rc1=$?
13643                 wait $pid_bio2
13644                 rc2=$?
13645                 if (( rc1 != 0 )); then
13646                         error "dio copy 1 w/bsize $bs failed: $rc1"
13647                 fi
13648                 if (( rc2 != 0 )); then
13649                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13650                 fi
13651
13652                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13653                         error "size incorrect"
13654                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13655                         error "files differ, bsize $bs"
13656                 rm -f $DIR/$tfile.2
13657         done
13658 }
13659 run_test 119g "dio vs buffered I/O race"
13660
13661 test_120a() {
13662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13663         remote_mds_nodsh && skip "remote MDS with nodsh"
13664         test_mkdir -i0 -c1 $DIR/$tdir
13665         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13666                 skip_env "no early lock cancel on server"
13667
13668         lru_resize_disable mdc
13669         lru_resize_disable osc
13670         cancel_lru_locks mdc
13671         # asynchronous object destroy at MDT could cause bl ast to client
13672         cancel_lru_locks osc
13673
13674         stat $DIR/$tdir > /dev/null
13675         can1=$(do_facet mds1 \
13676                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13677                awk '/ldlm_cancel/ {print $2}')
13678         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13679                awk '/ldlm_bl_callback/ {print $2}')
13680         test_mkdir -i0 -c1 $DIR/$tdir/d1
13681         can2=$(do_facet mds1 \
13682                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13683                awk '/ldlm_cancel/ {print $2}')
13684         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13685                awk '/ldlm_bl_callback/ {print $2}')
13686         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13687         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13688         lru_resize_enable mdc
13689         lru_resize_enable osc
13690 }
13691 run_test 120a "Early Lock Cancel: mkdir test"
13692
13693 test_120b() {
13694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13695         remote_mds_nodsh && skip "remote MDS with nodsh"
13696         test_mkdir $DIR/$tdir
13697         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13698                 skip_env "no early lock cancel on server"
13699
13700         lru_resize_disable mdc
13701         lru_resize_disable osc
13702         cancel_lru_locks mdc
13703         stat $DIR/$tdir > /dev/null
13704         can1=$(do_facet $SINGLEMDS \
13705                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13706                awk '/ldlm_cancel/ {print $2}')
13707         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13708                awk '/ldlm_bl_callback/ {print $2}')
13709         touch $DIR/$tdir/f1
13710         can2=$(do_facet $SINGLEMDS \
13711                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13712                awk '/ldlm_cancel/ {print $2}')
13713         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13714                awk '/ldlm_bl_callback/ {print $2}')
13715         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13716         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13717         lru_resize_enable mdc
13718         lru_resize_enable osc
13719 }
13720 run_test 120b "Early Lock Cancel: create test"
13721
13722 test_120c() {
13723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13724         remote_mds_nodsh && skip "remote MDS with nodsh"
13725         test_mkdir -i0 -c1 $DIR/$tdir
13726         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13727                 skip "no early lock cancel on server"
13728
13729         lru_resize_disable mdc
13730         lru_resize_disable osc
13731         test_mkdir -i0 -c1 $DIR/$tdir/d1
13732         test_mkdir -i0 -c1 $DIR/$tdir/d2
13733         touch $DIR/$tdir/d1/f1
13734         cancel_lru_locks mdc
13735         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13736         can1=$(do_facet mds1 \
13737                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13738                awk '/ldlm_cancel/ {print $2}')
13739         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13740                awk '/ldlm_bl_callback/ {print $2}')
13741         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13742         can2=$(do_facet mds1 \
13743                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13744                awk '/ldlm_cancel/ {print $2}')
13745         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13746                awk '/ldlm_bl_callback/ {print $2}')
13747         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13748         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13749         lru_resize_enable mdc
13750         lru_resize_enable osc
13751 }
13752 run_test 120c "Early Lock Cancel: link test"
13753
13754 test_120d() {
13755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13756         remote_mds_nodsh && skip "remote MDS with nodsh"
13757         test_mkdir -i0 -c1 $DIR/$tdir
13758         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13759                 skip_env "no early lock cancel on server"
13760
13761         lru_resize_disable mdc
13762         lru_resize_disable osc
13763         touch $DIR/$tdir
13764         cancel_lru_locks mdc
13765         stat $DIR/$tdir > /dev/null
13766         can1=$(do_facet mds1 \
13767                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13768                awk '/ldlm_cancel/ {print $2}')
13769         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13770                awk '/ldlm_bl_callback/ {print $2}')
13771         chmod a+x $DIR/$tdir
13772         can2=$(do_facet mds1 \
13773                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13774                awk '/ldlm_cancel/ {print $2}')
13775         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13776                awk '/ldlm_bl_callback/ {print $2}')
13777         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13778         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13779         lru_resize_enable mdc
13780         lru_resize_enable osc
13781 }
13782 run_test 120d "Early Lock Cancel: setattr test"
13783
13784 test_120e() {
13785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13786         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13787                 skip_env "no early lock cancel on server"
13788         remote_mds_nodsh && skip "remote MDS with nodsh"
13789
13790         local dlmtrace_set=false
13791
13792         test_mkdir -i0 -c1 $DIR/$tdir
13793         lru_resize_disable mdc
13794         lru_resize_disable osc
13795         ! $LCTL get_param debug | grep -q dlmtrace &&
13796                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13797         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13798         cancel_lru_locks mdc
13799         cancel_lru_locks osc
13800         dd if=$DIR/$tdir/f1 of=/dev/null
13801         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13802         # XXX client can not do early lock cancel of OST lock
13803         # during unlink (LU-4206), so cancel osc lock now.
13804         sleep 2
13805         cancel_lru_locks osc
13806         can1=$(do_facet mds1 \
13807                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13808                awk '/ldlm_cancel/ {print $2}')
13809         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13810                awk '/ldlm_bl_callback/ {print $2}')
13811         unlink $DIR/$tdir/f1
13812         sleep 5
13813         can2=$(do_facet mds1 \
13814                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13815                awk '/ldlm_cancel/ {print $2}')
13816         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13817                awk '/ldlm_bl_callback/ {print $2}')
13818         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13819                 $LCTL dk $TMP/cancel.debug.txt
13820         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13821                 $LCTL dk $TMP/blocking.debug.txt
13822         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13823         lru_resize_enable mdc
13824         lru_resize_enable osc
13825 }
13826 run_test 120e "Early Lock Cancel: unlink test"
13827
13828 test_120f() {
13829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13830         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13831                 skip_env "no early lock cancel on server"
13832         remote_mds_nodsh && skip "remote MDS with nodsh"
13833
13834         test_mkdir -i0 -c1 $DIR/$tdir
13835         lru_resize_disable mdc
13836         lru_resize_disable osc
13837         test_mkdir -i0 -c1 $DIR/$tdir/d1
13838         test_mkdir -i0 -c1 $DIR/$tdir/d2
13839         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13840         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13841         cancel_lru_locks mdc
13842         cancel_lru_locks osc
13843         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13844         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13845         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13846         # XXX client can not do early lock cancel of OST lock
13847         # during rename (LU-4206), so cancel osc lock now.
13848         sleep 2
13849         cancel_lru_locks osc
13850         can1=$(do_facet mds1 \
13851                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13852                awk '/ldlm_cancel/ {print $2}')
13853         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13854                awk '/ldlm_bl_callback/ {print $2}')
13855         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13856         sleep 5
13857         can2=$(do_facet mds1 \
13858                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13859                awk '/ldlm_cancel/ {print $2}')
13860         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13861                awk '/ldlm_bl_callback/ {print $2}')
13862         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13863         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13864         lru_resize_enable mdc
13865         lru_resize_enable osc
13866 }
13867 run_test 120f "Early Lock Cancel: rename test"
13868
13869 test_120g() {
13870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13871         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13872                 skip_env "no early lock cancel on server"
13873         remote_mds_nodsh && skip "remote MDS with nodsh"
13874
13875         lru_resize_disable mdc
13876         lru_resize_disable osc
13877         count=10000
13878         echo create $count files
13879         test_mkdir $DIR/$tdir
13880         cancel_lru_locks mdc
13881         cancel_lru_locks osc
13882         t0=$(date +%s)
13883
13884         can0=$(do_facet $SINGLEMDS \
13885                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13886                awk '/ldlm_cancel/ {print $2}')
13887         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13888                awk '/ldlm_bl_callback/ {print $2}')
13889         createmany -o $DIR/$tdir/f $count
13890         sync
13891         can1=$(do_facet $SINGLEMDS \
13892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13893                awk '/ldlm_cancel/ {print $2}')
13894         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13895                awk '/ldlm_bl_callback/ {print $2}')
13896         t1=$(date +%s)
13897         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13898         echo rm $count files
13899         rm -r $DIR/$tdir
13900         sync
13901         can2=$(do_facet $SINGLEMDS \
13902                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13903                awk '/ldlm_cancel/ {print $2}')
13904         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13905                awk '/ldlm_bl_callback/ {print $2}')
13906         t2=$(date +%s)
13907         echo total: $count removes in $((t2-t1))
13908         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13909         sleep 2
13910         # wait for commitment of removal
13911         lru_resize_enable mdc
13912         lru_resize_enable osc
13913 }
13914 run_test 120g "Early Lock Cancel: performance test"
13915
13916 test_121() { #bug #10589
13917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13918
13919         rm -rf $DIR/$tfile
13920         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13921 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13922         lctl set_param fail_loc=0x310
13923         cancel_lru_locks osc > /dev/null
13924         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13925         lctl set_param fail_loc=0
13926         [[ $reads -eq $writes ]] ||
13927                 error "read $reads blocks, must be $writes blocks"
13928 }
13929 run_test 121 "read cancel race ========="
13930
13931 test_123a_base() { # was test 123, statahead(bug 11401)
13932         local lsx="$1"
13933
13934         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13935
13936         SLOWOK=0
13937         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13938                 log "testing UP system. Performance may be lower than expected."
13939                 SLOWOK=1
13940         fi
13941         running_in_vm && SLOWOK=1
13942
13943         $LCTL set_param mdc.*.batch_stats=0
13944
13945         rm -rf $DIR/$tdir
13946         test_mkdir $DIR/$tdir
13947         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13948         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13949         MULT=10
13950         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13951                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13952
13953                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13954                 lctl set_param -n llite.*.statahead_max 0
13955                 lctl get_param llite.*.statahead_max
13956                 cancel_lru_locks mdc
13957                 cancel_lru_locks osc
13958                 stime=$(date +%s)
13959                 time $lsx $DIR/$tdir | wc -l
13960                 etime=$(date +%s)
13961                 delta=$((etime - stime))
13962                 log "$lsx $i files without statahead: $delta sec"
13963                 lctl set_param llite.*.statahead_max=$max
13964
13965                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13966                          awk '/statahead.wrong:/ { print $NF }')
13967                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13968                 cancel_lru_locks mdc
13969                 cancel_lru_locks osc
13970                 stime=$(date +%s)
13971                 time $lsx $DIR/$tdir | wc -l
13972                 etime=$(date +%s)
13973                 delta_sa=$((etime - stime))
13974                 log "$lsx $i files with statahead: $delta_sa sec"
13975                 lctl get_param -n llite.*.statahead_stats
13976                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13977                          awk '/statahead.wrong:/ { print $NF }')
13978
13979                 [[ $swrong -lt $ewrong ]] &&
13980                         log "statahead was stopped, maybe too many locks held!"
13981                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13982
13983                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13984                         max=$(lctl get_param -n llite.*.statahead_max |
13985                                 head -n 1)
13986                         lctl set_param -n llite.*.statahead_max 0
13987                         lctl get_param llite.*.statahead_max
13988                         cancel_lru_locks mdc
13989                         cancel_lru_locks osc
13990                         stime=$(date +%s)
13991                         time $lsx $DIR/$tdir | wc -l
13992                         etime=$(date +%s)
13993                         delta=$((etime - stime))
13994                         log "$lsx $i files again without statahead: $delta sec"
13995                         lctl set_param llite.*.statahead_max=$max
13996                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13997                                 if [ $SLOWOK -eq 0 ]; then
13998                                         error "$lsx $i files is slower with statahead!"
13999                                 else
14000                                         log "$lsx $i files is slower with statahead!"
14001                                 fi
14002                                 break
14003                         fi
14004                 fi
14005
14006                 [ $delta -gt 20 ] && break
14007                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14008                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14009         done
14010         log "$lsx done"
14011
14012         stime=$(date +%s)
14013         rm -r $DIR/$tdir
14014         sync
14015         etime=$(date +%s)
14016         delta=$((etime - stime))
14017         log "rm -r $DIR/$tdir/: $delta seconds"
14018         log "rm done"
14019         lctl get_param -n llite.*.statahead_stats
14020         $LCTL get_param mdc.*.batch_stats
14021 }
14022
14023 test_123aa() {
14024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14025
14026         test_123a_base "ls -l"
14027 }
14028 run_test 123aa "verify statahead work"
14029
14030 test_123ab() {
14031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14032
14033         statx_supported || skip_env "Test must be statx() syscall supported"
14034
14035         test_123a_base "$STATX -l"
14036 }
14037 run_test 123ab "verify statahead work by using statx"
14038
14039 test_123ac() {
14040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14041
14042         statx_supported || skip_env "Test must be statx() syscall supported"
14043
14044         local rpcs_before
14045         local rpcs_after
14046         local agl_before
14047         local agl_after
14048
14049         cancel_lru_locks $OSC
14050         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14051         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14052                      awk '/agl.total:/ { print $NF }')
14053         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14054         test_123a_base "$STATX --cached=always -D"
14055         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14056                     awk '/agl.total:/ { print $NF }')
14057         [ $agl_before -eq $agl_after ] ||
14058                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14059         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14060         [ $rpcs_after -eq $rpcs_before ] ||
14061                 error "$STATX should not send glimpse RPCs to $OSC"
14062 }
14063 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14064
14065 test_batch_statahead() {
14066         local max=$1
14067         local batch_max=$2
14068         local num=10000
14069         local batch_rpcs
14070         local unbatch_rpcs
14071         local hit_total
14072
14073         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14074         $LCTL set_param mdc.*.batch_stats=0
14075         $LCTL set_param llite.*.statahead_max=$max
14076         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14077         # Verify that batched statahead is faster than one without statahead
14078         test_123a_base "ls -l"
14079
14080         stack_trap "rm -rf $DIR/$tdir" EXIT
14081         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14082         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14083
14084         # unbatched statahead
14085         $LCTL set_param llite.*.statahead_batch_max=0
14086         $LCTL set_param llite.*.statahead_stats=clear
14087         $LCTL set_param mdc.*.stats=clear
14088         cancel_lru_locks mdc
14089         cancel_lru_locks osc
14090         time ls -l $DIR/$tdir | wc -l
14091         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14092         sleep 2
14093         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14094                     awk '/hit.total:/ { print $NF }')
14095         # hit ratio should be larger than 75% (7500).
14096         (( $hit_total > 7500 )) ||
14097                 error "unbatched statahead hit count ($hit_total) is too low"
14098
14099         # batched statahead
14100         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14101         $LCTL set_param llite.*.statahead_stats=clear
14102         $LCTL set_param mdc.*.batch_stats=clear
14103         $LCTL set_param mdc.*.stats=clear
14104         cancel_lru_locks mdc
14105         cancel_lru_locks osc
14106         time ls -l $DIR/$tdir | wc -l
14107         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14108         # wait for statahead thread to quit and update statahead stats
14109         sleep 2
14110         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14111                     awk '/hit.total:/ { print $NF }')
14112         # hit ratio should be larger than 75% (7500).
14113         (( $hit_total > 7500 )) ||
14114                 error "batched statahead hit count ($hit_total) is too low"
14115
14116         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14117         (( $unbatch_rpcs > $batch_rpcs )) ||
14118                 error "batched statahead does not reduce RPC count"
14119         $LCTL get_param mdc.*.batch_stats
14120 }
14121
14122 test_123ad() {
14123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14124
14125         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14126                 skip "Need server version at least 2.15.53"
14127
14128         local max
14129         local batch_max
14130
14131         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14132         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14133
14134         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14135         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14136
14137         test_batch_statahead 32 32
14138         test_batch_statahead 2048 256
14139 }
14140 run_test 123ad "Verify batching statahead works correctly"
14141
14142 test_123b () { # statahead(bug 15027)
14143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14144
14145         test_mkdir $DIR/$tdir
14146         createmany -o $DIR/$tdir/$tfile-%d 1000
14147
14148         cancel_lru_locks mdc
14149         cancel_lru_locks osc
14150
14151 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14152         lctl set_param fail_loc=0x80000803
14153         ls -lR $DIR/$tdir > /dev/null
14154         log "ls done"
14155         lctl set_param fail_loc=0x0
14156         lctl get_param -n llite.*.statahead_stats
14157         rm -r $DIR/$tdir
14158         sync
14159
14160 }
14161 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14162
14163 test_123c() {
14164         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14165
14166         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14167         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14168         touch $DIR/$tdir.1/{1..3}
14169         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14170
14171         remount_client $MOUNT
14172
14173         $MULTIOP $DIR/$tdir.0 Q
14174
14175         # let statahead to complete
14176         ls -l $DIR/$tdir.0 > /dev/null
14177
14178         testid=$(echo $TESTNAME | tr '_' ' ')
14179         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14180                 error "statahead warning" || true
14181 }
14182 run_test 123c "Can not initialize inode warning on DNE statahead"
14183
14184 test_123d() {
14185         local num=100
14186         local swrong
14187         local ewrong
14188
14189         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14190         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14191                 error "setdirstripe $DIR/$tdir failed"
14192         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14193         remount_client $MOUNT
14194         $LCTL get_param llite.*.statahead_max
14195         $LCTL set_param llite.*.statahead_stats=0 ||
14196                 error "clear statahead_stats failed"
14197         swrong=$(lctl get_param -n llite.*.statahead_stats |
14198                  awk '/statahead.wrong:/ { print $NF }')
14199         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14200         # wait for statahead thread finished to update hit/miss stats.
14201         sleep 1
14202         $LCTL get_param -n llite.*.statahead_stats
14203         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14204                  awk '/statahead.wrong:/ { print $NF }')
14205         (( $swrong == $ewrong )) ||
14206                 log "statahead was stopped, maybe too many locks held!"
14207 }
14208 run_test 123d "Statahead on striped directories works correctly"
14209
14210 test_123e() {
14211         local max
14212         local batch_max
14213         local dir=$DIR/$tdir
14214
14215         mkdir $dir || error "mkdir $dir failed"
14216         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14217         stack_trap "rm -rf $dir"
14218
14219         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14220
14221         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14222         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14223         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14224         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14225
14226         $LCTL set_param llite.*.statahead_max=2048
14227         $LCTL set_param llite.*.statahead_batch_max=1024
14228
14229         ls -l $dir
14230         $LCTL get_param mdc.*.batch_stats
14231         $LCTL get_param llite.*.statahead_*
14232 }
14233 run_test 123e "statahead with large wide striping"
14234
14235 test_123f() {
14236         local max
14237         local batch_max
14238         local dir=$DIR/$tdir
14239
14240         mkdir $dir || error "mkdir $dir failed"
14241         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14242         stack_trap "rm -rf $dir"
14243
14244         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14245
14246         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14247         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14248
14249         $LCTL set_param llite.*.statahead_max=64
14250         $LCTL set_param llite.*.statahead_batch_max=64
14251
14252         ls -l $dir
14253         lctl get_param mdc.*.batch_stats
14254         lctl get_param llite.*.statahead_*
14255
14256         $LCTL set_param llite.*.statahead_max=$max
14257         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14258 }
14259 run_test 123f "Retry mechanism with large wide striping files"
14260
14261 test_124a() {
14262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14263         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14264                 skip_env "no lru resize on server"
14265
14266         local NR=2000
14267
14268         test_mkdir $DIR/$tdir
14269
14270         log "create $NR files at $DIR/$tdir"
14271         createmany -o $DIR/$tdir/f $NR ||
14272                 error "failed to create $NR files in $DIR/$tdir"
14273
14274         cancel_lru_locks mdc
14275         ls -l $DIR/$tdir > /dev/null
14276
14277         local NSDIR=""
14278         local LRU_SIZE=0
14279         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14280                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14281                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14282                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14283                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14284                         log "NSDIR=$NSDIR"
14285                         log "NS=$(basename $NSDIR)"
14286                         break
14287                 fi
14288         done
14289
14290         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14291                 skip "Not enough cached locks created!"
14292         fi
14293         log "LRU=$LRU_SIZE"
14294
14295         local SLEEP=30
14296
14297         # We know that lru resize allows one client to hold $LIMIT locks
14298         # for 10h. After that locks begin to be killed by client.
14299         local MAX_HRS=10
14300         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14301         log "LIMIT=$LIMIT"
14302         if [ $LIMIT -lt $LRU_SIZE ]; then
14303                 skip "Limit is too small $LIMIT"
14304         fi
14305
14306         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14307         # killing locks. Some time was spent for creating locks. This means
14308         # that up to the moment of sleep finish we must have killed some of
14309         # them (10-100 locks). This depends on how fast ther were created.
14310         # Many of them were touched in almost the same moment and thus will
14311         # be killed in groups.
14312         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14313
14314         # Use $LRU_SIZE_B here to take into account real number of locks
14315         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14316         local LRU_SIZE_B=$LRU_SIZE
14317         log "LVF=$LVF"
14318         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14319         log "OLD_LVF=$OLD_LVF"
14320         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14321
14322         # Let's make sure that we really have some margin. Client checks
14323         # cached locks every 10 sec.
14324         SLEEP=$((SLEEP+20))
14325         log "Sleep ${SLEEP} sec"
14326         local SEC=0
14327         while ((SEC<$SLEEP)); do
14328                 echo -n "..."
14329                 sleep 5
14330                 SEC=$((SEC+5))
14331                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14332                 echo -n "$LRU_SIZE"
14333         done
14334         echo ""
14335         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14336         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14337
14338         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14339                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14340                 unlinkmany $DIR/$tdir/f $NR
14341                 return
14342         }
14343
14344         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14345         log "unlink $NR files at $DIR/$tdir"
14346         unlinkmany $DIR/$tdir/f $NR
14347 }
14348 run_test 124a "lru resize ======================================="
14349
14350 get_max_pool_limit()
14351 {
14352         local limit=$($LCTL get_param \
14353                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14354         local max=0
14355         for l in $limit; do
14356                 if [[ $l -gt $max ]]; then
14357                         max=$l
14358                 fi
14359         done
14360         echo $max
14361 }
14362
14363 test_124b() {
14364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14365         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14366                 skip_env "no lru resize on server"
14367
14368         LIMIT=$(get_max_pool_limit)
14369
14370         NR=$(($(default_lru_size)*20))
14371         if [[ $NR -gt $LIMIT ]]; then
14372                 log "Limit lock number by $LIMIT locks"
14373                 NR=$LIMIT
14374         fi
14375
14376         IFree=$(mdsrate_inodes_available)
14377         if [ $IFree -lt $NR ]; then
14378                 log "Limit lock number by $IFree inodes"
14379                 NR=$IFree
14380         fi
14381
14382         lru_resize_disable mdc
14383         test_mkdir -p $DIR/$tdir/disable_lru_resize
14384
14385         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14386         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14387         cancel_lru_locks mdc
14388         stime=`date +%s`
14389         PID=""
14390         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14391         PID="$PID $!"
14392         sleep 2
14393         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14394         PID="$PID $!"
14395         sleep 2
14396         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14397         PID="$PID $!"
14398         wait $PID
14399         etime=`date +%s`
14400         nolruresize_delta=$((etime-stime))
14401         log "ls -la time: $nolruresize_delta seconds"
14402         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14403         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14404
14405         lru_resize_enable mdc
14406         test_mkdir -p $DIR/$tdir/enable_lru_resize
14407
14408         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14409         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14410         cancel_lru_locks mdc
14411         stime=`date +%s`
14412         PID=""
14413         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14414         PID="$PID $!"
14415         sleep 2
14416         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14417         PID="$PID $!"
14418         sleep 2
14419         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14420         PID="$PID $!"
14421         wait $PID
14422         etime=`date +%s`
14423         lruresize_delta=$((etime-stime))
14424         log "ls -la time: $lruresize_delta seconds"
14425         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14426
14427         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14428                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14429         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14430                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14431         else
14432                 log "lru resize performs the same with no lru resize"
14433         fi
14434         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14435 }
14436 run_test 124b "lru resize (performance test) ======================="
14437
14438 test_124c() {
14439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14440         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14441                 skip_env "no lru resize on server"
14442
14443         # cache ununsed locks on client
14444         local nr=100
14445         cancel_lru_locks mdc
14446         test_mkdir $DIR/$tdir
14447         createmany -o $DIR/$tdir/f $nr ||
14448                 error "failed to create $nr files in $DIR/$tdir"
14449         ls -l $DIR/$tdir > /dev/null
14450
14451         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14452         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14453         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14454         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14455         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14456
14457         # set lru_max_age to 1 sec
14458         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14459         echo "sleep $((recalc_p * 2)) seconds..."
14460         sleep $((recalc_p * 2))
14461
14462         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14463         # restore lru_max_age
14464         $LCTL set_param -n $nsdir.lru_max_age $max_age
14465         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14466         unlinkmany $DIR/$tdir/f $nr
14467 }
14468 run_test 124c "LRUR cancel very aged locks"
14469
14470 test_124d() {
14471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14472         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14473                 skip_env "no lru resize on server"
14474
14475         # cache ununsed locks on client
14476         local nr=100
14477
14478         lru_resize_disable mdc
14479         stack_trap "lru_resize_enable mdc" EXIT
14480
14481         cancel_lru_locks mdc
14482
14483         # asynchronous object destroy at MDT could cause bl ast to client
14484         test_mkdir $DIR/$tdir
14485         createmany -o $DIR/$tdir/f $nr ||
14486                 error "failed to create $nr files in $DIR/$tdir"
14487         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14488
14489         ls -l $DIR/$tdir > /dev/null
14490
14491         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14492         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14493         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14494         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14495
14496         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14497
14498         # set lru_max_age to 1 sec
14499         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14500         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14501
14502         echo "sleep $((recalc_p * 2)) seconds..."
14503         sleep $((recalc_p * 2))
14504
14505         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14506
14507         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14508 }
14509 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14510
14511 test_125() { # 13358
14512         $LCTL get_param -n llite.*.client_type | grep -q local ||
14513                 skip "must run as local client"
14514         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14515                 skip_env "must have acl enabled"
14516         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14517         id $USER0 || skip_env "missing user $USER0"
14518
14519         test_mkdir $DIR/$tdir
14520         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14521         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14522                 error "setfacl $DIR/$tdir failed"
14523         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14524 }
14525 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14526
14527 test_126() { # bug 12829/13455
14528         $GSS && skip_env "must run as gss disabled"
14529         $LCTL get_param -n llite.*.client_type | grep -q local ||
14530                 skip "must run as local client"
14531         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14532
14533         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14534         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14535         rm -f $DIR/$tfile
14536         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14537 }
14538 run_test 126 "check that the fsgid provided by the client is taken into account"
14539
14540 test_127a() { # bug 15521
14541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14542         local name count samp unit min max sum sumsq
14543         local tmpfile=$TMP/$tfile.tmp
14544
14545         # enable stats header if it is disabled
14546         $LCTL set_param enable_stats_header=1
14547
14548         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14549         echo "stats before reset"
14550         stack_trap "rm -f $tmpfile"
14551         local now=$(date +%s)
14552
14553         $LCTL get_param osc.*.stats | tee $tmpfile
14554
14555         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14556         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14557         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14558         local uptime=$(awk '{ print $1 }' /proc/uptime)
14559
14560         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14561         (( ${snapshot_time%\.*} >= $now - 5 &&
14562            ${snapshot_time%\.*} <= $now + 5 )) ||
14563                 error "snapshot_time=$snapshot_time != now=$now"
14564         # elapsed _should_ be from mount, but at least less than uptime
14565         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14566                 error "elapsed=$elapsed > uptime=$uptime"
14567         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14568            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14569                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14570
14571         $LCTL set_param osc.*.stats=0
14572         local reset=$(date +%s)
14573         local fsize=$((2048 * 1024))
14574
14575         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14576         cancel_lru_locks osc
14577         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14578
14579         now=$(date +%s)
14580         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14581         while read name count samp unit min max sum sumsq; do
14582                 [[ "$samp" == "samples" ]] || continue
14583
14584                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14585                 [ ! $min ] && error "Missing min value for $name proc entry"
14586                 eval $name=$count || error "Wrong proc format"
14587
14588                 case $name in
14589                 read_bytes|write_bytes)
14590                         [[ "$unit" =~ "bytes" ]] ||
14591                                 error "unit is not 'bytes': $unit"
14592                         (( $min >= 4096 )) || error "min is too small: $min"
14593                         (( $min <= $fsize )) || error "min is too big: $min"
14594                         (( $max >= 4096 )) || error "max is too small: $max"
14595                         (( $max <= $fsize )) || error "max is too big: $max"
14596                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14597                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14598                                 error "sumsquare is too small: $sumsq"
14599                         (( $sumsq <= $fsize * $fsize )) ||
14600                                 error "sumsquare is too big: $sumsq"
14601                         ;;
14602                 ost_read|ost_write)
14603                         [[ "$unit" =~ "usec" ]] ||
14604                                 error "unit is not 'usec': $unit"
14605                         ;;
14606                 *)      ;;
14607                 esac
14608         done < $tmpfile
14609
14610         #check that we actually got some stats
14611         [ "$read_bytes" ] || error "Missing read_bytes stats"
14612         [ "$write_bytes" ] || error "Missing write_bytes stats"
14613         [ "$read_bytes" != 0 ] || error "no read done"
14614         [ "$write_bytes" != 0 ] || error "no write done"
14615
14616         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14617         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14618         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14619
14620         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14621         (( ${snapshot_time%\.*} >= $now - 5 &&
14622            ${snapshot_time%\.*} <= $now + 5 )) ||
14623                 error "reset snapshot_time=$snapshot_time != now=$now"
14624         # elapsed should be from time of stats reset
14625         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14626            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14627                 error "reset elapsed=$elapsed > $now - $reset"
14628         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14629            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14630                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14631 }
14632 run_test 127a "verify the client stats are sane"
14633
14634 test_127b() { # bug LU-333
14635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14636         local name count samp unit min max sum sumsq
14637
14638         echo "stats before reset"
14639         $LCTL get_param llite.*.stats
14640         $LCTL set_param llite.*.stats=0
14641
14642         # perform 2 reads and writes so MAX is different from SUM.
14643         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14644         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14645         cancel_lru_locks osc
14646         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14647         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14648
14649         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14650         stack_trap "rm -f $TMP/$tfile.tmp"
14651         while read name count samp unit min max sum sumsq; do
14652                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14653                 eval $name=$count || error "Wrong proc format"
14654
14655                 case $name in
14656                 read_bytes|write_bytes)
14657                         [[ "$unit" =~ "bytes" ]] ||
14658                                 error "unit is not 'bytes': $unit"
14659                         (( $count == 2 )) || error "count is not 2: $count"
14660                         (( $min == $PAGE_SIZE )) ||
14661                                 error "min is not $PAGE_SIZE: $min"
14662                         (( $max == $PAGE_SIZE )) ||
14663                                 error "max is not $PAGE_SIZE: $max"
14664                         (( $sum == $PAGE_SIZE * 2 )) ||
14665                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14666                         ;;
14667                 read|write)
14668                         [[ "$unit" =~ "usec" ]] ||
14669                                 error "unit is not 'usec': $unit"
14670                         ;;
14671                 *)      ;;
14672                 esac
14673         done < $TMP/$tfile.tmp
14674
14675         #check that we actually got some stats
14676         [ "$read_bytes" ] || error "Missing read_bytes stats"
14677         [ "$write_bytes" ] || error "Missing write_bytes stats"
14678         [ "$read_bytes" != 0 ] || error "no read done"
14679         [ "$write_bytes" != 0 ] || error "no write done"
14680 }
14681 run_test 127b "verify the llite client stats are sane"
14682
14683 test_127c() { # LU-12394
14684         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14685         local size
14686         local bsize
14687         local reads
14688         local writes
14689         local count
14690
14691         $LCTL set_param llite.*.extents_stats=1
14692         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14693
14694         # Use two stripes so there is enough space in default config
14695         $LFS setstripe -c 2 $DIR/$tfile
14696
14697         # Extent stats start at 0-4K and go in power of two buckets
14698         # LL_HIST_START = 12 --> 2^12 = 4K
14699         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14700         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14701         # small configs
14702         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14703                 do
14704                 # Write and read, 2x each, second time at a non-zero offset
14705                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14706                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14707                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14708                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14709                 rm -f $DIR/$tfile
14710         done
14711
14712         $LCTL get_param llite.*.extents_stats
14713
14714         count=2
14715         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14716                 do
14717                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14718                                 grep -m 1 $bsize)
14719                 reads=$(echo $bucket | awk '{print $5}')
14720                 writes=$(echo $bucket | awk '{print $9}')
14721                 [ "$reads" -eq $count ] ||
14722                         error "$reads reads in < $bsize bucket, expect $count"
14723                 [ "$writes" -eq $count ] ||
14724                         error "$writes writes in < $bsize bucket, expect $count"
14725         done
14726
14727         # Test mmap write and read
14728         $LCTL set_param llite.*.extents_stats=c
14729         size=512
14730         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14731         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14732         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14733
14734         $LCTL get_param llite.*.extents_stats
14735
14736         count=$(((size*1024) / PAGE_SIZE))
14737
14738         bsize=$((2 * PAGE_SIZE / 1024))K
14739
14740         bucket=$($LCTL get_param -n llite.*.extents_stats |
14741                         grep -m 1 $bsize)
14742         reads=$(echo $bucket | awk '{print $5}')
14743         writes=$(echo $bucket | awk '{print $9}')
14744         # mmap writes fault in the page first, creating an additonal read
14745         [ "$reads" -eq $((2 * count)) ] ||
14746                 error "$reads reads in < $bsize bucket, expect $count"
14747         [ "$writes" -eq $count ] ||
14748                 error "$writes writes in < $bsize bucket, expect $count"
14749 }
14750 run_test 127c "test llite extent stats with regular & mmap i/o"
14751
14752 test_128() { # bug 15212
14753         touch $DIR/$tfile
14754         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14755                 find $DIR/$tfile
14756                 find $DIR/$tfile
14757         EOF
14758
14759         result=$(grep error $TMP/$tfile.log)
14760         rm -f $DIR/$tfile $TMP/$tfile.log
14761         [ -z "$result" ] ||
14762                 error "consecutive find's under interactive lfs failed"
14763 }
14764 run_test 128 "interactive lfs for 2 consecutive find's"
14765
14766 set_dir_limits () {
14767         local mntdev
14768         local canondev
14769         local node
14770
14771         local ldproc=/proc/fs/ldiskfs
14772         local facets=$(get_facets MDS)
14773
14774         for facet in ${facets//,/ }; do
14775                 canondev=$(ldiskfs_canon \
14776                            *.$(convert_facet2label $facet).mntdev $facet)
14777                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14778                         ldproc=/sys/fs/ldiskfs
14779                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14780                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14781         done
14782 }
14783
14784 check_mds_dmesg() {
14785         local facets=$(get_facets MDS)
14786         for facet in ${facets//,/ }; do
14787                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14788         done
14789         return 1
14790 }
14791
14792 test_129() {
14793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14794         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14795                 skip "Need MDS version with at least 2.5.56"
14796         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14797                 skip_env "ldiskfs only test"
14798         fi
14799         remote_mds_nodsh && skip "remote MDS with nodsh"
14800
14801         local ENOSPC=28
14802         local has_warning=false
14803
14804         rm -rf $DIR/$tdir
14805         mkdir -p $DIR/$tdir
14806
14807         # block size of mds1
14808         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14809         set_dir_limits $maxsize $((maxsize * 6 / 8))
14810         stack_trap "set_dir_limits 0 0"
14811         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14812         local dirsize=$(stat -c%s "$DIR/$tdir")
14813         local nfiles=0
14814         while (( $dirsize <= $maxsize )); do
14815                 $MCREATE $DIR/$tdir/file_base_$nfiles
14816                 rc=$?
14817                 # check two errors:
14818                 # ENOSPC for ext4 max_dir_size, which has been used since
14819                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14820                 if (( rc == ENOSPC )); then
14821                         set_dir_limits 0 0
14822                         echo "rc=$rc returned as expected after $nfiles files"
14823
14824                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14825                                 error "create failed w/o dir size limit"
14826
14827                         # messages may be rate limited if test is run repeatedly
14828                         check_mds_dmesg '"is approaching max"' ||
14829                                 echo "warning message should be output"
14830                         check_mds_dmesg '"has reached max"' ||
14831                                 echo "reached message should be output"
14832
14833                         dirsize=$(stat -c%s "$DIR/$tdir")
14834
14835                         [[ $dirsize -ge $maxsize ]] && return 0
14836                         error "dirsize $dirsize < $maxsize after $nfiles files"
14837                 elif (( rc != 0 )); then
14838                         break
14839                 fi
14840                 nfiles=$((nfiles + 1))
14841                 dirsize=$(stat -c%s "$DIR/$tdir")
14842         done
14843
14844         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14845 }
14846 run_test 129 "test directory size limit ========================"
14847
14848 OLDIFS="$IFS"
14849 cleanup_130() {
14850         trap 0
14851         IFS="$OLDIFS"
14852         rm -f $DIR/$tfile
14853 }
14854
14855 test_130a() {
14856         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14857         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14858
14859         trap cleanup_130 EXIT RETURN
14860
14861         local fm_file=$DIR/$tfile
14862         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14863         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14864                 error "dd failed for $fm_file"
14865
14866         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14867         filefrag -ves $fm_file
14868         local rc=$?
14869         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14870                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14871         (( $rc == 0 )) || error "filefrag $fm_file failed"
14872
14873         filefrag_op=$(filefrag -ve -k $fm_file |
14874                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14875         local lun=$($LFS getstripe -i $fm_file)
14876
14877         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14878         IFS=$'\n'
14879         local tot_len=0
14880         for line in $filefrag_op; do
14881                 local frag_lun=$(echo $line | cut -d: -f5)
14882                 local ext_len=$(echo $line | cut -d: -f4)
14883
14884                 if (( $frag_lun != $lun )); then
14885                         error "FIEMAP on 1-stripe file($fm_file) failed"
14886                         return
14887                 fi
14888                 (( tot_len += ext_len ))
14889         done
14890
14891         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14892                 error "FIEMAP on 1-stripe file($fm_file) failed"
14893                 return
14894         fi
14895
14896         echo "FIEMAP on single striped file succeeded"
14897 }
14898 run_test 130a "FIEMAP (1-stripe file)"
14899
14900 test_130b() {
14901         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14902
14903         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14904         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14905         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14906                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14907
14908         trap cleanup_130 EXIT RETURN
14909
14910         local fm_file=$DIR/$tfile
14911         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14912                 error "setstripe on $fm_file"
14913
14914         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14915                 error "dd failed on $fm_file"
14916
14917         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14918         filefrag_op=$(filefrag -ve -k $fm_file |
14919                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14920
14921         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14922                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14923
14924         IFS=$'\n'
14925         local tot_len=0
14926         local num_luns=1
14927
14928         for line in $filefrag_op; do
14929                 local frag_lun=$(echo $line | cut -d: -f5 |
14930                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14931                 local ext_len=$(echo $line | cut -d: -f4)
14932                 if (( $frag_lun != $last_lun )); then
14933                         if (( tot_len != 1024 )); then
14934                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14935                                 return
14936                         else
14937                                 (( num_luns += 1 ))
14938                                 tot_len=0
14939                         fi
14940                 fi
14941                 (( tot_len += ext_len ))
14942                 last_lun=$frag_lun
14943         done
14944         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14945                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14946                 return
14947         fi
14948
14949         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14950 }
14951 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14952
14953 test_130c() {
14954         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14955
14956         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14957         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14958         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14959                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14960
14961         trap cleanup_130 EXIT RETURN
14962
14963         local fm_file=$DIR/$tfile
14964         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14965
14966         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
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                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14985                         if (( logical != 512 )); then
14986                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14987                                 return
14988                         fi
14989                         if (( tot_len != 512 )); then
14990                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14991                                 return
14992                         else
14993                                 (( num_luns += 1 ))
14994                                 tot_len=0
14995                         fi
14996                 fi
14997                 (( tot_len += ext_len ))
14998                 last_lun=$frag_lun
14999         done
15000         if (( num_luns != 2 || tot_len != 512 )); then
15001                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15002                 return
15003         fi
15004
15005         echo "FIEMAP on 2-stripe file with hole succeeded"
15006 }
15007 run_test 130c "FIEMAP (2-stripe file with hole)"
15008
15009 test_130d() {
15010         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15011
15012         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15013         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15014         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15015                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15016
15017         trap cleanup_130 EXIT RETURN
15018
15019         local fm_file=$DIR/$tfile
15020         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15021                         error "setstripe on $fm_file"
15022
15023         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15024         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15025                 error "dd failed on $fm_file"
15026
15027         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15028         filefrag_op=$(filefrag -ve -k $fm_file |
15029                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15030
15031         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15032                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15033
15034         IFS=$'\n'
15035         local tot_len=0
15036         local num_luns=1
15037         for line in $filefrag_op; do
15038                 local frag_lun=$(echo $line | cut -d: -f5 |
15039                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15040                 local ext_len=$(echo $line | cut -d: -f4)
15041                 if (( $frag_lun != $last_lun )); then
15042                         if (( tot_len != 1024 )); then
15043                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15044                                 return
15045                         else
15046                                 (( num_luns += 1 ))
15047                                 local tot_len=0
15048                         fi
15049                 fi
15050                 (( tot_len += ext_len ))
15051                 last_lun=$frag_lun
15052         done
15053         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15054                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15055                 return
15056         fi
15057
15058         echo "FIEMAP on N-stripe file succeeded"
15059 }
15060 run_test 130d "FIEMAP (N-stripe file)"
15061
15062 test_130e() {
15063         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15064
15065         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15066         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15067         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15068                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15069
15070         trap cleanup_130 EXIT RETURN
15071
15072         local fm_file=$DIR/$tfile
15073         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15074         stack_trap "rm -f $fm_file"
15075
15076         local num_blks=512
15077         local expected_len=$(( (num_blks / 2) * 64 ))
15078         for ((i = 0; i < $num_blks; i++)); do
15079                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15080                         conv=notrunc > /dev/null 2>&1
15081         done
15082
15083         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15084         filefrag_op=$(filefrag -ve -k $fm_file |
15085                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15086
15087         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15088
15089         IFS=$'\n'
15090         local tot_len=0
15091         local num_luns=1
15092         for line in $filefrag_op; do
15093                 local frag_lun=$(echo $line | cut -d: -f5)
15094                 local ext_len=$(echo $line | cut -d: -f4)
15095                 if (( $frag_lun != $last_lun )); then
15096                         if (( tot_len != $expected_len )); then
15097                                 error "OST$last_lun $tot_len != $expected_len"
15098                         else
15099                                 (( num_luns += 1 ))
15100                                 tot_len=0
15101                         fi
15102                 fi
15103                 (( tot_len += ext_len ))
15104                 last_lun=$frag_lun
15105         done
15106         if (( num_luns != 2 || tot_len != $expected_len )); then
15107                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15108         fi
15109
15110         echo "FIEMAP with continuation calls succeeded"
15111 }
15112 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15113
15114 test_130f() {
15115         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15116         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15117         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15118                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15119
15120         local fm_file=$DIR/$tfile
15121         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15122                 error "multiop create with lov_delay_create on $fm_file"
15123
15124         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15125         filefrag_extents=$(filefrag -vek $fm_file |
15126                            awk '/extents? found/ { print $2 }')
15127         if (( $filefrag_extents != 0 )); then
15128                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15129         fi
15130
15131         rm -f $fm_file
15132 }
15133 run_test 130f "FIEMAP (unstriped file)"
15134
15135 test_130g() {
15136         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15137                 skip "Need MDS version with at least 2.12.53 for overstriping"
15138         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15139         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15140         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15141                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15142
15143         local file=$DIR/$tfile
15144         local nr=$((OSTCOUNT * 100))
15145
15146         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
15147
15148         stack_trap "rm -f $file"
15149         dd if=/dev/zero of=$file count=$nr bs=1M
15150         sync
15151         nr=$($LFS getstripe -c $file)
15152
15153         local extents=$(filefrag -v $file |
15154                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15155
15156         echo "filefrag list $extents extents in file with stripecount $nr"
15157         if (( extents < nr )); then
15158                 $LFS getstripe $file
15159                 filefrag -v $file
15160                 error "filefrag printed $extents < $nr extents"
15161         fi
15162 }
15163 run_test 130g "FIEMAP (overstripe file)"
15164
15165 # Test for writev/readv
15166 test_131a() {
15167         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15168                 error "writev test failed"
15169         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15170                 error "readv failed"
15171         rm -f $DIR/$tfile
15172 }
15173 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15174
15175 test_131b() {
15176         local fsize=$((524288 + 1048576 + 1572864))
15177         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15178                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15179                         error "append writev test failed"
15180
15181         ((fsize += 1572864 + 1048576))
15182         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15183                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15184                         error "append writev test failed"
15185         rm -f $DIR/$tfile
15186 }
15187 run_test 131b "test append writev"
15188
15189 test_131c() {
15190         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15191         error "NOT PASS"
15192 }
15193 run_test 131c "test read/write on file w/o objects"
15194
15195 test_131d() {
15196         rwv -f $DIR/$tfile -w -n 1 1572864
15197         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15198         if [ "$NOB" != 1572864 ]; then
15199                 error "Short read filed: read $NOB bytes instead of 1572864"
15200         fi
15201         rm -f $DIR/$tfile
15202 }
15203 run_test 131d "test short read"
15204
15205 test_131e() {
15206         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15207         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15208         error "read hitting hole failed"
15209         rm -f $DIR/$tfile
15210 }
15211 run_test 131e "test read hitting hole"
15212
15213 check_stats() {
15214         local facet=$1
15215         local op=$2
15216         local want=${3:-0}
15217         local res
15218
15219         # open             11 samples [usecs] 468 4793 13658 35791898
15220         case $facet in
15221         mds*) res=($(do_facet $facet \
15222                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15223                  ;;
15224         ost*) res=($(do_facet $facet \
15225                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15226                  ;;
15227         *) error "Wrong facet '$facet'" ;;
15228         esac
15229         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15230         # if $want is zero, it means any stat increment is ok.
15231         if (( $want > 0 )); then
15232                 local count=${res[1]}
15233
15234                 if (( $count != $want )); then
15235                         if [[ $facet =~ "mds" ]]; then
15236                                 do_nodes $(comma_list $(mdts_nodes)) \
15237                                         $LCTL get_param mdt.*.md_stats
15238                         else
15239                                 do_nodes $(comma_list $(osts-nodes)) \
15240                                         $LCTL get_param obdfilter.*.stats
15241                         fi
15242                         error "The $op counter on $facet is $count, not $want"
15243                 fi
15244         fi
15245 }
15246
15247 test_133a() {
15248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15249         remote_ost_nodsh && skip "remote OST with nodsh"
15250         remote_mds_nodsh && skip "remote MDS with nodsh"
15251         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15252                 skip_env "MDS doesn't support rename stats"
15253
15254         local testdir=$DIR/${tdir}/stats_testdir
15255
15256         mkdir -p $DIR/${tdir}
15257
15258         # clear stats.
15259         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15260         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15261
15262         # verify mdt stats first.
15263         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15264         check_stats $SINGLEMDS "mkdir" 1
15265
15266         # clear "open" from "lfs mkdir" above
15267         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15268         touch ${testdir}/${tfile} || error "touch failed"
15269         check_stats $SINGLEMDS "open" 1
15270         check_stats $SINGLEMDS "close" 1
15271         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15272                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15273                 check_stats $SINGLEMDS "mknod" 2
15274         }
15275         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15276         check_stats $SINGLEMDS "unlink" 1
15277         rm -f ${testdir}/${tfile} || error "file remove failed"
15278         check_stats $SINGLEMDS "unlink" 2
15279
15280         # remove working dir and check mdt stats again.
15281         rmdir ${testdir} || error "rmdir failed"
15282         check_stats $SINGLEMDS "rmdir" 1
15283
15284         local testdir1=$DIR/${tdir}/stats_testdir1
15285         mkdir_on_mdt0 -p ${testdir}
15286         mkdir_on_mdt0 -p ${testdir1}
15287         touch ${testdir1}/test1
15288         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15289         check_stats $SINGLEMDS "crossdir_rename" 1
15290
15291         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15292         check_stats $SINGLEMDS "samedir_rename" 1
15293
15294         rm -rf $DIR/${tdir}
15295 }
15296 run_test 133a "Verifying MDT stats ========================================"
15297
15298 test_133b() {
15299         local res
15300
15301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15302         remote_ost_nodsh && skip "remote OST with nodsh"
15303         remote_mds_nodsh && skip "remote MDS with nodsh"
15304
15305         local testdir=$DIR/${tdir}/stats_testdir
15306
15307         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15308         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15309         touch ${testdir}/${tfile} || error "touch failed"
15310         cancel_lru_locks mdc
15311
15312         # clear stats.
15313         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15314         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15315
15316         # extra mdt stats verification.
15317         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15318         check_stats $SINGLEMDS "setattr" 1
15319         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15320         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15321         then            # LU-1740
15322                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15323                 check_stats $SINGLEMDS "getattr" 1
15324         fi
15325         rm -rf $DIR/${tdir}
15326
15327         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15328         # so the check below is not reliable
15329         [ $MDSCOUNT -eq 1 ] || return 0
15330
15331         # Sleep to avoid a cached response.
15332         #define OBD_STATFS_CACHE_SECONDS 1
15333         sleep 2
15334         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15335         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15336         $LFS df || error "lfs failed"
15337         check_stats $SINGLEMDS "statfs" 1
15338
15339         # check aggregated statfs (LU-10018)
15340         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15341                 return 0
15342         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15343                 return 0
15344         sleep 2
15345         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15346         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15347         df $DIR
15348         check_stats $SINGLEMDS "statfs" 1
15349
15350         # We want to check that the client didn't send OST_STATFS to
15351         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15352         # extra care is needed here.
15353         if remote_mds; then
15354                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15355                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15356
15357                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15358                 [ "$res" ] && error "OST got STATFS"
15359         fi
15360
15361         return 0
15362 }
15363 run_test 133b "Verifying extra MDT stats =================================="
15364
15365 test_133c() {
15366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15367         remote_ost_nodsh && skip "remote OST with nodsh"
15368         remote_mds_nodsh && skip "remote MDS with nodsh"
15369
15370         local testdir=$DIR/$tdir/stats_testdir
15371
15372         test_mkdir -p $testdir
15373
15374         # verify obdfilter stats.
15375         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15376         sync
15377         cancel_lru_locks osc
15378         wait_delete_completed
15379
15380         # clear stats.
15381         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15382         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15383
15384         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15385                 error "dd failed"
15386         sync
15387         cancel_lru_locks osc
15388         check_stats ost1 "write" 1
15389
15390         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15391         check_stats ost1 "read" 1
15392
15393         > $testdir/$tfile || error "truncate failed"
15394         check_stats ost1 "punch" 1
15395
15396         rm -f $testdir/$tfile || error "file remove failed"
15397         wait_delete_completed
15398         check_stats ost1 "destroy" 1
15399
15400         rm -rf $DIR/$tdir
15401 }
15402 run_test 133c "Verifying OST stats ========================================"
15403
15404 order_2() {
15405         local value=$1
15406         local orig=$value
15407         local order=1
15408
15409         while [ $value -ge 2 ]; do
15410                 order=$((order*2))
15411                 value=$((value/2))
15412         done
15413
15414         if [ $orig -gt $order ]; then
15415                 order=$((order*2))
15416         fi
15417         echo $order
15418 }
15419
15420 size_in_KMGT() {
15421     local value=$1
15422     local size=('K' 'M' 'G' 'T');
15423     local i=0
15424     local size_string=$value
15425
15426     while [ $value -ge 1024 ]; do
15427         if [ $i -gt 3 ]; then
15428             #T is the biggest unit we get here, if that is bigger,
15429             #just return XXXT
15430             size_string=${value}T
15431             break
15432         fi
15433         value=$((value >> 10))
15434         if [ $value -lt 1024 ]; then
15435             size_string=${value}${size[$i]}
15436             break
15437         fi
15438         i=$((i + 1))
15439     done
15440
15441     echo $size_string
15442 }
15443
15444 get_rename_size() {
15445         local size=$1
15446         local context=${2:-.}
15447         local sample=$(do_facet $SINGLEMDS $LCTL \
15448                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15449                 grep -A1 $context |
15450                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15451         echo $sample
15452 }
15453
15454 test_133d() {
15455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15456         remote_ost_nodsh && skip "remote OST with nodsh"
15457         remote_mds_nodsh && skip "remote MDS with nodsh"
15458         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15459                 skip_env "MDS doesn't support rename stats"
15460
15461         local testdir1=$DIR/${tdir}/stats_testdir1
15462         local testdir2=$DIR/${tdir}/stats_testdir2
15463         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15464
15465         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15466
15467         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15468         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15469
15470         createmany -o $testdir1/test 512 || error "createmany failed"
15471
15472         # check samedir rename size
15473         mv ${testdir1}/test0 ${testdir1}/test_0
15474
15475         local testdir1_size=$(ls -l $DIR/${tdir} |
15476                 awk '/stats_testdir1/ {print $5}')
15477         local testdir2_size=$(ls -l $DIR/${tdir} |
15478                 awk '/stats_testdir2/ {print $5}')
15479
15480         testdir1_size=$(order_2 $testdir1_size)
15481         testdir2_size=$(order_2 $testdir2_size)
15482
15483         testdir1_size=$(size_in_KMGT $testdir1_size)
15484         testdir2_size=$(size_in_KMGT $testdir2_size)
15485
15486         echo "source rename dir size: ${testdir1_size}"
15487         echo "target rename dir size: ${testdir2_size}"
15488
15489         local cmd="do_facet $SINGLEMDS $LCTL "
15490         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15491
15492         eval $cmd || error "$cmd failed"
15493         local samedir=$($cmd | grep 'same_dir')
15494         local same_sample=$(get_rename_size $testdir1_size)
15495         [ -z "$samedir" ] && error "samedir_rename_size count error"
15496         [[ $same_sample -eq 1 ]] ||
15497                 error "samedir_rename_size error $same_sample"
15498         echo "Check same dir rename stats success"
15499
15500         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15501
15502         # check crossdir rename size
15503         mv ${testdir1}/test_0 ${testdir2}/test_0
15504
15505         testdir1_size=$(ls -l $DIR/${tdir} |
15506                 awk '/stats_testdir1/ {print $5}')
15507         testdir2_size=$(ls -l $DIR/${tdir} |
15508                 awk '/stats_testdir2/ {print $5}')
15509
15510         testdir1_size=$(order_2 $testdir1_size)
15511         testdir2_size=$(order_2 $testdir2_size)
15512
15513         testdir1_size=$(size_in_KMGT $testdir1_size)
15514         testdir2_size=$(size_in_KMGT $testdir2_size)
15515
15516         echo "source rename dir size: ${testdir1_size}"
15517         echo "target rename dir size: ${testdir2_size}"
15518
15519         eval $cmd || error "$cmd failed"
15520         local crossdir=$($cmd | grep 'crossdir')
15521         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15522         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15523         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15524         [[ $src_sample -eq 1 ]] ||
15525                 error "crossdir_rename_size error $src_sample"
15526         [[ $tgt_sample -eq 1 ]] ||
15527                 error "crossdir_rename_size error $tgt_sample"
15528         echo "Check cross dir rename stats success"
15529         rm -rf $DIR/${tdir}
15530 }
15531 run_test 133d "Verifying rename_stats ========================================"
15532
15533 test_133e() {
15534         remote_mds_nodsh && skip "remote MDS with nodsh"
15535         remote_ost_nodsh && skip "remote OST with nodsh"
15536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15537
15538         local testdir=$DIR/${tdir}/stats_testdir
15539         local ctr f0 f1 bs=32768 count=42 sum
15540
15541         mkdir -p ${testdir} || error "mkdir failed"
15542
15543         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15544
15545         for ctr in {write,read}_bytes; do
15546                 sync
15547                 cancel_lru_locks osc
15548
15549                 do_facet ost1 $LCTL set_param -n \
15550                         "obdfilter.*.exports.clear=clear"
15551
15552                 if [ $ctr = write_bytes ]; then
15553                         f0=/dev/zero
15554                         f1=${testdir}/${tfile}
15555                 else
15556                         f0=${testdir}/${tfile}
15557                         f1=/dev/null
15558                 fi
15559
15560                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15561                         error "dd failed"
15562                 sync
15563                 cancel_lru_locks osc
15564
15565                 sum=$(do_facet ost1 $LCTL get_param \
15566                         "obdfilter.*.exports.*.stats" |
15567                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15568                                 $1 == ctr { sum += $7 }
15569                                 END { printf("%0.0f", sum) }')
15570
15571                 if ((sum != bs * count)); then
15572                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15573                 fi
15574         done
15575
15576         rm -rf $DIR/${tdir}
15577 }
15578 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15579
15580 test_133f() {
15581         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15582                 skip "too old lustre for get_param -R ($facet_ver)"
15583
15584         # verifying readability.
15585         $LCTL get_param -R '*' &> /dev/null
15586
15587         # Verifing writability with badarea_io.
15588         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15589         local skipped_params='force_lbug|changelog_mask|daemon_file'
15590         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15591                 egrep -v "$skipped_params" |
15592                 xargs -n 1 find $proc_dirs -name |
15593                 xargs -n 1 badarea_io ||
15594                 error "client badarea_io failed"
15595
15596         # remount the FS in case writes/reads /proc break the FS
15597         cleanup || error "failed to unmount"
15598         setup || error "failed to setup"
15599 }
15600 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15601
15602 test_133g() {
15603         remote_mds_nodsh && skip "remote MDS with nodsh"
15604         remote_ost_nodsh && skip "remote OST with nodsh"
15605
15606         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15607         local proc_dirs_str=$(eval echo $proc_dirs)
15608         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15609         local facet
15610         for facet in mds1 ost1; do
15611                 local facet_ver=$(lustre_version_code $facet)
15612                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15613                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15614                 else
15615                         log "$facet: too old lustre for get_param -R"
15616                 fi
15617                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15618                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15619                                 tr -d = | egrep -v $skipped_params |
15620                                 xargs -n 1 find $proc_dirs_str -name |
15621                                 xargs -n 1 badarea_io" ||
15622                                         error "$facet badarea_io failed"
15623                 else
15624                         skip_noexit "$facet: too old lustre for get_param -R"
15625                 fi
15626         done
15627
15628         # remount the FS in case writes/reads /proc break the FS
15629         cleanup || error "failed to unmount"
15630         setup || error "failed to setup"
15631 }
15632 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15633
15634 test_133h() {
15635         remote_mds_nodsh && skip "remote MDS with nodsh"
15636         remote_ost_nodsh && skip "remote OST with nodsh"
15637         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15638                 skip "Need MDS version at least 2.9.54"
15639
15640         local facet
15641         for facet in client mds1 ost1; do
15642                 # Get the list of files that are missing the terminating newline
15643                 local plist=$(do_facet $facet
15644                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15645                 local ent
15646                 for ent in $plist; do
15647                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15648                                 awk -v FS='\v' -v RS='\v\v' \
15649                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15650                                         print FILENAME}'" 2>/dev/null)
15651                         [ -z $missing ] || {
15652                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15653                                 error "file does not end with newline: $facet-$ent"
15654                         }
15655                 done
15656         done
15657 }
15658 run_test 133h "Proc files should end with newlines"
15659
15660 test_134a() {
15661         remote_mds_nodsh && skip "remote MDS with nodsh"
15662         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15663                 skip "Need MDS version at least 2.7.54"
15664
15665         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15666         cancel_lru_locks mdc
15667
15668         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15669         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15670         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15671
15672         local nr=1000
15673         createmany -o $DIR/$tdir/f $nr ||
15674                 error "failed to create $nr files in $DIR/$tdir"
15675         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15676
15677         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15678         do_facet mds1 $LCTL set_param fail_loc=0x327
15679         do_facet mds1 $LCTL set_param fail_val=500
15680         touch $DIR/$tdir/m
15681
15682         echo "sleep 10 seconds ..."
15683         sleep 10
15684         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15685
15686         do_facet mds1 $LCTL set_param fail_loc=0
15687         do_facet mds1 $LCTL set_param fail_val=0
15688         [ $lck_cnt -lt $unused ] ||
15689                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15690
15691         rm $DIR/$tdir/m
15692         unlinkmany $DIR/$tdir/f $nr
15693 }
15694 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15695
15696 test_134b() {
15697         remote_mds_nodsh && skip "remote MDS with nodsh"
15698         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15699                 skip "Need MDS version at least 2.7.54"
15700
15701         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15702         cancel_lru_locks mdc
15703
15704         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15705                         ldlm.lock_reclaim_threshold_mb)
15706         # disable reclaim temporarily
15707         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15708
15709         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15710         do_facet mds1 $LCTL set_param fail_loc=0x328
15711         do_facet mds1 $LCTL set_param fail_val=500
15712
15713         $LCTL set_param debug=+trace
15714
15715         local nr=600
15716         createmany -o $DIR/$tdir/f $nr &
15717         local create_pid=$!
15718
15719         echo "Sleep $TIMEOUT seconds ..."
15720         sleep $TIMEOUT
15721         if ! ps -p $create_pid  > /dev/null 2>&1; then
15722                 do_facet mds1 $LCTL set_param fail_loc=0
15723                 do_facet mds1 $LCTL set_param fail_val=0
15724                 do_facet mds1 $LCTL set_param \
15725                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15726                 error "createmany finished incorrectly!"
15727         fi
15728         do_facet mds1 $LCTL set_param fail_loc=0
15729         do_facet mds1 $LCTL set_param fail_val=0
15730         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15731         wait $create_pid || return 1
15732
15733         unlinkmany $DIR/$tdir/f $nr
15734 }
15735 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15736
15737 test_135() {
15738         remote_mds_nodsh && skip "remote MDS with nodsh"
15739         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15740                 skip "Need MDS version at least 2.13.50"
15741         local fname
15742
15743         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15744
15745 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15746         #set only one record at plain llog
15747         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15748
15749         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15750
15751         #fill already existed plain llog each 64767
15752         #wrapping whole catalog
15753         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15754
15755         createmany -o $DIR/$tdir/$tfile_ 64700
15756         for (( i = 0; i < 64700; i = i + 2 ))
15757         do
15758                 rm $DIR/$tdir/$tfile_$i &
15759                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15760                 local pid=$!
15761                 wait $pid
15762         done
15763
15764         #waiting osp synchronization
15765         wait_delete_completed
15766 }
15767 run_test 135 "Race catalog processing"
15768
15769 test_136() {
15770         remote_mds_nodsh && skip "remote MDS with nodsh"
15771         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15772                 skip "Need MDS version at least 2.13.50"
15773         local fname
15774
15775         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15776         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15777         #set only one record at plain llog
15778 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15779         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15780
15781         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15782
15783         #fill already existed 2 plain llogs each 64767
15784         #wrapping whole catalog
15785         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15786         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15787         wait_delete_completed
15788
15789         createmany -o $DIR/$tdir/$tfile_ 10
15790         sleep 25
15791
15792         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15793         for (( i = 0; i < 10; i = i + 3 ))
15794         do
15795                 rm $DIR/$tdir/$tfile_$i &
15796                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15797                 local pid=$!
15798                 wait $pid
15799                 sleep 7
15800                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15801         done
15802
15803         #waiting osp synchronization
15804         wait_delete_completed
15805 }
15806 run_test 136 "Race catalog processing 2"
15807
15808 test_140() { #bug-17379
15809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15810
15811         test_mkdir $DIR/$tdir
15812         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15813         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15814
15815         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15816         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15817         local i=0
15818         while i=$((i + 1)); do
15819                 test_mkdir $i
15820                 cd $i || error "Changing to $i"
15821                 ln -s ../stat stat || error "Creating stat symlink"
15822                 # Read the symlink until ELOOP present,
15823                 # not LBUGing the system is considered success,
15824                 # we didn't overrun the stack.
15825                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15826                 if [ $ret -ne 0 ]; then
15827                         if [ $ret -eq 40 ]; then
15828                                 break  # -ELOOP
15829                         else
15830                                 error "Open stat symlink"
15831                                         return
15832                         fi
15833                 fi
15834         done
15835         i=$((i - 1))
15836         echo "The symlink depth = $i"
15837         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15838                 error "Invalid symlink depth"
15839
15840         # Test recursive symlink
15841         ln -s symlink_self symlink_self
15842         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15843         echo "open symlink_self returns $ret"
15844         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15845 }
15846 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15847
15848 test_150a() {
15849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15850
15851         local TF="$TMP/$tfile"
15852
15853         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15854         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15855         cp $TF $DIR/$tfile
15856         cancel_lru_locks $OSC
15857         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15858         remount_client $MOUNT
15859         df -P $MOUNT
15860         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15861
15862         $TRUNCATE $TF 6000
15863         $TRUNCATE $DIR/$tfile 6000
15864         cancel_lru_locks $OSC
15865         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15866
15867         echo "12345" >>$TF
15868         echo "12345" >>$DIR/$tfile
15869         cancel_lru_locks $OSC
15870         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15871
15872         echo "12345" >>$TF
15873         echo "12345" >>$DIR/$tfile
15874         cancel_lru_locks $OSC
15875         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15876 }
15877 run_test 150a "truncate/append tests"
15878
15879 test_150b() {
15880         check_set_fallocate_or_skip
15881         local out
15882
15883         touch $DIR/$tfile
15884         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15885         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15886                 skip_eopnotsupp "$out|check_fallocate failed"
15887 }
15888 run_test 150b "Verify fallocate (prealloc) functionality"
15889
15890 test_150bb() {
15891         check_set_fallocate_or_skip
15892
15893         touch $DIR/$tfile
15894         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15895         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15896         > $DIR/$tfile
15897         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15898         # precomputed md5sum for 20MB of zeroes
15899         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15900         local sum=($(md5sum $DIR/$tfile))
15901
15902         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15903
15904         check_set_fallocate 1
15905
15906         > $DIR/$tfile
15907         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15908         sum=($(md5sum $DIR/$tfile))
15909
15910         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15911 }
15912 run_test 150bb "Verify fallocate modes both zero space"
15913
15914 test_150c() {
15915         check_set_fallocate_or_skip
15916         local striping="-c2"
15917
15918         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15919         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15920         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15921         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15922         local want=$((OSTCOUNT * 1048576))
15923
15924         # Must allocate all requested space, not more than 5% extra
15925         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15926                 error "bytes $bytes is not $want"
15927
15928         rm -f $DIR/$tfile
15929
15930         echo "verify fallocate on PFL file"
15931
15932         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15933
15934         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15935                 error "Create $DIR/$tfile failed"
15936         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15937         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15938         want=$((512 * 1048576))
15939
15940         # Must allocate all requested space, not more than 5% extra
15941         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15942                 error "bytes $bytes is not $want"
15943 }
15944 run_test 150c "Verify fallocate Size and Blocks"
15945
15946 test_150d() {
15947         check_set_fallocate_or_skip
15948         local striping="-c2"
15949
15950         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15951
15952         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15953         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15954                 error "setstripe failed"
15955         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15956         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15957         local want=$((OSTCOUNT * 1048576))
15958
15959         # Must allocate all requested space, not more than 5% extra
15960         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15961                 error "bytes $bytes is not $want"
15962 }
15963 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15964
15965 test_150e() {
15966         check_set_fallocate_or_skip
15967
15968         echo "df before:"
15969         $LFS df
15970         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15971         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15972                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15973
15974         # Find OST with Minimum Size
15975         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15976                        sort -un | head -1)
15977
15978         # Get 100MB per OST of the available space to reduce run time
15979         # else 60% of the available space if we are running SLOW tests
15980         if [ $SLOW == "no" ]; then
15981                 local space=$((1024 * 100 * OSTCOUNT))
15982         else
15983                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15984         fi
15985
15986         fallocate -l${space}k $DIR/$tfile ||
15987                 error "fallocate ${space}k $DIR/$tfile failed"
15988         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15989
15990         # get size immediately after fallocate. This should be correctly
15991         # updated
15992         local size=$(stat -c '%s' $DIR/$tfile)
15993         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15994
15995         # Sleep for a while for statfs to get updated. And not pull from cache.
15996         sleep 2
15997
15998         echo "df after fallocate:"
15999         $LFS df
16000
16001         (( size / 1024 == space )) || error "size $size != requested $space"
16002         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16003                 error "used $used < space $space"
16004
16005         rm $DIR/$tfile || error "rm failed"
16006         sync
16007         wait_delete_completed
16008
16009         echo "df after unlink:"
16010         $LFS df
16011 }
16012 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16013
16014 test_150f() {
16015         local size
16016         local blocks
16017         local want_size_before=20480 # in bytes
16018         local want_blocks_before=40 # 512 sized blocks
16019         local want_blocks_after=24  # 512 sized blocks
16020         local length=$(((want_blocks_before - want_blocks_after) * 512))
16021
16022         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16023                 skip "need at least 2.14.0 for fallocate punch"
16024
16025         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16026                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16027         fi
16028
16029         check_set_fallocate_or_skip
16030         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16031
16032         [[ "x$DOM" == "xyes" ]] &&
16033                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16034
16035         echo "Verify fallocate punch: Range within the file range"
16036         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16037                 error "dd failed for bs 4096 and count 5"
16038
16039         # Call fallocate with punch range which is within the file range
16040         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16041                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16042         # client must see changes immediately after fallocate
16043         size=$(stat -c '%s' $DIR/$tfile)
16044         blocks=$(stat -c '%b' $DIR/$tfile)
16045
16046         # Verify punch worked.
16047         (( blocks == want_blocks_after )) ||
16048                 error "punch failed: blocks $blocks != $want_blocks_after"
16049
16050         (( size == want_size_before )) ||
16051                 error "punch failed: size $size != $want_size_before"
16052
16053         # Verify there is hole in file
16054         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16055         # precomputed md5sum
16056         local expect="4a9a834a2db02452929c0a348273b4aa"
16057
16058         cksum=($(md5sum $DIR/$tfile))
16059         [[ "${cksum[0]}" == "$expect" ]] ||
16060                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16061
16062         # Start second sub-case for fallocate punch.
16063         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16064         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16065                 error "dd failed for bs 4096 and count 5"
16066
16067         # Punch range less than block size will have no change in block count
16068         want_blocks_after=40  # 512 sized blocks
16069
16070         # Punch overlaps two blocks and less than blocksize
16071         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16072                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16073         size=$(stat -c '%s' $DIR/$tfile)
16074         blocks=$(stat -c '%b' $DIR/$tfile)
16075
16076         # Verify punch worked.
16077         (( blocks == want_blocks_after )) ||
16078                 error "punch failed: blocks $blocks != $want_blocks_after"
16079
16080         (( size == want_size_before )) ||
16081                 error "punch failed: size $size != $want_size_before"
16082
16083         # Verify if range is really zero'ed out. We expect Zeros.
16084         # precomputed md5sum
16085         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16086         cksum=($(md5sum $DIR/$tfile))
16087         [[ "${cksum[0]}" == "$expect" ]] ||
16088                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16089 }
16090 run_test 150f "Verify fallocate punch functionality"
16091
16092 test_150g() {
16093         local space
16094         local size
16095         local blocks
16096         local blocks_after
16097         local size_after
16098         local BS=4096 # Block size in bytes
16099
16100         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16101                 skip "need at least 2.14.0 for fallocate punch"
16102
16103         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16104                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16105         fi
16106
16107         check_set_fallocate_or_skip
16108         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16109
16110         if [[ "x$DOM" == "xyes" ]]; then
16111                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16112                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16113         else
16114                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16115                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16116         fi
16117
16118         # Get 100MB per OST of the available space to reduce run time
16119         # else 60% of the available space if we are running SLOW tests
16120         if [ $SLOW == "no" ]; then
16121                 space=$((1024 * 100 * OSTCOUNT))
16122         else
16123                 # Find OST with Minimum Size
16124                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16125                         sort -un | head -1)
16126                 echo "min size OST: $space"
16127                 space=$(((space * 60)/100 * OSTCOUNT))
16128         fi
16129         # space in 1k units, round to 4k blocks
16130         local blkcount=$((space * 1024 / $BS))
16131
16132         echo "Verify fallocate punch: Very large Range"
16133         fallocate -l${space}k $DIR/$tfile ||
16134                 error "fallocate ${space}k $DIR/$tfile failed"
16135         # write 1M at the end, start and in the middle
16136         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16137                 error "dd failed: bs $BS count 256"
16138         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16139                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16140         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16141                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16142
16143         # Gather stats.
16144         size=$(stat -c '%s' $DIR/$tfile)
16145
16146         # gather punch length.
16147         local punch_size=$((size - (BS * 2)))
16148
16149         echo "punch_size = $punch_size"
16150         echo "size - punch_size: $((size - punch_size))"
16151         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16152
16153         # Call fallocate to punch all except 2 blocks. We leave the
16154         # first and the last block
16155         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16156         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16157                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16158
16159         size_after=$(stat -c '%s' $DIR/$tfile)
16160         blocks_after=$(stat -c '%b' $DIR/$tfile)
16161
16162         # Verify punch worked.
16163         # Size should be kept
16164         (( size == size_after )) ||
16165                 error "punch failed: size $size != $size_after"
16166
16167         # two 4k data blocks to remain plus possible 1 extra extent block
16168         (( blocks_after <= ((BS / 512) * 3) )) ||
16169                 error "too many blocks remains: $blocks_after"
16170
16171         # Verify that file has hole between the first and the last blocks
16172         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16173         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16174
16175         echo "Hole at [$hole_start, $hole_end)"
16176         (( hole_start == BS )) ||
16177                 error "no hole at offset $BS after punch"
16178
16179         (( hole_end == BS + punch_size )) ||
16180                 error "data at offset $hole_end < $((BS + punch_size))"
16181 }
16182 run_test 150g "Verify fallocate punch on large range"
16183
16184 test_150h() {
16185         local file=$DIR/$tfile
16186         local size
16187
16188         check_set_fallocate_or_skip
16189         statx_supported || skip_env "Test must be statx() syscall supported"
16190
16191         # fallocate() does not update the size information on the MDT
16192         fallocate -l 16K $file || error "failed to fallocate $file"
16193         cancel_lru_locks $OSC
16194         # STATX with cached-always mode will not send glimpse RPCs to OST,
16195         # it uses the caching attrs on the client side as much as possible.
16196         size=$($STATX --cached=always -c %s $file)
16197         [ $size == 16384 ] ||
16198                 error "size after fallocate() is $size, expected 16384"
16199 }
16200 run_test 150h "Verify extend fallocate updates the file size"
16201
16202 #LU-2902 roc_hit was not able to read all values from lproc
16203 function roc_hit_init() {
16204         local list=$(comma_list $(osts_nodes))
16205         local dir=$DIR/$tdir-check
16206         local file=$dir/$tfile
16207         local BEFORE
16208         local AFTER
16209         local idx
16210
16211         test_mkdir $dir
16212         #use setstripe to do a write to every ost
16213         for i in $(seq 0 $((OSTCOUNT-1))); do
16214                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16215                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16216                 idx=$(printf %04x $i)
16217                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16218                         awk '$1 == "cache_access" {sum += $7}
16219                                 END { printf("%0.0f", sum) }')
16220
16221                 cancel_lru_locks osc
16222                 cat $file >/dev/null
16223
16224                 AFTER=$(get_osd_param $list *OST*$idx stats |
16225                         awk '$1 == "cache_access" {sum += $7}
16226                                 END { printf("%0.0f", sum) }')
16227
16228                 echo BEFORE:$BEFORE AFTER:$AFTER
16229                 if ! let "AFTER - BEFORE == 4"; then
16230                         rm -rf $dir
16231                         error "roc_hit is not safe to use"
16232                 fi
16233                 rm $file
16234         done
16235
16236         rm -rf $dir
16237 }
16238
16239 function roc_hit() {
16240         local list=$(comma_list $(osts_nodes))
16241         echo $(get_osd_param $list '' stats |
16242                 awk '$1 == "cache_hit" {sum += $7}
16243                         END { printf("%0.0f", sum) }')
16244 }
16245
16246 function set_cache() {
16247         local on=1
16248
16249         if [ "$2" == "off" ]; then
16250                 on=0;
16251         fi
16252         local list=$(comma_list $(osts_nodes))
16253         set_osd_param $list '' $1_cache_enable $on
16254
16255         cancel_lru_locks osc
16256 }
16257
16258 test_151() {
16259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16260         remote_ost_nodsh && skip "remote OST with nodsh"
16261         (( CLIENT_VERSION == OST1_VERSION )) ||
16262                 skip "LU-13081: no interop testing for OSS cache"
16263
16264         local CPAGES=3
16265         local list=$(comma_list $(osts_nodes))
16266
16267         # check whether obdfilter is cache capable at all
16268         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16269                 skip "not cache-capable obdfilter"
16270         fi
16271
16272         # check cache is enabled on all obdfilters
16273         if get_osd_param $list '' read_cache_enable | grep 0; then
16274                 skip "oss cache is disabled"
16275         fi
16276
16277         set_osd_param $list '' writethrough_cache_enable 1
16278
16279         # check write cache is enabled on all obdfilters
16280         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16281                 skip "oss write cache is NOT enabled"
16282         fi
16283
16284         roc_hit_init
16285
16286         #define OBD_FAIL_OBD_NO_LRU  0x609
16287         do_nodes $list $LCTL set_param fail_loc=0x609
16288
16289         # pages should be in the case right after write
16290         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16291                 error "dd failed"
16292
16293         local BEFORE=$(roc_hit)
16294         cancel_lru_locks osc
16295         cat $DIR/$tfile >/dev/null
16296         local AFTER=$(roc_hit)
16297
16298         do_nodes $list $LCTL set_param fail_loc=0
16299
16300         if ! let "AFTER - BEFORE == CPAGES"; then
16301                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16302         fi
16303
16304         cancel_lru_locks osc
16305         # invalidates OST cache
16306         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16307         set_osd_param $list '' read_cache_enable 0
16308         cat $DIR/$tfile >/dev/null
16309
16310         # now data shouldn't be found in the cache
16311         BEFORE=$(roc_hit)
16312         cancel_lru_locks osc
16313         cat $DIR/$tfile >/dev/null
16314         AFTER=$(roc_hit)
16315         if let "AFTER - BEFORE != 0"; then
16316                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16317         fi
16318
16319         set_osd_param $list '' read_cache_enable 1
16320         rm -f $DIR/$tfile
16321 }
16322 run_test 151 "test cache on oss and controls ==============================="
16323
16324 test_152() {
16325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16326
16327         local TF="$TMP/$tfile"
16328
16329         # simulate ENOMEM during write
16330 #define OBD_FAIL_OST_NOMEM      0x226
16331         lctl set_param fail_loc=0x80000226
16332         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16333         cp $TF $DIR/$tfile
16334         sync || error "sync failed"
16335         lctl set_param fail_loc=0
16336
16337         # discard client's cache
16338         cancel_lru_locks osc
16339
16340         # simulate ENOMEM during read
16341         lctl set_param fail_loc=0x80000226
16342         cmp $TF $DIR/$tfile || error "cmp failed"
16343         lctl set_param fail_loc=0
16344
16345         rm -f $TF
16346 }
16347 run_test 152 "test read/write with enomem ============================"
16348
16349 test_153() {
16350         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16351 }
16352 run_test 153 "test if fdatasync does not crash ======================="
16353
16354 dot_lustre_fid_permission_check() {
16355         local fid=$1
16356         local ffid=$MOUNT/.lustre/fid/$fid
16357         local test_dir=$2
16358
16359         echo "stat fid $fid"
16360         stat $ffid || error "stat $ffid failed."
16361         echo "touch fid $fid"
16362         touch $ffid || error "touch $ffid failed."
16363         echo "write to fid $fid"
16364         cat /etc/hosts > $ffid || error "write $ffid failed."
16365         echo "read fid $fid"
16366         diff /etc/hosts $ffid || error "read $ffid failed."
16367         echo "append write to fid $fid"
16368         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16369         echo "rename fid $fid"
16370         mv $ffid $test_dir/$tfile.1 &&
16371                 error "rename $ffid to $tfile.1 should fail."
16372         touch $test_dir/$tfile.1
16373         mv $test_dir/$tfile.1 $ffid &&
16374                 error "rename $tfile.1 to $ffid should fail."
16375         rm -f $test_dir/$tfile.1
16376         echo "truncate fid $fid"
16377         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16378         echo "link fid $fid"
16379         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16380         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16381                 id $USER0 || skip_env "missing user $USER0"
16382                 echo "setfacl fid $fid"
16383                 setfacl -R -m u:$USER0:rwx $ffid ||
16384                         error "setfacl $ffid failed"
16385                 echo "getfacl fid $fid"
16386                 getfacl $ffid || error "getfacl $ffid failed."
16387         fi
16388         echo "unlink fid $fid"
16389         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16390         echo "mknod fid $fid"
16391         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16392
16393         fid=[0xf00000400:0x1:0x0]
16394         ffid=$MOUNT/.lustre/fid/$fid
16395
16396         echo "stat non-exist fid $fid"
16397         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16398         echo "write to non-exist fid $fid"
16399         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16400         echo "link new fid $fid"
16401         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16402
16403         mkdir -p $test_dir/$tdir
16404         touch $test_dir/$tdir/$tfile
16405         fid=$($LFS path2fid $test_dir/$tdir)
16406         rc=$?
16407         [ $rc -ne 0 ] &&
16408                 error "error: could not get fid for $test_dir/$dir/$tfile."
16409
16410         ffid=$MOUNT/.lustre/fid/$fid
16411
16412         echo "ls $fid"
16413         ls $ffid || error "ls $ffid failed."
16414         echo "touch $fid/$tfile.1"
16415         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16416
16417         echo "touch $MOUNT/.lustre/fid/$tfile"
16418         touch $MOUNT/.lustre/fid/$tfile && \
16419                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16420
16421         echo "setxattr to $MOUNT/.lustre/fid"
16422         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16423
16424         echo "listxattr for $MOUNT/.lustre/fid"
16425         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16426
16427         echo "delxattr from $MOUNT/.lustre/fid"
16428         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16429
16430         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16431         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16432                 error "touch invalid fid should fail."
16433
16434         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16435         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16436                 error "touch non-normal fid should fail."
16437
16438         echo "rename $tdir to $MOUNT/.lustre/fid"
16439         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16440                 error "rename to $MOUNT/.lustre/fid should fail."
16441
16442         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16443         then            # LU-3547
16444                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16445                 local new_obf_mode=777
16446
16447                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16448                 chmod $new_obf_mode $DIR/.lustre/fid ||
16449                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16450
16451                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16452                 [ $obf_mode -eq $new_obf_mode ] ||
16453                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16454
16455                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16456                 chmod $old_obf_mode $DIR/.lustre/fid ||
16457                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16458         fi
16459
16460         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16461         fid=$($LFS path2fid $test_dir/$tfile-2)
16462
16463         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16464         then # LU-5424
16465                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16466                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16467                         error "create lov data thru .lustre failed"
16468         fi
16469         echo "cp /etc/passwd $test_dir/$tfile-2"
16470         cp /etc/passwd $test_dir/$tfile-2 ||
16471                 error "copy to $test_dir/$tfile-2 failed."
16472         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16473         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16474                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16475
16476         rm -rf $test_dir/tfile.lnk
16477         rm -rf $test_dir/$tfile-2
16478 }
16479
16480 test_154A() {
16481         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16482                 skip "Need MDS version at least 2.4.1"
16483
16484         local tf=$DIR/$tfile
16485         touch $tf
16486
16487         local fid=$($LFS path2fid $tf)
16488         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16489
16490         # check that we get the same pathname back
16491         local rootpath
16492         local found
16493         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16494                 echo "$rootpath $fid"
16495                 found=$($LFS fid2path $rootpath "$fid")
16496                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16497                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16498         done
16499
16500         # check wrong root path format
16501         rootpath=$MOUNT"_wrong"
16502         found=$($LFS fid2path $rootpath "$fid")
16503         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16504 }
16505 run_test 154A "lfs path2fid and fid2path basic checks"
16506
16507 test_154B() {
16508         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16509                 skip "Need MDS version at least 2.4.1"
16510
16511         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16512         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16513         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16514         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16515
16516         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16517         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16518
16519         # check that we get the same pathname
16520         echo "PFID: $PFID, name: $name"
16521         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16522         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16523         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16524                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16525
16526         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16527 }
16528 run_test 154B "verify the ll_decode_linkea tool"
16529
16530 test_154a() {
16531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16532         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16533         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16534                 skip "Need MDS version at least 2.2.51"
16535         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16536
16537         cp /etc/hosts $DIR/$tfile
16538
16539         fid=$($LFS path2fid $DIR/$tfile)
16540         rc=$?
16541         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16542
16543         dot_lustre_fid_permission_check "$fid" $DIR ||
16544                 error "dot lustre permission check $fid failed"
16545
16546         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16547
16548         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16549
16550         touch $MOUNT/.lustre/file &&
16551                 error "creation is not allowed under .lustre"
16552
16553         mkdir $MOUNT/.lustre/dir &&
16554                 error "mkdir is not allowed under .lustre"
16555
16556         rm -rf $DIR/$tfile
16557 }
16558 run_test 154a "Open-by-FID"
16559
16560 test_154b() {
16561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16562         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16564         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16565                 skip "Need MDS version at least 2.2.51"
16566
16567         local remote_dir=$DIR/$tdir/remote_dir
16568         local MDTIDX=1
16569         local rc=0
16570
16571         mkdir -p $DIR/$tdir
16572         $LFS mkdir -i $MDTIDX $remote_dir ||
16573                 error "create remote directory failed"
16574
16575         cp /etc/hosts $remote_dir/$tfile
16576
16577         fid=$($LFS path2fid $remote_dir/$tfile)
16578         rc=$?
16579         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16580
16581         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16582                 error "dot lustre permission check $fid failed"
16583         rm -rf $DIR/$tdir
16584 }
16585 run_test 154b "Open-by-FID for remote directory"
16586
16587 test_154c() {
16588         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16589                 skip "Need MDS version at least 2.4.1"
16590
16591         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16592         local FID1=$($LFS path2fid $DIR/$tfile.1)
16593         local FID2=$($LFS path2fid $DIR/$tfile.2)
16594         local FID3=$($LFS path2fid $DIR/$tfile.3)
16595
16596         local N=1
16597         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16598                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16599                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16600                 local want=FID$N
16601                 [ "$FID" = "${!want}" ] ||
16602                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16603                 N=$((N + 1))
16604         done
16605
16606         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16607         do
16608                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16609                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16610                 N=$((N + 1))
16611         done
16612 }
16613 run_test 154c "lfs path2fid and fid2path multiple arguments"
16614
16615 test_154d() {
16616         remote_mds_nodsh && skip "remote MDS with nodsh"
16617         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16618                 skip "Need MDS version at least 2.5.53"
16619
16620         if remote_mds; then
16621                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16622         else
16623                 nid="0@lo"
16624         fi
16625         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16626         local fd
16627         local cmd
16628
16629         rm -f $DIR/$tfile
16630         touch $DIR/$tfile
16631
16632         local fid=$($LFS path2fid $DIR/$tfile)
16633         # Open the file
16634         fd=$(free_fd)
16635         cmd="exec $fd<$DIR/$tfile"
16636         eval $cmd
16637         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16638         echo "$fid_list" | grep "$fid"
16639         rc=$?
16640
16641         cmd="exec $fd>/dev/null"
16642         eval $cmd
16643         if [ $rc -ne 0 ]; then
16644                 error "FID $fid not found in open files list $fid_list"
16645         fi
16646 }
16647 run_test 154d "Verify open file fid"
16648
16649 test_154e()
16650 {
16651         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16652                 skip "Need MDS version at least 2.6.50"
16653
16654         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16655                 error ".lustre returned by readdir"
16656         fi
16657 }
16658 run_test 154e ".lustre is not returned by readdir"
16659
16660 test_154f() {
16661         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16662
16663         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16664         mkdir_on_mdt0 $DIR/$tdir
16665         # test dirs inherit from its stripe
16666         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16667         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16668         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16669         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16670         touch $DIR/f
16671
16672         # get fid of parents
16673         local FID0=$($LFS path2fid $DIR/$tdir)
16674         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16675         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16676         local FID3=$($LFS path2fid $DIR)
16677
16678         # check that path2fid --parents returns expected <parent_fid>/name
16679         # 1) test for a directory (single parent)
16680         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16681         [ "$parent" == "$FID0/foo1" ] ||
16682                 error "expected parent: $FID0/foo1, got: $parent"
16683
16684         # 2) test for a file with nlink > 1 (multiple parents)
16685         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16686         echo "$parent" | grep -F "$FID1/$tfile" ||
16687                 error "$FID1/$tfile not returned in parent list"
16688         echo "$parent" | grep -F "$FID2/link" ||
16689                 error "$FID2/link not returned in parent list"
16690
16691         # 3) get parent by fid
16692         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16693         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16694         echo "$parent" | grep -F "$FID1/$tfile" ||
16695                 error "$FID1/$tfile not returned in parent list (by fid)"
16696         echo "$parent" | grep -F "$FID2/link" ||
16697                 error "$FID2/link not returned in parent list (by fid)"
16698
16699         # 4) test for entry in root directory
16700         parent=$($LFS path2fid --parents $DIR/f)
16701         echo "$parent" | grep -F "$FID3/f" ||
16702                 error "$FID3/f not returned in parent list"
16703
16704         # 5) test it on root directory
16705         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16706                 error "$MOUNT should not have parents"
16707
16708         # enable xattr caching and check that linkea is correctly updated
16709         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16710         save_lustre_params client "llite.*.xattr_cache" > $save
16711         lctl set_param llite.*.xattr_cache 1
16712
16713         # 6.1) linkea update on rename
16714         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16715
16716         # get parents by fid
16717         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16718         # foo1 should no longer be returned in parent list
16719         echo "$parent" | grep -F "$FID1" &&
16720                 error "$FID1 should no longer be in parent list"
16721         # the new path should appear
16722         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16723                 error "$FID2/$tfile.moved is not in parent list"
16724
16725         # 6.2) linkea update on unlink
16726         rm -f $DIR/$tdir/foo2/link
16727         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16728         # foo2/link should no longer be returned in parent list
16729         echo "$parent" | grep -F "$FID2/link" &&
16730                 error "$FID2/link should no longer be in parent list"
16731         true
16732
16733         rm -f $DIR/f
16734         restore_lustre_params < $save
16735         rm -f $save
16736 }
16737 run_test 154f "get parent fids by reading link ea"
16738
16739 test_154g()
16740 {
16741         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16742            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16743                 skip "Need MDS version at least 2.6.92"
16744
16745         mkdir_on_mdt0 $DIR/$tdir
16746         llapi_fid_test -d $DIR/$tdir
16747 }
16748 run_test 154g "various llapi FID tests"
16749
16750 test_154h()
16751 {
16752         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16753                 skip "Need client at least version 2.15.55.1"
16754
16755         # Create an empty file
16756         touch $DIR/$tfile
16757
16758         # Get FID (interactive mode) and save under $TMP/$tfile.log
16759         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16760                 path2fid $DIR/$tfile
16761         EOF
16762
16763         fid=$(cat $TMP/$tfile.log)
16764         # $fid should not be empty
16765         [[ ! -z $fid ]] || error "FID is empty"
16766         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16767 }
16768 run_test 154h "Verify interactive path2fid"
16769
16770 test_155_small_load() {
16771     local temp=$TMP/$tfile
16772     local file=$DIR/$tfile
16773
16774     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16775         error "dd of=$temp bs=6096 count=1 failed"
16776     cp $temp $file
16777     cancel_lru_locks $OSC
16778     cmp $temp $file || error "$temp $file differ"
16779
16780     $TRUNCATE $temp 6000
16781     $TRUNCATE $file 6000
16782     cmp $temp $file || error "$temp $file differ (truncate1)"
16783
16784     echo "12345" >>$temp
16785     echo "12345" >>$file
16786     cmp $temp $file || error "$temp $file differ (append1)"
16787
16788     echo "12345" >>$temp
16789     echo "12345" >>$file
16790     cmp $temp $file || error "$temp $file differ (append2)"
16791
16792     rm -f $temp $file
16793     true
16794 }
16795
16796 test_155_big_load() {
16797         remote_ost_nodsh && skip "remote OST with nodsh"
16798
16799         local temp=$TMP/$tfile
16800         local file=$DIR/$tfile
16801
16802         free_min_max
16803         local cache_size=$(do_facet ost$((MAXI+1)) \
16804                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16805
16806         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16807         # pre-set value
16808         if [ -z "$cache_size" ]; then
16809                 cache_size=256
16810         fi
16811         local large_file_size=$((cache_size * 2))
16812
16813         echo "OSS cache size: $cache_size KB"
16814         echo "Large file size: $large_file_size KB"
16815
16816         [ $MAXV -le $large_file_size ] &&
16817                 skip_env "max available OST size needs > $large_file_size KB"
16818
16819         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16820
16821         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16822                 error "dd of=$temp bs=$large_file_size count=1k failed"
16823         cp $temp $file
16824         ls -lh $temp $file
16825         cancel_lru_locks osc
16826         cmp $temp $file || error "$temp $file differ"
16827
16828         rm -f $temp $file
16829         true
16830 }
16831
16832 save_writethrough() {
16833         local facets=$(get_facets OST)
16834
16835         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16836 }
16837
16838 test_155a() {
16839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16840
16841         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16842
16843         save_writethrough $p
16844
16845         set_cache read on
16846         set_cache writethrough on
16847         test_155_small_load
16848         restore_lustre_params < $p
16849         rm -f $p
16850 }
16851 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16852
16853 test_155b() {
16854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16855
16856         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16857
16858         save_writethrough $p
16859
16860         set_cache read on
16861         set_cache writethrough off
16862         test_155_small_load
16863         restore_lustre_params < $p
16864         rm -f $p
16865 }
16866 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16867
16868 test_155c() {
16869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16870
16871         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16872
16873         save_writethrough $p
16874
16875         set_cache read off
16876         set_cache writethrough on
16877         test_155_small_load
16878         restore_lustre_params < $p
16879         rm -f $p
16880 }
16881 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16882
16883 test_155d() {
16884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16885
16886         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16887
16888         save_writethrough $p
16889
16890         set_cache read off
16891         set_cache writethrough off
16892         test_155_small_load
16893         restore_lustre_params < $p
16894         rm -f $p
16895 }
16896 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16897
16898 test_155e() {
16899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16900
16901         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16902
16903         save_writethrough $p
16904
16905         set_cache read on
16906         set_cache writethrough on
16907         test_155_big_load
16908         restore_lustre_params < $p
16909         rm -f $p
16910 }
16911 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16912
16913 test_155f() {
16914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16915
16916         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16917
16918         save_writethrough $p
16919
16920         set_cache read on
16921         set_cache writethrough off
16922         test_155_big_load
16923         restore_lustre_params < $p
16924         rm -f $p
16925 }
16926 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16927
16928 test_155g() {
16929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16930
16931         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16932
16933         save_writethrough $p
16934
16935         set_cache read off
16936         set_cache writethrough on
16937         test_155_big_load
16938         restore_lustre_params < $p
16939         rm -f $p
16940 }
16941 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16942
16943 test_155h() {
16944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16945
16946         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16947
16948         save_writethrough $p
16949
16950         set_cache read off
16951         set_cache writethrough off
16952         test_155_big_load
16953         restore_lustre_params < $p
16954         rm -f $p
16955 }
16956 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16957
16958 test_156() {
16959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16960         remote_ost_nodsh && skip "remote OST with nodsh"
16961         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16962                 skip "stats not implemented on old servers"
16963         [ "$ost1_FSTYPE" = "zfs" ] &&
16964                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16965         (( CLIENT_VERSION == OST1_VERSION )) ||
16966                 skip "LU-13081: no interop testing for OSS cache"
16967
16968         local CPAGES=3
16969         local BEFORE
16970         local AFTER
16971         local file="$DIR/$tfile"
16972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16973
16974         save_writethrough $p
16975         roc_hit_init
16976
16977         log "Turn on read and write cache"
16978         set_cache read on
16979         set_cache writethrough on
16980
16981         log "Write data and read it back."
16982         log "Read should be satisfied from the cache."
16983         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16984         BEFORE=$(roc_hit)
16985         cancel_lru_locks osc
16986         cat $file >/dev/null
16987         AFTER=$(roc_hit)
16988         if ! let "AFTER - BEFORE == CPAGES"; then
16989                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16990         else
16991                 log "cache hits: before: $BEFORE, after: $AFTER"
16992         fi
16993
16994         log "Read again; it should be satisfied from the cache."
16995         BEFORE=$AFTER
16996         cancel_lru_locks osc
16997         cat $file >/dev/null
16998         AFTER=$(roc_hit)
16999         if ! let "AFTER - BEFORE == CPAGES"; then
17000                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17001         else
17002                 log "cache hits:: before: $BEFORE, after: $AFTER"
17003         fi
17004
17005         log "Turn off the read cache and turn on the write cache"
17006         set_cache read off
17007         set_cache writethrough on
17008
17009         log "Read again; it should be satisfied from the cache."
17010         BEFORE=$(roc_hit)
17011         cancel_lru_locks osc
17012         cat $file >/dev/null
17013         AFTER=$(roc_hit)
17014         if ! let "AFTER - BEFORE == CPAGES"; then
17015                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17016         else
17017                 log "cache hits:: before: $BEFORE, after: $AFTER"
17018         fi
17019
17020         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17021                 # > 2.12.56 uses pagecache if cached
17022                 log "Read again; it should not be satisfied from the cache."
17023                 BEFORE=$AFTER
17024                 cancel_lru_locks osc
17025                 cat $file >/dev/null
17026                 AFTER=$(roc_hit)
17027                 if ! let "AFTER - BEFORE == 0"; then
17028                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17029                 else
17030                         log "cache hits:: before: $BEFORE, after: $AFTER"
17031                 fi
17032         fi
17033
17034         log "Write data and read it back."
17035         log "Read should be satisfied from the cache."
17036         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17037         BEFORE=$(roc_hit)
17038         cancel_lru_locks osc
17039         cat $file >/dev/null
17040         AFTER=$(roc_hit)
17041         if ! let "AFTER - BEFORE == CPAGES"; then
17042                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17043         else
17044                 log "cache hits:: before: $BEFORE, after: $AFTER"
17045         fi
17046
17047         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17048                 # > 2.12.56 uses pagecache if cached
17049                 log "Read again; it should not be satisfied from the cache."
17050                 BEFORE=$AFTER
17051                 cancel_lru_locks osc
17052                 cat $file >/dev/null
17053                 AFTER=$(roc_hit)
17054                 if ! let "AFTER - BEFORE == 0"; then
17055                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17056                 else
17057                         log "cache hits:: before: $BEFORE, after: $AFTER"
17058                 fi
17059         fi
17060
17061         log "Turn off read and write cache"
17062         set_cache read off
17063         set_cache writethrough off
17064
17065         log "Write data and read it back"
17066         log "It should not be satisfied from the cache."
17067         rm -f $file
17068         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17069         cancel_lru_locks osc
17070         BEFORE=$(roc_hit)
17071         cat $file >/dev/null
17072         AFTER=$(roc_hit)
17073         if ! let "AFTER - BEFORE == 0"; then
17074                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17075         else
17076                 log "cache hits:: before: $BEFORE, after: $AFTER"
17077         fi
17078
17079         log "Turn on the read cache and turn off the write cache"
17080         set_cache read on
17081         set_cache writethrough off
17082
17083         log "Write data and read it back"
17084         log "It should not be satisfied from the cache."
17085         rm -f $file
17086         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17087         BEFORE=$(roc_hit)
17088         cancel_lru_locks osc
17089         cat $file >/dev/null
17090         AFTER=$(roc_hit)
17091         if ! let "AFTER - BEFORE == 0"; then
17092                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17093         else
17094                 log "cache hits:: before: $BEFORE, after: $AFTER"
17095         fi
17096
17097         log "Read again; it should be satisfied from the cache."
17098         BEFORE=$(roc_hit)
17099         cancel_lru_locks osc
17100         cat $file >/dev/null
17101         AFTER=$(roc_hit)
17102         if ! let "AFTER - BEFORE == CPAGES"; then
17103                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17104         else
17105                 log "cache hits:: before: $BEFORE, after: $AFTER"
17106         fi
17107
17108         restore_lustre_params < $p
17109         rm -f $p $file
17110 }
17111 run_test 156 "Verification of tunables"
17112
17113 test_160a() {
17114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17115         remote_mds_nodsh && skip "remote MDS with nodsh"
17116         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17117                 skip "Need MDS version at least 2.2.0"
17118
17119         changelog_register || error "changelog_register failed"
17120         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17121         changelog_users $SINGLEMDS | grep -q $cl_user ||
17122                 error "User $cl_user not found in changelog_users"
17123
17124         mkdir_on_mdt0 $DIR/$tdir
17125
17126         # change something
17127         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17128         changelog_clear 0 || error "changelog_clear failed"
17129         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17130         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17131         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17132         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17133         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17134         rm $DIR/$tdir/pics/desktop.jpg
17135
17136         echo "verifying changelog mask"
17137         changelog_chmask "-MKDIR"
17138         changelog_chmask "-CLOSE"
17139
17140         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17141         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17142
17143         changelog_chmask "+MKDIR"
17144         changelog_chmask "+CLOSE"
17145
17146         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17147         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17148
17149         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17150         CLOSES=$(changelog_dump | grep -c "CLOSE")
17151         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17152         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17153
17154         # verify contents
17155         echo "verifying target fid"
17156         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17157         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17158         [ "$fidc" == "$fidf" ] ||
17159                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17160         echo "verifying parent fid"
17161         # The FID returned from the Changelog may be the directory shard on
17162         # a different MDT, and not the FID returned by path2fid on the parent.
17163         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17164         # since this is what will matter when recreating this file in the tree.
17165         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17166         local pathp=$($LFS fid2path $MOUNT "$fidp")
17167         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17168                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17169
17170         echo "getting records for $cl_user"
17171         changelog_users $SINGLEMDS
17172         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17173         local nclr=3
17174         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17175                 error "changelog_clear failed"
17176         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17177         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17178         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17179                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17180
17181         local min0_rec=$(changelog_users $SINGLEMDS |
17182                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17183         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17184                           awk '{ print $1; exit; }')
17185
17186         changelog_dump | tail -n 5
17187         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17188         [ $first_rec == $((min0_rec + 1)) ] ||
17189                 error "first index should be $min0_rec + 1 not $first_rec"
17190
17191         # LU-3446 changelog index reset on MDT restart
17192         local cur_rec1=$(changelog_users $SINGLEMDS |
17193                          awk '/^current.index:/ { print $NF }')
17194         changelog_clear 0 ||
17195                 error "clear all changelog records for $cl_user failed"
17196         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17197         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17198                 error "Fail to start $SINGLEMDS"
17199         local cur_rec2=$(changelog_users $SINGLEMDS |
17200                          awk '/^current.index:/ { print $NF }')
17201         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17202         [ $cur_rec1 == $cur_rec2 ] ||
17203                 error "current index should be $cur_rec1 not $cur_rec2"
17204
17205         echo "verifying users from this test are deregistered"
17206         changelog_deregister || error "changelog_deregister failed"
17207         changelog_users $SINGLEMDS | grep -q $cl_user &&
17208                 error "User '$cl_user' still in changelog_users"
17209
17210         # lctl get_param -n mdd.*.changelog_users
17211         # current_index: 144
17212         # ID    index (idle seconds)
17213         # cl3   144   (2) mask=<list>
17214         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17215                 # this is the normal case where all users were deregistered
17216                 # make sure no new records are added when no users are present
17217                 local last_rec1=$(changelog_users $SINGLEMDS |
17218                                   awk '/^current.index:/ { print $NF }')
17219                 touch $DIR/$tdir/chloe
17220                 local last_rec2=$(changelog_users $SINGLEMDS |
17221                                   awk '/^current.index:/ { print $NF }')
17222                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17223                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17224         else
17225                 # any changelog users must be leftovers from a previous test
17226                 changelog_users $SINGLEMDS
17227                 echo "other changelog users; can't verify off"
17228         fi
17229 }
17230 run_test 160a "changelog sanity"
17231
17232 test_160b() { # LU-3587
17233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17234         remote_mds_nodsh && skip "remote MDS with nodsh"
17235         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17236                 skip "Need MDS version at least 2.2.0"
17237
17238         changelog_register || error "changelog_register failed"
17239         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17240         changelog_users $SINGLEMDS | grep -q $cl_user ||
17241                 error "User '$cl_user' not found in changelog_users"
17242
17243         local longname1=$(str_repeat a 255)
17244         local longname2=$(str_repeat b 255)
17245
17246         cd $DIR
17247         echo "creating very long named file"
17248         touch $longname1 || error "create of '$longname1' failed"
17249         echo "renaming very long named file"
17250         mv $longname1 $longname2
17251
17252         changelog_dump | grep RENME | tail -n 5
17253         rm -f $longname2
17254 }
17255 run_test 160b "Verify that very long rename doesn't crash in changelog"
17256
17257 test_160c() {
17258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17259         remote_mds_nodsh && skip "remote MDS with nodsh"
17260
17261         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17262                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17263                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17264                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17265
17266         local rc=0
17267
17268         # Registration step
17269         changelog_register || error "changelog_register failed"
17270
17271         rm -rf $DIR/$tdir
17272         mkdir -p $DIR/$tdir
17273         $MCREATE $DIR/$tdir/foo_160c
17274         changelog_chmask "-TRUNC"
17275         $TRUNCATE $DIR/$tdir/foo_160c 200
17276         changelog_chmask "+TRUNC"
17277         $TRUNCATE $DIR/$tdir/foo_160c 199
17278         changelog_dump | tail -n 5
17279         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17280         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17281 }
17282 run_test 160c "verify that changelog log catch the truncate event"
17283
17284 test_160d() {
17285         remote_mds_nodsh && skip "remote MDS with nodsh"
17286         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17288         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17289                 skip "Need MDS version at least 2.7.60"
17290
17291         # Registration step
17292         changelog_register || error "changelog_register failed"
17293
17294         mkdir -p $DIR/$tdir/migrate_dir
17295         changelog_clear 0 || error "changelog_clear failed"
17296
17297         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17298         changelog_dump | tail -n 5
17299         local migrates=$(changelog_dump | grep -c "MIGRT")
17300         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17301 }
17302 run_test 160d "verify that changelog log catch the migrate event"
17303
17304 test_160e() {
17305         remote_mds_nodsh && skip "remote MDS with nodsh"
17306
17307         # Create a user
17308         changelog_register || error "changelog_register failed"
17309
17310         local MDT0=$(facet_svc $SINGLEMDS)
17311         local rc
17312
17313         # No user (expect fail)
17314         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17315         rc=$?
17316         if [ $rc -eq 0 ]; then
17317                 error "Should fail without user"
17318         elif [ $rc -ne 4 ]; then
17319                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17320         fi
17321
17322         # Delete a future user (expect fail)
17323         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17324         rc=$?
17325         if [ $rc -eq 0 ]; then
17326                 error "Deleted non-existant user cl77"
17327         elif [ $rc -ne 2 ]; then
17328                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17329         fi
17330
17331         # Clear to a bad index (1 billion should be safe)
17332         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17333         rc=$?
17334
17335         if [ $rc -eq 0 ]; then
17336                 error "Successfully cleared to invalid CL index"
17337         elif [ $rc -ne 22 ]; then
17338                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17339         fi
17340 }
17341 run_test 160e "changelog negative testing (should return errors)"
17342
17343 test_160f() {
17344         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17345         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17346                 skip "Need MDS version at least 2.10.56"
17347
17348         local mdts=$(comma_list $(mdts_nodes))
17349
17350         # Create a user
17351         changelog_register || error "first changelog_register failed"
17352         changelog_register || error "second changelog_register failed"
17353         local cl_users
17354         declare -A cl_user1
17355         declare -A cl_user2
17356         local user_rec1
17357         local user_rec2
17358         local i
17359
17360         # generate some changelog records to accumulate on each MDT
17361         # use all_char because created files should be evenly distributed
17362         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17363                 error "test_mkdir $tdir failed"
17364         log "$(date +%s): creating first files"
17365         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17366                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17367                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17368         done
17369
17370         # check changelogs have been generated
17371         local start=$SECONDS
17372         local idle_time=$((MDSCOUNT * 5 + 5))
17373         local nbcl=$(changelog_dump | wc -l)
17374         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17375
17376         for param in "changelog_max_idle_time=$idle_time" \
17377                      "changelog_gc=1" \
17378                      "changelog_min_gc_interval=2" \
17379                      "changelog_min_free_cat_entries=3"; do
17380                 local MDT0=$(facet_svc $SINGLEMDS)
17381                 local var="${param%=*}"
17382                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17383
17384                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17385                 do_nodes $mdts $LCTL set_param mdd.*.$param
17386         done
17387
17388         # force cl_user2 to be idle (1st part), but also cancel the
17389         # cl_user1 records so that it is not evicted later in the test.
17390         local sleep1=$((idle_time / 2))
17391         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17392         sleep $sleep1
17393
17394         # simulate changelog catalog almost full
17395         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17396         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17397
17398         for i in $(seq $MDSCOUNT); do
17399                 cl_users=(${CL_USERS[mds$i]})
17400                 cl_user1[mds$i]="${cl_users[0]}"
17401                 cl_user2[mds$i]="${cl_users[1]}"
17402
17403                 [ -n "${cl_user1[mds$i]}" ] ||
17404                         error "mds$i: no user registered"
17405                 [ -n "${cl_user2[mds$i]}" ] ||
17406                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17407
17408                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17409                 [ -n "$user_rec1" ] ||
17410                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17411                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17412                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17413                 [ -n "$user_rec2" ] ||
17414                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17415                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17416                      "$user_rec1 + 2 == $user_rec2"
17417                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17418                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17419                               "$user_rec1 + 2, but is $user_rec2"
17420                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17421                 [ -n "$user_rec2" ] ||
17422                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17423                 [ $user_rec1 == $user_rec2 ] ||
17424                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17425                               "$user_rec1, but is $user_rec2"
17426         done
17427
17428         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17429         local sleep2=$((idle_time - (SECONDS - start) + 1))
17430         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17431         sleep $sleep2
17432
17433         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17434         # cl_user1 should be OK because it recently processed records.
17435         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17436         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17437                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17438                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17439         done
17440
17441         # ensure gc thread is done
17442         for i in $(mdts_nodes); do
17443                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17444                         error "$i: GC-thread not done"
17445         done
17446
17447         local first_rec
17448         for (( i = 1; i <= MDSCOUNT; i++ )); do
17449                 # check cl_user1 still registered
17450                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17451                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17452                 # check cl_user2 unregistered
17453                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17454                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17455
17456                 # check changelogs are present and starting at $user_rec1 + 1
17457                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17458                 [ -n "$user_rec1" ] ||
17459                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17460                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17461                             awk '{ print $1; exit; }')
17462
17463                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17464                 [ $((user_rec1 + 1)) == $first_rec ] ||
17465                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17466         done
17467 }
17468 run_test 160f "changelog garbage collect (timestamped users)"
17469
17470 test_160g() {
17471         remote_mds_nodsh && skip "remote MDS with nodsh"
17472         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17473                 skip "Need MDS version at least 2.14.55"
17474
17475         local mdts=$(comma_list $(mdts_nodes))
17476
17477         # Create a user
17478         changelog_register || error "first changelog_register failed"
17479         changelog_register || error "second changelog_register failed"
17480         local cl_users
17481         declare -A cl_user1
17482         declare -A cl_user2
17483         local user_rec1
17484         local user_rec2
17485         local i
17486
17487         # generate some changelog records to accumulate on each MDT
17488         # use all_char because created files should be evenly distributed
17489         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17490                 error "test_mkdir $tdir failed"
17491         for ((i = 0; i < MDSCOUNT; i++)); do
17492                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17493                         error "create $DIR/$tdir/d$i.1 failed"
17494         done
17495
17496         # check changelogs have been generated
17497         local nbcl=$(changelog_dump | wc -l)
17498         (( $nbcl > 0 )) || error "no changelogs found"
17499
17500         # reduce the max_idle_indexes value to make sure we exceed it
17501         for param in "changelog_max_idle_indexes=2" \
17502                      "changelog_gc=1" \
17503                      "changelog_min_gc_interval=2"; do
17504                 local MDT0=$(facet_svc $SINGLEMDS)
17505                 local var="${param%=*}"
17506                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17507
17508                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17509                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17510                         error "unable to set mdd.*.$param"
17511         done
17512
17513         local start=$SECONDS
17514         for i in $(seq $MDSCOUNT); do
17515                 cl_users=(${CL_USERS[mds$i]})
17516                 cl_user1[mds$i]="${cl_users[0]}"
17517                 cl_user2[mds$i]="${cl_users[1]}"
17518
17519                 [ -n "${cl_user1[mds$i]}" ] ||
17520                         error "mds$i: user1 is not registered"
17521                 [ -n "${cl_user2[mds$i]}" ] ||
17522                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17523
17524                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17525                 [ -n "$user_rec1" ] ||
17526                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17527                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17528                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17529                 [ -n "$user_rec2" ] ||
17530                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17531                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17532                      "$user_rec1 + 2 == $user_rec2"
17533                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17534                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17535                               "expected $user_rec1 + 2, but is $user_rec2"
17536                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17537                 [ -n "$user_rec2" ] ||
17538                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17539                 [ $user_rec1 == $user_rec2 ] ||
17540                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17541                               "expected $user_rec1, but is $user_rec2"
17542         done
17543
17544         # ensure we are past the previous changelog_min_gc_interval set above
17545         local sleep2=$((start + 2 - SECONDS))
17546         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17547         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17548         # cl_user1 should be OK because it recently processed records.
17549         for ((i = 0; i < MDSCOUNT; i++)); do
17550                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17551                         error "create $DIR/$tdir/d$i.3 failed"
17552         done
17553
17554         # ensure gc thread is done
17555         for i in $(mdts_nodes); do
17556                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17557                         error "$i: GC-thread not done"
17558         done
17559
17560         local first_rec
17561         for (( i = 1; i <= MDSCOUNT; i++ )); do
17562                 # check cl_user1 still registered
17563                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17564                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17565                 # check cl_user2 unregistered
17566                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17567                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17568
17569                 # check changelogs are present and starting at $user_rec1 + 1
17570                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17571                 [ -n "$user_rec1" ] ||
17572                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17573                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17574                             awk '{ print $1; exit; }')
17575
17576                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17577                 [ $((user_rec1 + 1)) == $first_rec ] ||
17578                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17579         done
17580 }
17581 run_test 160g "changelog garbage collect on idle records"
17582
17583 test_160h() {
17584         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17585         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17586                 skip "Need MDS version at least 2.10.56"
17587
17588         local mdts=$(comma_list $(mdts_nodes))
17589
17590         # Create a user
17591         changelog_register || error "first changelog_register failed"
17592         changelog_register || error "second changelog_register failed"
17593         local cl_users
17594         declare -A cl_user1
17595         declare -A cl_user2
17596         local user_rec1
17597         local user_rec2
17598         local i
17599
17600         # generate some changelog records to accumulate on each MDT
17601         # use all_char because created files should be evenly distributed
17602         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17603                 error "test_mkdir $tdir failed"
17604         for ((i = 0; i < MDSCOUNT; i++)); do
17605                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17606                         error "create $DIR/$tdir/d$i.1 failed"
17607         done
17608
17609         # check changelogs have been generated
17610         local nbcl=$(changelog_dump | wc -l)
17611         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17612
17613         for param in "changelog_max_idle_time=10" \
17614                      "changelog_gc=1" \
17615                      "changelog_min_gc_interval=2"; do
17616                 local MDT0=$(facet_svc $SINGLEMDS)
17617                 local var="${param%=*}"
17618                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17619
17620                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17621                 do_nodes $mdts $LCTL set_param mdd.*.$param
17622         done
17623
17624         # force cl_user2 to be idle (1st part)
17625         sleep 9
17626
17627         for i in $(seq $MDSCOUNT); do
17628                 cl_users=(${CL_USERS[mds$i]})
17629                 cl_user1[mds$i]="${cl_users[0]}"
17630                 cl_user2[mds$i]="${cl_users[1]}"
17631
17632                 [ -n "${cl_user1[mds$i]}" ] ||
17633                         error "mds$i: no user registered"
17634                 [ -n "${cl_user2[mds$i]}" ] ||
17635                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17636
17637                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17638                 [ -n "$user_rec1" ] ||
17639                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17640                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17641                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17642                 [ -n "$user_rec2" ] ||
17643                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17644                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17645                      "$user_rec1 + 2 == $user_rec2"
17646                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17647                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17648                               "$user_rec1 + 2, but is $user_rec2"
17649                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17650                 [ -n "$user_rec2" ] ||
17651                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17652                 [ $user_rec1 == $user_rec2 ] ||
17653                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17654                               "$user_rec1, but is $user_rec2"
17655         done
17656
17657         # force cl_user2 to be idle (2nd part) and to reach
17658         # changelog_max_idle_time
17659         sleep 2
17660
17661         # force each GC-thread start and block then
17662         # one per MDT/MDD, set fail_val accordingly
17663         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17664         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17665
17666         # generate more changelogs to trigger fail_loc
17667         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17668                 error "create $DIR/$tdir/${tfile}bis failed"
17669
17670         # stop MDT to stop GC-thread, should be done in back-ground as it will
17671         # block waiting for the thread to be released and exit
17672         declare -A stop_pids
17673         for i in $(seq $MDSCOUNT); do
17674                 stop mds$i &
17675                 stop_pids[mds$i]=$!
17676         done
17677
17678         for i in $(mdts_nodes); do
17679                 local facet
17680                 local nb=0
17681                 local facets=$(facets_up_on_host $i)
17682
17683                 for facet in ${facets//,/ }; do
17684                         if [[ $facet == mds* ]]; then
17685                                 nb=$((nb + 1))
17686                         fi
17687                 done
17688                 # ensure each MDS's gc threads are still present and all in "R"
17689                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17690                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17691                         error "$i: expected $nb GC-thread"
17692                 wait_update $i \
17693                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17694                         "R" 20 ||
17695                         error "$i: GC-thread not found in R-state"
17696                 # check umounts of each MDT on MDS have reached kthread_stop()
17697                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17698                         error "$i: expected $nb umount"
17699                 wait_update $i \
17700                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17701                         error "$i: umount not found in D-state"
17702         done
17703
17704         # release all GC-threads
17705         do_nodes $mdts $LCTL set_param fail_loc=0
17706
17707         # wait for MDT stop to complete
17708         for i in $(seq $MDSCOUNT); do
17709                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17710         done
17711
17712         # XXX
17713         # may try to check if any orphan changelog records are present
17714         # via ldiskfs/zfs and llog_reader...
17715
17716         # re-start/mount MDTs
17717         for i in $(seq $MDSCOUNT); do
17718                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17719                         error "Fail to start mds$i"
17720         done
17721
17722         local first_rec
17723         for i in $(seq $MDSCOUNT); do
17724                 # check cl_user1 still registered
17725                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17726                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17727                 # check cl_user2 unregistered
17728                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17729                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17730
17731                 # check changelogs are present and starting at $user_rec1 + 1
17732                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17733                 [ -n "$user_rec1" ] ||
17734                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17735                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17736                             awk '{ print $1; exit; }')
17737
17738                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17739                 [ $((user_rec1 + 1)) == $first_rec ] ||
17740                         error "mds$i: first index should be $user_rec1 + 1, " \
17741                               "but is $first_rec"
17742         done
17743 }
17744 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17745               "during mount"
17746
17747 test_160i() {
17748
17749         local mdts=$(comma_list $(mdts_nodes))
17750
17751         changelog_register || error "first changelog_register failed"
17752
17753         # generate some changelog records to accumulate on each MDT
17754         # use all_char because created files should be evenly distributed
17755         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17756                 error "test_mkdir $tdir failed"
17757         for ((i = 0; i < MDSCOUNT; i++)); do
17758                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17759                         error "create $DIR/$tdir/d$i.1 failed"
17760         done
17761
17762         # check changelogs have been generated
17763         local nbcl=$(changelog_dump | wc -l)
17764         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17765
17766         # simulate race between register and unregister
17767         # XXX as fail_loc is set per-MDS, with DNE configs the race
17768         # simulation will only occur for one MDT per MDS and for the
17769         # others the normal race scenario will take place
17770         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17771         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17772         do_nodes $mdts $LCTL set_param fail_val=1
17773
17774         # unregister 1st user
17775         changelog_deregister &
17776         local pid1=$!
17777         # wait some time for deregister work to reach race rdv
17778         sleep 2
17779         # register 2nd user
17780         changelog_register || error "2nd user register failed"
17781
17782         wait $pid1 || error "1st user deregister failed"
17783
17784         local i
17785         local last_rec
17786         declare -A LAST_REC
17787         for i in $(seq $MDSCOUNT); do
17788                 if changelog_users mds$i | grep "^cl"; then
17789                         # make sure new records are added with one user present
17790                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17791                                           awk '/^current.index:/ { print $NF }')
17792                 else
17793                         error "mds$i has no user registered"
17794                 fi
17795         done
17796
17797         # generate more changelog records to accumulate on each MDT
17798         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17799                 error "create $DIR/$tdir/${tfile}bis failed"
17800
17801         for i in $(seq $MDSCOUNT); do
17802                 last_rec=$(changelog_users $SINGLEMDS |
17803                            awk '/^current.index:/ { print $NF }')
17804                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17805                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17806                         error "changelogs are off on mds$i"
17807         done
17808 }
17809 run_test 160i "changelog user register/unregister race"
17810
17811 test_160j() {
17812         remote_mds_nodsh && skip "remote MDS with nodsh"
17813         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17814                 skip "Need MDS version at least 2.12.56"
17815
17816         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17817         stack_trap "umount $MOUNT2" EXIT
17818
17819         changelog_register || error "first changelog_register failed"
17820         stack_trap "changelog_deregister" EXIT
17821
17822         # generate some changelog
17823         # use all_char because created files should be evenly distributed
17824         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17825                 error "mkdir $tdir failed"
17826         for ((i = 0; i < MDSCOUNT; i++)); do
17827                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17828                         error "create $DIR/$tdir/d$i.1 failed"
17829         done
17830
17831         # open the changelog device
17832         exec 3>/dev/changelog-$FSNAME-MDT0000
17833         stack_trap "exec 3>&-" EXIT
17834         exec 4</dev/changelog-$FSNAME-MDT0000
17835         stack_trap "exec 4<&-" EXIT
17836
17837         # umount the first lustre mount
17838         umount $MOUNT
17839         stack_trap "mount_client $MOUNT" EXIT
17840
17841         # read changelog, which may or may not fail, but should not crash
17842         cat <&4 >/dev/null
17843
17844         # clear changelog
17845         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17846         changelog_users $SINGLEMDS | grep -q $cl_user ||
17847                 error "User $cl_user not found in changelog_users"
17848
17849         printf 'clear:'$cl_user':0' >&3
17850 }
17851 run_test 160j "client can be umounted while its chanangelog is being used"
17852
17853 test_160k() {
17854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17855         remote_mds_nodsh && skip "remote MDS with nodsh"
17856
17857         mkdir -p $DIR/$tdir/1/1
17858
17859         changelog_register || error "changelog_register failed"
17860         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17861
17862         changelog_users $SINGLEMDS | grep -q $cl_user ||
17863                 error "User '$cl_user' not found in changelog_users"
17864 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17865         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17866         rmdir $DIR/$tdir/1/1 & sleep 1
17867         mkdir $DIR/$tdir/2
17868         touch $DIR/$tdir/2/2
17869         rm -rf $DIR/$tdir/2
17870
17871         wait
17872         sleep 4
17873
17874         changelog_dump | grep rmdir || error "rmdir not recorded"
17875 }
17876 run_test 160k "Verify that changelog records are not lost"
17877
17878 # Verifies that a file passed as a parameter has recently had an operation
17879 # performed on it that has generated an MTIME changelog which contains the
17880 # correct parent FID. As files might reside on a different MDT from the
17881 # parent directory in DNE configurations, the FIDs are translated to paths
17882 # before being compared, which should be identical
17883 compare_mtime_changelog() {
17884         local file="${1}"
17885         local mdtidx
17886         local mtime
17887         local cl_fid
17888         local pdir
17889         local dir
17890
17891         mdtidx=$($LFS getstripe --mdt-index $file)
17892         mdtidx=$(printf "%04x" $mdtidx)
17893
17894         # Obtain the parent FID from the MTIME changelog
17895         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17896         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17897
17898         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17899         [ -z "$cl_fid" ] && error "parent FID not present"
17900
17901         # Verify that the path for the parent FID is the same as the path for
17902         # the test directory
17903         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17904
17905         dir=$(dirname $1)
17906
17907         [[ "${pdir%/}" == "$dir" ]] ||
17908                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17909 }
17910
17911 test_160l() {
17912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17913
17914         remote_mds_nodsh && skip "remote MDS with nodsh"
17915         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17916                 skip "Need MDS version at least 2.13.55"
17917
17918         local cl_user
17919
17920         changelog_register || error "changelog_register failed"
17921         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17922
17923         changelog_users $SINGLEMDS | grep -q $cl_user ||
17924                 error "User '$cl_user' not found in changelog_users"
17925
17926         # Clear some types so that MTIME changelogs are generated
17927         changelog_chmask "-CREAT"
17928         changelog_chmask "-CLOSE"
17929
17930         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17931
17932         # Test CL_MTIME during setattr
17933         touch $DIR/$tdir/$tfile
17934         compare_mtime_changelog $DIR/$tdir/$tfile
17935
17936         # Test CL_MTIME during close
17937         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17938         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17939 }
17940 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17941
17942 test_160m() {
17943         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17944         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17945                 skip "Need MDS version at least 2.14.51"
17946         local cl_users
17947         local cl_user1
17948         local cl_user2
17949         local pid1
17950
17951         # Create a user
17952         changelog_register || error "first changelog_register failed"
17953         changelog_register || error "second changelog_register failed"
17954
17955         cl_users=(${CL_USERS[mds1]})
17956         cl_user1="${cl_users[0]}"
17957         cl_user2="${cl_users[1]}"
17958         # generate some changelog records to accumulate on MDT0
17959         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17960         createmany -m $DIR/$tdir/$tfile 50 ||
17961                 error "create $DIR/$tdir/$tfile failed"
17962         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17963         rm -f $DIR/$tdir
17964
17965         # check changelogs have been generated
17966         local nbcl=$(changelog_dump | wc -l)
17967         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17968
17969 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17970         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17971
17972         __changelog_clear mds1 $cl_user1 +10
17973         __changelog_clear mds1 $cl_user2 0 &
17974         pid1=$!
17975         sleep 2
17976         __changelog_clear mds1 $cl_user1 0 ||
17977                 error "fail to cancel record for $cl_user1"
17978         wait $pid1
17979         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17980 }
17981 run_test 160m "Changelog clear race"
17982
17983 test_160n() {
17984         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17985         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17986                 skip "Need MDS version at least 2.14.51"
17987         local cl_users
17988         local cl_user1
17989         local cl_user2
17990         local pid1
17991         local first_rec
17992         local last_rec=0
17993
17994         # Create a user
17995         changelog_register || error "first changelog_register failed"
17996
17997         cl_users=(${CL_USERS[mds1]})
17998         cl_user1="${cl_users[0]}"
17999
18000         # generate some changelog records to accumulate on MDT0
18001         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18002         first_rec=$(changelog_users $SINGLEMDS |
18003                         awk '/^current.index:/ { print $NF }')
18004         while (( last_rec < (( first_rec + 65000)) )); do
18005                 createmany -m $DIR/$tdir/$tfile 10000 ||
18006                         error "create $DIR/$tdir/$tfile failed"
18007
18008                 for i in $(seq 0 10000); do
18009                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18010                                 > /dev/null
18011                 done
18012
18013                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18014                         error "unlinkmany failed unlink"
18015                 last_rec=$(changelog_users $SINGLEMDS |
18016                         awk '/^current.index:/ { print $NF }')
18017                 echo last record $last_rec
18018                 (( last_rec == 0 )) && error "no changelog found"
18019         done
18020
18021 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18022         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18023
18024         __changelog_clear mds1 $cl_user1 0 &
18025         pid1=$!
18026         sleep 2
18027         __changelog_clear mds1 $cl_user1 0 ||
18028                 error "fail to cancel record for $cl_user1"
18029         wait $pid1
18030         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18031 }
18032 run_test 160n "Changelog destroy race"
18033
18034 test_160o() {
18035         local mdt="$(facet_svc $SINGLEMDS)"
18036
18037         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18038         remote_mds_nodsh && skip "remote MDS with nodsh"
18039         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18040                 skip "Need MDS version at least 2.14.52"
18041
18042         changelog_register --user test_160o -m unlnk+close+open ||
18043                 error "changelog_register failed"
18044
18045         do_facet $SINGLEMDS $LCTL --device $mdt \
18046                                 changelog_register -u "Tt3_-#" &&
18047                 error "bad symbols in name should fail"
18048
18049         do_facet $SINGLEMDS $LCTL --device $mdt \
18050                                 changelog_register -u test_160o &&
18051                 error "the same name registration should fail"
18052
18053         do_facet $SINGLEMDS $LCTL --device $mdt \
18054                         changelog_register -u test_160toolongname &&
18055                 error "too long name registration should fail"
18056
18057         changelog_chmask "MARK+HSM"
18058         lctl get_param mdd.*.changelog*mask
18059         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18060         changelog_users $SINGLEMDS | grep -q $cl_user ||
18061                 error "User $cl_user not found in changelog_users"
18062         #verify username
18063         echo $cl_user | grep -q test_160o ||
18064                 error "User $cl_user has no specific name 'test160o'"
18065
18066         # change something
18067         changelog_clear 0 || error "changelog_clear failed"
18068         # generate some changelog records to accumulate on MDT0
18069         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18070         touch $DIR/$tdir/$tfile                 # open 1
18071
18072         OPENS=$(changelog_dump | grep -c "OPEN")
18073         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18074
18075         # must be no MKDIR it wasn't set as user mask
18076         MKDIR=$(changelog_dump | grep -c "MKDIR")
18077         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18078
18079         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18080                                 mdd.$mdt.changelog_current_mask -n)
18081         # register maskless user
18082         changelog_register || error "changelog_register failed"
18083         # effective mask should be not changed because it is not minimal
18084         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18085                                 mdd.$mdt.changelog_current_mask -n)
18086         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18087         # set server mask to minimal value
18088         changelog_chmask "MARK"
18089         # check effective mask again, should be treated as DEFMASK now
18090         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18091                                 mdd.$mdt.changelog_current_mask -n)
18092         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18093
18094         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18095                 # set server mask back to some value
18096                 changelog_chmask "CLOSE,UNLNK"
18097                 # check effective mask again, should not remain as DEFMASK
18098                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18099                                 mdd.$mdt.changelog_current_mask -n)
18100                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18101         fi
18102
18103         do_facet $SINGLEMDS $LCTL --device $mdt \
18104                                 changelog_deregister -u test_160o ||
18105                 error "cannot deregister by name"
18106 }
18107 run_test 160o "changelog user name and mask"
18108
18109 test_160p() {
18110         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18111         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18112                 skip "Need MDS version at least 2.14.51"
18113         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18114         local cl_users
18115         local cl_user1
18116         local entry_count
18117
18118         # Create a user
18119         changelog_register || error "first changelog_register failed"
18120
18121         cl_users=(${CL_USERS[mds1]})
18122         cl_user1="${cl_users[0]}"
18123
18124         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18125         createmany -m $DIR/$tdir/$tfile 50 ||
18126                 error "create $DIR/$tdir/$tfile failed"
18127         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18128         rm -rf $DIR/$tdir
18129
18130         # check changelogs have been generated
18131         entry_count=$(changelog_dump | wc -l)
18132         ((entry_count != 0)) || error "no changelog entries found"
18133
18134         # remove changelog_users and check that orphan entries are removed
18135         stop mds1
18136         local dev=$(mdsdevname 1)
18137         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18138         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18139         entry_count=$(changelog_dump | wc -l)
18140         ((entry_count == 0)) ||
18141                 error "found $entry_count changelog entries, expected none"
18142 }
18143 run_test 160p "Changelog orphan cleanup with no users"
18144
18145 test_160q() {
18146         local mdt="$(facet_svc $SINGLEMDS)"
18147         local clu
18148
18149         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18150         remote_mds_nodsh && skip "remote MDS with nodsh"
18151         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18152                 skip "Need MDS version at least 2.14.54"
18153
18154         # set server mask to minimal value like server init does
18155         changelog_chmask "MARK"
18156         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18157                 error "changelog_register failed"
18158         # check effective mask again, should be treated as DEFMASK now
18159         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18160                                 mdd.$mdt.changelog_current_mask -n)
18161         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18162                 error "changelog_deregister failed"
18163         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18164 }
18165 run_test 160q "changelog effective mask is DEFMASK if not set"
18166
18167 test_160s() {
18168         remote_mds_nodsh && skip "remote MDS with nodsh"
18169         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18170                 skip "Need MDS version at least 2.14.55"
18171
18172         local mdts=$(comma_list $(mdts_nodes))
18173
18174         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18175         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18176                                        fail_val=$((24 * 3600 * 10))
18177
18178         # Create a user which is 10 days old
18179         changelog_register || error "first changelog_register failed"
18180         local cl_users
18181         declare -A cl_user1
18182         local i
18183
18184         # generate some changelog records to accumulate on each MDT
18185         # use all_char because created files should be evenly distributed
18186         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18187                 error "test_mkdir $tdir failed"
18188         for ((i = 0; i < MDSCOUNT; i++)); do
18189                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18190                         error "create $DIR/$tdir/d$i.1 failed"
18191         done
18192
18193         # check changelogs have been generated
18194         local nbcl=$(changelog_dump | wc -l)
18195         (( nbcl > 0 )) || error "no changelogs found"
18196
18197         # reduce the max_idle_indexes value to make sure we exceed it
18198         for param in "changelog_max_idle_indexes=2097446912" \
18199                      "changelog_max_idle_time=2592000" \
18200                      "changelog_gc=1" \
18201                      "changelog_min_gc_interval=2"; do
18202                 local MDT0=$(facet_svc $SINGLEMDS)
18203                 local var="${param%=*}"
18204                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18205
18206                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18207                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18208                         error "unable to set mdd.*.$param"
18209         done
18210
18211         local start=$SECONDS
18212         for i in $(seq $MDSCOUNT); do
18213                 cl_users=(${CL_USERS[mds$i]})
18214                 cl_user1[mds$i]="${cl_users[0]}"
18215
18216                 [[ -n "${cl_user1[mds$i]}" ]] ||
18217                         error "mds$i: no user registered"
18218         done
18219
18220         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18221         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18222
18223         # ensure we are past the previous changelog_min_gc_interval set above
18224         local sleep2=$((start + 2 - SECONDS))
18225         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18226
18227         # Generate one more changelog to trigger GC
18228         for ((i = 0; i < MDSCOUNT; i++)); do
18229                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18230                         error "create $DIR/$tdir/d$i.3 failed"
18231         done
18232
18233         # ensure gc thread is done
18234         for node in $(mdts_nodes); do
18235                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18236                         error "$node: GC-thread not done"
18237         done
18238
18239         do_nodes $mdts $LCTL set_param fail_loc=0
18240
18241         for (( i = 1; i <= MDSCOUNT; i++ )); do
18242                 # check cl_user1 is purged
18243                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18244                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18245         done
18246         return 0
18247 }
18248 run_test 160s "changelog garbage collect on idle records * time"
18249
18250 test_160t() {
18251         remote_mds_nodsh && skip "remote MDS with nodsh"
18252         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18253                 skip "Need MDS version at least 2.15.50"
18254
18255         local MDT0=$(facet_svc $SINGLEMDS)
18256         local cl_users
18257         local cl_user1
18258         local cl_user2
18259         local start
18260
18261         changelog_register --user user1 -m all ||
18262                 error "user1 failed to register"
18263
18264         mkdir_on_mdt0 $DIR/$tdir
18265         # create default overstripe to maximize changelog size
18266         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18267         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18268         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18269
18270         # user2 consumes less records so less space
18271         changelog_register --user user2 || error "user2 failed to register"
18272         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18273         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18274
18275         # check changelogs have been generated
18276         local nbcl=$(changelog_dump | wc -l)
18277         (( nbcl > 0 )) || error "no changelogs found"
18278
18279         # reduce the changelog_min_gc_interval to force check
18280         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18281                 local var="${param%=*}"
18282                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18283
18284                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18285                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18286                         error "unable to set mdd.*.$param"
18287         done
18288
18289         start=$SECONDS
18290         cl_users=(${CL_USERS[mds1]})
18291         cl_user1="${cl_users[0]}"
18292         cl_user2="${cl_users[1]}"
18293
18294         [[ -n $cl_user1 ]] ||
18295                 error "mds1: user #1 isn't registered"
18296         [[ -n $cl_user2 ]] ||
18297                 error "mds1: user #2 isn't registered"
18298
18299         # ensure we are past the previous changelog_min_gc_interval set above
18300         local sleep2=$((start + 2 - SECONDS))
18301         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18302
18303         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18304         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18305                         fail_val=$(((llog_size1 + llog_size2) / 2))
18306
18307         # Generate more changelog to trigger GC
18308         createmany -o $DIR/$tdir/u3_ 4 ||
18309                 error "create failed for more files"
18310
18311         # ensure gc thread is done
18312         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18313                 error "mds1: GC-thread not done"
18314
18315         do_facet mds1 $LCTL set_param fail_loc=0
18316
18317         # check cl_user1 is purged
18318         changelog_users mds1 | grep -q "$cl_user1" &&
18319                 error "User $cl_user1 is registered"
18320         # check cl_user2 is not purged
18321         changelog_users mds1 | grep -q "$cl_user2" ||
18322                 error "User $cl_user2 is not registered"
18323 }
18324 run_test 160t "changelog garbage collect on lack of space"
18325
18326 test_161a() {
18327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18328
18329         test_mkdir -c1 $DIR/$tdir
18330         cp /etc/hosts $DIR/$tdir/$tfile
18331         test_mkdir -c1 $DIR/$tdir/foo1
18332         test_mkdir -c1 $DIR/$tdir/foo2
18333         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18334         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18335         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18336         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18337         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18338         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18339                 $LFS fid2path $DIR $FID
18340                 error "bad link ea"
18341         fi
18342         # middle
18343         rm $DIR/$tdir/foo2/zachary
18344         # last
18345         rm $DIR/$tdir/foo2/thor
18346         # first
18347         rm $DIR/$tdir/$tfile
18348         # rename
18349         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18350         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18351                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18352         rm $DIR/$tdir/foo2/maggie
18353
18354         # overflow the EA
18355         local longname=$tfile.avg_len_is_thirty_two_
18356         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18357                 error_noexit 'failed to unlink many hardlinks'" EXIT
18358         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18359                 error "failed to hardlink many files"
18360         links=$($LFS fid2path $DIR $FID | wc -l)
18361         echo -n "${links}/1000 links in link EA"
18362         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18363 }
18364 run_test 161a "link ea sanity"
18365
18366 test_161b() {
18367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18368         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18369
18370         local MDTIDX=1
18371         local remote_dir=$DIR/$tdir/remote_dir
18372
18373         mkdir -p $DIR/$tdir
18374         $LFS mkdir -i $MDTIDX $remote_dir ||
18375                 error "create remote directory failed"
18376
18377         cp /etc/hosts $remote_dir/$tfile
18378         mkdir -p $remote_dir/foo1
18379         mkdir -p $remote_dir/foo2
18380         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18381         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18382         ln $remote_dir/$tfile $remote_dir/foo1/luna
18383         ln $remote_dir/$tfile $remote_dir/foo2/thor
18384
18385         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18386                      tr -d ']')
18387         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18388                 $LFS fid2path $DIR $FID
18389                 error "bad link ea"
18390         fi
18391         # middle
18392         rm $remote_dir/foo2/zachary
18393         # last
18394         rm $remote_dir/foo2/thor
18395         # first
18396         rm $remote_dir/$tfile
18397         # rename
18398         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18399         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18400         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18401                 $LFS fid2path $DIR $FID
18402                 error "bad link rename"
18403         fi
18404         rm $remote_dir/foo2/maggie
18405
18406         # overflow the EA
18407         local longname=filename_avg_len_is_thirty_two_
18408         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18409                 error "failed to hardlink many files"
18410         links=$($LFS fid2path $DIR $FID | wc -l)
18411         echo -n "${links}/1000 links in link EA"
18412         [[ ${links} -gt 60 ]] ||
18413                 error "expected at least 60 links in link EA"
18414         unlinkmany $remote_dir/foo2/$longname 1000 ||
18415         error "failed to unlink many hardlinks"
18416 }
18417 run_test 161b "link ea sanity under remote directory"
18418
18419 test_161c() {
18420         remote_mds_nodsh && skip "remote MDS with nodsh"
18421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18422         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18423                 skip "Need MDS version at least 2.1.5"
18424
18425         # define CLF_RENAME_LAST 0x0001
18426         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18427         changelog_register || error "changelog_register failed"
18428
18429         rm -rf $DIR/$tdir
18430         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18431         touch $DIR/$tdir/foo_161c
18432         touch $DIR/$tdir/bar_161c
18433         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18434         changelog_dump | grep RENME | tail -n 5
18435         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18436         changelog_clear 0 || error "changelog_clear failed"
18437         if [ x$flags != "x0x1" ]; then
18438                 error "flag $flags is not 0x1"
18439         fi
18440
18441         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18442         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18443         touch $DIR/$tdir/foo_161c
18444         touch $DIR/$tdir/bar_161c
18445         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18446         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18447         changelog_dump | grep RENME | tail -n 5
18448         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18449         changelog_clear 0 || error "changelog_clear failed"
18450         if [ x$flags != "x0x0" ]; then
18451                 error "flag $flags is not 0x0"
18452         fi
18453         echo "rename overwrite a target having nlink > 1," \
18454                 "changelog record has flags of $flags"
18455
18456         # rename doesn't overwrite a target (changelog flag 0x0)
18457         touch $DIR/$tdir/foo_161c
18458         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18459         changelog_dump | grep RENME | tail -n 5
18460         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18461         changelog_clear 0 || error "changelog_clear failed"
18462         if [ x$flags != "x0x0" ]; then
18463                 error "flag $flags is not 0x0"
18464         fi
18465         echo "rename doesn't overwrite a target," \
18466                 "changelog record has flags of $flags"
18467
18468         # define CLF_UNLINK_LAST 0x0001
18469         # unlink a file having nlink = 1 (changelog flag 0x1)
18470         rm -f $DIR/$tdir/foo2_161c
18471         changelog_dump | grep UNLNK | tail -n 5
18472         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18473         changelog_clear 0 || error "changelog_clear failed"
18474         if [ x$flags != "x0x1" ]; then
18475                 error "flag $flags is not 0x1"
18476         fi
18477         echo "unlink a file having nlink = 1," \
18478                 "changelog record has flags of $flags"
18479
18480         # unlink a file having nlink > 1 (changelog flag 0x0)
18481         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18482         rm -f $DIR/$tdir/foobar_161c
18483         changelog_dump | grep UNLNK | tail -n 5
18484         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18485         changelog_clear 0 || error "changelog_clear failed"
18486         if [ x$flags != "x0x0" ]; then
18487                 error "flag $flags is not 0x0"
18488         fi
18489         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18490 }
18491 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18492
18493 test_161d() {
18494         remote_mds_nodsh && skip "remote MDS with nodsh"
18495         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18496
18497         local pid
18498         local fid
18499
18500         changelog_register || error "changelog_register failed"
18501
18502         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18503         # interfer with $MOUNT/.lustre/fid/ access
18504         mkdir $DIR/$tdir
18505         [[ $? -eq 0 ]] || error "mkdir failed"
18506
18507         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18508         $LCTL set_param fail_loc=0x8000140c
18509         # 5s pause
18510         $LCTL set_param fail_val=5
18511
18512         # create file
18513         echo foofoo > $DIR/$tdir/$tfile &
18514         pid=$!
18515
18516         # wait for create to be delayed
18517         sleep 2
18518
18519         ps -p $pid
18520         [[ $? -eq 0 ]] || error "create should be blocked"
18521
18522         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18523         stack_trap "rm -f $tempfile"
18524         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18525         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18526         # some delay may occur during ChangeLog publishing and file read just
18527         # above, that could allow file write to happen finally
18528         [[ -s $tempfile ]] && echo "file should be empty"
18529
18530         $LCTL set_param fail_loc=0
18531
18532         wait $pid
18533         [[ $? -eq 0 ]] || error "create failed"
18534 }
18535 run_test 161d "create with concurrent .lustre/fid access"
18536
18537 check_path() {
18538         local expected="$1"
18539         shift
18540         local fid="$2"
18541
18542         local path
18543         path=$($LFS fid2path "$@")
18544         local rc=$?
18545
18546         if [ $rc -ne 0 ]; then
18547                 error "path looked up of '$expected' failed: rc=$rc"
18548         elif [ "$path" != "$expected" ]; then
18549                 error "path looked up '$path' instead of '$expected'"
18550         else
18551                 echo "FID '$fid' resolves to path '$path' as expected"
18552         fi
18553 }
18554
18555 test_162a() { # was test_162
18556         test_mkdir -p -c1 $DIR/$tdir/d2
18557         touch $DIR/$tdir/d2/$tfile
18558         touch $DIR/$tdir/d2/x1
18559         touch $DIR/$tdir/d2/x2
18560         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18561         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18562         # regular file
18563         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18564         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18565
18566         # softlink
18567         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18568         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18569         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18570
18571         # softlink to wrong file
18572         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18573         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18574         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18575
18576         # hardlink
18577         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18578         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18579         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18580         # fid2path dir/fsname should both work
18581         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18582         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18583
18584         # hardlink count: check that there are 2 links
18585         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18586         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18587
18588         # hardlink indexing: remove the first link
18589         rm $DIR/$tdir/d2/p/q/r/hlink
18590         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18591 }
18592 run_test 162a "path lookup sanity"
18593
18594 test_162b() {
18595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18596         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18597
18598         mkdir $DIR/$tdir
18599         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18600                                 error "create striped dir failed"
18601
18602         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18603                                         tail -n 1 | awk '{print $2}')
18604         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18605
18606         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18607         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18608
18609         # regular file
18610         for ((i=0;i<5;i++)); do
18611                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18612                         error "get fid for f$i failed"
18613                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18614
18615                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18616                         error "get fid for d$i failed"
18617                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18618         done
18619
18620         return 0
18621 }
18622 run_test 162b "striped directory path lookup sanity"
18623
18624 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18625 test_162c() {
18626         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18627                 skip "Need MDS version at least 2.7.51"
18628
18629         local lpath=$tdir.local
18630         local rpath=$tdir.remote
18631
18632         test_mkdir $DIR/$lpath
18633         test_mkdir $DIR/$rpath
18634
18635         for ((i = 0; i <= 101; i++)); do
18636                 lpath="$lpath/$i"
18637                 mkdir $DIR/$lpath
18638                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18639                         error "get fid for local directory $DIR/$lpath failed"
18640                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18641
18642                 rpath="$rpath/$i"
18643                 test_mkdir $DIR/$rpath
18644                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18645                         error "get fid for remote directory $DIR/$rpath failed"
18646                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18647         done
18648
18649         return 0
18650 }
18651 run_test 162c "fid2path works with paths 100 or more directories deep"
18652
18653 oalr_event_count() {
18654         local event="${1}"
18655         local trace="${2}"
18656
18657         awk -v name="${FSNAME}-OST0000" \
18658             -v event="${event}" \
18659             '$1 == "TRACE" && $2 == event && $3 == name' \
18660             "${trace}" |
18661         wc -l
18662 }
18663
18664 oalr_expect_event_count() {
18665         local event="${1}"
18666         local trace="${2}"
18667         local expect="${3}"
18668         local count
18669
18670         count=$(oalr_event_count "${event}" "${trace}")
18671         if ((count == expect)); then
18672                 return 0
18673         fi
18674
18675         error_noexit "${event} event count was '${count}', expected ${expect}"
18676         cat "${trace}" >&2
18677         exit 1
18678 }
18679
18680 cleanup_165() {
18681         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18682         stop ost1
18683         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18684 }
18685
18686 setup_165() {
18687         sync # Flush previous IOs so we can count log entries.
18688         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18689         stack_trap cleanup_165 EXIT
18690 }
18691
18692 test_165a() {
18693         local trace="/tmp/${tfile}.trace"
18694         local rc
18695         local count
18696
18697         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18698                 skip "OFD access log unsupported"
18699
18700         setup_165
18701         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18702         sleep 5
18703
18704         do_facet ost1 ofd_access_log_reader --list
18705         stop ost1
18706
18707         do_facet ost1 killall -TERM ofd_access_log_reader
18708         wait
18709         rc=$?
18710
18711         if ((rc != 0)); then
18712                 error "ofd_access_log_reader exited with rc = '${rc}'"
18713         fi
18714
18715         # Parse trace file for discovery events:
18716         oalr_expect_event_count alr_log_add "${trace}" 1
18717         oalr_expect_event_count alr_log_eof "${trace}" 1
18718         oalr_expect_event_count alr_log_free "${trace}" 1
18719 }
18720 run_test 165a "ofd access log discovery"
18721
18722 test_165b() {
18723         local trace="/tmp/${tfile}.trace"
18724         local file="${DIR}/${tfile}"
18725         local pfid1
18726         local pfid2
18727         local -a entry
18728         local rc
18729         local count
18730         local size
18731         local flags
18732
18733         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18734                 skip "OFD access log unsupported"
18735
18736         setup_165
18737         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18738         sleep 5
18739
18740         do_facet ost1 ofd_access_log_reader --list
18741
18742         lfs setstripe -c 1 -i 0 "${file}"
18743         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18744                 error "cannot create '${file}'"
18745
18746         sleep 5
18747         do_facet ost1 killall -TERM ofd_access_log_reader
18748         wait
18749         rc=$?
18750
18751         if ((rc != 0)); then
18752                 error "ofd_access_log_reader exited with rc = '${rc}'"
18753         fi
18754
18755         oalr_expect_event_count alr_log_entry "${trace}" 1
18756
18757         pfid1=$($LFS path2fid "${file}")
18758
18759         # 1     2             3   4    5     6   7    8    9     10
18760         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18761         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18762
18763         echo "entry = '${entry[*]}'" >&2
18764
18765         pfid2=${entry[4]}
18766         if [[ "${pfid1}" != "${pfid2}" ]]; then
18767                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18768         fi
18769
18770         size=${entry[8]}
18771         if ((size != 1048576)); then
18772                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18773         fi
18774
18775         flags=${entry[10]}
18776         if [[ "${flags}" != "w" ]]; then
18777                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18778         fi
18779
18780         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18781         sleep 5
18782
18783         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18784                 error "cannot read '${file}'"
18785         sleep 5
18786
18787         do_facet ost1 killall -TERM ofd_access_log_reader
18788         wait
18789         rc=$?
18790
18791         if ((rc != 0)); then
18792                 error "ofd_access_log_reader exited with rc = '${rc}'"
18793         fi
18794
18795         oalr_expect_event_count alr_log_entry "${trace}" 1
18796
18797         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18798         echo "entry = '${entry[*]}'" >&2
18799
18800         pfid2=${entry[4]}
18801         if [[ "${pfid1}" != "${pfid2}" ]]; then
18802                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18803         fi
18804
18805         size=${entry[8]}
18806         if ((size != 524288)); then
18807                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18808         fi
18809
18810         flags=${entry[10]}
18811         if [[ "${flags}" != "r" ]]; then
18812                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18813         fi
18814 }
18815 run_test 165b "ofd access log entries are produced and consumed"
18816
18817 test_165c() {
18818         local trace="/tmp/${tfile}.trace"
18819         local file="${DIR}/${tdir}/${tfile}"
18820
18821         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18822                 skip "OFD access log unsupported"
18823
18824         test_mkdir "${DIR}/${tdir}"
18825
18826         setup_165
18827         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18828         sleep 5
18829
18830         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18831
18832         # 4096 / 64 = 64. Create twice as many entries.
18833         for ((i = 0; i < 128; i++)); do
18834                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18835                         error "cannot create file"
18836         done
18837
18838         sync
18839
18840         do_facet ost1 killall -TERM ofd_access_log_reader
18841         wait
18842         rc=$?
18843         if ((rc != 0)); then
18844                 error "ofd_access_log_reader exited with rc = '${rc}'"
18845         fi
18846
18847         unlinkmany  "${file}-%d" 128
18848 }
18849 run_test 165c "full ofd access logs do not block IOs"
18850
18851 oal_get_read_count() {
18852         local stats="$1"
18853
18854         # STATS lustre-OST0001 alr_read_count 1
18855
18856         do_facet ost1 cat "${stats}" |
18857         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18858              END { print count; }'
18859 }
18860
18861 oal_expect_read_count() {
18862         local stats="$1"
18863         local count
18864         local expect="$2"
18865
18866         # Ask ofd_access_log_reader to write stats.
18867         do_facet ost1 killall -USR1 ofd_access_log_reader
18868
18869         # Allow some time for things to happen.
18870         sleep 1
18871
18872         count=$(oal_get_read_count "${stats}")
18873         if ((count == expect)); then
18874                 return 0
18875         fi
18876
18877         error_noexit "bad read count, got ${count}, expected ${expect}"
18878         do_facet ost1 cat "${stats}" >&2
18879         exit 1
18880 }
18881
18882 test_165d() {
18883         local stats="/tmp/${tfile}.stats"
18884         local file="${DIR}/${tdir}/${tfile}"
18885         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18886
18887         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18888                 skip "OFD access log unsupported"
18889
18890         test_mkdir "${DIR}/${tdir}"
18891
18892         setup_165
18893         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18894         sleep 5
18895
18896         lfs setstripe -c 1 -i 0 "${file}"
18897
18898         do_facet ost1 lctl set_param "${param}=rw"
18899         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18900                 error "cannot create '${file}'"
18901         oal_expect_read_count "${stats}" 1
18902
18903         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18904                 error "cannot read '${file}'"
18905         oal_expect_read_count "${stats}" 2
18906
18907         do_facet ost1 lctl set_param "${param}=r"
18908         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18909                 error "cannot create '${file}'"
18910         oal_expect_read_count "${stats}" 2
18911
18912         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18913                 error "cannot read '${file}'"
18914         oal_expect_read_count "${stats}" 3
18915
18916         do_facet ost1 lctl set_param "${param}=w"
18917         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18918                 error "cannot create '${file}'"
18919         oal_expect_read_count "${stats}" 4
18920
18921         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18922                 error "cannot read '${file}'"
18923         oal_expect_read_count "${stats}" 4
18924
18925         do_facet ost1 lctl set_param "${param}=0"
18926         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18927                 error "cannot create '${file}'"
18928         oal_expect_read_count "${stats}" 4
18929
18930         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18931                 error "cannot read '${file}'"
18932         oal_expect_read_count "${stats}" 4
18933
18934         do_facet ost1 killall -TERM ofd_access_log_reader
18935         wait
18936         rc=$?
18937         if ((rc != 0)); then
18938                 error "ofd_access_log_reader exited with rc = '${rc}'"
18939         fi
18940 }
18941 run_test 165d "ofd_access_log mask works"
18942
18943 test_165e() {
18944         local stats="/tmp/${tfile}.stats"
18945         local file0="${DIR}/${tdir}-0/${tfile}"
18946         local file1="${DIR}/${tdir}-1/${tfile}"
18947
18948         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18949                 skip "OFD access log unsupported"
18950
18951         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18952
18953         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18954         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18955
18956         lfs setstripe -c 1 -i 0 "${file0}"
18957         lfs setstripe -c 1 -i 0 "${file1}"
18958
18959         setup_165
18960         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18961         sleep 5
18962
18963         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18964                 error "cannot create '${file0}'"
18965         sync
18966         oal_expect_read_count "${stats}" 0
18967
18968         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18969                 error "cannot create '${file1}'"
18970         sync
18971         oal_expect_read_count "${stats}" 1
18972
18973         do_facet ost1 killall -TERM ofd_access_log_reader
18974         wait
18975         rc=$?
18976         if ((rc != 0)); then
18977                 error "ofd_access_log_reader exited with rc = '${rc}'"
18978         fi
18979 }
18980 run_test 165e "ofd_access_log MDT index filter works"
18981
18982 test_165f() {
18983         local trace="/tmp/${tfile}.trace"
18984         local rc
18985         local count
18986
18987         setup_165
18988         do_facet ost1 timeout 60 ofd_access_log_reader \
18989                 --exit-on-close --debug=- --trace=- > "${trace}" &
18990         sleep 5
18991         stop ost1
18992
18993         wait
18994         rc=$?
18995
18996         if ((rc != 0)); then
18997                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18998                 cat "${trace}"
18999                 exit 1
19000         fi
19001 }
19002 run_test 165f "ofd_access_log_reader --exit-on-close works"
19003
19004 test_169() {
19005         # do directio so as not to populate the page cache
19006         log "creating a 10 Mb file"
19007         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19008                 error "multiop failed while creating a file"
19009         log "starting reads"
19010         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19011         log "truncating the file"
19012         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19013                 error "multiop failed while truncating the file"
19014         log "killing dd"
19015         kill %+ || true # reads might have finished
19016         echo "wait until dd is finished"
19017         wait
19018         log "removing the temporary file"
19019         rm -rf $DIR/$tfile || error "tmp file removal failed"
19020 }
19021 run_test 169 "parallel read and truncate should not deadlock"
19022
19023 test_170() {
19024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19025
19026         $LCTL clear     # bug 18514
19027         $LCTL debug_daemon start $TMP/${tfile}_log_good
19028         touch $DIR/$tfile
19029         $LCTL debug_daemon stop
19030         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19031                 error "sed failed to read log_good"
19032
19033         $LCTL debug_daemon start $TMP/${tfile}_log_good
19034         rm -rf $DIR/$tfile
19035         $LCTL debug_daemon stop
19036
19037         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19038                error "lctl df log_bad failed"
19039
19040         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19041         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19042
19043         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19044         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19045
19046         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19047                 error "bad_line good_line1 good_line2 are empty"
19048
19049         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19050         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19051         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19052
19053         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19054         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19055         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19056
19057         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19058                 error "bad_line_new good_line_new are empty"
19059
19060         local expected_good=$((good_line1 + good_line2*2))
19061
19062         rm -f $TMP/${tfile}*
19063         # LU-231, short malformed line may not be counted into bad lines
19064         if [ $bad_line -ne $bad_line_new ] &&
19065                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19066                 error "expected $bad_line bad lines, but got $bad_line_new"
19067                 return 1
19068         fi
19069
19070         if [ $expected_good -ne $good_line_new ]; then
19071                 error "expected $expected_good good lines, but got $good_line_new"
19072                 return 2
19073         fi
19074         true
19075 }
19076 run_test 170 "test lctl df to handle corrupted log ====================="
19077
19078 test_171() { # bug20592
19079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19080
19081         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19082         $LCTL set_param fail_loc=0x50e
19083         $LCTL set_param fail_val=3000
19084         multiop_bg_pause $DIR/$tfile O_s || true
19085         local MULTIPID=$!
19086         kill -USR1 $MULTIPID
19087         # cause log dump
19088         sleep 3
19089         wait $MULTIPID
19090         if dmesg | grep "recursive fault"; then
19091                 error "caught a recursive fault"
19092         fi
19093         $LCTL set_param fail_loc=0
19094         true
19095 }
19096 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19097
19098 test_172() {
19099
19100         #define OBD_FAIL_OBD_CLEANUP  0x60e
19101         $LCTL set_param fail_loc=0x60e
19102         umount $MOUNT || error "umount $MOUNT failed"
19103         stack_trap "mount_client $MOUNT"
19104
19105         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19106                 error "no client OBDs are remained"
19107
19108         $LCTL dl | while read devno state type name foo; do
19109                 case $type in
19110                 lov|osc|lmv|mdc)
19111                         $LCTL --device $name cleanup
19112                         $LCTL --device $name detach
19113                         ;;
19114                 *)
19115                         # skip server devices
19116                         ;;
19117                 esac
19118         done
19119
19120         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19121                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19122                 error "some client OBDs are still remained"
19123         fi
19124
19125 }
19126 run_test 172 "manual device removal with lctl cleanup/detach ======"
19127
19128 # it would be good to share it with obdfilter-survey/iokit-libecho code
19129 setup_obdecho_osc () {
19130         local rc=0
19131         local ost_nid=$1
19132         local obdfilter_name=$2
19133         echo "Creating new osc for $obdfilter_name on $ost_nid"
19134         # make sure we can find loopback nid
19135         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19136
19137         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19138                            ${obdfilter_name}_osc_UUID || rc=2; }
19139         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19140                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19141         return $rc
19142 }
19143
19144 cleanup_obdecho_osc () {
19145         local obdfilter_name=$1
19146         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19147         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19148         return 0
19149 }
19150
19151 obdecho_test() {
19152         local OBD=$1
19153         local node=$2
19154         local pages=${3:-64}
19155         local rc=0
19156         local id
19157
19158         local count=10
19159         local obd_size=$(get_obd_size $node $OBD)
19160         local page_size=$(get_page_size $node)
19161         if [[ -n "$obd_size" ]]; then
19162                 local new_count=$((obd_size / (pages * page_size / 1024)))
19163                 [[ $new_count -ge $count ]] || count=$new_count
19164         fi
19165
19166         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19167         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19168                            rc=2; }
19169         if [ $rc -eq 0 ]; then
19170             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19171             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19172         fi
19173         echo "New object id is $id"
19174         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19175                            rc=4; }
19176         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19177                            "test_brw $count w v $pages $id" || rc=4; }
19178         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19179                            rc=4; }
19180         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19181                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19182         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19183                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19184         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19185         return $rc
19186 }
19187
19188 test_180a() {
19189         skip "obdecho on osc is no longer supported"
19190 }
19191 run_test 180a "test obdecho on osc"
19192
19193 test_180b() {
19194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19195         remote_ost_nodsh && skip "remote OST with nodsh"
19196
19197         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19198                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19199                 error "failed to load module obdecho"
19200
19201         local target=$(do_facet ost1 $LCTL dl |
19202                        awk '/obdfilter/ { print $4; exit; }')
19203
19204         if [ -n "$target" ]; then
19205                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19206         else
19207                 do_facet ost1 $LCTL dl
19208                 error "there is no obdfilter target on ost1"
19209         fi
19210 }
19211 run_test 180b "test obdecho directly on obdfilter"
19212
19213 test_180c() { # LU-2598
19214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19215         remote_ost_nodsh && skip "remote OST with nodsh"
19216         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19217                 skip "Need MDS version at least 2.4.0"
19218
19219         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19220                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19221                 error "failed to load module obdecho"
19222
19223         local target=$(do_facet ost1 $LCTL dl |
19224                        awk '/obdfilter/ { print $4; exit; }')
19225
19226         if [ -n "$target" ]; then
19227                 local pages=16384 # 64MB bulk I/O RPC size
19228
19229                 obdecho_test "$target" ost1 "$pages" ||
19230                         error "obdecho_test with pages=$pages failed with $?"
19231         else
19232                 do_facet ost1 $LCTL dl
19233                 error "there is no obdfilter target on ost1"
19234         fi
19235 }
19236 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19237
19238 test_181() { # bug 22177
19239         test_mkdir $DIR/$tdir
19240         # create enough files to index the directory
19241         createmany -o $DIR/$tdir/foobar 4000
19242         # print attributes for debug purpose
19243         lsattr -d .
19244         # open dir
19245         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19246         MULTIPID=$!
19247         # remove the files & current working dir
19248         unlinkmany $DIR/$tdir/foobar 4000
19249         rmdir $DIR/$tdir
19250         kill -USR1 $MULTIPID
19251         wait $MULTIPID
19252         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19253         return 0
19254 }
19255 run_test 181 "Test open-unlinked dir ========================"
19256
19257 test_182a() {
19258         local fcount=1000
19259         local tcount=10
19260
19261         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19262
19263         $LCTL set_param mdc.*.rpc_stats=clear
19264
19265         for (( i = 0; i < $tcount; i++ )) ; do
19266                 mkdir $DIR/$tdir/$i
19267         done
19268
19269         for (( i = 0; i < $tcount; i++ )) ; do
19270                 createmany -o $DIR/$tdir/$i/f- $fcount &
19271         done
19272         wait
19273
19274         for (( i = 0; i < $tcount; i++ )) ; do
19275                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19276         done
19277         wait
19278
19279         $LCTL get_param mdc.*.rpc_stats
19280
19281         rm -rf $DIR/$tdir
19282 }
19283 run_test 182a "Test parallel modify metadata operations from mdc"
19284
19285 test_182b() {
19286         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19287         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19288         local dcount=1000
19289         local tcount=10
19290         local stime
19291         local etime
19292         local delta
19293
19294         do_facet mds1 $LCTL list_param \
19295                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19296                 skip "MDS lacks parallel RPC handling"
19297
19298         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19299
19300         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19301                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19302
19303         stime=$(date +%s)
19304         createmany -i 0 -d $DIR/$tdir/t- $tcount
19305
19306         for (( i = 0; i < $tcount; i++ )) ; do
19307                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19308         done
19309         wait
19310         etime=$(date +%s)
19311         delta=$((etime - stime))
19312         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19313
19314         stime=$(date +%s)
19315         for (( i = 0; i < $tcount; i++ )) ; do
19316                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19317         done
19318         wait
19319         etime=$(date +%s)
19320         delta=$((etime - stime))
19321         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19322
19323         rm -rf $DIR/$tdir
19324
19325         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19326
19327         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19328
19329         stime=$(date +%s)
19330         createmany -i 0 -d $DIR/$tdir/t- $tcount
19331
19332         for (( i = 0; i < $tcount; i++ )) ; do
19333                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19334         done
19335         wait
19336         etime=$(date +%s)
19337         delta=$((etime - stime))
19338         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19339
19340         stime=$(date +%s)
19341         for (( i = 0; i < $tcount; i++ )) ; do
19342                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19343         done
19344         wait
19345         etime=$(date +%s)
19346         delta=$((etime - stime))
19347         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19348
19349         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19350 }
19351 run_test 182b "Test parallel modify metadata operations from osp"
19352
19353 test_183() { # LU-2275
19354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19355         remote_mds_nodsh && skip "remote MDS with nodsh"
19356         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19357                 skip "Need MDS version at least 2.3.56"
19358
19359         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19360         echo aaa > $DIR/$tdir/$tfile
19361
19362 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19363         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19364
19365         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19366         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19367
19368         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19369
19370         # Flush negative dentry cache
19371         touch $DIR/$tdir/$tfile
19372
19373         # We are not checking for any leaked references here, they'll
19374         # become evident next time we do cleanup with module unload.
19375         rm -rf $DIR/$tdir
19376 }
19377 run_test 183 "No crash or request leak in case of strange dispositions ========"
19378
19379 # test suite 184 is for LU-2016, LU-2017
19380 test_184a() {
19381         check_swap_layouts_support
19382
19383         dir0=$DIR/$tdir/$testnum
19384         test_mkdir -p -c1 $dir0
19385         ref1=/etc/passwd
19386         ref2=/etc/group
19387         file1=$dir0/f1
19388         file2=$dir0/f2
19389         $LFS setstripe -c1 $file1
19390         cp $ref1 $file1
19391         $LFS setstripe -c2 $file2
19392         cp $ref2 $file2
19393         gen1=$($LFS getstripe -g $file1)
19394         gen2=$($LFS getstripe -g $file2)
19395
19396         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19397         gen=$($LFS getstripe -g $file1)
19398         [[ $gen1 != $gen ]] ||
19399                 error "Layout generation on $file1 does not change"
19400         gen=$($LFS getstripe -g $file2)
19401         [[ $gen2 != $gen ]] ||
19402                 error "Layout generation on $file2 does not change"
19403
19404         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19405         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19406
19407         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19408 }
19409 run_test 184a "Basic layout swap"
19410
19411 test_184b() {
19412         check_swap_layouts_support
19413
19414         dir0=$DIR/$tdir/$testnum
19415         mkdir -p $dir0 || error "creating dir $dir0"
19416         file1=$dir0/f1
19417         file2=$dir0/f2
19418         file3=$dir0/f3
19419         dir1=$dir0/d1
19420         dir2=$dir0/d2
19421         mkdir $dir1 $dir2
19422         $LFS setstripe -c1 $file1
19423         $LFS setstripe -c2 $file2
19424         $LFS setstripe -c1 $file3
19425         chown $RUNAS_ID $file3
19426         gen1=$($LFS getstripe -g $file1)
19427         gen2=$($LFS getstripe -g $file2)
19428
19429         $LFS swap_layouts $dir1 $dir2 &&
19430                 error "swap of directories layouts should fail"
19431         $LFS swap_layouts $dir1 $file1 &&
19432                 error "swap of directory and file layouts should fail"
19433         $RUNAS $LFS swap_layouts $file1 $file2 &&
19434                 error "swap of file we cannot write should fail"
19435         $LFS swap_layouts $file1 $file3 &&
19436                 error "swap of file with different owner should fail"
19437         /bin/true # to clear error code
19438 }
19439 run_test 184b "Forbidden layout swap (will generate errors)"
19440
19441 test_184c() {
19442         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19443         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19444         check_swap_layouts_support
19445         check_swap_layout_no_dom $DIR
19446
19447         local dir0=$DIR/$tdir/$testnum
19448         mkdir -p $dir0 || error "creating dir $dir0"
19449
19450         local ref1=$dir0/ref1
19451         local ref2=$dir0/ref2
19452         local file1=$dir0/file1
19453         local file2=$dir0/file2
19454         # create a file large enough for the concurrent test
19455         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19456         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19457         echo "ref file size: ref1($(stat -c %s $ref1))," \
19458              "ref2($(stat -c %s $ref2))"
19459
19460         cp $ref2 $file2
19461         dd if=$ref1 of=$file1 bs=16k &
19462         local DD_PID=$!
19463
19464         # Make sure dd starts to copy file, but wait at most 5 seconds
19465         local loops=0
19466         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19467
19468         $LFS swap_layouts $file1 $file2
19469         local rc=$?
19470         wait $DD_PID
19471         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19472         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19473
19474         # how many bytes copied before swapping layout
19475         local copied=$(stat -c %s $file2)
19476         local remaining=$(stat -c %s $ref1)
19477         remaining=$((remaining - copied))
19478         echo "Copied $copied bytes before swapping layout..."
19479
19480         cmp -n $copied $file1 $ref2 | grep differ &&
19481                 error "Content mismatch [0, $copied) of ref2 and file1"
19482         cmp -n $copied $file2 $ref1 ||
19483                 error "Content mismatch [0, $copied) of ref1 and file2"
19484         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19485                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19486
19487         # clean up
19488         rm -f $ref1 $ref2 $file1 $file2
19489 }
19490 run_test 184c "Concurrent write and layout swap"
19491
19492 test_184d() {
19493         check_swap_layouts_support
19494         check_swap_layout_no_dom $DIR
19495         [ -z "$(which getfattr 2>/dev/null)" ] &&
19496                 skip_env "no getfattr command"
19497
19498         local file1=$DIR/$tdir/$tfile-1
19499         local file2=$DIR/$tdir/$tfile-2
19500         local file3=$DIR/$tdir/$tfile-3
19501         local lovea1
19502         local lovea2
19503
19504         mkdir -p $DIR/$tdir
19505         touch $file1 || error "create $file1 failed"
19506         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19507                 error "create $file2 failed"
19508         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19509                 error "create $file3 failed"
19510         lovea1=$(get_layout_param $file1)
19511
19512         $LFS swap_layouts $file2 $file3 ||
19513                 error "swap $file2 $file3 layouts failed"
19514         $LFS swap_layouts $file1 $file2 ||
19515                 error "swap $file1 $file2 layouts failed"
19516
19517         lovea2=$(get_layout_param $file2)
19518         echo "$lovea1"
19519         echo "$lovea2"
19520         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19521
19522         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19523         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19524 }
19525 run_test 184d "allow stripeless layouts swap"
19526
19527 test_184e() {
19528         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19529                 skip "Need MDS version at least 2.6.94"
19530         check_swap_layouts_support
19531         check_swap_layout_no_dom $DIR
19532         [ -z "$(which getfattr 2>/dev/null)" ] &&
19533                 skip_env "no getfattr command"
19534
19535         local file1=$DIR/$tdir/$tfile-1
19536         local file2=$DIR/$tdir/$tfile-2
19537         local file3=$DIR/$tdir/$tfile-3
19538         local lovea
19539
19540         mkdir -p $DIR/$tdir
19541         touch $file1 || error "create $file1 failed"
19542         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19543                 error "create $file2 failed"
19544         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19545                 error "create $file3 failed"
19546
19547         $LFS swap_layouts $file1 $file2 ||
19548                 error "swap $file1 $file2 layouts failed"
19549
19550         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19551         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19552
19553         echo 123 > $file1 || error "Should be able to write into $file1"
19554
19555         $LFS swap_layouts $file1 $file3 ||
19556                 error "swap $file1 $file3 layouts failed"
19557
19558         echo 123 > $file1 || error "Should be able to write into $file1"
19559
19560         rm -rf $file1 $file2 $file3
19561 }
19562 run_test 184e "Recreate layout after stripeless layout swaps"
19563
19564 test_184f() {
19565         # Create a file with name longer than sizeof(struct stat) ==
19566         # 144 to see if we can get chars from the file name to appear
19567         # in the returned striping. Note that 'f' == 0x66.
19568         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19569
19570         mkdir -p $DIR/$tdir
19571         mcreate $DIR/$tdir/$file
19572         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19573                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19574         fi
19575 }
19576 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19577
19578 test_185() { # LU-2441
19579         # LU-3553 - no volatile file support in old servers
19580         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19581                 skip "Need MDS version at least 2.3.60"
19582
19583         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19584         touch $DIR/$tdir/spoo
19585         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19586         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19587                 error "cannot create/write a volatile file"
19588         [ "$FILESET" == "" ] &&
19589         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19590                 error "FID is still valid after close"
19591
19592         multiop_bg_pause $DIR/$tdir Vw4096_c
19593         local multi_pid=$!
19594
19595         local OLD_IFS=$IFS
19596         IFS=":"
19597         local fidv=($fid)
19598         IFS=$OLD_IFS
19599         # assume that the next FID for this client is sequential, since stdout
19600         # is unfortunately eaten by multiop_bg_pause
19601         local n=$((${fidv[1]} + 1))
19602         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19603         if [ "$FILESET" == "" ]; then
19604                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19605                         error "FID is missing before close"
19606         fi
19607         kill -USR1 $multi_pid
19608         # 1 second delay, so if mtime change we will see it
19609         sleep 1
19610         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19611         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19612 }
19613 run_test 185 "Volatile file support"
19614
19615 function create_check_volatile() {
19616         local idx=$1
19617         local tgt
19618
19619         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19620         local PID=$!
19621         sleep 1
19622         local FID=$(cat /tmp/${tfile}.fid)
19623         [ "$FID" == "" ] && error "can't get FID for volatile"
19624         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19625         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19626         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19627         kill -USR1 $PID
19628         wait
19629         sleep 1
19630         cancel_lru_locks mdc # flush opencache
19631         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19632         return 0
19633 }
19634
19635 test_185a(){
19636         # LU-12516 - volatile creation via .lustre
19637         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19638                 skip "Need MDS version at least 2.3.55"
19639
19640         create_check_volatile 0
19641         [ $MDSCOUNT -lt 2 ] && return 0
19642
19643         # DNE case
19644         create_check_volatile 1
19645
19646         return 0
19647 }
19648 run_test 185a "Volatile file creation in .lustre/fid/"
19649
19650 test_187a() {
19651         remote_mds_nodsh && skip "remote MDS with nodsh"
19652         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19653                 skip "Need MDS version at least 2.3.0"
19654
19655         local dir0=$DIR/$tdir/$testnum
19656         mkdir -p $dir0 || error "creating dir $dir0"
19657
19658         local file=$dir0/file1
19659         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19660         stack_trap "rm -f $file"
19661         local dv1=$($LFS data_version $file)
19662         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19663         local dv2=$($LFS data_version $file)
19664         [[ $dv1 != $dv2 ]] ||
19665                 error "data version did not change on write $dv1 == $dv2"
19666 }
19667 run_test 187a "Test data version change"
19668
19669 test_187b() {
19670         remote_mds_nodsh && skip "remote MDS with nodsh"
19671         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19672                 skip "Need MDS version at least 2.3.0"
19673
19674         local dir0=$DIR/$tdir/$testnum
19675         mkdir -p $dir0 || error "creating dir $dir0"
19676
19677         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19678         [[ ${DV[0]} != ${DV[1]} ]] ||
19679                 error "data version did not change on write"\
19680                       " ${DV[0]} == ${DV[1]}"
19681
19682         # clean up
19683         rm -f $file1
19684 }
19685 run_test 187b "Test data version change on volatile file"
19686
19687 test_200() {
19688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19689         remote_mgs_nodsh && skip "remote MGS with nodsh"
19690         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19691
19692         local POOL=${POOL:-cea1}
19693         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19694         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19695         # Pool OST targets
19696         local first_ost=0
19697         local last_ost=$(($OSTCOUNT - 1))
19698         local ost_step=2
19699         local ost_list=$(seq $first_ost $ost_step $last_ost)
19700         local ost_range="$first_ost $last_ost $ost_step"
19701         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19702         local file_dir=$POOL_ROOT/file_tst
19703         local subdir=$test_path/subdir
19704         local rc=0
19705
19706         while : ; do
19707                 # former test_200a test_200b
19708                 pool_add $POOL                          || { rc=$? ; break; }
19709                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19710                 # former test_200c test_200d
19711                 mkdir -p $test_path
19712                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19713                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19714                 mkdir -p $subdir
19715                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19716                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19717                                                         || { rc=$? ; break; }
19718                 # former test_200e test_200f
19719                 local files=$((OSTCOUNT*3))
19720                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19721                                                         || { rc=$? ; break; }
19722                 pool_create_files $POOL $file_dir $files "$ost_list" \
19723                                                         || { rc=$? ; break; }
19724                 # former test_200g test_200h
19725                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19726                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19727
19728                 # former test_201a test_201b test_201c
19729                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19730
19731                 local f=$test_path/$tfile
19732                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19733                 pool_remove $POOL $f                    || { rc=$? ; break; }
19734                 break
19735         done
19736
19737         destroy_test_pools
19738
19739         return $rc
19740 }
19741 run_test 200 "OST pools"
19742
19743 # usage: default_attr <count | size | offset>
19744 default_attr() {
19745         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19746 }
19747
19748 # usage: check_default_stripe_attr
19749 check_default_stripe_attr() {
19750         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19751         case $1 in
19752         --stripe-count|-c)
19753                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19754         --stripe-size|-S)
19755                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19756         --stripe-index|-i)
19757                 EXPECTED=-1;;
19758         *)
19759                 error "unknown getstripe attr '$1'"
19760         esac
19761
19762         [ $ACTUAL == $EXPECTED ] ||
19763                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19764 }
19765
19766 test_204a() {
19767         test_mkdir $DIR/$tdir
19768         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19769
19770         check_default_stripe_attr --stripe-count
19771         check_default_stripe_attr --stripe-size
19772         check_default_stripe_attr --stripe-index
19773 }
19774 run_test 204a "Print default stripe attributes"
19775
19776 test_204b() {
19777         test_mkdir $DIR/$tdir
19778         $LFS setstripe --stripe-count 1 $DIR/$tdir
19779
19780         check_default_stripe_attr --stripe-size
19781         check_default_stripe_attr --stripe-index
19782 }
19783 run_test 204b "Print default stripe size and offset"
19784
19785 test_204c() {
19786         test_mkdir $DIR/$tdir
19787         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19788
19789         check_default_stripe_attr --stripe-count
19790         check_default_stripe_attr --stripe-index
19791 }
19792 run_test 204c "Print default stripe count and offset"
19793
19794 test_204d() {
19795         test_mkdir $DIR/$tdir
19796         $LFS setstripe --stripe-index 0 $DIR/$tdir
19797
19798         check_default_stripe_attr --stripe-count
19799         check_default_stripe_attr --stripe-size
19800 }
19801 run_test 204d "Print default stripe count and size"
19802
19803 test_204e() {
19804         test_mkdir $DIR/$tdir
19805         $LFS setstripe -d $DIR/$tdir
19806
19807         # LU-16904 check if root is set as PFL layout
19808         local numcomp=$($LFS getstripe --component-count $MOUNT)
19809
19810         if [[ $numcomp -gt 0 ]]; then
19811                 check_default_stripe_attr --stripe-count
19812         else
19813                 check_default_stripe_attr --stripe-count --raw
19814         fi
19815         check_default_stripe_attr --stripe-size --raw
19816         check_default_stripe_attr --stripe-index --raw
19817 }
19818 run_test 204e "Print raw stripe attributes"
19819
19820 test_204f() {
19821         test_mkdir $DIR/$tdir
19822         $LFS setstripe --stripe-count 1 $DIR/$tdir
19823
19824         check_default_stripe_attr --stripe-size --raw
19825         check_default_stripe_attr --stripe-index --raw
19826 }
19827 run_test 204f "Print raw stripe size and offset"
19828
19829 test_204g() {
19830         test_mkdir $DIR/$tdir
19831         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19832
19833         check_default_stripe_attr --stripe-count --raw
19834         check_default_stripe_attr --stripe-index --raw
19835 }
19836 run_test 204g "Print raw stripe count and offset"
19837
19838 test_204h() {
19839         test_mkdir $DIR/$tdir
19840         $LFS setstripe --stripe-index 0 $DIR/$tdir
19841
19842         check_default_stripe_attr --stripe-count --raw
19843         check_default_stripe_attr --stripe-size --raw
19844 }
19845 run_test 204h "Print raw stripe count and size"
19846
19847 # Figure out which job scheduler is being used, if any,
19848 # or use a fake one
19849 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19850         JOBENV=SLURM_JOB_ID
19851 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19852         JOBENV=LSB_JOBID
19853 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19854         JOBENV=PBS_JOBID
19855 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19856         JOBENV=LOADL_STEP_ID
19857 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19858         JOBENV=JOB_ID
19859 else
19860         $LCTL list_param jobid_name > /dev/null 2>&1
19861         if [ $? -eq 0 ]; then
19862                 JOBENV=nodelocal
19863         else
19864                 JOBENV=FAKE_JOBID
19865         fi
19866 fi
19867 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19868
19869 verify_jobstats() {
19870         local cmd=($1)
19871         shift
19872         local facets="$@"
19873
19874 # we don't really need to clear the stats for this test to work, since each
19875 # command has a unique jobid, but it makes debugging easier if needed.
19876 #       for facet in $facets; do
19877 #               local dev=$(convert_facet2label $facet)
19878 #               # clear old jobstats
19879 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19880 #       done
19881
19882         # use a new JobID for each test, or we might see an old one
19883         [ "$JOBENV" = "FAKE_JOBID" ] &&
19884                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19885
19886         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19887
19888         [ "$JOBENV" = "nodelocal" ] && {
19889                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19890                 $LCTL set_param jobid_name=$FAKE_JOBID
19891                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19892         }
19893
19894         log "Test: ${cmd[*]}"
19895         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19896
19897         if [ $JOBENV = "FAKE_JOBID" ]; then
19898                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19899         else
19900                 ${cmd[*]}
19901         fi
19902
19903         # all files are created on OST0000
19904         for facet in $facets; do
19905                 local stats="*.$(convert_facet2label $facet).job_stats"
19906
19907                 # strip out libtool wrappers for in-tree executables
19908                 if (( $(do_facet $facet lctl get_param $stats |
19909                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19910                         do_facet $facet lctl get_param $stats
19911                         error "No jobstats for $JOBVAL found on $facet::$stats"
19912                 fi
19913         done
19914 }
19915
19916 jobstats_set() {
19917         local new_jobenv=$1
19918
19919         set_persistent_param_and_check client "jobid_var" \
19920                 "$FSNAME.sys.jobid_var" $new_jobenv
19921 }
19922
19923 test_205a() { # Job stats
19924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19925         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19926                 skip "Need MDS version with at least 2.7.1"
19927         remote_mgs_nodsh && skip "remote MGS with nodsh"
19928         remote_mds_nodsh && skip "remote MDS with nodsh"
19929         remote_ost_nodsh && skip "remote OST with nodsh"
19930         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19931                 skip "Server doesn't support jobstats"
19932         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19933
19934         local old_jobenv=$($LCTL get_param -n jobid_var)
19935         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19936         stack_trap "jobstats_set $old_jobenv" EXIT
19937
19938         changelog_register
19939
19940         local old_jobid_name=$($LCTL get_param jobid_name)
19941         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19942
19943         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19944                                 mdt.*.job_cleanup_interval | head -n 1)
19945         local new_interval=5
19946         do_facet $SINGLEMDS \
19947                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19948         stack_trap "do_facet $SINGLEMDS \
19949                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19950         local start=$SECONDS
19951
19952         local cmd
19953         # mkdir
19954         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19955         verify_jobstats "$cmd" "$SINGLEMDS"
19956         # rmdir
19957         cmd="rmdir $DIR/$tdir"
19958         verify_jobstats "$cmd" "$SINGLEMDS"
19959         # mkdir on secondary MDT
19960         if [ $MDSCOUNT -gt 1 ]; then
19961                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19962                 verify_jobstats "$cmd" "mds2"
19963         fi
19964         # mknod
19965         cmd="mknod $DIR/$tfile c 1 3"
19966         verify_jobstats "$cmd" "$SINGLEMDS"
19967         # unlink
19968         cmd="rm -f $DIR/$tfile"
19969         verify_jobstats "$cmd" "$SINGLEMDS"
19970         # create all files on OST0000 so verify_jobstats can find OST stats
19971         # open & close
19972         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19973         verify_jobstats "$cmd" "$SINGLEMDS"
19974         # setattr
19975         cmd="touch $DIR/$tfile"
19976         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19977         # write
19978         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19979         verify_jobstats "$cmd" "ost1"
19980         # read
19981         cancel_lru_locks osc
19982         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19983         verify_jobstats "$cmd" "ost1"
19984         # truncate
19985         cmd="$TRUNCATE $DIR/$tfile 0"
19986         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19987         # rename
19988         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19989         verify_jobstats "$cmd" "$SINGLEMDS"
19990         # jobstats expiry - sleep until old stats should be expired
19991         local left=$((new_interval + 5 - (SECONDS - start)))
19992         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19993                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19994                         "0" $left
19995         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19996         verify_jobstats "$cmd" "$SINGLEMDS"
19997         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19998             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19999
20000         # Ensure that jobid are present in changelog (if supported by MDS)
20001         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20002                 changelog_dump | tail -10
20003                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20004                 [ $jobids -eq 9 ] ||
20005                         error "Wrong changelog jobid count $jobids != 9"
20006
20007                 # LU-5862
20008                 JOBENV="disable"
20009                 jobstats_set $JOBENV
20010                 touch $DIR/$tfile
20011                 changelog_dump | grep $tfile
20012                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20013                 [ $jobids -eq 0 ] ||
20014                         error "Unexpected jobids when jobid_var=$JOBENV"
20015         fi
20016
20017         # test '%j' access to environment variable - if supported
20018         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20019                 JOBENV="JOBCOMPLEX"
20020                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20021
20022                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20023         fi
20024
20025         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20026                 JOBENV="JOBCOMPLEX"
20027                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20028
20029                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20030         fi
20031
20032         # test '%j' access to per-session jobid - if supported
20033         if lctl list_param jobid_this_session > /dev/null 2>&1
20034         then
20035                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20036                 lctl set_param jobid_this_session=$USER
20037
20038                 JOBENV="JOBCOMPLEX"
20039                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20040
20041                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20042         fi
20043 }
20044 run_test 205a "Verify job stats"
20045
20046 # LU-13117, LU-13597, LU-16599
20047 test_205b() {
20048         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20049                 skip "Need MDS version at least 2.13.54.91"
20050
20051         local job_stats="mdt.*.job_stats"
20052         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20053
20054         do_facet mds1 $LCTL set_param $job_stats=clear
20055
20056         # Setting jobid_var to USER might not be supported
20057         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20058         $LCTL set_param jobid_var=USER || true
20059         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20060         $LCTL set_param jobid_name="%j.%e.%u"
20061
20062         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20063         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20064                 { do_facet mds1 $LCTL get_param $job_stats;
20065                   error "Unexpected jobid found"; }
20066         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20067                 { do_facet mds1 $LCTL get_param $job_stats;
20068                   error "wrong job_stats format found"; }
20069
20070         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20071                 echo "MDS does not yet escape jobid" && return 0
20072
20073         mkdir_on_mdt0 $DIR/$tdir
20074         $LCTL set_param jobid_var=TEST205b
20075         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20076         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20077                       awk '/has\\x20sp/ {print $3}')
20078         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20079                   error "jobid not escaped"; }
20080
20081         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20082                 # need to run such a command on mds1:
20083                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20084                 #
20085                 # there might be multiple MDTs on single mds server, so need to
20086                 # specifiy MDT0000. Or the command will fail due to other MDTs
20087                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20088                         error "cannot clear escaped jobid in job_stats";
20089         else
20090                 echo "MDS does not support clearing escaped jobid"
20091         fi
20092 }
20093 run_test 205b "Verify job stats jobid and output format"
20094
20095 # LU-13733
20096 test_205c() {
20097         $LCTL set_param llite.*.stats=0
20098         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20099         $LCTL get_param llite.*.stats
20100         $LCTL get_param llite.*.stats | grep \
20101                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20102                         error "wrong client stats format found"
20103 }
20104 run_test 205c "Verify client stats format"
20105
20106 test_205d() {
20107         local file=$DIR/$tdir/$tfile
20108
20109         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20110                 skip "need lustre >= 2.15.53 for lljobstat"
20111         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20112                 skip "need lustre >= 2.15.53 for lljobstat"
20113         verify_yaml_available || skip_env "YAML verification not installed"
20114
20115         test_mkdir -i 0 $DIR/$tdir
20116         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20117         stack_trap "rm -rf $DIR/$tdir"
20118
20119         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20120                 error "failed to write data to $file"
20121         mv $file $file.2
20122
20123         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20124         echo -n 'verify rename_stats...'
20125         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20126                 verify_yaml || error "rename_stats is not valid YAML"
20127         echo " OK"
20128
20129         echo -n 'verify mdt job_stats...'
20130         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20131                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20132         echo " OK"
20133
20134         echo -n 'verify ost job_stats...'
20135         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20136                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20137         echo " OK"
20138 }
20139 run_test 205d "verify the format of some stats files"
20140
20141 test_205e() {
20142         local ops_comma
20143         local file=$DIR/$tdir/$tfile
20144         local -a cli_params
20145
20146         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20147                 skip "need lustre >= 2.15.53 for lljobstat"
20148         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20149                 skip "need lustre >= 2.15.53 for lljobstat"
20150         verify_yaml_available || skip_env "YAML verification not installed"
20151
20152         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20153         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20154         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20155
20156         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20157         stack_trap "rm -rf $DIR/$tdir"
20158
20159         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20160                 error "failed to create $file on ost1"
20161         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20162                 error "failed to write data to $file"
20163
20164         do_facet mds1 "$LCTL get_param *.*.job_stats"
20165         do_facet ost1 "$LCTL get_param *.*.job_stats"
20166
20167         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20168         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20169                 error "The output of lljobstat is not an valid YAML"
20170
20171         # verify that job dd.0 does exist and has some ops on ost1
20172         # typically this line is like:
20173         # - 205e.dd.0:            {ops: 20, ...}
20174         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20175                     awk '$2=="205e.dd.0:" {print $4}')
20176
20177         (( ${ops_comma%,} >= 10 )) ||
20178                 error "cannot find job 205e.dd.0 with ops >= 10"
20179 }
20180 run_test 205e "verify the output of lljobstat"
20181
20182 test_205f() {
20183         verify_yaml_available || skip_env "YAML verification not installed"
20184
20185         # check both qos_ost_weights and qos_mdt_weights
20186         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20187         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20188                 error "qos_ost_weights is not valid YAML"
20189 }
20190 run_test 205f "verify qos_ost_weights YAML format "
20191
20192 __test_205_jobstats_dump() {
20193         local -a pids
20194         local nbr_instance=$1
20195
20196         while true; do
20197                 if (( ${#pids[@]} >= nbr_instance )); then
20198                         wait ${pids[@]}
20199                         pids=()
20200                 fi
20201
20202                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20203                 pids+=( $! )
20204         done
20205 }
20206
20207 __test_205_cleanup() {
20208         kill $@
20209         # Clear all job entries
20210         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20211 }
20212
20213 test_205g() {
20214         local -a mds1_params
20215         local -a cli_params
20216         local pids
20217         local interval=5
20218
20219         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20220         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20221         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20222
20223         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20224         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20225         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20226
20227         # start jobs loop
20228         export TEST205G_ID=205g
20229         stack_trap "unset TEST205G_ID" EXIT
20230         while true; do
20231                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20232         done & pids="$! "
20233
20234         __test_205_jobstats_dump 4 & pids+="$! "
20235         stack_trap "__test_205_cleanup $pids" EXIT INT
20236
20237         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20238 }
20239 run_test 205g "stress test for job_stats procfile"
20240
20241 test_205h() {
20242         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20243                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20244         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20245
20246         local dir=$DIR/$tdir
20247         local f=$dir/$tfile
20248         local f2=$dir/$tfile-2
20249         local f3=$dir/$tfile-3
20250         local subdir=$DIR/dir
20251         local val
20252
20253         local mdts=$(comma_list $(mdts_nodes))
20254         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20255         local client_saved=$($LCTL get_param -n jobid_var)
20256
20257         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20258         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20259
20260         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20261                 error "failed to set job_xattr parameter to user.job"
20262         $LCTL set_param jobid_var=procname.uid ||
20263                 error "failed to set jobid_var parameter"
20264
20265         test_mkdir $dir
20266
20267         touch $f
20268         val=$(getfattr -n user.job $f | grep user.job)
20269         [[ $val = user.job=\"touch.0\" ]] ||
20270                 error "expected user.job=\"touch.0\", got '$val'"
20271
20272         mkdir $subdir
20273         val=$(getfattr -n user.job $subdir | grep user.job)
20274         [[ $val = user.job=\"mkdir.0\" ]] ||
20275                 error "expected user.job=\"mkdir.0\", got '$val'"
20276
20277         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20278                 error "failed to set job_xattr parameter to NONE"
20279
20280         touch $f2
20281         val=$(getfattr -d $f2)
20282         [[ -z $val ]] ||
20283                 error "expected no user xattr, got '$val'"
20284
20285         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20286                 error "failed to set job_xattr parameter to trusted.job"
20287
20288         touch $f3
20289         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20290         [[ $val = trusted.job=\"touch.0\" ]] ||
20291                 error "expected trusted.job=\"touch.0\", got '$val'"
20292 }
20293 run_test 205h "check jobid xattr is stored correctly"
20294
20295 test_205i() {
20296         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20297                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20298
20299         local mdts=$(comma_list $(mdts_nodes))
20300         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20301
20302         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20303
20304         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20305                 error "failed to set mdt.*.job_xattr to user.1234567"
20306
20307         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20308                 error "failed to reject too long job_xattr name"
20309
20310         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20311                 error "failed to reject job_xattr name in bad format"
20312
20313         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20314                 error "failed to reject job_xattr name with invalid character"
20315
20316         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20317                         xargs $LCTL set_param" &&
20318                 error "failed to reject job_xattr name with non-ascii character"
20319
20320         return 0
20321 }
20322 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20323
20324 # LU-1480, LU-1773 and LU-1657
20325 test_206() {
20326         mkdir -p $DIR/$tdir
20327         $LFS setstripe -c -1 $DIR/$tdir
20328 #define OBD_FAIL_LOV_INIT 0x1403
20329         $LCTL set_param fail_loc=0xa0001403
20330         $LCTL set_param fail_val=1
20331         touch $DIR/$tdir/$tfile || true
20332 }
20333 run_test 206 "fail lov_init_raid0() doesn't lbug"
20334
20335 test_207a() {
20336         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20337         local fsz=`stat -c %s $DIR/$tfile`
20338         cancel_lru_locks mdc
20339
20340         # do not return layout in getattr intent
20341 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20342         $LCTL set_param fail_loc=0x170
20343         local sz=`stat -c %s $DIR/$tfile`
20344
20345         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20346
20347         rm -rf $DIR/$tfile
20348 }
20349 run_test 207a "can refresh layout at glimpse"
20350
20351 test_207b() {
20352         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20353         local cksum=`md5sum $DIR/$tfile`
20354         local fsz=`stat -c %s $DIR/$tfile`
20355         cancel_lru_locks mdc
20356         cancel_lru_locks osc
20357
20358         # do not return layout in getattr intent
20359 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20360         $LCTL set_param fail_loc=0x171
20361
20362         # it will refresh layout after the file is opened but before read issues
20363         echo checksum is "$cksum"
20364         echo "$cksum" |md5sum -c --quiet || error "file differs"
20365
20366         rm -rf $DIR/$tfile
20367 }
20368 run_test 207b "can refresh layout at open"
20369
20370 test_208() {
20371         # FIXME: in this test suite, only RD lease is used. This is okay
20372         # for now as only exclusive open is supported. After generic lease
20373         # is done, this test suite should be revised. - Jinshan
20374
20375         remote_mds_nodsh && skip "remote MDS with nodsh"
20376         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20377                 skip "Need MDS version at least 2.4.52"
20378
20379         echo "==== test 1: verify get lease work"
20380         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20381
20382         echo "==== test 2: verify lease can be broken by upcoming open"
20383         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20384         local PID=$!
20385         sleep 2
20386
20387         $MULTIOP $DIR/$tfile oO_RDWR:c
20388         kill -USR1 $PID && wait $PID || error "break lease error"
20389
20390         echo "==== test 3: verify lease can't be granted if an open already exists"
20391         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20392         local PID=$!
20393         sleep 2
20394
20395         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20396         kill -USR1 $PID && wait $PID || error "open file error"
20397
20398         echo "==== test 4: lease can sustain over recovery"
20399         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20400         PID=$!
20401         sleep 2
20402
20403         fail mds1
20404
20405         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20406
20407         echo "==== test 5: lease broken can't be regained by replay"
20408         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20409         PID=$!
20410         sleep 2
20411
20412         # open file to break lease and then recovery
20413         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20414         fail mds1
20415
20416         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20417
20418         rm -f $DIR/$tfile
20419 }
20420 run_test 208 "Exclusive open"
20421
20422 test_209() {
20423         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20424                 skip_env "must have disp_stripe"
20425
20426         touch $DIR/$tfile
20427         sync; sleep 5; sync;
20428
20429         echo 3 > /proc/sys/vm/drop_caches
20430         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20431                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20432         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20433
20434         # open/close 500 times
20435         for i in $(seq 500); do
20436                 cat $DIR/$tfile
20437         done
20438
20439         echo 3 > /proc/sys/vm/drop_caches
20440         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20441                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20442         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20443
20444         echo "before: $req_before, after: $req_after"
20445         [ $((req_after - req_before)) -ge 300 ] &&
20446                 error "open/close requests are not freed"
20447         return 0
20448 }
20449 run_test 209 "read-only open/close requests should be freed promptly"
20450
20451 test_210() {
20452         local pid
20453
20454         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20455         pid=$!
20456         sleep 1
20457
20458         $LFS getstripe $DIR/$tfile
20459         kill -USR1 $pid
20460         wait $pid || error "multiop failed"
20461
20462         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20463         pid=$!
20464         sleep 1
20465
20466         $LFS getstripe $DIR/$tfile
20467         kill -USR1 $pid
20468         wait $pid || error "multiop failed"
20469 }
20470 run_test 210 "lfs getstripe does not break leases"
20471
20472 function test_211() {
20473         local PID
20474         local id
20475         local rc
20476
20477         stack_trap "rm -f $DIR/$tfile" EXIT
20478         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20479                 error "can't create file"
20480         $LFS mirror extend -N $DIR/$tfile ||
20481                 error "can't create a replica"
20482         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20483         $LFS getstripe $DIR/$tfile
20484         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20485         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20486
20487         $MULTIOP $DIR/$tfile OeW_E+eUc &
20488         PID=$!
20489         sleep 0.3
20490
20491         id=$($LFS getstripe $DIR/$tfile |
20492                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20493         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20494                 error "removed last in-sync replica?"
20495
20496         kill -USR1 $PID
20497         wait $PID
20498         (( $? == 0 )) || error "failed split broke the lease"
20499 }
20500 run_test 211 "failed mirror split doesn't break write lease"
20501
20502 test_212() {
20503         size=`date +%s`
20504         size=$((size % 8192 + 1))
20505         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20506         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20507         rm -f $DIR/f212 $DIR/f212.xyz
20508 }
20509 run_test 212 "Sendfile test ============================================"
20510
20511 test_213() {
20512         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20513         cancel_lru_locks osc
20514         lctl set_param fail_loc=0x8000040f
20515         # generate a read lock
20516         cat $DIR/$tfile > /dev/null
20517         # write to the file, it will try to cancel the above read lock.
20518         cat /etc/hosts >> $DIR/$tfile
20519 }
20520 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20521
20522 test_214() { # for bug 20133
20523         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20524         for (( i=0; i < 340; i++ )) ; do
20525                 touch $DIR/$tdir/d214c/a$i
20526         done
20527
20528         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20529         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20530         ls $DIR/d214c || error "ls $DIR/d214c failed"
20531         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20532         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20533 }
20534 run_test 214 "hash-indexed directory test - bug 20133"
20535
20536 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20537 create_lnet_proc_files() {
20538         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20539 }
20540
20541 # counterpart of create_lnet_proc_files
20542 remove_lnet_proc_files() {
20543         rm -f $TMP/lnet_$1.sys
20544 }
20545
20546 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20547 # 3rd arg as regexp for body
20548 check_lnet_proc_stats() {
20549         local l=$(cat "$TMP/lnet_$1" |wc -l)
20550         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20551
20552         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20553 }
20554
20555 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20556 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20557 # optional and can be regexp for 2nd line (lnet.routes case)
20558 check_lnet_proc_entry() {
20559         local blp=2          # blp stands for 'position of 1st line of body'
20560         [ -z "$5" ] || blp=3 # lnet.routes case
20561
20562         local l=$(cat "$TMP/lnet_$1" |wc -l)
20563         # subtracting one from $blp because the body can be empty
20564         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20565
20566         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20567                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20568
20569         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20570                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20571
20572         # bail out if any unexpected line happened
20573         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20574         [ "$?" != 0 ] || error "$2 misformatted"
20575 }
20576
20577 test_215() { # for bugs 18102, 21079, 21517
20578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20579
20580         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20581         local P='[1-9][0-9]*'           # positive numeric
20582         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20583         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20584         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20585         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20586
20587         local L1 # regexp for 1st line
20588         local L2 # regexp for 2nd line (optional)
20589         local BR # regexp for the rest (body)
20590
20591         # lnet.stats should look as 11 space-separated non-negative numerics
20592         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20593         create_lnet_proc_files "stats"
20594         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20595         remove_lnet_proc_files "stats"
20596
20597         # lnet.routes should look like this:
20598         # Routing disabled/enabled
20599         # net hops priority state router
20600         # where net is a string like tcp0, hops > 0, priority >= 0,
20601         # state is up/down,
20602         # router is a string like 192.168.1.1@tcp2
20603         L1="^Routing (disabled|enabled)$"
20604         L2="^net +hops +priority +state +router$"
20605         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20606         create_lnet_proc_files "routes"
20607         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20608         remove_lnet_proc_files "routes"
20609
20610         # lnet.routers should look like this:
20611         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20612         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20613         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20614         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20615         L1="^ref +rtr_ref +alive +router$"
20616         BR="^$P +$P +(up|down) +$NID$"
20617         create_lnet_proc_files "routers"
20618         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20619         remove_lnet_proc_files "routers"
20620
20621         # lnet.peers should look like this:
20622         # nid refs state last max rtr min tx min queue
20623         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20624         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20625         # numeric (0 or >0 or <0), queue >= 0.
20626         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20627         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20628         create_lnet_proc_files "peers"
20629         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20630         remove_lnet_proc_files "peers"
20631
20632         # lnet.buffers  should look like this:
20633         # pages count credits min
20634         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20635         L1="^pages +count +credits +min$"
20636         BR="^ +$N +$N +$I +$I$"
20637         create_lnet_proc_files "buffers"
20638         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20639         remove_lnet_proc_files "buffers"
20640
20641         # lnet.nis should look like this:
20642         # nid status alive refs peer rtr max tx min
20643         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20644         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20645         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20646         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20647         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20648         create_lnet_proc_files "nis"
20649         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20650         remove_lnet_proc_files "nis"
20651
20652         # can we successfully write to lnet.stats?
20653         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20654 }
20655 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20656
20657 test_216() { # bug 20317
20658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20659         remote_ost_nodsh && skip "remote OST with nodsh"
20660
20661         local node
20662         local facets=$(get_facets OST)
20663         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20664
20665         save_lustre_params client "osc.*.contention_seconds" > $p
20666         save_lustre_params $facets \
20667                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20668         save_lustre_params $facets \
20669                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20670         save_lustre_params $facets \
20671                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20672         clear_stats osc.*.osc_stats
20673
20674         # agressive lockless i/o settings
20675         do_nodes $(comma_list $(osts_nodes)) \
20676                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20677                         ldlm.namespaces.filter-*.contended_locks=0 \
20678                         ldlm.namespaces.filter-*.contention_seconds=60"
20679         lctl set_param -n osc.*.contention_seconds=60
20680
20681         $DIRECTIO write $DIR/$tfile 0 10 4096
20682         $CHECKSTAT -s 40960 $DIR/$tfile
20683
20684         # disable lockless i/o
20685         do_nodes $(comma_list $(osts_nodes)) \
20686                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20687                         ldlm.namespaces.filter-*.contended_locks=32 \
20688                         ldlm.namespaces.filter-*.contention_seconds=0"
20689         lctl set_param -n osc.*.contention_seconds=0
20690         clear_stats osc.*.osc_stats
20691
20692         dd if=/dev/zero of=$DIR/$tfile count=0
20693         $CHECKSTAT -s 0 $DIR/$tfile
20694
20695         restore_lustre_params <$p
20696         rm -f $p
20697         rm $DIR/$tfile
20698 }
20699 run_test 216 "check lockless direct write updates file size and kms correctly"
20700
20701 test_217() { # bug 22430
20702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20703
20704         local node
20705
20706         for node in $(nodes_list); do
20707                 local nid=$(host_nids_address $node $NETTYPE)
20708                 local node_ip=$(do_node $node getent ahostsv4 $node |
20709                                 awk '{ print $1; exit; }')
20710
20711                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20712                 # if hostname matches any NID, use hostname for better testing
20713                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20714                         echo "lctl ping node $node@$NETTYPE"
20715                         lctl ping $node@$NETTYPE
20716                 else # otherwise, at least test 'lctl ping' is working
20717                         echo "lctl ping nid $(h2nettype $nid)"
20718                         lctl ping $(h2nettype $nid)
20719                         echo "skipping $node (no hyphen detected)"
20720                 fi
20721         done
20722 }
20723 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20724
20725 test_218() {
20726         # do directio so as not to populate the page cache
20727         log "creating a 10 Mb file"
20728         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20729                 error "multiop failed while creating a file"
20730         log "starting reads"
20731         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20732         log "truncating the file"
20733         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20734                 error "multiop failed while truncating the file"
20735         log "killing dd"
20736         kill %+ || true # reads might have finished
20737         echo "wait until dd is finished"
20738         wait
20739         log "removing the temporary file"
20740         rm -rf $DIR/$tfile || error "tmp file removal failed"
20741 }
20742 run_test 218 "parallel read and truncate should not deadlock"
20743
20744 test_219() {
20745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20746
20747         # write one partial page
20748         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20749         # set no grant so vvp_io_commit_write will do sync write
20750         $LCTL set_param fail_loc=0x411
20751         # write a full page at the end of file
20752         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20753
20754         $LCTL set_param fail_loc=0
20755         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20756         $LCTL set_param fail_loc=0x411
20757         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20758
20759         # LU-4201
20760         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20761         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20762 }
20763 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20764
20765 test_220() { #LU-325
20766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20767         remote_ost_nodsh && skip "remote OST with nodsh"
20768         remote_mds_nodsh && skip "remote MDS with nodsh"
20769         remote_mgs_nodsh && skip "remote MGS with nodsh"
20770
20771         local OSTIDX=0
20772
20773         # create on MDT0000 so the last_id and next_id are correct
20774         mkdir_on_mdt0 $DIR/$tdir
20775         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20776         OST=${OST%_UUID}
20777
20778         # on the mdt's osc
20779         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20780         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20781                         osp.$mdtosc_proc1.prealloc_last_id)
20782         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20783                         osp.$mdtosc_proc1.prealloc_next_id)
20784
20785         $LFS df -i
20786
20787         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20788         #define OBD_FAIL_OST_ENOINO              0x229
20789         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20790         create_pool $FSNAME.$TESTNAME || return 1
20791         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20792
20793         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20794
20795         MDSOBJS=$((last_id - next_id))
20796         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20797
20798         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20799         echo "OST still has $count kbytes free"
20800
20801         echo "create $MDSOBJS files @next_id..."
20802         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20803
20804         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20805                         osp.$mdtosc_proc1.prealloc_last_id)
20806         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20807                         osp.$mdtosc_proc1.prealloc_next_id)
20808
20809         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20810         $LFS df -i
20811
20812         echo "cleanup..."
20813
20814         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20815         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20816
20817         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20818                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20819         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20820                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20821         echo "unlink $MDSOBJS files @$next_id..."
20822         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20823 }
20824 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20825
20826 test_221() {
20827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20828
20829         dd if=`which date` of=$MOUNT/date oflag=sync
20830         chmod +x $MOUNT/date
20831
20832         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20833         $LCTL set_param fail_loc=0x80001401
20834
20835         $MOUNT/date > /dev/null
20836         rm -f $MOUNT/date
20837 }
20838 run_test 221 "make sure fault and truncate race to not cause OOM"
20839
20840 test_222a () {
20841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20842
20843         rm -rf $DIR/$tdir
20844         test_mkdir $DIR/$tdir
20845         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20846         createmany -o $DIR/$tdir/$tfile 10
20847         cancel_lru_locks mdc
20848         cancel_lru_locks osc
20849         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20850         $LCTL set_param fail_loc=0x31a
20851         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20852         $LCTL set_param fail_loc=0
20853         rm -r $DIR/$tdir
20854 }
20855 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20856
20857 test_222b () {
20858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20859
20860         rm -rf $DIR/$tdir
20861         test_mkdir $DIR/$tdir
20862         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20863         createmany -o $DIR/$tdir/$tfile 10
20864         cancel_lru_locks mdc
20865         cancel_lru_locks osc
20866         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20867         $LCTL set_param fail_loc=0x31a
20868         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20869         $LCTL set_param fail_loc=0
20870 }
20871 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20872
20873 test_223 () {
20874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20875
20876         rm -rf $DIR/$tdir
20877         test_mkdir $DIR/$tdir
20878         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20879         createmany -o $DIR/$tdir/$tfile 10
20880         cancel_lru_locks mdc
20881         cancel_lru_locks osc
20882         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20883         $LCTL set_param fail_loc=0x31b
20884         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20885         $LCTL set_param fail_loc=0
20886         rm -r $DIR/$tdir
20887 }
20888 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20889
20890 test_224a() { # LU-1039, MRP-303
20891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20892         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20893         $LCTL set_param fail_loc=0x508
20894         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20895         $LCTL set_param fail_loc=0
20896         df $DIR
20897 }
20898 run_test 224a "Don't panic on bulk IO failure"
20899
20900 test_224bd_sub() { # LU-1039, MRP-303
20901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20902         local timeout=$1
20903
20904         shift
20905         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20906
20907         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20908
20909         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20910         cancel_lru_locks osc
20911         set_checksums 0
20912         stack_trap "set_checksums $ORIG_CSUM" EXIT
20913         local at_max_saved=0
20914
20915         # adaptive timeouts may prevent seeing the issue
20916         if at_is_enabled; then
20917                 at_max_saved=$(at_max_get mds)
20918                 at_max_set 0 mds client
20919                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20920         fi
20921
20922         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20923         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20924         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20925
20926         do_facet ost1 $LCTL set_param fail_loc=0
20927         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20928         df $DIR
20929 }
20930
20931 test_224b() {
20932         test_224bd_sub 3 error "dd failed"
20933 }
20934 run_test 224b "Don't panic on bulk IO failure"
20935
20936 test_224c() { # LU-6441
20937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20938         remote_mds_nodsh && skip "remote MDS with nodsh"
20939
20940         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20941         save_writethrough $p
20942         set_cache writethrough on
20943
20944         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20945         local at_max=$($LCTL get_param -n at_max)
20946         local timeout=$($LCTL get_param -n timeout)
20947         local test_at="at_max"
20948         local param_at="$FSNAME.sys.at_max"
20949         local test_timeout="timeout"
20950         local param_timeout="$FSNAME.sys.timeout"
20951
20952         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20953
20954         set_persistent_param_and_check client "$test_at" "$param_at" 0
20955         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20956
20957         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20958         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20959         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20960         stack_trap "rm -f $DIR/$tfile"
20961         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20962         sync
20963         do_facet ost1 "$LCTL set_param fail_loc=0"
20964
20965         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20966         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20967                 $timeout
20968
20969         $LCTL set_param -n $pages_per_rpc
20970         restore_lustre_params < $p
20971         rm -f $p
20972 }
20973 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20974
20975 test_224d() { # LU-11169
20976         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20977 }
20978 run_test 224d "Don't corrupt data on bulk IO timeout"
20979
20980 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20981 test_225a () {
20982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20983         if [ -z ${MDSSURVEY} ]; then
20984                 skip_env "mds-survey not found"
20985         fi
20986         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20987                 skip "Need MDS version at least 2.2.51"
20988
20989         local mds=$(facet_host $SINGLEMDS)
20990         local target=$(do_nodes $mds 'lctl dl' |
20991                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20992
20993         local cmd1="file_count=1000 thrhi=4"
20994         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20995         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20996         local cmd="$cmd1 $cmd2 $cmd3"
20997
20998         rm -f ${TMP}/mds_survey*
20999         echo + $cmd
21000         eval $cmd || error "mds-survey with zero-stripe failed"
21001         cat ${TMP}/mds_survey*
21002         rm -f ${TMP}/mds_survey*
21003 }
21004 run_test 225a "Metadata survey sanity with zero-stripe"
21005
21006 test_225b () {
21007         if [ -z ${MDSSURVEY} ]; then
21008                 skip_env "mds-survey not found"
21009         fi
21010         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21011                 skip "Need MDS version at least 2.2.51"
21012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21013         remote_mds_nodsh && skip "remote MDS with nodsh"
21014         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21015                 skip_env "Need to mount OST to test"
21016         fi
21017
21018         local mds=$(facet_host $SINGLEMDS)
21019         local target=$(do_nodes $mds 'lctl dl' |
21020                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21021
21022         local cmd1="file_count=1000 thrhi=4"
21023         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21024         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21025         local cmd="$cmd1 $cmd2 $cmd3"
21026
21027         rm -f ${TMP}/mds_survey*
21028         echo + $cmd
21029         eval $cmd || error "mds-survey with stripe_count failed"
21030         cat ${TMP}/mds_survey*
21031         rm -f ${TMP}/mds_survey*
21032 }
21033 run_test 225b "Metadata survey sanity with stripe_count = 1"
21034
21035 mcreate_path2fid () {
21036         local mode=$1
21037         local major=$2
21038         local minor=$3
21039         local name=$4
21040         local desc=$5
21041         local path=$DIR/$tdir/$name
21042         local fid
21043         local rc
21044         local fid_path
21045
21046         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21047                 error "cannot create $desc"
21048
21049         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21050         rc=$?
21051         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21052
21053         fid_path=$($LFS fid2path $MOUNT $fid)
21054         rc=$?
21055         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21056
21057         [ "$path" == "$fid_path" ] ||
21058                 error "fid2path returned $fid_path, expected $path"
21059
21060         echo "pass with $path and $fid"
21061 }
21062
21063 test_226a () {
21064         rm -rf $DIR/$tdir
21065         mkdir -p $DIR/$tdir
21066
21067         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21068         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21069         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21070         mcreate_path2fid 0040666 0 0 dir "directory"
21071         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21072         mcreate_path2fid 0100666 0 0 file "regular file"
21073         mcreate_path2fid 0120666 0 0 link "symbolic link"
21074         mcreate_path2fid 0140666 0 0 sock "socket"
21075 }
21076 run_test 226a "call path2fid and fid2path on files of all type"
21077
21078 test_226b () {
21079         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21080
21081         local MDTIDX=1
21082
21083         rm -rf $DIR/$tdir
21084         mkdir -p $DIR/$tdir
21085         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21086                 error "create remote directory failed"
21087         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21088         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21089                                 "character special file (null)"
21090         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21091                                 "character special file (no device)"
21092         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21093         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21094                                 "block special file (loop)"
21095         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21096         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21097         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21098 }
21099 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21100
21101 test_226c () {
21102         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21103         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21104                 skip "Need MDS version at least 2.13.55"
21105
21106         local submnt=/mnt/submnt
21107         local srcfile=/etc/passwd
21108         local dstfile=$submnt/passwd
21109         local path
21110         local fid
21111
21112         rm -rf $DIR/$tdir
21113         rm -rf $submnt
21114         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21115                 error "create remote directory failed"
21116         mkdir -p $submnt || error "create $submnt failed"
21117         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21118                 error "mount $submnt failed"
21119         stack_trap "umount $submnt" EXIT
21120
21121         cp $srcfile $dstfile
21122         fid=$($LFS path2fid $dstfile)
21123         path=$($LFS fid2path $submnt "$fid")
21124         [ "$path" = "$dstfile" ] ||
21125                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21126 }
21127 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21128
21129 test_226d () {
21130         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21131                 skip "Need client at least version 2.15.57"
21132
21133         # Define First test dataset
21134         local testdirs_01=$DIR/$tdir
21135         local testdata_01=$testdirs_01/${tdir}_01
21136         local testresult_01=${tdir}_01
21137         # Define Second test dataset
21138         local testdirs_02=$DIR/$tdir/$tdir
21139         local testdata_02=$testdirs_02/${tdir}_02
21140         local testresult_02=${tdir}_02
21141         # Define third test dataset (top level)
21142         local testdata_03=$DIR/${tdir}_03
21143         local testresult_03=${tdir}_03
21144
21145         # Create first test dataset
21146         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21147         touch $testdata_01 || error "cannot create file $testdata_01"
21148
21149         # Create second test dataset
21150         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21151         touch $testdata_02 || error "cannot create file $testdata_02"
21152
21153         # Create third test dataset
21154         touch $testdata_03 || error "cannot create file $testdata_03"
21155
21156         local fid01=$($LFS getstripe -F "$testdata_01") ||
21157                 error "getstripe failed on $testdata_01"
21158         local fid02=$($LFS getstripe -F "$testdata_02") ||
21159                 error "getstripe failed on $testdata_01"
21160         local fid03=$($LFS getstripe -F "$testdata_03") ||
21161                 error "getstripe failed on $testdata_03"
21162
21163         # Verify only -n option
21164         local out1=$($LFS fid2path -n $DIR $fid01) ||
21165                 error "fid2path failed on $fid01"
21166         local out2=$($LFS fid2path -n $DIR $fid02) ||
21167                 error "fid2path failed on $fid02"
21168         local out3=$($LFS fid2path -n $DIR $fid03) ||
21169                 error "fid2path failed on $fid03"
21170
21171         [[ "$out1" == "$testresult_01" ]] ||
21172                 error "fid2path failed: Expected $testresult_01 got $out1"
21173         [[ "$out2" == "$testresult_02" ]] ||
21174                 error "fid2path failed: Expected $testresult_02 got $out2"
21175         [[ "$out3" == "$testresult_03" ]] ||
21176                 error "fid2path failed: Expected $testresult_03 got $out3"
21177
21178         # Verify with option -fn together
21179         out1=$($LFS fid2path -fn $DIR $fid01) ||
21180                 error "fid2path -fn failed on $fid01"
21181         out2=$($LFS fid2path -fn $DIR $fid02) ||
21182                 error "fid2path -fn failed on $fid02"
21183         out3=$($LFS fid2path -fn $DIR $fid03) ||
21184                 error "fid2path -fn failed on $fid03"
21185
21186         local tmpout=$(echo $out1 | cut -d" " -f2)
21187         [[ "$tmpout" == "$testresult_01" ]] ||
21188                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21189
21190         tmpout=$(echo $out2 | cut -d" " -f2)
21191         [[ "$tmpout" == "$testresult_02" ]] ||
21192                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21193
21194         tmpout=$(echo $out3 | cut -d" " -f2)
21195         [[ "$tmpout" == "$testresult_03" ]] ||
21196                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21197 }
21198 run_test 226d "verify fid2path with -n and -fn option"
21199
21200 test_226e () {
21201         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21202                 skip "Need client at least version 2.15.56"
21203
21204         # Define filename with 'newline' and a space
21205         local testfile="Test"$'\n'"file 01"
21206         # Define link name with multiple 'newline' and a space
21207         local linkfile="Link"$'\n'"file "$'\n'"01"
21208         # Remove prior hard link
21209         rm -f $DIR/"$linkfile"
21210
21211         # Create file
21212         touch $DIR/"$testfile"
21213         # Create link
21214         ln $DIR/"$testfile" $DIR/"$linkfile"
21215
21216         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21217                 error "getstripe failed on $DIR/$testfile"
21218
21219         # Call with -0 option
21220         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21221                 echo "FILE:" | grep -c "FILE:")
21222
21223         # With -0 option the output should be exactly 2 lines.
21224         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21225 }
21226 run_test 226e "Verify path2fid -0 option with newline and space"
21227
21228 # LU-1299 Executing or running ldd on a truncated executable does not
21229 # cause an out-of-memory condition.
21230 test_227() {
21231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21232         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21233
21234         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21235         chmod +x $MOUNT/date
21236
21237         $MOUNT/date > /dev/null
21238         ldd $MOUNT/date > /dev/null
21239         rm -f $MOUNT/date
21240 }
21241 run_test 227 "running truncated executable does not cause OOM"
21242
21243 # LU-1512 try to reuse idle OI blocks
21244 test_228a() {
21245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21246         remote_mds_nodsh && skip "remote MDS with nodsh"
21247         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21248
21249         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21250         local myDIR=$DIR/$tdir
21251
21252         mkdir -p $myDIR
21253         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21254         $LCTL set_param fail_loc=0x80001002
21255         createmany -o $myDIR/t- 10000
21256         $LCTL set_param fail_loc=0
21257         # The guard is current the largest FID holder
21258         touch $myDIR/guard
21259         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21260                     tr -d '[')
21261         local IDX=$(($SEQ % 64))
21262
21263         do_facet $SINGLEMDS sync
21264         # Make sure journal flushed.
21265         sleep 6
21266         local blk1=$(do_facet $SINGLEMDS \
21267                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21268                      grep Blockcount | awk '{print $4}')
21269
21270         # Remove old files, some OI blocks will become idle.
21271         unlinkmany $myDIR/t- 10000
21272         # Create new files, idle OI blocks should be reused.
21273         createmany -o $myDIR/t- 2000
21274         do_facet $SINGLEMDS sync
21275         # Make sure journal flushed.
21276         sleep 6
21277         local blk2=$(do_facet $SINGLEMDS \
21278                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21279                      grep Blockcount | awk '{print $4}')
21280
21281         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21282 }
21283 run_test 228a "try to reuse idle OI blocks"
21284
21285 test_228b() {
21286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21287         remote_mds_nodsh && skip "remote MDS with nodsh"
21288         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21289
21290         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21291         local myDIR=$DIR/$tdir
21292
21293         mkdir -p $myDIR
21294         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21295         $LCTL set_param fail_loc=0x80001002
21296         createmany -o $myDIR/t- 10000
21297         $LCTL set_param fail_loc=0
21298         # The guard is current the largest FID holder
21299         touch $myDIR/guard
21300         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21301                     tr -d '[')
21302         local IDX=$(($SEQ % 64))
21303
21304         do_facet $SINGLEMDS sync
21305         # Make sure journal flushed.
21306         sleep 6
21307         local blk1=$(do_facet $SINGLEMDS \
21308                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21309                      grep Blockcount | awk '{print $4}')
21310
21311         # Remove old files, some OI blocks will become idle.
21312         unlinkmany $myDIR/t- 10000
21313
21314         # stop the MDT
21315         stop $SINGLEMDS || error "Fail to stop MDT."
21316         # remount the MDT
21317         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21318                 error "Fail to start MDT."
21319
21320         client_up || error "Fail to df."
21321         # Create new files, idle OI blocks should be reused.
21322         createmany -o $myDIR/t- 2000
21323         do_facet $SINGLEMDS sync
21324         # Make sure journal flushed.
21325         sleep 6
21326         local blk2=$(do_facet $SINGLEMDS \
21327                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21328                      grep Blockcount | awk '{print $4}')
21329
21330         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21331 }
21332 run_test 228b "idle OI blocks can be reused after MDT restart"
21333
21334 #LU-1881
21335 test_228c() {
21336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21337         remote_mds_nodsh && skip "remote MDS with nodsh"
21338         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21339
21340         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21341         local myDIR=$DIR/$tdir
21342
21343         mkdir -p $myDIR
21344         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21345         $LCTL set_param fail_loc=0x80001002
21346         # 20000 files can guarantee there are index nodes in the OI file
21347         createmany -o $myDIR/t- 20000
21348         $LCTL set_param fail_loc=0
21349         # The guard is current the largest FID holder
21350         touch $myDIR/guard
21351         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21352                     tr -d '[')
21353         local IDX=$(($SEQ % 64))
21354
21355         do_facet $SINGLEMDS sync
21356         # Make sure journal flushed.
21357         sleep 6
21358         local blk1=$(do_facet $SINGLEMDS \
21359                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21360                      grep Blockcount | awk '{print $4}')
21361
21362         # Remove old files, some OI blocks will become idle.
21363         unlinkmany $myDIR/t- 20000
21364         rm -f $myDIR/guard
21365         # The OI file should become empty now
21366
21367         # Create new files, idle OI blocks should be reused.
21368         createmany -o $myDIR/t- 2000
21369         do_facet $SINGLEMDS sync
21370         # Make sure journal flushed.
21371         sleep 6
21372         local blk2=$(do_facet $SINGLEMDS \
21373                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21374                      grep Blockcount | awk '{print $4}')
21375
21376         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21377 }
21378 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21379
21380 test_229() { # LU-2482, LU-3448
21381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21382         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21383         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21384                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21385
21386         rm -f $DIR/$tfile
21387
21388         # Create a file with a released layout and stripe count 2.
21389         $MULTIOP $DIR/$tfile H2c ||
21390                 error "failed to create file with released layout"
21391
21392         $LFS getstripe -v $DIR/$tfile
21393
21394         local pattern=$($LFS getstripe -L $DIR/$tfile)
21395         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21396
21397         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21398                 error "getstripe"
21399         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21400         stat $DIR/$tfile || error "failed to stat released file"
21401
21402         chown $RUNAS_ID $DIR/$tfile ||
21403                 error "chown $RUNAS_ID $DIR/$tfile failed"
21404
21405         chgrp $RUNAS_ID $DIR/$tfile ||
21406                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21407
21408         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21409         rm $DIR/$tfile || error "failed to remove released file"
21410 }
21411 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21412
21413 test_230a() {
21414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21415         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21416         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21417                 skip "Need MDS version at least 2.11.52"
21418
21419         local MDTIDX=1
21420
21421         test_mkdir $DIR/$tdir
21422         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21423         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21424         [ $mdt_idx -ne 0 ] &&
21425                 error "create local directory on wrong MDT $mdt_idx"
21426
21427         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21428                         error "create remote directory failed"
21429         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21430         [ $mdt_idx -ne $MDTIDX ] &&
21431                 error "create remote directory on wrong MDT $mdt_idx"
21432
21433         createmany -o $DIR/$tdir/test_230/t- 10 ||
21434                 error "create files on remote directory failed"
21435         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21436         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21437         rm -r $DIR/$tdir || error "unlink remote directory failed"
21438 }
21439 run_test 230a "Create remote directory and files under the remote directory"
21440
21441 test_230b() {
21442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21444         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21445                 skip "Need MDS version at least 2.11.52"
21446
21447         local MDTIDX=1
21448         local mdt_index
21449         local i
21450         local file
21451         local pid
21452         local stripe_count
21453         local migrate_dir=$DIR/$tdir/migrate_dir
21454         local other_dir=$DIR/$tdir/other_dir
21455
21456         test_mkdir $DIR/$tdir
21457         test_mkdir -i0 -c1 $migrate_dir
21458         test_mkdir -i0 -c1 $other_dir
21459         for ((i=0; i<10; i++)); do
21460                 mkdir -p $migrate_dir/dir_${i}
21461                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21462                         error "create files under remote dir failed $i"
21463         done
21464
21465         cp /etc/passwd $migrate_dir/$tfile
21466         cp /etc/passwd $other_dir/$tfile
21467         chattr +SAD $migrate_dir
21468         chattr +SAD $migrate_dir/$tfile
21469
21470         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21471         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21472         local old_dir_mode=$(stat -c%f $migrate_dir)
21473         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21474
21475         mkdir -p $migrate_dir/dir_default_stripe2
21476         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21477         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21478
21479         mkdir -p $other_dir
21480         ln $migrate_dir/$tfile $other_dir/luna
21481         ln $migrate_dir/$tfile $migrate_dir/sofia
21482         ln $other_dir/$tfile $migrate_dir/david
21483         ln -s $migrate_dir/$tfile $other_dir/zachary
21484         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21485         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21486
21487         local len
21488         local lnktgt
21489
21490         # inline symlink
21491         for len in 58 59 60; do
21492                 lnktgt=$(str_repeat 'l' $len)
21493                 touch $migrate_dir/$lnktgt
21494                 ln -s $lnktgt $migrate_dir/${len}char_ln
21495         done
21496
21497         # PATH_MAX
21498         for len in 4094 4095; do
21499                 lnktgt=$(str_repeat 'l' $len)
21500                 ln -s $lnktgt $migrate_dir/${len}char_ln
21501         done
21502
21503         # NAME_MAX
21504         for len in 254 255; do
21505                 touch $migrate_dir/$(str_repeat 'l' $len)
21506         done
21507
21508         $LFS migrate -m $MDTIDX $migrate_dir ||
21509                 error "fails on migrating remote dir to MDT1"
21510
21511         echo "migratate to MDT1, then checking.."
21512         for ((i = 0; i < 10; i++)); do
21513                 for file in $(find $migrate_dir/dir_${i}); do
21514                         mdt_index=$($LFS getstripe -m $file)
21515                         # broken symlink getstripe will fail
21516                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21517                                 error "$file is not on MDT${MDTIDX}"
21518                 done
21519         done
21520
21521         # the multiple link file should still in MDT0
21522         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21523         [ $mdt_index == 0 ] ||
21524                 error "$file is not on MDT${MDTIDX}"
21525
21526         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21527         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21528                 error " expect $old_dir_flag get $new_dir_flag"
21529
21530         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21531         [ "$old_file_flag" = "$new_file_flag" ] ||
21532                 error " expect $old_file_flag get $new_file_flag"
21533
21534         local new_dir_mode=$(stat -c%f $migrate_dir)
21535         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21536                 error "expect mode $old_dir_mode get $new_dir_mode"
21537
21538         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21539         [ "$old_file_mode" = "$new_file_mode" ] ||
21540                 error "expect mode $old_file_mode get $new_file_mode"
21541
21542         diff /etc/passwd $migrate_dir/$tfile ||
21543                 error "$tfile different after migration"
21544
21545         diff /etc/passwd $other_dir/luna ||
21546                 error "luna different after migration"
21547
21548         diff /etc/passwd $migrate_dir/sofia ||
21549                 error "sofia different after migration"
21550
21551         diff /etc/passwd $migrate_dir/david ||
21552                 error "david different after migration"
21553
21554         diff /etc/passwd $other_dir/zachary ||
21555                 error "zachary different after migration"
21556
21557         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21558                 error "${tfile}_ln different after migration"
21559
21560         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21561                 error "${tfile}_ln_other different after migration"
21562
21563         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21564         [ $stripe_count = 2 ] ||
21565                 error "dir strpe_count $d != 2 after migration."
21566
21567         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21568         [ $stripe_count = 2 ] ||
21569                 error "file strpe_count $d != 2 after migration."
21570
21571         #migrate back to MDT0
21572         MDTIDX=0
21573
21574         $LFS migrate -m $MDTIDX $migrate_dir ||
21575                 error "fails on migrating remote dir to MDT0"
21576
21577         echo "migrate back to MDT0, checking.."
21578         for file in $(find $migrate_dir); do
21579                 mdt_index=$($LFS getstripe -m $file)
21580                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21581                         error "$file is not on MDT${MDTIDX}"
21582         done
21583
21584         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21585         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21586                 error " expect $old_dir_flag get $new_dir_flag"
21587
21588         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21589         [ "$old_file_flag" = "$new_file_flag" ] ||
21590                 error " expect $old_file_flag get $new_file_flag"
21591
21592         local new_dir_mode=$(stat -c%f $migrate_dir)
21593         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21594                 error "expect mode $old_dir_mode get $new_dir_mode"
21595
21596         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21597         [ "$old_file_mode" = "$new_file_mode" ] ||
21598                 error "expect mode $old_file_mode get $new_file_mode"
21599
21600         diff /etc/passwd ${migrate_dir}/$tfile ||
21601                 error "$tfile different after migration"
21602
21603         diff /etc/passwd ${other_dir}/luna ||
21604                 error "luna different after migration"
21605
21606         diff /etc/passwd ${migrate_dir}/sofia ||
21607                 error "sofia different after migration"
21608
21609         diff /etc/passwd ${other_dir}/zachary ||
21610                 error "zachary different after migration"
21611
21612         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21613                 error "${tfile}_ln different after migration"
21614
21615         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21616                 error "${tfile}_ln_other different after migration"
21617
21618         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21619         [ $stripe_count = 2 ] ||
21620                 error "dir strpe_count $d != 2 after migration."
21621
21622         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21623         [ $stripe_count = 2 ] ||
21624                 error "file strpe_count $d != 2 after migration."
21625
21626         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21627 }
21628 run_test 230b "migrate directory"
21629
21630 test_230c() {
21631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21633         remote_mds_nodsh && skip "remote MDS with nodsh"
21634         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21635                 skip "Need MDS version at least 2.11.52"
21636
21637         local MDTIDX=1
21638         local total=3
21639         local mdt_index
21640         local file
21641         local migrate_dir=$DIR/$tdir/migrate_dir
21642
21643         #If migrating directory fails in the middle, all entries of
21644         #the directory is still accessiable.
21645         test_mkdir $DIR/$tdir
21646         test_mkdir -i0 -c1 $migrate_dir
21647         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21648         stat $migrate_dir
21649         createmany -o $migrate_dir/f $total ||
21650                 error "create files under ${migrate_dir} failed"
21651
21652         # fail after migrating top dir, and this will fail only once, so the
21653         # first sub file migration will fail (currently f3), others succeed.
21654         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21655         do_facet mds1 lctl set_param fail_loc=0x1801
21656         local t=$(ls $migrate_dir | wc -l)
21657         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21658                 error "migrate should fail"
21659         local u=$(ls $migrate_dir | wc -l)
21660         [ "$u" == "$t" ] || error "$u != $t during migration"
21661
21662         # add new dir/file should succeed
21663         mkdir $migrate_dir/dir ||
21664                 error "mkdir failed under migrating directory"
21665         touch $migrate_dir/file ||
21666                 error "create file failed under migrating directory"
21667
21668         # add file with existing name should fail
21669         for file in $migrate_dir/f*; do
21670                 stat $file > /dev/null || error "stat $file failed"
21671                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21672                         error "open(O_CREAT|O_EXCL) $file should fail"
21673                 $MULTIOP $file m && error "create $file should fail"
21674                 touch $DIR/$tdir/remote_dir/$tfile ||
21675                         error "touch $tfile failed"
21676                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21677                         error "link $file should fail"
21678                 mdt_index=$($LFS getstripe -m $file)
21679                 if [ $mdt_index == 0 ]; then
21680                         # file failed to migrate is not allowed to rename to
21681                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21682                                 error "rename to $file should fail"
21683                 else
21684                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21685                                 error "rename to $file failed"
21686                 fi
21687                 echo hello >> $file || error "write $file failed"
21688         done
21689
21690         # resume migration with different options should fail
21691         $LFS migrate -m 0 $migrate_dir &&
21692                 error "migrate -m 0 $migrate_dir should fail"
21693
21694         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21695                 error "migrate -c 2 $migrate_dir should fail"
21696
21697         # resume migration should succeed
21698         $LFS migrate -m $MDTIDX $migrate_dir ||
21699                 error "migrate $migrate_dir failed"
21700
21701         echo "Finish migration, then checking.."
21702         for file in $(find $migrate_dir); do
21703                 mdt_index=$($LFS getstripe -m $file)
21704                 [ $mdt_index == $MDTIDX ] ||
21705                         error "$file is not on MDT${MDTIDX}"
21706         done
21707
21708         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21709 }
21710 run_test 230c "check directory accessiblity if migration failed"
21711
21712 test_230d() {
21713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21714         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21715         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21716                 skip "Need MDS version at least 2.11.52"
21717         # LU-11235
21718         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21719
21720         local migrate_dir=$DIR/$tdir/migrate_dir
21721         local old_index
21722         local new_index
21723         local old_count
21724         local new_count
21725         local new_hash
21726         local mdt_index
21727         local i
21728         local j
21729
21730         old_index=$((RANDOM % MDSCOUNT))
21731         old_count=$((MDSCOUNT - old_index))
21732         new_index=$((RANDOM % MDSCOUNT))
21733         new_count=$((MDSCOUNT - new_index))
21734         new_hash=1 # for all_char
21735
21736         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21737         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21738
21739         test_mkdir $DIR/$tdir
21740         test_mkdir -i $old_index -c $old_count $migrate_dir
21741
21742         for ((i=0; i<100; i++)); do
21743                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21744                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21745                         error "create files under remote dir failed $i"
21746         done
21747
21748         echo -n "Migrate from MDT$old_index "
21749         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21750         echo -n "to MDT$new_index"
21751         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21752         echo
21753
21754         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21755         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21756                 error "migrate remote dir error"
21757
21758         echo "Finish migration, then checking.."
21759         for file in $(find $migrate_dir -maxdepth 1); do
21760                 mdt_index=$($LFS getstripe -m $file)
21761                 if [ $mdt_index -lt $new_index ] ||
21762                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21763                         error "$file is on MDT$mdt_index"
21764                 fi
21765         done
21766
21767         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21768 }
21769 run_test 230d "check migrate big directory"
21770
21771 test_230e() {
21772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21773         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21774         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21775                 skip "Need MDS version at least 2.11.52"
21776
21777         local i
21778         local j
21779         local a_fid
21780         local b_fid
21781
21782         mkdir_on_mdt0 $DIR/$tdir
21783         mkdir $DIR/$tdir/migrate_dir
21784         mkdir $DIR/$tdir/other_dir
21785         touch $DIR/$tdir/migrate_dir/a
21786         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21787         ls $DIR/$tdir/other_dir
21788
21789         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21790                 error "migrate dir fails"
21791
21792         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21793         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21794
21795         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21796         [ $mdt_index == 0 ] || error "a is not on MDT0"
21797
21798         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21799                 error "migrate dir fails"
21800
21801         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21802         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21803
21804         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21805         [ $mdt_index == 1 ] || error "a is not on MDT1"
21806
21807         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21808         [ $mdt_index == 1 ] || error "b is not on MDT1"
21809
21810         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21811         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21812
21813         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21814
21815         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21816 }
21817 run_test 230e "migrate mulitple local link files"
21818
21819 test_230f() {
21820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21822         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21823                 skip "Need MDS version at least 2.11.52"
21824
21825         local a_fid
21826         local ln_fid
21827
21828         mkdir -p $DIR/$tdir
21829         mkdir $DIR/$tdir/migrate_dir
21830         $LFS mkdir -i1 $DIR/$tdir/other_dir
21831         touch $DIR/$tdir/migrate_dir/a
21832         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21833         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21834         ls $DIR/$tdir/other_dir
21835
21836         # a should be migrated to MDT1, since no other links on MDT0
21837         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21838                 error "#1 migrate dir fails"
21839         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21840         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21841         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21842         [ $mdt_index == 1 ] || error "a is not on MDT1"
21843
21844         # a should stay on MDT1, because it is a mulitple link file
21845         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21846                 error "#2 migrate dir fails"
21847         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21848         [ $mdt_index == 1 ] || error "a is not on MDT1"
21849
21850         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21851                 error "#3 migrate dir fails"
21852
21853         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21854         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21855         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21856
21857         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21858         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21859
21860         # a should be migrated to MDT0, since no other links on MDT1
21861         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21862                 error "#4 migrate dir fails"
21863         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21864         [ $mdt_index == 0 ] || error "a is not on MDT0"
21865
21866         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21867 }
21868 run_test 230f "migrate mulitple remote link files"
21869
21870 test_230g() {
21871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21872         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21873         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21874                 skip "Need MDS version at least 2.11.52"
21875
21876         mkdir -p $DIR/$tdir/migrate_dir
21877
21878         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21879                 error "migrating dir to non-exist MDT succeeds"
21880         true
21881 }
21882 run_test 230g "migrate dir to non-exist MDT"
21883
21884 test_230h() {
21885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21886         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21887         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21888                 skip "Need MDS version at least 2.11.52"
21889
21890         local mdt_index
21891
21892         mkdir -p $DIR/$tdir/migrate_dir
21893
21894         $LFS migrate -m1 $DIR &&
21895                 error "migrating mountpoint1 should fail"
21896
21897         $LFS migrate -m1 $DIR/$tdir/.. &&
21898                 error "migrating mountpoint2 should fail"
21899
21900         # same as mv
21901         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21902                 error "migrating $tdir/migrate_dir/.. should fail"
21903
21904         true
21905 }
21906 run_test 230h "migrate .. and root"
21907
21908 test_230i() {
21909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21910         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21911         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21912                 skip "Need MDS version at least 2.11.52"
21913
21914         mkdir -p $DIR/$tdir/migrate_dir
21915
21916         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21917                 error "migration fails with a tailing slash"
21918
21919         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21920                 error "migration fails with two tailing slashes"
21921 }
21922 run_test 230i "lfs migrate -m tolerates trailing slashes"
21923
21924 test_230j() {
21925         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21926         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21927                 skip "Need MDS version at least 2.11.52"
21928
21929         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21930         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21931                 error "create $tfile failed"
21932         cat /etc/passwd > $DIR/$tdir/$tfile
21933
21934         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21935
21936         cmp /etc/passwd $DIR/$tdir/$tfile ||
21937                 error "DoM file mismatch after migration"
21938 }
21939 run_test 230j "DoM file data not changed after dir migration"
21940
21941 test_230k() {
21942         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21943         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21944                 skip "Need MDS version at least 2.11.56"
21945
21946         local total=20
21947         local files_on_starting_mdt=0
21948
21949         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21950         $LFS getdirstripe $DIR/$tdir
21951         for i in $(seq $total); do
21952                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21953                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21954                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21955         done
21956
21957         echo "$files_on_starting_mdt files on MDT0"
21958
21959         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21960         $LFS getdirstripe $DIR/$tdir
21961
21962         files_on_starting_mdt=0
21963         for i in $(seq $total); do
21964                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21965                         error "file $tfile.$i mismatch after migration"
21966                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21967                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21968         done
21969
21970         echo "$files_on_starting_mdt files on MDT1 after migration"
21971         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21972
21973         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21974         $LFS getdirstripe $DIR/$tdir
21975
21976         files_on_starting_mdt=0
21977         for i in $(seq $total); do
21978                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21979                         error "file $tfile.$i mismatch after 2nd migration"
21980                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21981                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21982         done
21983
21984         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21985         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21986
21987         true
21988 }
21989 run_test 230k "file data not changed after dir migration"
21990
21991 test_230l() {
21992         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21993         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21994                 skip "Need MDS version at least 2.11.56"
21995
21996         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21997         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21998                 error "create files under remote dir failed $i"
21999         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22000 }
22001 run_test 230l "readdir between MDTs won't crash"
22002
22003 test_230m() {
22004         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22005         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22006                 skip "Need MDS version at least 2.11.56"
22007
22008         local MDTIDX=1
22009         local mig_dir=$DIR/$tdir/migrate_dir
22010         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22011         local shortstr="b"
22012         local val
22013
22014         echo "Creating files and dirs with xattrs"
22015         test_mkdir $DIR/$tdir
22016         test_mkdir -i0 -c1 $mig_dir
22017         mkdir $mig_dir/dir
22018         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22019                 error "cannot set xattr attr1 on dir"
22020         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22021                 error "cannot set xattr attr2 on dir"
22022         touch $mig_dir/dir/f0
22023         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22024                 error "cannot set xattr attr1 on file"
22025         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22026                 error "cannot set xattr attr2 on file"
22027         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22028         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22029         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22030         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22031         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22032         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22033         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22034         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22035         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22036
22037         echo "Migrating to MDT1"
22038         $LFS migrate -m $MDTIDX $mig_dir ||
22039                 error "fails on migrating dir to MDT1"
22040
22041         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22042         echo "Checking xattrs"
22043         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22044         [ "$val" = $longstr ] ||
22045                 error "expecting xattr1 $longstr on dir, found $val"
22046         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22047         [ "$val" = $shortstr ] ||
22048                 error "expecting xattr2 $shortstr on dir, found $val"
22049         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22050         [ "$val" = $longstr ] ||
22051                 error "expecting xattr1 $longstr on file, found $val"
22052         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22053         [ "$val" = $shortstr ] ||
22054                 error "expecting xattr2 $shortstr on file, found $val"
22055 }
22056 run_test 230m "xattrs not changed after dir migration"
22057
22058 test_230n() {
22059         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22060         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22061                 skip "Need MDS version at least 2.13.53"
22062
22063         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22064         cat /etc/hosts > $DIR/$tdir/$tfile
22065         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22066         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22067
22068         cmp /etc/hosts $DIR/$tdir/$tfile ||
22069                 error "File data mismatch after migration"
22070 }
22071 run_test 230n "Dir migration with mirrored file"
22072
22073 test_230o() {
22074         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22075         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22076                 skip "Need MDS version at least 2.13.52"
22077
22078         local mdts=$(comma_list $(mdts_nodes))
22079         local timeout=100
22080         local restripe_status
22081         local delta
22082         local i
22083
22084         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22085
22086         # in case "crush" hash type is not set
22087         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22088
22089         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22090                            mdt.*MDT0000.enable_dir_restripe)
22091         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22092         stack_trap "do_nodes $mdts $LCTL set_param \
22093                     mdt.*.enable_dir_restripe=$restripe_status"
22094
22095         mkdir $DIR/$tdir
22096         createmany -m $DIR/$tdir/f 100 ||
22097                 error "create files under remote dir failed $i"
22098         createmany -d $DIR/$tdir/d 100 ||
22099                 error "create dirs under remote dir failed $i"
22100
22101         for i in $(seq 2 $MDSCOUNT); do
22102                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22103                 $LFS setdirstripe -c $i $DIR/$tdir ||
22104                         error "split -c $i $tdir failed"
22105                 wait_update $HOSTNAME \
22106                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22107                         error "dir split not finished"
22108                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22109                         awk '/migrate/ {sum += $2} END { print sum }')
22110                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22111                 # delta is around total_files/stripe_count
22112                 (( $delta < 200 / (i - 1) + 4 )) ||
22113                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22114         done
22115 }
22116 run_test 230o "dir split"
22117
22118 test_230p() {
22119         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22120         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22121                 skip "Need MDS version at least 2.13.52"
22122
22123         local mdts=$(comma_list $(mdts_nodes))
22124         local timeout=100
22125         local restripe_status
22126         local delta
22127         local c
22128
22129         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22130
22131         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22132
22133         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22134                            mdt.*MDT0000.enable_dir_restripe)
22135         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22136         stack_trap "do_nodes $mdts $LCTL set_param \
22137                     mdt.*.enable_dir_restripe=$restripe_status"
22138
22139         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22140         createmany -m $DIR/$tdir/f 100 ||
22141                 error "create files under remote dir failed"
22142         createmany -d $DIR/$tdir/d 100 ||
22143                 error "create dirs under remote dir failed"
22144
22145         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22146                 local mdt_hash="crush"
22147
22148                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22149                 $LFS setdirstripe -c $c $DIR/$tdir ||
22150                         error "split -c $c $tdir failed"
22151                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22152                         mdt_hash="$mdt_hash,fixed"
22153                 elif [ $c -eq 1 ]; then
22154                         mdt_hash="none"
22155                 fi
22156                 wait_update $HOSTNAME \
22157                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22158                         error "dir merge not finished"
22159                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22160                         awk '/migrate/ {sum += $2} END { print sum }')
22161                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22162                 # delta is around total_files/stripe_count
22163                 (( delta < 200 / c + 4 )) ||
22164                         error "$delta files migrated >= $((200 / c + 4))"
22165         done
22166 }
22167 run_test 230p "dir merge"
22168
22169 test_230q() {
22170         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22171         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22172                 skip "Need MDS version at least 2.13.52"
22173
22174         local mdts=$(comma_list $(mdts_nodes))
22175         local saved_threshold=$(do_facet mds1 \
22176                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22177         local saved_delta=$(do_facet mds1 \
22178                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22179         local threshold=100
22180         local delta=2
22181         local total=0
22182         local stripe_count=0
22183         local stripe_index
22184         local nr_files
22185         local create
22186
22187         # test with fewer files on ZFS
22188         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22189
22190         stack_trap "do_nodes $mdts $LCTL set_param \
22191                     mdt.*.dir_split_count=$saved_threshold"
22192         stack_trap "do_nodes $mdts $LCTL set_param \
22193                     mdt.*.dir_split_delta=$saved_delta"
22194         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22195         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22196         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22197         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22198         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22199         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22200
22201         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22202         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22203
22204         create=$((threshold * 3 / 2))
22205         while [ $stripe_count -lt $MDSCOUNT ]; do
22206                 createmany -m $DIR/$tdir/f $total $create ||
22207                         error "create sub files failed"
22208                 stat $DIR/$tdir > /dev/null
22209                 total=$((total + create))
22210                 stripe_count=$((stripe_count + delta))
22211                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22212
22213                 wait_update $HOSTNAME \
22214                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22215                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22216
22217                 wait_update $HOSTNAME \
22218                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22219                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22220
22221                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22222                 echo "$nr_files/$total files on MDT$stripe_index after split"
22223                 # allow 10% margin of imbalance with crush hash
22224                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22225                         error "$nr_files files on MDT$stripe_index after split"
22226
22227                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22228                 [ $nr_files -eq $total ] ||
22229                         error "total sub files $nr_files != $total"
22230         done
22231
22232         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22233
22234         echo "fixed layout directory won't auto split"
22235         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22236         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22237                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22238         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22239                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22240 }
22241 run_test 230q "dir auto split"
22242
22243 test_230r() {
22244         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22245         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22246         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22247                 skip "Need MDS version at least 2.13.54"
22248
22249         # maximum amount of local locks:
22250         # parent striped dir - 2 locks
22251         # new stripe in parent to migrate to - 1 lock
22252         # source and target - 2 locks
22253         # Total 5 locks for regular file
22254         mkdir -p $DIR/$tdir
22255         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22256         touch $DIR/$tdir/dir1/eee
22257
22258         # create 4 hardlink for 4 more locks
22259         # Total: 9 locks > RS_MAX_LOCKS (8)
22260         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22261         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22262         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22263         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22264         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22265         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22266         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22267         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22268
22269         cancel_lru_locks mdc
22270
22271         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22272                 error "migrate dir fails"
22273
22274         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22275 }
22276 run_test 230r "migrate with too many local locks"
22277
22278 test_230s() {
22279         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22280                 skip "Need MDS version at least 2.14.52"
22281
22282         local mdts=$(comma_list $(mdts_nodes))
22283         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22284                                 mdt.*MDT0000.enable_dir_restripe)
22285
22286         stack_trap "do_nodes $mdts $LCTL set_param \
22287                     mdt.*.enable_dir_restripe=$restripe_status"
22288
22289         local st
22290         for st in 0 1; do
22291                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22292                 test_mkdir $DIR/$tdir
22293                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22294                         error "$LFS mkdir should return EEXIST if target exists"
22295                 rmdir $DIR/$tdir
22296         done
22297 }
22298 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22299
22300 test_230t()
22301 {
22302         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22303         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22304                 skip "Need MDS version at least 2.14.50"
22305
22306         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22307         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22308         $LFS project -p 1 -s $DIR/$tdir ||
22309                 error "set $tdir project id failed"
22310         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22311                 error "set subdir project id failed"
22312         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22313 }
22314 run_test 230t "migrate directory with project ID set"
22315
22316 test_230u()
22317 {
22318         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22319         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22320                 skip "Need MDS version at least 2.14.53"
22321
22322         local count
22323
22324         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22325         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22326         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22327         for i in $(seq 0 $((MDSCOUNT - 1))); do
22328                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22329                 echo "$count dirs migrated to MDT$i"
22330         done
22331         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22332         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22333 }
22334 run_test 230u "migrate directory by QOS"
22335
22336 test_230v()
22337 {
22338         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22339         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22340                 skip "Need MDS version at least 2.14.53"
22341
22342         local count
22343
22344         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22345         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22346         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22347         for i in $(seq 0 $((MDSCOUNT - 1))); do
22348                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22349                 echo "$count subdirs migrated to MDT$i"
22350                 (( i == 3 )) && (( count > 0 )) &&
22351                         error "subdir shouldn't be migrated to MDT3"
22352         done
22353         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22354         (( count == 3 )) || error "dirs migrated to $count MDTs"
22355 }
22356 run_test 230v "subdir migrated to the MDT where its parent is located"
22357
22358 test_230w() {
22359         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22360         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22361                 skip "Need MDS version at least 2.15.0"
22362
22363         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22364         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22365         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22366
22367         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22368                 error "migrate failed"
22369
22370         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22371                 error "$tdir stripe count mismatch"
22372
22373         for i in $(seq 0 9); do
22374                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22375                         error "d$i is striped"
22376         done
22377 }
22378 run_test 230w "non-recursive mode dir migration"
22379
22380 test_230x() {
22381         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22382         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22383                 skip "Need MDS version at least 2.15.0"
22384
22385         mkdir -p $DIR/$tdir || error "mkdir failed"
22386         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22387
22388         local mdt_name=$(mdtname_from_index 0)
22389         local low=$(do_facet mds2 $LCTL get_param -n \
22390                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22391         local high=$(do_facet mds2 $LCTL get_param -n \
22392                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22393         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22394         local maxage=$(do_facet mds2 $LCTL get_param -n \
22395                 osp.*$mdt_name-osp-MDT0001.maxage)
22396
22397         stack_trap "do_facet mds2 $LCTL set_param -n \
22398                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22399                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22400         stack_trap "do_facet mds2 $LCTL set_param -n \
22401                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22402
22403         do_facet mds2 $LCTL set_param -n \
22404                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22405         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22406         sleep 4
22407         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22408                 error "migrate $tdir should fail"
22409
22410         do_facet mds2 $LCTL set_param -n \
22411                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22412         do_facet mds2 $LCTL set_param -n \
22413                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22414         sleep 4
22415         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22416                 error "migrate failed"
22417         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22418                 error "$tdir stripe count mismatch"
22419 }
22420 run_test 230x "dir migration check space"
22421
22422 test_230y() {
22423         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22424         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22425                 skip "Need MDS version at least 2.15.55.45"
22426
22427         local pid
22428
22429         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22430         $LFS getdirstripe $DIR/$tdir
22431         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22432         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22433         pid=$!
22434         sleep 1
22435
22436         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22437         do_facet mds2 lctl set_param fail_loc=0x1802
22438
22439         wait $pid
22440         do_facet mds2 lctl set_param fail_loc=0
22441         $LFS getdirstripe $DIR/$tdir
22442         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22443         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22444 }
22445 run_test 230y "unlink dir with bad hash type"
22446
22447 test_230z() {
22448         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22449         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22450                 skip "Need MDS version at least 2.15.55.45"
22451
22452         local pid
22453
22454         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22455         $LFS getdirstripe $DIR/$tdir
22456         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22457         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22458         pid=$!
22459         sleep 1
22460
22461         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22462         do_facet mds2 lctl set_param fail_loc=0x1802
22463
22464         wait $pid
22465         do_facet mds2 lctl set_param fail_loc=0
22466         $LFS getdirstripe $DIR/$tdir
22467
22468         # resume migration
22469         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22470                 error "resume migration failed"
22471         $LFS getdirstripe $DIR/$tdir
22472         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22473                 error "migration is not finished"
22474 }
22475 run_test 230z "resume dir migration with bad hash type"
22476
22477 test_231a()
22478 {
22479         # For simplicity this test assumes that max_pages_per_rpc
22480         # is the same across all OSCs
22481         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22482         local bulk_size=$((max_pages * PAGE_SIZE))
22483         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22484                                        head -n 1)
22485
22486         mkdir -p $DIR/$tdir
22487         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22488                 error "failed to set stripe with -S ${brw_size}M option"
22489         stack_trap "rm -rf $DIR/$tdir"
22490
22491         # clear the OSC stats
22492         $LCTL set_param osc.*.stats=0 &>/dev/null
22493         stop_writeback
22494
22495         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22496         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22497                 oflag=direct &>/dev/null || error "dd failed"
22498
22499         sync; sleep 1; sync # just to be safe
22500         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22501         if [ x$nrpcs != "x1" ]; then
22502                 $LCTL get_param osc.*.stats
22503                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22504         fi
22505
22506         start_writeback
22507         # Drop the OSC cache, otherwise we will read from it
22508         cancel_lru_locks osc
22509
22510         # clear the OSC stats
22511         $LCTL set_param osc.*.stats=0 &>/dev/null
22512
22513         # Client reads $bulk_size.
22514         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22515                 iflag=direct &>/dev/null || error "dd failed"
22516
22517         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22518         if [ x$nrpcs != "x1" ]; then
22519                 $LCTL get_param osc.*.stats
22520                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22521         fi
22522 }
22523 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22524
22525 test_231b() {
22526         mkdir -p $DIR/$tdir
22527         stack_trap "rm -rf $DIR/$tdir"
22528         local i
22529         for i in {0..1023}; do
22530                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22531                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22532                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22533         done
22534         sync
22535 }
22536 run_test 231b "must not assert on fully utilized OST request buffer"
22537
22538 test_232a() {
22539         mkdir -p $DIR/$tdir
22540         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22541
22542         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22543         do_facet ost1 $LCTL set_param fail_loc=0x31c
22544
22545         # ignore dd failure
22546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22547         stack_trap "rm -f $DIR/$tdir/$tfile"
22548
22549         do_facet ost1 $LCTL set_param fail_loc=0
22550         umount_client $MOUNT || error "umount failed"
22551         mount_client $MOUNT || error "mount failed"
22552         stop ost1 || error "cannot stop ost1"
22553         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22554 }
22555 run_test 232a "failed lock should not block umount"
22556
22557 test_232b() {
22558         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22559                 skip "Need MDS version at least 2.10.58"
22560
22561         mkdir -p $DIR/$tdir
22562         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22563         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22564         stack_trap "rm -f $DIR/$tdir/$tfile"
22565         sync
22566         cancel_lru_locks osc
22567
22568         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22569         do_facet ost1 $LCTL set_param fail_loc=0x31c
22570
22571         # ignore failure
22572         $LFS data_version $DIR/$tdir/$tfile || true
22573
22574         do_facet ost1 $LCTL set_param fail_loc=0
22575         umount_client $MOUNT || error "umount failed"
22576         mount_client $MOUNT || error "mount failed"
22577         stop ost1 || error "cannot stop ost1"
22578         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22579 }
22580 run_test 232b "failed data version lock should not block umount"
22581
22582 test_233a() {
22583         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22584                 skip "Need MDS version at least 2.3.64"
22585         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22586
22587         local fid=$($LFS path2fid $MOUNT)
22588
22589         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22590                 error "cannot access $MOUNT using its FID '$fid'"
22591 }
22592 run_test 233a "checking that OBF of the FS root succeeds"
22593
22594 test_233b() {
22595         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22596                 skip "Need MDS version at least 2.5.90"
22597         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22598
22599         local fid=$($LFS path2fid $MOUNT/.lustre)
22600
22601         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22602                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22603
22604         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22605         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22606                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22607 }
22608 run_test 233b "checking that OBF of the FS .lustre succeeds"
22609
22610 test_234() {
22611         local p="$TMP/sanityN-$TESTNAME.parameters"
22612         save_lustre_params client "llite.*.xattr_cache" > $p
22613         lctl set_param llite.*.xattr_cache 1 ||
22614                 skip_env "xattr cache is not supported"
22615
22616         mkdir -p $DIR/$tdir || error "mkdir failed"
22617         touch $DIR/$tdir/$tfile || error "touch failed"
22618         # OBD_FAIL_LLITE_XATTR_ENOMEM
22619         $LCTL set_param fail_loc=0x1405
22620         getfattr -n user.attr $DIR/$tdir/$tfile &&
22621                 error "getfattr should have failed with ENOMEM"
22622         $LCTL set_param fail_loc=0x0
22623         rm -rf $DIR/$tdir
22624
22625         restore_lustre_params < $p
22626         rm -f $p
22627 }
22628 run_test 234 "xattr cache should not crash on ENOMEM"
22629
22630 test_235() {
22631         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22632                 skip "Need MDS version at least 2.4.52"
22633
22634         flock_deadlock $DIR/$tfile
22635         local RC=$?
22636         case $RC in
22637                 0)
22638                 ;;
22639                 124) error "process hangs on a deadlock"
22640                 ;;
22641                 *) error "error executing flock_deadlock $DIR/$tfile"
22642                 ;;
22643         esac
22644 }
22645 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22646
22647 #LU-2935
22648 test_236() {
22649         check_swap_layouts_support
22650
22651         local ref1=/etc/passwd
22652         local ref2=/etc/group
22653         local file1=$DIR/$tdir/f1
22654         local file2=$DIR/$tdir/f2
22655
22656         test_mkdir -c1 $DIR/$tdir
22657         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22658         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22659         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22660         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22661         local fd=$(free_fd)
22662         local cmd="exec $fd<>$file2"
22663         eval $cmd
22664         rm $file2
22665         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22666                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22667         cmd="exec $fd>&-"
22668         eval $cmd
22669         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22670
22671         #cleanup
22672         rm -rf $DIR/$tdir
22673 }
22674 run_test 236 "Layout swap on open unlinked file"
22675
22676 # LU-4659 linkea consistency
22677 test_238() {
22678         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22679                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22680                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22681                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22682
22683         touch $DIR/$tfile
22684         ln $DIR/$tfile $DIR/$tfile.lnk
22685         touch $DIR/$tfile.new
22686         mv $DIR/$tfile.new $DIR/$tfile
22687         local fid1=$($LFS path2fid $DIR/$tfile)
22688         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22689         local path1=$($LFS fid2path $FSNAME "$fid1")
22690         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22691         local path2=$($LFS fid2path $FSNAME "$fid2")
22692         [ $tfile.lnk == $path2 ] ||
22693                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22694         rm -f $DIR/$tfile*
22695 }
22696 run_test 238 "Verify linkea consistency"
22697
22698 test_239A() { # was test_239
22699         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22700                 skip "Need MDS version at least 2.5.60"
22701
22702         local list=$(comma_list $(mdts_nodes))
22703
22704         mkdir -p $DIR/$tdir
22705         createmany -o $DIR/$tdir/f- 5000
22706         unlinkmany $DIR/$tdir/f- 5000
22707         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22708                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22709         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22710                         osp.*MDT*.sync_in_flight" | calc_sum)
22711         [ "$changes" -eq 0 ] || error "$changes not synced"
22712 }
22713 run_test 239A "osp_sync test"
22714
22715 test_239a() { #LU-5297
22716         remote_mds_nodsh && skip "remote MDS with nodsh"
22717
22718         touch $DIR/$tfile
22719         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22720         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22721         chgrp $RUNAS_GID $DIR/$tfile
22722         wait_delete_completed
22723 }
22724 run_test 239a "process invalid osp sync record correctly"
22725
22726 test_239b() { #LU-5297
22727         remote_mds_nodsh && skip "remote MDS with nodsh"
22728
22729         touch $DIR/$tfile1
22730         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22731         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22732         chgrp $RUNAS_GID $DIR/$tfile1
22733         wait_delete_completed
22734         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22735         touch $DIR/$tfile2
22736         chgrp $RUNAS_GID $DIR/$tfile2
22737         wait_delete_completed
22738 }
22739 run_test 239b "process osp sync record with ENOMEM error correctly"
22740
22741 test_240() {
22742         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22743         remote_mds_nodsh && skip "remote MDS with nodsh"
22744
22745         mkdir -p $DIR/$tdir
22746
22747         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22748                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22749         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22750                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22751
22752         umount_client $MOUNT || error "umount failed"
22753         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22754         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22755         mount_client $MOUNT || error "failed to mount client"
22756
22757         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22758         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22759 }
22760 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22761
22762 test_241_bio() {
22763         local count=$1
22764         local bsize=$2
22765
22766         for LOOP in $(seq $count); do
22767                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22768                 cancel_lru_locks $OSC || true
22769         done
22770 }
22771
22772 test_241_dio() {
22773         local count=$1
22774         local bsize=$2
22775
22776         for LOOP in $(seq $1); do
22777                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22778                         2>/dev/null
22779         done
22780 }
22781
22782 test_241a() { # was test_241
22783         local bsize=$PAGE_SIZE
22784
22785         (( bsize < 40960 )) && bsize=40960
22786         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22787         ls -la $DIR/$tfile
22788         cancel_lru_locks $OSC
22789         test_241_bio 1000 $bsize &
22790         PID=$!
22791         test_241_dio 1000 $bsize
22792         wait $PID
22793 }
22794 run_test 241a "bio vs dio"
22795
22796 test_241b() {
22797         local bsize=$PAGE_SIZE
22798
22799         (( bsize < 40960 )) && bsize=40960
22800         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22801         ls -la $DIR/$tfile
22802         test_241_dio 1000 $bsize &
22803         PID=$!
22804         test_241_dio 1000 $bsize
22805         wait $PID
22806 }
22807 run_test 241b "dio vs dio"
22808
22809 test_242() {
22810         remote_mds_nodsh && skip "remote MDS with nodsh"
22811
22812         mkdir_on_mdt0 $DIR/$tdir
22813         touch $DIR/$tdir/$tfile
22814
22815         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22816         do_facet mds1 lctl set_param fail_loc=0x105
22817         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22818
22819         do_facet mds1 lctl set_param fail_loc=0
22820         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22821 }
22822 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22823
22824 test_243()
22825 {
22826         test_mkdir $DIR/$tdir
22827         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22828 }
22829 run_test 243 "various group lock tests"
22830
22831 test_244a()
22832 {
22833         test_mkdir $DIR/$tdir
22834         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22835         sendfile_grouplock $DIR/$tdir/$tfile || \
22836                 error "sendfile+grouplock failed"
22837         rm -rf $DIR/$tdir
22838 }
22839 run_test 244a "sendfile with group lock tests"
22840
22841 test_244b()
22842 {
22843         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22844
22845         local threads=50
22846         local size=$((1024*1024))
22847
22848         test_mkdir $DIR/$tdir
22849         for i in $(seq 1 $threads); do
22850                 local file=$DIR/$tdir/file_$((i / 10))
22851                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22852                 local pids[$i]=$!
22853         done
22854         for i in $(seq 1 $threads); do
22855                 wait ${pids[$i]}
22856         done
22857 }
22858 run_test 244b "multi-threaded write with group lock"
22859
22860 test_245a() {
22861         local flagname="multi_mod_rpcs"
22862         local connect_data_name="max_mod_rpcs"
22863         local out
22864
22865         # check if multiple modify RPCs flag is set
22866         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22867                 grep "connect_flags:")
22868         echo "$out"
22869
22870         echo "$out" | grep -qw $flagname
22871         if [ $? -ne 0 ]; then
22872                 echo "connect flag $flagname is not set"
22873                 return
22874         fi
22875
22876         # check if multiple modify RPCs data is set
22877         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22878         echo "$out"
22879
22880         echo "$out" | grep -qw $connect_data_name ||
22881                 error "import should have connect data $connect_data_name"
22882 }
22883 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22884
22885 test_245b() {
22886         local flagname="multi_mod_rpcs"
22887         local connect_data_name="max_mod_rpcs"
22888         local out
22889
22890         remote_mds_nodsh && skip "remote MDS with nodsh"
22891         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22892
22893         # check if multiple modify RPCs flag is set
22894         out=$(do_facet mds1 \
22895               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22896               grep "connect_flags:")
22897         echo "$out"
22898
22899         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22900
22901         # check if multiple modify RPCs data is set
22902         out=$(do_facet mds1 \
22903               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22904
22905         [[ "$out" =~ $connect_data_name ]] ||
22906                 {
22907                         echo "$out"
22908                         error "missing connect data $connect_data_name"
22909                 }
22910 }
22911 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22912
22913 cleanup_247() {
22914         local submount=$1
22915
22916         trap 0
22917         umount_client $submount
22918         rmdir $submount
22919 }
22920
22921 test_247a() {
22922         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22923                 grep -q subtree ||
22924                 skip_env "Fileset feature is not supported"
22925
22926         local submount=${MOUNT}_$tdir
22927
22928         mkdir $MOUNT/$tdir
22929         mkdir -p $submount || error "mkdir $submount failed"
22930         FILESET="$FILESET/$tdir" mount_client $submount ||
22931                 error "mount $submount failed"
22932         trap "cleanup_247 $submount" EXIT
22933         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22934         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22935                 error "read $MOUNT/$tdir/$tfile failed"
22936         cleanup_247 $submount
22937 }
22938 run_test 247a "mount subdir as fileset"
22939
22940 test_247b() {
22941         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22942                 skip_env "Fileset feature is not supported"
22943
22944         local submount=${MOUNT}_$tdir
22945
22946         rm -rf $MOUNT/$tdir
22947         mkdir -p $submount || error "mkdir $submount failed"
22948         SKIP_FILESET=1
22949         FILESET="$FILESET/$tdir" mount_client $submount &&
22950                 error "mount $submount should fail"
22951         rmdir $submount
22952 }
22953 run_test 247b "mount subdir that dose not exist"
22954
22955 test_247c() {
22956         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22957                 skip_env "Fileset feature is not supported"
22958
22959         local submount=${MOUNT}_$tdir
22960
22961         mkdir -p $MOUNT/$tdir/dir1
22962         mkdir -p $submount || error "mkdir $submount failed"
22963         trap "cleanup_247 $submount" EXIT
22964         FILESET="$FILESET/$tdir" mount_client $submount ||
22965                 error "mount $submount failed"
22966         local fid=$($LFS path2fid $MOUNT/)
22967         $LFS fid2path $submount $fid && error "fid2path should fail"
22968         cleanup_247 $submount
22969 }
22970 run_test 247c "running fid2path outside subdirectory root"
22971
22972 test_247d() {
22973         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22974                 skip "Fileset feature is not supported"
22975
22976         local submount=${MOUNT}_$tdir
22977
22978         mkdir -p $MOUNT/$tdir/dir1
22979         mkdir -p $submount || error "mkdir $submount failed"
22980         FILESET="$FILESET/$tdir" mount_client $submount ||
22981                 error "mount $submount failed"
22982         trap "cleanup_247 $submount" EXIT
22983
22984         local td=$submount/dir1
22985         local fid=$($LFS path2fid $td)
22986         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22987
22988         # check that we get the same pathname back
22989         local rootpath
22990         local found
22991         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22992                 echo "$rootpath $fid"
22993                 found=$($LFS fid2path $rootpath "$fid")
22994                 [ -n "$found" ] || error "fid2path should succeed"
22995                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22996         done
22997         # check wrong root path format
22998         rootpath=$submount"_wrong"
22999         found=$($LFS fid2path $rootpath "$fid")
23000         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23001
23002         cleanup_247 $submount
23003 }
23004 run_test 247d "running fid2path inside subdirectory root"
23005
23006 # LU-8037
23007 test_247e() {
23008         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23009                 grep -q subtree ||
23010                 skip "Fileset feature is not supported"
23011
23012         local submount=${MOUNT}_$tdir
23013
23014         mkdir $MOUNT/$tdir
23015         mkdir -p $submount || error "mkdir $submount failed"
23016         FILESET="$FILESET/.." mount_client $submount &&
23017                 error "mount $submount should fail"
23018         rmdir $submount
23019 }
23020 run_test 247e "mount .. as fileset"
23021
23022 test_247f() {
23023         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23024         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23025                 skip "Need at least version 2.14.50.162"
23026         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23027                 skip "Fileset feature is not supported"
23028
23029         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23030         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23031                 error "mkdir remote failed"
23032         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23033                 error "mkdir remote/subdir failed"
23034         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23035                 error "mkdir striped failed"
23036         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23037
23038         local submount=${MOUNT}_$tdir
23039
23040         mkdir -p $submount || error "mkdir $submount failed"
23041         stack_trap "rmdir $submount"
23042
23043         local dir
23044         local fileset=$FILESET
23045         local mdts=$(comma_list $(mdts_nodes))
23046
23047         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23048         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23049                 $tdir/striped/subdir $tdir/striped/.; do
23050                 FILESET="$fileset/$dir" mount_client $submount ||
23051                         error "mount $dir failed"
23052                 umount_client $submount
23053         done
23054 }
23055 run_test 247f "mount striped or remote directory as fileset"
23056
23057 test_subdir_mount_lock()
23058 {
23059         local testdir=$1
23060         local submount=${MOUNT}_$(basename $testdir)
23061
23062         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23063
23064         mkdir -p $submount || error "mkdir $submount failed"
23065         stack_trap "rmdir $submount"
23066
23067         FILESET="$fileset/$testdir" mount_client $submount ||
23068                 error "mount $FILESET failed"
23069         stack_trap "umount $submount"
23070
23071         local mdts=$(comma_list $(mdts_nodes))
23072
23073         local nrpcs
23074
23075         stat $submount > /dev/null || error "stat $submount failed"
23076         cancel_lru_locks $MDC
23077         stat $submount > /dev/null || error "stat $submount failed"
23078         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23079         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23080         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23081         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23082                 awk '/getattr/ {sum += $2} END {print sum}')
23083
23084         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23085 }
23086
23087 test_247g() {
23088         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23089
23090         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23091                 error "mkdir $tdir failed"
23092         test_subdir_mount_lock $tdir
23093 }
23094 run_test 247g "striped directory submount revalidate ROOT from cache"
23095
23096 test_247h() {
23097         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23098         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23099                 skip "Need MDS version at least 2.15.51"
23100
23101         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23102         test_subdir_mount_lock $tdir
23103         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23104         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23105                 error "mkdir $tdir.1 failed"
23106         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23107 }
23108 run_test 247h "remote directory submount revalidate ROOT from cache"
23109
23110 test_248a() {
23111         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23112         [ -z "$fast_read_sav" ] && skip "no fast read support"
23113
23114         # create a large file for fast read verification
23115         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23116
23117         # make sure the file is created correctly
23118         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23119                 { rm -f $DIR/$tfile; skip "file creation error"; }
23120
23121         echo "Test 1: verify that fast read is 4 times faster on cache read"
23122
23123         # small read with fast read enabled
23124         $LCTL set_param -n llite.*.fast_read=1
23125         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23126                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23127                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23128         # small read with fast read disabled
23129         $LCTL set_param -n llite.*.fast_read=0
23130         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23131                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23132                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23133
23134         # verify that fast read is 4 times faster for cache read
23135         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23136                 error_not_in_vm "fast read was not 4 times faster: " \
23137                            "$t_fast vs $t_slow"
23138
23139         echo "Test 2: verify the performance between big and small read"
23140         $LCTL set_param -n llite.*.fast_read=1
23141
23142         # 1k non-cache read
23143         cancel_lru_locks osc
23144         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23145                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23146                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23147
23148         # 1M non-cache read
23149         cancel_lru_locks osc
23150         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23151                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23152                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23153
23154         # verify that big IO is not 4 times faster than small IO
23155         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23156                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23157
23158         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23159         rm -f $DIR/$tfile
23160 }
23161 run_test 248a "fast read verification"
23162
23163 test_248b() {
23164         # Default short_io_bytes=16384, try both smaller and larger sizes.
23165         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23166         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23167         echo "bs=53248 count=113 normal buffered write"
23168         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23169                 error "dd of initial data file failed"
23170         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23171
23172         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23173         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23174                 error "dd with sync normal writes failed"
23175         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23176
23177         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23178         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23179                 error "dd with sync small writes failed"
23180         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23181
23182         cancel_lru_locks osc
23183
23184         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23185         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23186         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23187         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23188                 iflag=direct || error "dd with O_DIRECT small read failed"
23189         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23190         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23191                 error "compare $TMP/$tfile.1 failed"
23192
23193         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23194         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23195
23196         # just to see what the maximum tunable value is, and test parsing
23197         echo "test invalid parameter 2MB"
23198         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23199                 error "too-large short_io_bytes allowed"
23200         echo "test maximum parameter 512KB"
23201         # if we can set a larger short_io_bytes, run test regardless of version
23202         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23203                 # older clients may not allow setting it this large, that's OK
23204                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23205                         skip "Need at least client version 2.13.50"
23206                 error "medium short_io_bytes failed"
23207         fi
23208         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23209         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23210
23211         echo "test large parameter 64KB"
23212         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23213         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23214
23215         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23216         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23217                 error "dd with sync large writes failed"
23218         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23219
23220         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23221         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23222         num=$((113 * 4096 / PAGE_SIZE))
23223         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23224         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23225                 error "dd with O_DIRECT large writes failed"
23226         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23227                 error "compare $DIR/$tfile.3 failed"
23228
23229         cancel_lru_locks osc
23230
23231         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23232         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23233                 error "dd with O_DIRECT large read failed"
23234         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23235                 error "compare $TMP/$tfile.2 failed"
23236
23237         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23238         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23239                 error "dd with O_DIRECT large read failed"
23240         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23241                 error "compare $TMP/$tfile.3 failed"
23242 }
23243 run_test 248b "test short_io read and write for both small and large sizes"
23244
23245 test_249() { # LU-7890
23246         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23247                 skip "Need at least version 2.8.54"
23248
23249         rm -f $DIR/$tfile
23250         $LFS setstripe -c 1 $DIR/$tfile
23251         # Offset 2T == 4k * 512M
23252         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23253                 error "dd to 2T offset failed"
23254 }
23255 run_test 249 "Write above 2T file size"
23256
23257 test_250() {
23258         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23259          && skip "no 16TB file size limit on ZFS"
23260
23261         $LFS setstripe -c 1 $DIR/$tfile
23262         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23263         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23264         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23265         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23266                 conv=notrunc,fsync && error "append succeeded"
23267         return 0
23268 }
23269 run_test 250 "Write above 16T limit"
23270
23271 test_251() {
23272         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23273
23274         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23275         #Skip once - writing the first stripe will succeed
23276         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23277         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23278                 error "short write happened"
23279
23280         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23281         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23282                 error "short read happened"
23283
23284         rm -f $DIR/$tfile
23285 }
23286 run_test 251 "Handling short read and write correctly"
23287
23288 test_252() {
23289         remote_mds_nodsh && skip "remote MDS with nodsh"
23290         remote_ost_nodsh && skip "remote OST with nodsh"
23291         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23292                 skip_env "ldiskfs only test"
23293         fi
23294
23295         local tgt
23296         local dev
23297         local out
23298         local uuid
23299         local num
23300         local gen
23301
23302         # check lr_reader on OST0000
23303         tgt=ost1
23304         dev=$(facet_device $tgt)
23305         out=$(do_facet $tgt $LR_READER $dev)
23306         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23307         echo "$out"
23308         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23309         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23310                 error "Invalid uuid returned by $LR_READER on target $tgt"
23311         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23312
23313         # check lr_reader -c on MDT0000
23314         tgt=mds1
23315         dev=$(facet_device $tgt)
23316         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23317                 skip "$LR_READER does not support additional options"
23318         fi
23319         out=$(do_facet $tgt $LR_READER -c $dev)
23320         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23321         echo "$out"
23322         num=$(echo "$out" | grep -c "mdtlov")
23323         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23324                 error "Invalid number of mdtlov clients returned by $LR_READER"
23325         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23326
23327         # check lr_reader -cr on MDT0000
23328         out=$(do_facet $tgt $LR_READER -cr $dev)
23329         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23330         echo "$out"
23331         echo "$out" | grep -q "^reply_data:$" ||
23332                 error "$LR_READER should have returned 'reply_data' section"
23333         num=$(echo "$out" | grep -c "client_generation")
23334         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23335 }
23336 run_test 252 "check lr_reader tool"
23337
23338 test_253() {
23339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23340         remote_mds_nodsh && skip "remote MDS with nodsh"
23341         remote_mgs_nodsh && skip "remote MGS with nodsh"
23342
23343         local ostidx=0
23344         local rc=0
23345         local ost_name=$(ostname_from_index $ostidx)
23346
23347         # on the mdt's osc
23348         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23349         do_facet $SINGLEMDS $LCTL get_param -n \
23350                 osp.$mdtosc_proc1.reserved_mb_high ||
23351                 skip  "remote MDS does not support reserved_mb_high"
23352
23353         rm -rf $DIR/$tdir
23354         wait_mds_ost_sync
23355         wait_delete_completed
23356         mkdir $DIR/$tdir
23357         stack_trap "rm -rf $DIR/$tdir"
23358
23359         pool_add $TESTNAME || error "Pool creation failed"
23360         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23361
23362         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23363                 error "Setstripe failed"
23364
23365         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23366
23367         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23368                     grep "watermarks")
23369         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23370
23371         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23372                         osp.$mdtosc_proc1.prealloc_status)
23373         echo "prealloc_status $oa_status"
23374
23375         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23376                 error "File creation should fail"
23377
23378         #object allocation was stopped, but we still able to append files
23379         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23380                 oflag=append || error "Append failed"
23381
23382         rm -f $DIR/$tdir/$tfile.0
23383
23384         # For this test, we want to delete the files we created to go out of
23385         # space but leave the watermark, so we remain nearly out of space
23386         ost_watermarks_enospc_delete_files $tfile $ostidx
23387
23388         wait_delete_completed
23389
23390         sleep_maxage
23391
23392         for i in $(seq 10 12); do
23393                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23394                         2>/dev/null || error "File creation failed after rm"
23395         done
23396
23397         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23398                         osp.$mdtosc_proc1.prealloc_status)
23399         echo "prealloc_status $oa_status"
23400
23401         if (( oa_status != 0 )); then
23402                 error "Object allocation still disable after rm"
23403         fi
23404 }
23405 run_test 253 "Check object allocation limit"
23406
23407 test_254() {
23408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23409         remote_mds_nodsh && skip "remote MDS with nodsh"
23410
23411         local mdt=$(facet_svc $SINGLEMDS)
23412
23413         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23414                 skip "MDS does not support changelog_size"
23415
23416         local cl_user
23417
23418         changelog_register || error "changelog_register failed"
23419
23420         changelog_clear 0 || error "changelog_clear failed"
23421
23422         local size1=$(do_facet $SINGLEMDS \
23423                       $LCTL get_param -n mdd.$mdt.changelog_size)
23424         echo "Changelog size $size1"
23425
23426         rm -rf $DIR/$tdir
23427         $LFS mkdir -i 0 $DIR/$tdir
23428         # change something
23429         mkdir -p $DIR/$tdir/pics/2008/zachy
23430         touch $DIR/$tdir/pics/2008/zachy/timestamp
23431         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23432         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23433         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23434         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23435         rm $DIR/$tdir/pics/desktop.jpg
23436
23437         local size2=$(do_facet $SINGLEMDS \
23438                       $LCTL get_param -n mdd.$mdt.changelog_size)
23439         echo "Changelog size after work $size2"
23440
23441         (( $size2 > $size1 )) ||
23442                 error "new Changelog size=$size2 less than old size=$size1"
23443 }
23444 run_test 254 "Check changelog size"
23445
23446 ladvise_no_type()
23447 {
23448         local type=$1
23449         local file=$2
23450
23451         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23452                 awk -F: '{print $2}' | grep $type > /dev/null
23453         if [ $? -ne 0 ]; then
23454                 return 0
23455         fi
23456         return 1
23457 }
23458
23459 ladvise_no_ioctl()
23460 {
23461         local file=$1
23462
23463         lfs ladvise -a willread $file > /dev/null 2>&1
23464         if [ $? -eq 0 ]; then
23465                 return 1
23466         fi
23467
23468         lfs ladvise -a willread $file 2>&1 |
23469                 grep "Inappropriate ioctl for device" > /dev/null
23470         if [ $? -eq 0 ]; then
23471                 return 0
23472         fi
23473         return 1
23474 }
23475
23476 percent() {
23477         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23478 }
23479
23480 # run a random read IO workload
23481 # usage: random_read_iops <filename> <filesize> <iosize>
23482 random_read_iops() {
23483         local file=$1
23484         local fsize=$2
23485         local iosize=${3:-4096}
23486
23487         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23488                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23489 }
23490
23491 drop_file_oss_cache() {
23492         local file="$1"
23493         local nodes="$2"
23494
23495         $LFS ladvise -a dontneed $file 2>/dev/null ||
23496                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23497 }
23498
23499 ladvise_willread_performance()
23500 {
23501         local repeat=10
23502         local average_origin=0
23503         local average_cache=0
23504         local average_ladvise=0
23505
23506         for ((i = 1; i <= $repeat; i++)); do
23507                 echo "Iter $i/$repeat: reading without willread hint"
23508                 cancel_lru_locks osc
23509                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23510                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23511                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23512                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23513
23514                 cancel_lru_locks osc
23515                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23516                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23517                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23518
23519                 cancel_lru_locks osc
23520                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23521                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23522                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23523                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23524                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23525         done
23526         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23527         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23528         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23529
23530         speedup_cache=$(percent $average_cache $average_origin)
23531         speedup_ladvise=$(percent $average_ladvise $average_origin)
23532
23533         echo "Average uncached read: $average_origin"
23534         echo "Average speedup with OSS cached read: " \
23535                 "$average_cache = +$speedup_cache%"
23536         echo "Average speedup with ladvise willread: " \
23537                 "$average_ladvise = +$speedup_ladvise%"
23538
23539         local lowest_speedup=20
23540         if (( ${average_cache%.*} < $lowest_speedup )); then
23541                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23542                      " got $average_cache%. Skipping ladvise willread check."
23543                 return 0
23544         fi
23545
23546         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23547         # it is still good to run until then to exercise 'ladvise willread'
23548         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23549                 [ "$ost1_FSTYPE" = "zfs" ] &&
23550                 echo "osd-zfs does not support dontneed or drop_caches" &&
23551                 return 0
23552
23553         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23554         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23555                 error_not_in_vm "Speedup with willread is less than " \
23556                         "$lowest_speedup%, got $average_ladvise%"
23557 }
23558
23559 test_255a() {
23560         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23561                 skip "lustre < 2.8.54 does not support ladvise "
23562         remote_ost_nodsh && skip "remote OST with nodsh"
23563
23564         stack_trap "rm -f $DIR/$tfile"
23565         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23566
23567         ladvise_no_type willread $DIR/$tfile &&
23568                 skip "willread ladvise is not supported"
23569
23570         ladvise_no_ioctl $DIR/$tfile &&
23571                 skip "ladvise ioctl is not supported"
23572
23573         local size_mb=100
23574         local size=$((size_mb * 1048576))
23575         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23576                 error "dd to $DIR/$tfile failed"
23577
23578         lfs ladvise -a willread $DIR/$tfile ||
23579                 error "Ladvise failed with no range argument"
23580
23581         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23582                 error "Ladvise failed with no -l or -e argument"
23583
23584         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23585                 error "Ladvise failed with only -e argument"
23586
23587         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23588                 error "Ladvise failed with only -l argument"
23589
23590         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23591                 error "End offset should not be smaller than start offset"
23592
23593         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23594                 error "End offset should not be equal to start offset"
23595
23596         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23597                 error "Ladvise failed with overflowing -s argument"
23598
23599         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23600                 error "Ladvise failed with overflowing -e argument"
23601
23602         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23603                 error "Ladvise failed with overflowing -l argument"
23604
23605         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23606                 error "Ladvise succeeded with conflicting -l and -e arguments"
23607
23608         echo "Synchronous ladvise should wait"
23609         local delay=8
23610 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23611         do_nodes $(comma_list $(osts_nodes)) \
23612                 $LCTL set_param fail_val=$delay fail_loc=0x237
23613         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23614                 $LCTL set_param fail_loc=0"
23615
23616         local start_ts=$SECONDS
23617         lfs ladvise -a willread $DIR/$tfile ||
23618                 error "Ladvise failed with no range argument"
23619         local end_ts=$SECONDS
23620         local inteval_ts=$((end_ts - start_ts))
23621
23622         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23623                 error "Synchronous advice didn't wait reply"
23624         fi
23625
23626         echo "Asynchronous ladvise shouldn't wait"
23627         local start_ts=$SECONDS
23628         lfs ladvise -a willread -b $DIR/$tfile ||
23629                 error "Ladvise failed with no range argument"
23630         local end_ts=$SECONDS
23631         local inteval_ts=$((end_ts - start_ts))
23632
23633         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23634                 error "Asynchronous advice blocked"
23635         fi
23636
23637         ladvise_willread_performance
23638 }
23639 run_test 255a "check 'lfs ladvise -a willread'"
23640
23641 facet_meminfo() {
23642         local facet=$1
23643         local info=$2
23644
23645         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23646 }
23647
23648 test_255b() {
23649         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23650                 skip "lustre < 2.8.54 does not support ladvise "
23651         remote_ost_nodsh && skip "remote OST with nodsh"
23652
23653         stack_trap "rm -f $DIR/$tfile"
23654         lfs setstripe -c 1 -i 0 $DIR/$tfile
23655
23656         ladvise_no_type dontneed $DIR/$tfile &&
23657                 skip "dontneed ladvise is not supported"
23658
23659         ladvise_no_ioctl $DIR/$tfile &&
23660                 skip "ladvise ioctl is not supported"
23661
23662         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23663                 [ "$ost1_FSTYPE" = "zfs" ] &&
23664                 skip "zfs-osd does not support 'ladvise dontneed'"
23665
23666         local size_mb=100
23667         local size=$((size_mb * 1048576))
23668         # In order to prevent disturbance of other processes, only check 3/4
23669         # of the memory usage
23670         local kibibytes=$((size_mb * 1024 * 3 / 4))
23671
23672         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23673                 error "dd to $DIR/$tfile failed"
23674
23675         #force write to complete before dropping OST cache & checking memory
23676         sync
23677
23678         local total=$(facet_meminfo ost1 MemTotal)
23679         echo "Total memory: $total KiB"
23680
23681         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23682         local before_read=$(facet_meminfo ost1 Cached)
23683         echo "Cache used before read: $before_read KiB"
23684
23685         lfs ladvise -a willread $DIR/$tfile ||
23686                 error "Ladvise willread failed"
23687         local after_read=$(facet_meminfo ost1 Cached)
23688         echo "Cache used after read: $after_read KiB"
23689
23690         lfs ladvise -a dontneed $DIR/$tfile ||
23691                 error "Ladvise dontneed again failed"
23692         local no_read=$(facet_meminfo ost1 Cached)
23693         echo "Cache used after dontneed ladvise: $no_read KiB"
23694
23695         if [ $total -lt $((before_read + kibibytes)) ]; then
23696                 echo "Memory is too small, abort checking"
23697                 return 0
23698         fi
23699
23700         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23701                 error "Ladvise willread should use more memory" \
23702                         "than $kibibytes KiB"
23703         fi
23704
23705         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23706                 error "Ladvise dontneed should release more memory" \
23707                         "than $kibibytes KiB"
23708         fi
23709 }
23710 run_test 255b "check 'lfs ladvise -a dontneed'"
23711
23712 test_255c() {
23713         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23714                 skip "lustre < 2.10.50 does not support lockahead"
23715
23716         local ost1_imp=$(get_osc_import_name client ost1)
23717         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23718                          cut -d'.' -f2)
23719         local count
23720         local new_count
23721         local difference
23722         local i
23723         local rc
23724
23725         test_mkdir -p $DIR/$tdir
23726         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23727
23728         #test 10 returns only success/failure
23729         i=10
23730         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23731         rc=$?
23732         if [ $rc -eq 255 ]; then
23733                 error "Ladvise test${i} failed, ${rc}"
23734         fi
23735
23736         #test 11 counts lock enqueue requests, all others count new locks
23737         i=11
23738         count=$(do_facet ost1 \
23739                 $LCTL get_param -n ost.OSS.ost.stats)
23740         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23741
23742         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23743         rc=$?
23744         if [ $rc -eq 255 ]; then
23745                 error "Ladvise test${i} failed, ${rc}"
23746         fi
23747
23748         new_count=$(do_facet ost1 \
23749                 $LCTL get_param -n ost.OSS.ost.stats)
23750         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23751                    awk '{ print $2 }')
23752
23753         difference="$((new_count - count))"
23754         if [ $difference -ne $rc ]; then
23755                 error "Ladvise test${i}, bad enqueue count, returned " \
23756                       "${rc}, actual ${difference}"
23757         fi
23758
23759         for i in $(seq 12 21); do
23760                 # If we do not do this, we run the risk of having too many
23761                 # locks and starting lock cancellation while we are checking
23762                 # lock counts.
23763                 cancel_lru_locks osc
23764
23765                 count=$($LCTL get_param -n \
23766                        ldlm.namespaces.$imp_name.lock_unused_count)
23767
23768                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23769                 rc=$?
23770                 if [ $rc -eq 255 ]; then
23771                         error "Ladvise test ${i} failed, ${rc}"
23772                 fi
23773
23774                 new_count=$($LCTL get_param -n \
23775                        ldlm.namespaces.$imp_name.lock_unused_count)
23776                 difference="$((new_count - count))"
23777
23778                 # Test 15 output is divided by 100 to map down to valid return
23779                 if [ $i -eq 15 ]; then
23780                         rc="$((rc * 100))"
23781                 fi
23782
23783                 if [ $difference -ne $rc ]; then
23784                         error "Ladvise test ${i}, bad lock count, returned " \
23785                               "${rc}, actual ${difference}"
23786                 fi
23787         done
23788
23789         #test 22 returns only success/failure
23790         i=22
23791         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23792         rc=$?
23793         if [ $rc -eq 255 ]; then
23794                 error "Ladvise test${i} failed, ${rc}"
23795         fi
23796 }
23797 run_test 255c "suite of ladvise lockahead tests"
23798
23799 test_256() {
23800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23801         remote_mds_nodsh && skip "remote MDS with nodsh"
23802         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23803         changelog_users $SINGLEMDS | grep "^cl" &&
23804                 skip "active changelog user"
23805
23806         local cl_user
23807         local cat_sl
23808         local mdt_dev
23809
23810         mdt_dev=$(facet_device $SINGLEMDS)
23811         echo $mdt_dev
23812
23813         changelog_register || error "changelog_register failed"
23814
23815         rm -rf $DIR/$tdir
23816         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23817
23818         changelog_clear 0 || error "changelog_clear failed"
23819
23820         # change something
23821         touch $DIR/$tdir/{1..10}
23822
23823         # stop the MDT
23824         stop $SINGLEMDS || error "Fail to stop MDT"
23825
23826         # remount the MDT
23827         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23828                 error "Fail to start MDT"
23829
23830         #after mount new plainllog is used
23831         touch $DIR/$tdir/{11..19}
23832         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23833         stack_trap "rm -f $tmpfile"
23834         cat_sl=$(do_facet $SINGLEMDS "sync; \
23835                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23836                  llog_reader $tmpfile | grep -c type=1064553b")
23837         do_facet $SINGLEMDS llog_reader $tmpfile
23838
23839         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23840
23841         changelog_clear 0 || error "changelog_clear failed"
23842
23843         cat_sl=$(do_facet $SINGLEMDS "sync; \
23844                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23845                  llog_reader $tmpfile | grep -c type=1064553b")
23846
23847         if (( cat_sl == 2 )); then
23848                 error "Empty plain llog was not deleted from changelog catalog"
23849         elif (( cat_sl != 1 )); then
23850                 error "Active plain llog shouldn't be deleted from catalog"
23851         fi
23852 }
23853 run_test 256 "Check llog delete for empty and not full state"
23854
23855 test_257() {
23856         remote_mds_nodsh && skip "remote MDS with nodsh"
23857         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23858                 skip "Need MDS version at least 2.8.55"
23859
23860         test_mkdir $DIR/$tdir
23861
23862         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23863                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23864         stat $DIR/$tdir
23865
23866 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23867         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23868         local facet=mds$((mdtidx + 1))
23869         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23870         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23871
23872         stop $facet || error "stop MDS failed"
23873         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23874                 error "start MDS fail"
23875         wait_recovery_complete $facet
23876 }
23877 run_test 257 "xattr locks are not lost"
23878
23879 # Verify we take the i_mutex when security requires it
23880 test_258a() {
23881 #define OBD_FAIL_IMUTEX_SEC 0x141c
23882         $LCTL set_param fail_loc=0x141c
23883         touch $DIR/$tfile
23884         chmod u+s $DIR/$tfile
23885         chmod a+rwx $DIR/$tfile
23886         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23887         RC=$?
23888         if [ $RC -ne 0 ]; then
23889                 error "error, failed to take i_mutex, rc=$?"
23890         fi
23891         rm -f $DIR/$tfile
23892 }
23893 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23894
23895 # Verify we do NOT take the i_mutex in the normal case
23896 test_258b() {
23897 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23898         $LCTL set_param fail_loc=0x141d
23899         touch $DIR/$tfile
23900         chmod a+rwx $DIR
23901         chmod a+rw $DIR/$tfile
23902         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23903         RC=$?
23904         if [ $RC -ne 0 ]; then
23905                 error "error, took i_mutex unnecessarily, rc=$?"
23906         fi
23907         rm -f $DIR/$tfile
23908
23909 }
23910 run_test 258b "verify i_mutex security behavior"
23911
23912 test_259() {
23913         local file=$DIR/$tfile
23914         local before
23915         local after
23916
23917         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23918
23919         stack_trap "rm -f $file" EXIT
23920
23921         wait_delete_completed
23922         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23923         echo "before: $before"
23924
23925         $LFS setstripe -i 0 -c 1 $file
23926         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23927         sync_all_data
23928         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23929         echo "after write: $after"
23930
23931 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23932         do_facet ost1 $LCTL set_param fail_loc=0x2301
23933         $TRUNCATE $file 0
23934         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23935         echo "after truncate: $after"
23936
23937         stop ost1
23938         do_facet ost1 $LCTL set_param fail_loc=0
23939         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23940         sleep 2
23941         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23942         echo "after restart: $after"
23943         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23944                 error "missing truncate?"
23945
23946         return 0
23947 }
23948 run_test 259 "crash at delayed truncate"
23949
23950 test_260() {
23951 #define OBD_FAIL_MDC_CLOSE               0x806
23952         $LCTL set_param fail_loc=0x80000806
23953         touch $DIR/$tfile
23954
23955 }
23956 run_test 260 "Check mdc_close fail"
23957
23958 ### Data-on-MDT sanity tests ###
23959 test_270a() {
23960         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23961                 skip "Need MDS version at least 2.10.55 for DoM"
23962
23963         # create DoM file
23964         local dom=$DIR/$tdir/dom_file
23965         local tmp=$DIR/$tdir/tmp_file
23966
23967         mkdir_on_mdt0 $DIR/$tdir
23968
23969         # basic checks for DoM component creation
23970         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23971                 error "Can set MDT layout to non-first entry"
23972
23973         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23974                 error "Can define multiple entries as MDT layout"
23975
23976         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23977
23978         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23979         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23980         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23981
23982         local mdtidx=$($LFS getstripe -m $dom)
23983         local mdtname=MDT$(printf %04x $mdtidx)
23984         local facet=mds$((mdtidx + 1))
23985         local space_check=1
23986
23987         # Skip free space checks with ZFS
23988         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23989
23990         # write
23991         sync
23992         local size_tmp=$((65536 * 3))
23993         local mdtfree1=$(do_facet $facet \
23994                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23995
23996         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23997         # check also direct IO along write
23998         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23999         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24000         sync
24001         cmp $tmp $dom || error "file data is different"
24002         [ $(stat -c%s $dom) == $size_tmp ] ||
24003                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24004         if [ $space_check == 1 ]; then
24005                 local mdtfree2=$(do_facet $facet \
24006                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24007
24008                 # increase in usage from by $size_tmp
24009                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24010                         error "MDT free space wrong after write: " \
24011                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24012         fi
24013
24014         # truncate
24015         local size_dom=10000
24016
24017         $TRUNCATE $dom $size_dom
24018         [ $(stat -c%s $dom) == $size_dom ] ||
24019                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24020         if [ $space_check == 1 ]; then
24021                 mdtfree1=$(do_facet $facet \
24022                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24023                 # decrease in usage from $size_tmp to new $size_dom
24024                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24025                   $(((size_tmp - size_dom) / 1024)) ] ||
24026                         error "MDT free space is wrong after truncate: " \
24027                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24028         fi
24029
24030         # append
24031         cat $tmp >> $dom
24032         sync
24033         size_dom=$((size_dom + size_tmp))
24034         [ $(stat -c%s $dom) == $size_dom ] ||
24035                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24036         if [ $space_check == 1 ]; then
24037                 mdtfree2=$(do_facet $facet \
24038                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24039                 # increase in usage by $size_tmp from previous
24040                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24041                         error "MDT free space is wrong after append: " \
24042                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24043         fi
24044
24045         # delete
24046         rm $dom
24047         if [ $space_check == 1 ]; then
24048                 mdtfree1=$(do_facet $facet \
24049                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24050                 # decrease in usage by $size_dom from previous
24051                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24052                         error "MDT free space is wrong after removal: " \
24053                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24054         fi
24055
24056         # combined striping
24057         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24058                 error "Can't create DoM + OST striping"
24059
24060         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24061         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24062         # check also direct IO along write
24063         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24064         sync
24065         cmp $tmp $dom || error "file data is different"
24066         [ $(stat -c%s $dom) == $size_tmp ] ||
24067                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24068         rm $dom $tmp
24069
24070         return 0
24071 }
24072 run_test 270a "DoM: basic functionality tests"
24073
24074 test_270b() {
24075         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24076                 skip "Need MDS version at least 2.10.55"
24077
24078         local dom=$DIR/$tdir/dom_file
24079         local max_size=1048576
24080
24081         mkdir -p $DIR/$tdir
24082         $LFS setstripe -E $max_size -L mdt $dom
24083
24084         # truncate over the limit
24085         $TRUNCATE $dom $(($max_size + 1)) &&
24086                 error "successful truncate over the maximum size"
24087         # write over the limit
24088         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24089                 error "successful write over the maximum size"
24090         # append over the limit
24091         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24092         echo "12345" >> $dom && error "successful append over the maximum size"
24093         rm $dom
24094
24095         return 0
24096 }
24097 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24098
24099 test_270c() {
24100         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24101                 skip "Need MDS version at least 2.10.55"
24102
24103         mkdir -p $DIR/$tdir
24104         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24105
24106         # check files inherit DoM EA
24107         touch $DIR/$tdir/first
24108         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24109                 error "bad pattern"
24110         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24111                 error "bad stripe count"
24112         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24113                 error "bad stripe size"
24114
24115         # check directory inherits DoM EA and uses it as default
24116         mkdir $DIR/$tdir/subdir
24117         touch $DIR/$tdir/subdir/second
24118         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24119                 error "bad pattern in sub-directory"
24120         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24121                 error "bad stripe count in sub-directory"
24122         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24123                 error "bad stripe size in sub-directory"
24124         return 0
24125 }
24126 run_test 270c "DoM: DoM EA inheritance tests"
24127
24128 test_270d() {
24129         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24130                 skip "Need MDS version at least 2.10.55"
24131
24132         mkdir -p $DIR/$tdir
24133         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24134
24135         # inherit default DoM striping
24136         mkdir $DIR/$tdir/subdir
24137         touch $DIR/$tdir/subdir/f1
24138
24139         # change default directory striping
24140         $LFS setstripe -c 1 $DIR/$tdir/subdir
24141         touch $DIR/$tdir/subdir/f2
24142         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24143                 error "wrong default striping in file 2"
24144         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24145                 error "bad pattern in file 2"
24146         return 0
24147 }
24148 run_test 270d "DoM: change striping from DoM to RAID0"
24149
24150 test_270e() {
24151         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24152                 skip "Need MDS version at least 2.10.55"
24153
24154         mkdir -p $DIR/$tdir/dom
24155         mkdir -p $DIR/$tdir/norm
24156         DOMFILES=20
24157         NORMFILES=10
24158         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24159         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24160
24161         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24162         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24163
24164         # find DoM files by layout
24165         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24166         [ $NUM -eq  $DOMFILES ] ||
24167                 error "lfs find -L: found $NUM, expected $DOMFILES"
24168         echo "Test 1: lfs find 20 DOM files by layout: OK"
24169
24170         # there should be 1 dir with default DOM striping
24171         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24172         [ $NUM -eq  1 ] ||
24173                 error "lfs find -L: found $NUM, expected 1 dir"
24174         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24175
24176         # find DoM files by stripe size
24177         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24178         [ $NUM -eq  $DOMFILES ] ||
24179                 error "lfs find -S: found $NUM, expected $DOMFILES"
24180         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24181
24182         # find files by stripe offset except DoM files
24183         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24184         [ $NUM -eq  $NORMFILES ] ||
24185                 error "lfs find -i: found $NUM, expected $NORMFILES"
24186         echo "Test 5: lfs find no DOM files by stripe index: OK"
24187         return 0
24188 }
24189 run_test 270e "DoM: lfs find with DoM files test"
24190
24191 test_270f() {
24192         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24193                 skip "Need MDS version at least 2.10.55"
24194
24195         local mdtname=${FSNAME}-MDT0000-mdtlov
24196         local dom=$DIR/$tdir/dom_file
24197         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24198                                                 lod.$mdtname.dom_stripesize)
24199         local dom_limit=131072
24200
24201         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24202         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24203                                                 lod.$mdtname.dom_stripesize)
24204         [ ${dom_limit} -eq ${dom_current} ] ||
24205                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24206
24207         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24208         $LFS setstripe -d $DIR/$tdir
24209         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24210                 error "Can't set directory default striping"
24211
24212         # exceed maximum stripe size
24213         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24214                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24215         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24216                 error "Able to create DoM component size more than LOD limit"
24217
24218         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24219         dom_current=$(do_facet mds1 $LCTL get_param -n \
24220                                                 lod.$mdtname.dom_stripesize)
24221         [ 0 -eq ${dom_current} ] ||
24222                 error "Can't set zero DoM stripe limit"
24223         rm $dom
24224
24225         # attempt to create DoM file on server with disabled DoM should
24226         # remove DoM entry from layout and be succeed
24227         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24228                 error "Can't create DoM file (DoM is disabled)"
24229         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24230                 error "File has DoM component while DoM is disabled"
24231         rm $dom
24232
24233         # attempt to create DoM file with only DoM stripe should return error
24234         $LFS setstripe -E $dom_limit -L mdt $dom &&
24235                 error "Able to create DoM-only file while DoM is disabled"
24236
24237         # too low values to be aligned with smallest stripe size 64K
24238         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24239         dom_current=$(do_facet mds1 $LCTL get_param -n \
24240                                                 lod.$mdtname.dom_stripesize)
24241         [ 30000 -eq ${dom_current} ] &&
24242                 error "Can set too small DoM stripe limit"
24243
24244         # 64K is a minimal stripe size in Lustre, expect limit of that size
24245         [ 65536 -eq ${dom_current} ] ||
24246                 error "Limit is not set to 64K but ${dom_current}"
24247
24248         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24249         dom_current=$(do_facet mds1 $LCTL get_param -n \
24250                                                 lod.$mdtname.dom_stripesize)
24251         echo $dom_current
24252         [ 2147483648 -eq ${dom_current} ] &&
24253                 error "Can set too large DoM stripe limit"
24254
24255         do_facet mds1 $LCTL set_param -n \
24256                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24257         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24258                 error "Can't create DoM component size after limit change"
24259         do_facet mds1 $LCTL set_param -n \
24260                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24261         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24262                 error "Can't create DoM file after limit decrease"
24263         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24264                 error "Can create big DoM component after limit decrease"
24265         touch ${dom}_def ||
24266                 error "Can't create file with old default layout"
24267
24268         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24269         return 0
24270 }
24271 run_test 270f "DoM: maximum DoM stripe size checks"
24272
24273 test_270g() {
24274         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24275                 skip "Need MDS version at least 2.13.52"
24276         local dom=$DIR/$tdir/$tfile
24277
24278         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24279         local lodname=${FSNAME}-MDT0000-mdtlov
24280
24281         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24282         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24283         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24284         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24285
24286         local dom_limit=1024
24287         local dom_threshold="50%"
24288
24289         $LFS setstripe -d $DIR/$tdir
24290         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24291                 error "Can't set directory default striping"
24292
24293         do_facet mds1 $LCTL set_param -n \
24294                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24295         # set 0 threshold and create DOM file to change tunable stripesize
24296         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24297         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24298                 error "Failed to create $dom file"
24299         # now tunable dom_cur_stripesize should reach maximum
24300         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24301                                         lod.${lodname}.dom_stripesize_cur_kb)
24302         [[ $dom_current == $dom_limit ]] ||
24303                 error "Current DOM stripesize is not maximum"
24304         rm $dom
24305
24306         # set threshold for further tests
24307         do_facet mds1 $LCTL set_param -n \
24308                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24309         echo "DOM threshold is $dom_threshold free space"
24310         local dom_def
24311         local dom_set
24312         # Spoof bfree to exceed threshold
24313         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24314         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24315         for spfree in 40 20 0 15 30 55; do
24316                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24317                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24318                         error "Failed to create $dom file"
24319                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24320                                         lod.${lodname}.dom_stripesize_cur_kb)
24321                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24322                 [[ $dom_def != $dom_current ]] ||
24323                         error "Default stripe size was not changed"
24324                 if (( spfree > 0 )) ; then
24325                         dom_set=$($LFS getstripe -S $dom)
24326                         (( dom_set == dom_def * 1024 )) ||
24327                                 error "DOM component size is still old"
24328                 else
24329                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24330                                 error "DoM component is set with no free space"
24331                 fi
24332                 rm $dom
24333                 dom_current=$dom_def
24334         done
24335 }
24336 run_test 270g "DoM: default DoM stripe size depends on free space"
24337
24338 test_270h() {
24339         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24340                 skip "Need MDS version at least 2.13.53"
24341
24342         local mdtname=${FSNAME}-MDT0000-mdtlov
24343         local dom=$DIR/$tdir/$tfile
24344         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24345
24346         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24347         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24348
24349         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24350         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24351                 error "can't create OST file"
24352         # mirrored file with DOM entry in the second mirror
24353         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24354                 error "can't create mirror with DoM component"
24355
24356         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24357
24358         # DOM component in the middle and has other enries in the same mirror,
24359         # should succeed but lost DoM component
24360         $LFS setstripe --copy=${dom}_1 $dom ||
24361                 error "Can't create file from OST|DOM mirror layout"
24362         # check new file has no DoM layout after all
24363         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24364                 error "File has DoM component while DoM is disabled"
24365 }
24366 run_test 270h "DoM: DoM stripe removal when disabled on server"
24367
24368 test_270i() {
24369         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24370                 skip "Need MDS version at least 2.14.54"
24371
24372         mkdir $DIR/$tdir
24373         # DoM with plain layout
24374         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24375                 error "default plain layout with DoM must fail"
24376         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24377                 error "setstripe plain file layout with DoM must fail"
24378         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24379                 error "default DoM layout with bad striping must fail"
24380         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24381                 error "setstripe to DoM layout with bad striping must fail"
24382         return 0
24383 }
24384 run_test 270i "DoM: setting invalid DoM striping should fail"
24385
24386 test_270j() {
24387         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24388                 skip "Need MDS version at least 2.15.55.203"
24389
24390         local dom=$DIR/$tdir/$tfile
24391         local odv
24392         local ndv
24393
24394         mkdir -p $DIR/$tdir
24395
24396         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24397
24398         odv=$($LFS data_version $dom)
24399         chmod 666 $dom
24400         mv $dom ${dom}_moved
24401         link ${dom}_moved $dom
24402         setfattr -n user.attrx -v "some_attr" $dom
24403         ndv=$($LFS data_version $dom)
24404         (( $ndv == $odv )) ||
24405                 error "data version was changed by metadata operations"
24406
24407         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24408                 error "failed to write data into $dom"
24409         cancel_lru_locks mdc
24410         ndv=$($LFS data_version $dom)
24411         (( $ndv != $odv )) ||
24412                 error "data version wasn't changed on write"
24413
24414         odv=$ndv
24415         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24416         ndv=$($LFS data_version $dom)
24417         (( $ndv != $odv )) ||
24418                 error "data version wasn't changed on truncate down"
24419
24420         odv=$ndv
24421         $TRUNCATE $dom 25000
24422         ndv=$($LFS data_version $dom)
24423         (( $ndv != $odv )) ||
24424                 error "data version wasn't changed on truncate up"
24425
24426         # check also fallocate for ldiskfs
24427         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24428                 odv=$ndv
24429                 fallocate -l 1048576 $dom
24430                 ndv=$($LFS data_version $dom)
24431                 (( $ndv != $odv )) ||
24432                         error "data version wasn't changed on fallocate"
24433
24434                 odv=$ndv
24435                 fallocate -p --offset 4096 -l 4096 $dom
24436                 ndv=$($LFS data_version $dom)
24437                 (( $ndv != $odv )) ||
24438                         error "data version wasn't changed on fallocate punch"
24439         fi
24440 }
24441 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24442
24443 test_271a() {
24444         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24445                 skip "Need MDS version at least 2.10.55"
24446
24447         local dom=$DIR/$tdir/dom
24448
24449         mkdir -p $DIR/$tdir
24450
24451         $LFS setstripe -E 1024K -L mdt $dom
24452
24453         lctl set_param -n mdc.*.stats=clear
24454         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24455         cat $dom > /dev/null
24456         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24457         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24458         ls $dom
24459         rm -f $dom
24460 }
24461 run_test 271a "DoM: data is cached for read after write"
24462
24463 test_271b() {
24464         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24465                 skip "Need MDS version at least 2.10.55"
24466
24467         local dom=$DIR/$tdir/dom
24468
24469         mkdir -p $DIR/$tdir
24470
24471         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24472
24473         lctl set_param -n mdc.*.stats=clear
24474         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24475         cancel_lru_locks mdc
24476         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24477         # second stat to check size is cached on client
24478         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24479         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24480         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24481         rm -f $dom
24482 }
24483 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24484
24485 test_271ba() {
24486         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24487                 skip "Need MDS version at least 2.10.55"
24488
24489         local dom=$DIR/$tdir/dom
24490
24491         mkdir -p $DIR/$tdir
24492
24493         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24494
24495         lctl set_param -n mdc.*.stats=clear
24496         lctl set_param -n osc.*.stats=clear
24497         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24498         cancel_lru_locks mdc
24499         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24500         # second stat to check size is cached on client
24501         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24502         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24503         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24504         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24505         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24506         rm -f $dom
24507 }
24508 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24509
24510
24511 get_mdc_stats() {
24512         local mdtidx=$1
24513         local param=$2
24514         local mdt=MDT$(printf %04x $mdtidx)
24515
24516         if [ -z $param ]; then
24517                 lctl get_param -n mdc.*$mdt*.stats
24518         else
24519                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24520         fi
24521 }
24522
24523 test_271c() {
24524         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24525                 skip "Need MDS version at least 2.10.55"
24526
24527         local dom=$DIR/$tdir/dom
24528
24529         mkdir -p $DIR/$tdir
24530
24531         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24532
24533         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24534         local facet=mds$((mdtidx + 1))
24535
24536         cancel_lru_locks mdc
24537         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24538         createmany -o $dom 1000
24539         lctl set_param -n mdc.*.stats=clear
24540         smalliomany -w $dom 1000 200
24541         get_mdc_stats $mdtidx
24542         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24543         # Each file has 1 open, 1 IO enqueues, total 2000
24544         # but now we have also +1 getxattr for security.capability, total 3000
24545         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24546         unlinkmany $dom 1000
24547
24548         cancel_lru_locks mdc
24549         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24550         createmany -o $dom 1000
24551         lctl set_param -n mdc.*.stats=clear
24552         smalliomany -w $dom 1000 200
24553         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24554         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24555         # for OPEN and IO lock.
24556         [ $((enq - enq_2)) -ge 1000 ] ||
24557                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24558         unlinkmany $dom 1000
24559         return 0
24560 }
24561 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24562
24563 cleanup_271def_tests() {
24564         trap 0
24565         rm -f $1
24566 }
24567
24568 test_271d() {
24569         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24570                 skip "Need MDS version at least 2.10.57"
24571
24572         local dom=$DIR/$tdir/dom
24573         local tmp=$TMP/$tfile
24574         trap "cleanup_271def_tests $tmp" EXIT
24575
24576         mkdir -p $DIR/$tdir
24577
24578         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24579
24580         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24581
24582         cancel_lru_locks mdc
24583         dd if=/dev/urandom of=$tmp bs=1000 count=1
24584         dd if=$tmp of=$dom bs=1000 count=1
24585         cancel_lru_locks mdc
24586
24587         cat /etc/hosts >> $tmp
24588         lctl set_param -n mdc.*.stats=clear
24589
24590         # append data to the same file it should update local page
24591         echo "Append to the same page"
24592         cat /etc/hosts >> $dom
24593         local num=$(get_mdc_stats $mdtidx ost_read)
24594         local ra=$(get_mdc_stats $mdtidx req_active)
24595         local rw=$(get_mdc_stats $mdtidx req_waittime)
24596
24597         [ -z $num ] || error "$num READ RPC occured"
24598         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24599         echo "... DONE"
24600
24601         # compare content
24602         cmp $tmp $dom || error "file miscompare"
24603
24604         cancel_lru_locks mdc
24605         lctl set_param -n mdc.*.stats=clear
24606
24607         echo "Open and read file"
24608         cat $dom > /dev/null
24609         local num=$(get_mdc_stats $mdtidx ost_read)
24610         local ra=$(get_mdc_stats $mdtidx req_active)
24611         local rw=$(get_mdc_stats $mdtidx req_waittime)
24612
24613         [ -z $num ] || error "$num READ RPC occured"
24614         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24615         echo "... DONE"
24616
24617         # compare content
24618         cmp $tmp $dom || error "file miscompare"
24619
24620         return 0
24621 }
24622 run_test 271d "DoM: read on open (1K file in reply buffer)"
24623
24624 test_271f() {
24625         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24626                 skip "Need MDS version at least 2.10.57"
24627
24628         local dom=$DIR/$tdir/dom
24629         local tmp=$TMP/$tfile
24630         trap "cleanup_271def_tests $tmp" EXIT
24631
24632         mkdir -p $DIR/$tdir
24633
24634         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24635
24636         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24637
24638         cancel_lru_locks mdc
24639         dd if=/dev/urandom of=$tmp bs=265000 count=1
24640         dd if=$tmp of=$dom bs=265000 count=1
24641         cancel_lru_locks mdc
24642         cat /etc/hosts >> $tmp
24643         lctl set_param -n mdc.*.stats=clear
24644
24645         echo "Append to the same page"
24646         cat /etc/hosts >> $dom
24647         local num=$(get_mdc_stats $mdtidx ost_read)
24648         local ra=$(get_mdc_stats $mdtidx req_active)
24649         local rw=$(get_mdc_stats $mdtidx req_waittime)
24650
24651         [ -z $num ] || error "$num READ RPC occured"
24652         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24653         echo "... DONE"
24654
24655         # compare content
24656         cmp $tmp $dom || error "file miscompare"
24657
24658         cancel_lru_locks mdc
24659         lctl set_param -n mdc.*.stats=clear
24660
24661         echo "Open and read file"
24662         cat $dom > /dev/null
24663         local num=$(get_mdc_stats $mdtidx ost_read)
24664         local ra=$(get_mdc_stats $mdtidx req_active)
24665         local rw=$(get_mdc_stats $mdtidx req_waittime)
24666
24667         [ -z $num ] && num=0
24668         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24669         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24670         echo "... DONE"
24671
24672         # compare content
24673         cmp $tmp $dom || error "file miscompare"
24674
24675         return 0
24676 }
24677 run_test 271f "DoM: read on open (200K file and read tail)"
24678
24679 test_271g() {
24680         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24681                 skip "Skipping due to old client or server version"
24682
24683         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24684         # to get layout
24685         $CHECKSTAT -t file $DIR1/$tfile
24686
24687         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24688         MULTIOP_PID=$!
24689         sleep 1
24690         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24691         $LCTL set_param fail_loc=0x80000314
24692         rm $DIR1/$tfile || error "Unlink fails"
24693         RC=$?
24694         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24695         [ $RC -eq 0 ] || error "Failed write to stale object"
24696 }
24697 run_test 271g "Discard DoM data vs client flush race"
24698
24699 test_272a() {
24700         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24701                 skip "Need MDS version at least 2.11.50"
24702
24703         local dom=$DIR/$tdir/dom
24704         mkdir -p $DIR/$tdir
24705
24706         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24707         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24708                 error "failed to write data into $dom"
24709         local old_md5=$(md5sum $dom)
24710
24711         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24712                 error "failed to migrate to the same DoM component"
24713
24714         local new_md5=$(md5sum $dom)
24715
24716         [ "$old_md5" == "$new_md5" ] ||
24717                 error "md5sum differ: $old_md5, $new_md5"
24718
24719         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24720                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24721 }
24722 run_test 272a "DoM migration: new layout with the same DOM component"
24723
24724 test_272b() {
24725         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24726                 skip "Need MDS version at least 2.11.50"
24727
24728         local dom=$DIR/$tdir/dom
24729         mkdir -p $DIR/$tdir
24730         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24731         stack_trap "rm -rf $DIR/$tdir"
24732
24733         local mdtidx=$($LFS getstripe -m $dom)
24734         local mdtname=MDT$(printf %04x $mdtidx)
24735         local facet=mds$((mdtidx + 1))
24736
24737         local mdtfree1=$(do_facet $facet \
24738                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24739         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24740                 error "failed to write data into $dom"
24741         local old_md5=$(md5sum $dom)
24742         cancel_lru_locks mdc
24743         local mdtfree1=$(do_facet $facet \
24744                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24745
24746         $LFS migrate -c2 $dom ||
24747                 error "failed to migrate to the new composite layout"
24748         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24749                 error "MDT stripe was not removed"
24750         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24751                 error "$dir1 shouldn't have DATAVER EA"
24752
24753         cancel_lru_locks mdc
24754         local new_md5=$(md5sum $dom)
24755         [ "$old_md5" == "$new_md5" ] ||
24756                 error "$old_md5 != $new_md5"
24757
24758         # Skip free space checks with ZFS
24759         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24760                 local mdtfree2=$(do_facet $facet \
24761                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24762                 [ $mdtfree2 -gt $mdtfree1 ] ||
24763                         error "MDT space is not freed after migration"
24764         fi
24765         return 0
24766 }
24767 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24768
24769 test_272c() {
24770         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24771                 skip "Need MDS version at least 2.11.50"
24772
24773         local dom=$DIR/$tdir/$tfile
24774         mkdir -p $DIR/$tdir
24775         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24776         stack_trap "rm -rf $DIR/$tdir"
24777
24778         local mdtidx=$($LFS getstripe -m $dom)
24779         local mdtname=MDT$(printf %04x $mdtidx)
24780         local facet=mds$((mdtidx + 1))
24781
24782         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24783                 error "failed to write data into $dom"
24784         local old_md5=$(md5sum $dom)
24785         cancel_lru_locks mdc
24786         local mdtfree1=$(do_facet $facet \
24787                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24788
24789         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24790                 error "failed to migrate to the new composite layout"
24791         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24792                 error "MDT stripe was not removed"
24793
24794         cancel_lru_locks mdc
24795         local new_md5=$(md5sum $dom)
24796         [ "$old_md5" == "$new_md5" ] ||
24797                 error "$old_md5 != $new_md5"
24798
24799         # Skip free space checks with ZFS
24800         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24801                 local mdtfree2=$(do_facet $facet \
24802                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24803                 [ $mdtfree2 -gt $mdtfree1 ] ||
24804                         error "MDS space is not freed after migration"
24805         fi
24806         return 0
24807 }
24808 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24809
24810 test_272d() {
24811         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24812                 skip "Need MDS version at least 2.12.55"
24813
24814         local dom=$DIR/$tdir/$tfile
24815         mkdir -p $DIR/$tdir
24816         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24817
24818         local mdtidx=$($LFS getstripe -m $dom)
24819         local mdtname=MDT$(printf %04x $mdtidx)
24820         local facet=mds$((mdtidx + 1))
24821
24822         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24823                 error "failed to write data into $dom"
24824         local old_md5=$(md5sum $dom)
24825         cancel_lru_locks mdc
24826         local mdtfree1=$(do_facet $facet \
24827                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24828
24829         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24830                 error "failed mirroring to the new composite layout"
24831         $LFS mirror resync $dom ||
24832                 error "failed mirror resync"
24833         $LFS mirror split --mirror-id 1 -d $dom ||
24834                 error "failed mirror split"
24835
24836         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24837                 error "MDT stripe was not removed"
24838
24839         cancel_lru_locks mdc
24840         local new_md5=$(md5sum $dom)
24841         [ "$old_md5" == "$new_md5" ] ||
24842                 error "$old_md5 != $new_md5"
24843
24844         # Skip free space checks with ZFS
24845         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24846                 local mdtfree2=$(do_facet $facet \
24847                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24848                 [ $mdtfree2 -gt $mdtfree1 ] ||
24849                         error "MDS space is not freed after DOM mirror deletion"
24850         fi
24851         return 0
24852 }
24853 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24854
24855 test_272e() {
24856         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24857                 skip "Need MDS version at least 2.12.55"
24858
24859         local dom=$DIR/$tdir/$tfile
24860         mkdir -p $DIR/$tdir
24861         $LFS setstripe -c 2 $dom
24862
24863         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24864                 error "failed to write data into $dom"
24865         local old_md5=$(md5sum $dom)
24866         cancel_lru_locks
24867
24868         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24869                 error "failed mirroring to the DOM layout"
24870         $LFS mirror resync $dom ||
24871                 error "failed mirror resync"
24872         $LFS mirror split --mirror-id 1 -d $dom ||
24873                 error "failed mirror split"
24874
24875         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24876                 error "MDT stripe wasn't set"
24877
24878         cancel_lru_locks
24879         local new_md5=$(md5sum $dom)
24880         [ "$old_md5" == "$new_md5" ] ||
24881                 error "$old_md5 != $new_md5"
24882
24883         return 0
24884 }
24885 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24886
24887 test_272f() {
24888         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24889                 skip "Need MDS version at least 2.12.55"
24890
24891         local dom=$DIR/$tdir/$tfile
24892         mkdir -p $DIR/$tdir
24893         $LFS setstripe -c 2 $dom
24894
24895         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24896                 error "failed to write data into $dom"
24897         local old_md5=$(md5sum $dom)
24898         cancel_lru_locks
24899
24900         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24901                 error "failed migrating to the DOM file"
24902
24903         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24904                 error "MDT stripe wasn't set"
24905
24906         cancel_lru_locks
24907         local new_md5=$(md5sum $dom)
24908         [ "$old_md5" != "$new_md5" ] &&
24909                 error "$old_md5 != $new_md5"
24910
24911         return 0
24912 }
24913 run_test 272f "DoM migration: OST-striped file to DOM file"
24914
24915 test_273a() {
24916         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24917                 skip "Need MDS version at least 2.11.50"
24918
24919         # Layout swap cannot be done if either file has DOM component,
24920         # this will never be supported, migration should be used instead
24921
24922         local dom=$DIR/$tdir/$tfile
24923         mkdir -p $DIR/$tdir
24924
24925         $LFS setstripe -c2 ${dom}_plain
24926         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24927         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24928                 error "can swap layout with DoM component"
24929         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24930                 error "can swap layout with DoM component"
24931
24932         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24933         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24934                 error "can swap layout with DoM component"
24935         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24936                 error "can swap layout with DoM component"
24937         return 0
24938 }
24939 run_test 273a "DoM: layout swapping should fail with DOM"
24940
24941 test_273b() {
24942         mkdir -p $DIR/$tdir
24943         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24944
24945 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24946         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24947
24948         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24949 }
24950 run_test 273b "DoM: race writeback and object destroy"
24951
24952 test_273c() {
24953         mkdir -p $DIR/$tdir
24954         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24955
24956         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24957         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24958
24959         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24960 }
24961 run_test 273c "race writeback and object destroy"
24962
24963 test_275() {
24964         remote_ost_nodsh && skip "remote OST with nodsh"
24965         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24966                 skip "Need OST version >= 2.10.57"
24967
24968         local file=$DIR/$tfile
24969         local oss
24970
24971         oss=$(comma_list $(osts_nodes))
24972
24973         dd if=/dev/urandom of=$file bs=1M count=2 ||
24974                 error "failed to create a file"
24975         stack_trap "rm -f $file"
24976         cancel_lru_locks osc
24977
24978         #lock 1
24979         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24980                 error "failed to read a file"
24981
24982 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24983         $LCTL set_param fail_loc=0x8000031f
24984
24985         cancel_lru_locks osc &
24986         sleep 1
24987
24988 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24989         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24990         #IO takes another lock, but matches the PENDING one
24991         #and places it to the IO RPC
24992         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24993                 error "failed to read a file with PENDING lock"
24994 }
24995 run_test 275 "Read on a canceled duplicate lock"
24996
24997 test_276() {
24998         remote_ost_nodsh && skip "remote OST with nodsh"
24999         local pid
25000
25001         do_facet ost1 "(while true; do \
25002                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25003                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25004         pid=$!
25005
25006         for LOOP in $(seq 20); do
25007                 stop ost1
25008                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25009         done
25010         kill -9 $pid
25011         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25012                 rm $TMP/sanity_276_pid"
25013 }
25014 run_test 276 "Race between mount and obd_statfs"
25015
25016 test_277() {
25017         $LCTL set_param ldlm.namespaces.*.lru_size=0
25018         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25019         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25020                           awk '/^used_mb/ { print $2 }')
25021         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25022         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25023                 oflag=direct conv=notrunc
25024         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25025                     awk '/^used_mb/ { print $2 }')
25026         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25027 }
25028 run_test 277 "Direct IO shall drop page cache"
25029
25030 test_278() {
25031         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25032         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25033         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25034                 skip "needs the same host for mdt1 mdt2" && return
25035
25036         local pid1
25037         local pid2
25038
25039 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25040         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25041         stop mds2 &
25042         pid2=$!
25043
25044         stop mds1
25045
25046         echo "Starting MDTs"
25047         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25048         wait $pid2
25049 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25050 #will return NULL
25051         do_facet mds2 $LCTL set_param fail_loc=0
25052
25053         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25054         wait_recovery_complete mds2
25055 }
25056 run_test 278 "Race starting MDS between MDTs stop/start"
25057
25058 test_280() {
25059         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25060                 skip "Need MGS version at least 2.13.52"
25061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25062         combined_mgs_mds || skip "needs combined MGS/MDT"
25063
25064         umount_client $MOUNT
25065 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25066         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25067
25068         mount_client $MOUNT &
25069         sleep 1
25070         stop mgs || error "stop mgs failed"
25071         #for a race mgs would crash
25072         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25073         # make sure we unmount client before remounting
25074         wait
25075         umount_client $MOUNT
25076         mount_client $MOUNT || error "mount client failed"
25077 }
25078 run_test 280 "Race between MGS umount and client llog processing"
25079
25080 cleanup_test_300() {
25081         trap 0
25082         umask $SAVE_UMASK
25083 }
25084 test_striped_dir() {
25085         local mdt_index=$1
25086         local stripe_count
25087         local stripe_index
25088
25089         mkdir -p $DIR/$tdir
25090
25091         SAVE_UMASK=$(umask)
25092         trap cleanup_test_300 RETURN EXIT
25093
25094         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25095                                                 $DIR/$tdir/striped_dir ||
25096                 error "set striped dir error"
25097
25098         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25099         [ "$mode" = "755" ] || error "expect 755 got $mode"
25100
25101         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25102                 error "getdirstripe failed"
25103         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25104         if [ "$stripe_count" != "2" ]; then
25105                 error "1:stripe_count is $stripe_count, expect 2"
25106         fi
25107         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25108         if [ "$stripe_count" != "2" ]; then
25109                 error "2:stripe_count is $stripe_count, expect 2"
25110         fi
25111
25112         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25113         if [ "$stripe_index" != "$mdt_index" ]; then
25114                 error "stripe_index is $stripe_index, expect $mdt_index"
25115         fi
25116
25117         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25118                 error "nlink error after create striped dir"
25119
25120         mkdir $DIR/$tdir/striped_dir/a
25121         mkdir $DIR/$tdir/striped_dir/b
25122
25123         stat $DIR/$tdir/striped_dir/a ||
25124                 error "create dir under striped dir failed"
25125         stat $DIR/$tdir/striped_dir/b ||
25126                 error "create dir under striped dir failed"
25127
25128         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25129                 error "nlink error after mkdir"
25130
25131         rmdir $DIR/$tdir/striped_dir/a
25132         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25133                 error "nlink error after rmdir"
25134
25135         rmdir $DIR/$tdir/striped_dir/b
25136         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25137                 error "nlink error after rmdir"
25138
25139         chattr +i $DIR/$tdir/striped_dir
25140         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25141                 error "immutable flags not working under striped dir!"
25142         chattr -i $DIR/$tdir/striped_dir
25143
25144         rmdir $DIR/$tdir/striped_dir ||
25145                 error "rmdir striped dir error"
25146
25147         cleanup_test_300
25148
25149         true
25150 }
25151
25152 test_300a() {
25153         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25154                 skip "skipped for lustre < 2.7.0"
25155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25157
25158         test_striped_dir 0 || error "failed on striped dir on MDT0"
25159         test_striped_dir 1 || error "failed on striped dir on MDT0"
25160 }
25161 run_test 300a "basic striped dir sanity test"
25162
25163 test_300b() {
25164         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25165                 skip "skipped for lustre < 2.7.0"
25166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25168
25169         local i
25170         local mtime1
25171         local mtime2
25172         local mtime3
25173
25174         test_mkdir $DIR/$tdir || error "mkdir fail"
25175         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25176                 error "set striped dir error"
25177         for i in {0..9}; do
25178                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25179                 sleep 1
25180                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25181                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25182                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25183                 sleep 1
25184                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25185                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25186                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25187         done
25188         true
25189 }
25190 run_test 300b "check ctime/mtime for striped dir"
25191
25192 test_300c() {
25193         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25194                 skip "skipped for lustre < 2.7.0"
25195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25197
25198         local file_count
25199
25200         mkdir_on_mdt0 $DIR/$tdir
25201         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25202                 error "set striped dir error"
25203
25204         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25205                 error "chown striped dir failed"
25206
25207         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25208                 error "create 5k files failed"
25209
25210         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25211
25212         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25213
25214         rm -rf $DIR/$tdir
25215 }
25216 run_test 300c "chown && check ls under striped directory"
25217
25218 test_300d() {
25219         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25220                 skip "skipped for lustre < 2.7.0"
25221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25222         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25223
25224         local stripe_count
25225         local file
25226
25227         mkdir -p $DIR/$tdir
25228         $LFS setstripe -c 2 $DIR/$tdir
25229
25230         #local striped directory
25231         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25232                 error "set striped dir error"
25233         #look at the directories for debug purposes
25234         ls -l $DIR/$tdir
25235         $LFS getdirstripe $DIR/$tdir
25236         ls -l $DIR/$tdir/striped_dir
25237         $LFS getdirstripe $DIR/$tdir/striped_dir
25238         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25239                 error "create 10 files failed"
25240
25241         #remote striped directory
25242         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25243                 error "set striped dir error"
25244         #look at the directories for debug purposes
25245         ls -l $DIR/$tdir
25246         $LFS getdirstripe $DIR/$tdir
25247         ls -l $DIR/$tdir/remote_striped_dir
25248         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25249         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25250                 error "create 10 files failed"
25251
25252         for file in $(find $DIR/$tdir); do
25253                 stripe_count=$($LFS getstripe -c $file)
25254                 [ $stripe_count -eq 2 ] ||
25255                         error "wrong stripe $stripe_count for $file"
25256         done
25257
25258         rm -rf $DIR/$tdir
25259 }
25260 run_test 300d "check default stripe under striped directory"
25261
25262 test_300e() {
25263         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25264                 skip "Need MDS version at least 2.7.55"
25265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25266         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25267
25268         local stripe_count
25269         local file
25270
25271         mkdir -p $DIR/$tdir
25272
25273         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25274                 error "set striped dir error"
25275
25276         touch $DIR/$tdir/striped_dir/a
25277         touch $DIR/$tdir/striped_dir/b
25278         touch $DIR/$tdir/striped_dir/c
25279
25280         mkdir $DIR/$tdir/striped_dir/dir_a
25281         mkdir $DIR/$tdir/striped_dir/dir_b
25282         mkdir $DIR/$tdir/striped_dir/dir_c
25283
25284         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25285                 error "set striped adir under striped dir error"
25286
25287         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25288                 error "set striped bdir under striped dir error"
25289
25290         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25291                 error "set striped cdir under striped dir error"
25292
25293         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25294                 error "rename dir under striped dir fails"
25295
25296         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25297                 error "rename dir under different stripes fails"
25298
25299         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25300                 error "rename file under striped dir should succeed"
25301
25302         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25303                 error "rename dir under striped dir should succeed"
25304
25305         rm -rf $DIR/$tdir
25306 }
25307 run_test 300e "check rename under striped directory"
25308
25309 test_300f() {
25310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25311         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25312         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25313                 skip "Need MDS version at least 2.7.55"
25314
25315         local stripe_count
25316         local file
25317
25318         rm -rf $DIR/$tdir
25319         mkdir -p $DIR/$tdir
25320
25321         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25322                 error "set striped dir error"
25323
25324         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25325                 error "set striped dir error"
25326
25327         touch $DIR/$tdir/striped_dir/a
25328         mkdir $DIR/$tdir/striped_dir/dir_a
25329         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25330                 error "create striped dir under striped dir fails"
25331
25332         touch $DIR/$tdir/striped_dir1/b
25333         mkdir $DIR/$tdir/striped_dir1/dir_b
25334         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25335                 error "create striped dir under striped dir fails"
25336
25337         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25338                 error "rename dir under different striped dir should fail"
25339
25340         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25341                 error "rename striped dir under diff striped dir should fail"
25342
25343         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25344                 error "rename file under diff striped dirs fails"
25345
25346         rm -rf $DIR/$tdir
25347 }
25348 run_test 300f "check rename cross striped directory"
25349
25350 test_300_check_default_striped_dir()
25351 {
25352         local dirname=$1
25353         local default_count=$2
25354         local default_index=$3
25355         local stripe_count
25356         local stripe_index
25357         local dir_stripe_index
25358         local dir
25359
25360         echo "checking $dirname $default_count $default_index"
25361         $LFS setdirstripe -D -c $default_count -i $default_index \
25362                                 -H all_char $DIR/$tdir/$dirname ||
25363                 error "set default stripe on striped dir error"
25364         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25365         [ $stripe_count -eq $default_count ] ||
25366                 error "expect $default_count get $stripe_count for $dirname"
25367
25368         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25369         [ $stripe_index -eq $default_index ] ||
25370                 error "expect $default_index get $stripe_index for $dirname"
25371
25372         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25373                                                 error "create dirs failed"
25374
25375         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25376         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25377         for dir in $(find $DIR/$tdir/$dirname/*); do
25378                 stripe_count=$($LFS getdirstripe -c $dir)
25379                 (( $stripe_count == $default_count )) ||
25380                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25381                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25382                 error "stripe count $default_count != $stripe_count for $dir"
25383
25384                 stripe_index=$($LFS getdirstripe -i $dir)
25385                 [ $default_index -eq -1 ] ||
25386                         [ $stripe_index -eq $default_index ] ||
25387                         error "$stripe_index != $default_index for $dir"
25388
25389                 #check default stripe
25390                 stripe_count=$($LFS getdirstripe -D -c $dir)
25391                 [ $stripe_count -eq $default_count ] ||
25392                 error "default count $default_count != $stripe_count for $dir"
25393
25394                 stripe_index=$($LFS getdirstripe -D -i $dir)
25395                 [ $stripe_index -eq $default_index ] ||
25396                 error "default index $default_index != $stripe_index for $dir"
25397         done
25398         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25399 }
25400
25401 test_300g() {
25402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25403         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25404                 skip "Need MDS version at least 2.7.55"
25405
25406         local dir
25407         local stripe_count
25408         local stripe_index
25409
25410         mkdir_on_mdt0 $DIR/$tdir
25411         mkdir $DIR/$tdir/normal_dir
25412
25413         #Checking when client cache stripe index
25414         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25415         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25416                 error "create striped_dir failed"
25417
25418         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25419                 error "create dir0 fails"
25420         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25421         [ $stripe_index -eq 0 ] ||
25422                 error "dir0 expect index 0 got $stripe_index"
25423
25424         mkdir $DIR/$tdir/striped_dir/dir1 ||
25425                 error "create dir1 fails"
25426         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25427         [ $stripe_index -eq 1 ] ||
25428                 error "dir1 expect index 1 got $stripe_index"
25429
25430         #check default stripe count/stripe index
25431         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25432         test_300_check_default_striped_dir normal_dir 1 0
25433         test_300_check_default_striped_dir normal_dir -1 1
25434         test_300_check_default_striped_dir normal_dir 2 -1
25435
25436         #delete default stripe information
25437         echo "delete default stripeEA"
25438         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25439                 error "set default stripe on striped dir error"
25440
25441         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25442         for dir in $(find $DIR/$tdir/normal_dir/*); do
25443                 stripe_count=$($LFS getdirstripe -c $dir)
25444                 [ $stripe_count -eq 0 ] ||
25445                         error "expect 1 get $stripe_count for $dir"
25446         done
25447 }
25448 run_test 300g "check default striped directory for normal directory"
25449
25450 test_300h() {
25451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25452         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25453                 skip "Need MDS version at least 2.7.55"
25454
25455         local dir
25456         local stripe_count
25457
25458         mkdir $DIR/$tdir
25459         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25460                 error "set striped dir error"
25461
25462         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25463         test_300_check_default_striped_dir striped_dir 1 0
25464         test_300_check_default_striped_dir striped_dir -1 1
25465         test_300_check_default_striped_dir striped_dir 2 -1
25466
25467         #delete default stripe information
25468         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25469                 error "set default stripe on striped dir error"
25470
25471         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25472         for dir in $(find $DIR/$tdir/striped_dir/*); do
25473                 stripe_count=$($LFS getdirstripe -c $dir)
25474                 [ $stripe_count -eq 0 ] ||
25475                         error "expect 1 get $stripe_count for $dir"
25476         done
25477 }
25478 run_test 300h "check default striped directory for striped directory"
25479
25480 test_300i() {
25481         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25482         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25483         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25484                 skip "Need MDS version at least 2.7.55"
25485
25486         local stripe_count
25487         local file
25488
25489         mkdir $DIR/$tdir
25490
25491         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25492                 error "set striped dir error"
25493
25494         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25495                 error "create files under striped dir failed"
25496
25497         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25498                 error "set striped hashdir error"
25499
25500         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25501                 error "create dir0 under hash dir failed"
25502         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25503                 error "create dir1 under hash dir failed"
25504         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25505                 error "create dir2 under hash dir failed"
25506
25507         # unfortunately, we need to umount to clear dir layout cache for now
25508         # once we fully implement dir layout, we can drop this
25509         umount_client $MOUNT || error "umount failed"
25510         mount_client $MOUNT || error "mount failed"
25511
25512         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25513         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25514         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25515
25516         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25517                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25518                         error "create crush2 dir $tdir/hashdir/d3 failed"
25519                 $LFS find -H crush2 $DIR/$tdir/hashdir
25520                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25521                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25522
25523                 # mkdir with an invalid hash type (hash=fail_val) from client
25524                 # should be replaced on MDS with a valid (default) hash type
25525                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25526                 $LCTL set_param fail_loc=0x1901 fail_val=99
25527                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25528
25529                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25530                 local expect=$(do_facet mds1 \
25531                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25532                 [[ $hash == $expect ]] ||
25533                         error "d99 hash '$hash' != expected hash '$expect'"
25534         fi
25535
25536         #set the stripe to be unknown hash type on read
25537         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25538         $LCTL set_param fail_loc=0x1901 fail_val=99
25539         for ((i = 0; i < 10; i++)); do
25540                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25541                         error "stat f-$i failed"
25542                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25543         done
25544
25545         touch $DIR/$tdir/striped_dir/f0 &&
25546                 error "create under striped dir with unknown hash should fail"
25547
25548         $LCTL set_param fail_loc=0
25549
25550         umount_client $MOUNT || error "umount failed"
25551         mount_client $MOUNT || error "mount failed"
25552
25553         return 0
25554 }
25555 run_test 300i "client handle unknown hash type striped directory"
25556
25557 test_300j() {
25558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25560         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25561                 skip "Need MDS version at least 2.7.55"
25562
25563         local stripe_count
25564         local file
25565
25566         mkdir $DIR/$tdir
25567
25568         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25569         $LCTL set_param fail_loc=0x1702
25570         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25571                 error "set striped dir error"
25572
25573         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25574                 error "create files under striped dir failed"
25575
25576         $LCTL set_param fail_loc=0
25577
25578         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25579
25580         return 0
25581 }
25582 run_test 300j "test large update record"
25583
25584 test_300k() {
25585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25586         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25587         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25588                 skip "Need MDS version at least 2.7.55"
25589
25590         # this test needs a huge transaction
25591         local kb
25592         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25593              osd*.$FSNAME-MDT0000.kbytestotal")
25594         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25595
25596         local stripe_count
25597         local file
25598
25599         mkdir $DIR/$tdir
25600
25601         #define OBD_FAIL_LARGE_STRIPE   0x1703
25602         $LCTL set_param fail_loc=0x1703
25603         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25604                 error "set striped dir error"
25605         $LCTL set_param fail_loc=0
25606
25607         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25608                 error "getstripeddir fails"
25609         rm -rf $DIR/$tdir/striped_dir ||
25610                 error "unlink striped dir fails"
25611
25612         return 0
25613 }
25614 run_test 300k "test large striped directory"
25615
25616 test_300l() {
25617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25619         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25620                 skip "Need MDS version at least 2.7.55"
25621
25622         local stripe_index
25623
25624         test_mkdir -p $DIR/$tdir/striped_dir
25625         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25626                         error "chown $RUNAS_ID failed"
25627         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25628                 error "set default striped dir failed"
25629
25630         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25631         $LCTL set_param fail_loc=0x80000158
25632         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25633
25634         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25635         [ $stripe_index -eq 1 ] ||
25636                 error "expect 1 get $stripe_index for $dir"
25637 }
25638 run_test 300l "non-root user to create dir under striped dir with stale layout"
25639
25640 test_300m() {
25641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25642         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25643         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25644                 skip "Need MDS version at least 2.7.55"
25645
25646         mkdir -p $DIR/$tdir/striped_dir
25647         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25648                 error "set default stripes dir error"
25649
25650         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25651
25652         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25653         [ $stripe_count -eq 0 ] ||
25654                         error "expect 0 get $stripe_count for a"
25655
25656         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25657                 error "set default stripes dir error"
25658
25659         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25660
25661         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25662         [ $stripe_count -eq 0 ] ||
25663                         error "expect 0 get $stripe_count for b"
25664
25665         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25666                 error "set default stripes dir error"
25667
25668         mkdir $DIR/$tdir/striped_dir/c &&
25669                 error "default stripe_index is invalid, mkdir c should fails"
25670
25671         rm -rf $DIR/$tdir || error "rmdir fails"
25672 }
25673 run_test 300m "setstriped directory on single MDT FS"
25674
25675 cleanup_300n() {
25676         local list=$(comma_list $(mdts_nodes))
25677
25678         trap 0
25679         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25680 }
25681
25682 test_300n() {
25683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25684         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25685         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25686                 skip "Need MDS version at least 2.7.55"
25687         remote_mds_nodsh && skip "remote MDS with nodsh"
25688
25689         local stripe_index
25690         local list=$(comma_list $(mdts_nodes))
25691
25692         trap cleanup_300n RETURN EXIT
25693         mkdir -p $DIR/$tdir
25694         chmod 777 $DIR/$tdir
25695         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25696                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25697                 error "create striped dir succeeds with gid=0"
25698
25699         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25700         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25701                 error "create striped dir fails with gid=-1"
25702
25703         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25704         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25705                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25706                 error "set default striped dir succeeds with gid=0"
25707
25708
25709         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25710         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25711                 error "set default striped dir fails with gid=-1"
25712
25713
25714         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25715         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25716                                         error "create test_dir fails"
25717         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25718                                         error "create test_dir1 fails"
25719         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25720                                         error "create test_dir2 fails"
25721         cleanup_300n
25722 }
25723 run_test 300n "non-root user to create dir under striped dir with default EA"
25724
25725 test_300o() {
25726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25727         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25728         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25729                 skip "Need MDS version at least 2.7.55"
25730
25731         local numfree1
25732         local numfree2
25733
25734         mkdir -p $DIR/$tdir
25735
25736         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25737         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25738         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25739                 skip "not enough free inodes $numfree1 $numfree2"
25740         fi
25741
25742         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25743         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25744         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25745                 skip "not enough free space $numfree1 $numfree2"
25746         fi
25747
25748         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25749                 error "setdirstripe fails"
25750
25751         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25752                 error "create dirs fails"
25753
25754         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25755         ls $DIR/$tdir/striped_dir > /dev/null ||
25756                 error "ls striped dir fails"
25757         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25758                 error "unlink big striped dir fails"
25759 }
25760 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25761
25762 test_300p() {
25763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25765         remote_mds_nodsh && skip "remote MDS with nodsh"
25766
25767         mkdir_on_mdt0 $DIR/$tdir
25768
25769         #define OBD_FAIL_OUT_ENOSPC     0x1704
25770         do_facet mds2 lctl set_param fail_loc=0x80001704
25771         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25772                  && error "create striped directory should fail"
25773
25774         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25775
25776         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25777         true
25778 }
25779 run_test 300p "create striped directory without space"
25780
25781 test_300q() {
25782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25784
25785         local fd=$(free_fd)
25786         local cmd="exec $fd<$tdir"
25787         cd $DIR
25788         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25789         eval $cmd
25790         cmd="exec $fd<&-"
25791         trap "eval $cmd" EXIT
25792         cd $tdir || error "cd $tdir fails"
25793         rmdir  ../$tdir || error "rmdir $tdir fails"
25794         mkdir local_dir && error "create dir succeeds"
25795         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25796         eval $cmd
25797         return 0
25798 }
25799 run_test 300q "create remote directory under orphan directory"
25800
25801 test_300r() {
25802         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25803                 skip "Need MDS version at least 2.7.55" && return
25804         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25805
25806         mkdir $DIR/$tdir
25807
25808         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25809                 error "set striped dir error"
25810
25811         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25812                 error "getstripeddir fails"
25813
25814         local stripe_count
25815         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25816                       awk '/lmv_stripe_count:/ { print $2 }')
25817
25818         [ $MDSCOUNT -ne $stripe_count ] &&
25819                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25820
25821         rm -rf $DIR/$tdir/striped_dir ||
25822                 error "unlink striped dir fails"
25823 }
25824 run_test 300r "test -1 striped directory"
25825
25826 test_300s_helper() {
25827         local count=$1
25828
25829         local stripe_dir=$DIR/$tdir/striped_dir.$count
25830
25831         $LFS mkdir -c $count $stripe_dir ||
25832                 error "lfs mkdir -c error"
25833
25834         $LFS getdirstripe $stripe_dir ||
25835                 error "lfs getdirstripe fails"
25836
25837         local stripe_count
25838         stripe_count=$($LFS getdirstripe $stripe_dir |
25839                       awk '/lmv_stripe_count:/ { print $2 }')
25840
25841         [ $count -ne $stripe_count ] &&
25842                 error_noexit "bad stripe count $stripe_count expected $count"
25843
25844         local dupe_stripes
25845         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25846                 awk '/0x/ {count[$1] += 1}; END {
25847                         for (idx in count) {
25848                                 if (count[idx]>1) {
25849                                         print "index " idx " count " count[idx]
25850                                 }
25851                         }
25852                 }')
25853
25854         if [[ -n "$dupe_stripes" ]] ; then
25855                 lfs getdirstripe $stripe_dir
25856                 error_noexit "Dupe MDT above: $dupe_stripes "
25857         fi
25858
25859         rm -rf $stripe_dir ||
25860                 error_noexit "unlink $stripe_dir fails"
25861 }
25862
25863 test_300s() {
25864         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25865                 skip "Need MDS version at least 2.7.55" && return
25866         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25867
25868         mkdir $DIR/$tdir
25869         for count in $(seq 2 $MDSCOUNT); do
25870                 test_300s_helper $count
25871         done
25872 }
25873 run_test 300s "test lfs mkdir -c without -i"
25874
25875 test_300t() {
25876         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25877                 skip "need MDS 2.14.55 or later"
25878         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25879
25880         local testdir="$DIR/$tdir/striped_dir"
25881         local dir1=$testdir/dir1
25882         local dir2=$testdir/dir2
25883
25884         mkdir -p $testdir
25885
25886         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25887                 error "failed to set default stripe count for $testdir"
25888
25889         mkdir $dir1
25890         local stripe_count=$($LFS getdirstripe -c $dir1)
25891
25892         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25893
25894         local max_count=$((MDSCOUNT - 1))
25895         local mdts=$(comma_list $(mdts_nodes))
25896
25897         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25898         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25899
25900         mkdir $dir2
25901         stripe_count=$($LFS getdirstripe -c $dir2)
25902
25903         (( $stripe_count == $max_count )) || error "wrong stripe count"
25904 }
25905 run_test 300t "test max_mdt_stripecount"
25906
25907 prepare_remote_file() {
25908         mkdir $DIR/$tdir/src_dir ||
25909                 error "create remote source failed"
25910
25911         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25912                  error "cp to remote source failed"
25913         touch $DIR/$tdir/src_dir/a
25914
25915         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25916                 error "create remote target dir failed"
25917
25918         touch $DIR/$tdir/tgt_dir/b
25919
25920         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25921                 error "rename dir cross MDT failed!"
25922
25923         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25924                 error "src_child still exists after rename"
25925
25926         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25927                 error "missing file(a) after rename"
25928
25929         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25930                 error "diff after rename"
25931 }
25932
25933 test_310a() {
25934         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25936
25937         local remote_file=$DIR/$tdir/tgt_dir/b
25938
25939         mkdir -p $DIR/$tdir
25940
25941         prepare_remote_file || error "prepare remote file failed"
25942
25943         #open-unlink file
25944         $OPENUNLINK $remote_file $remote_file ||
25945                 error "openunlink $remote_file failed"
25946         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25947 }
25948 run_test 310a "open unlink remote file"
25949
25950 test_310b() {
25951         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25953
25954         local remote_file=$DIR/$tdir/tgt_dir/b
25955
25956         mkdir -p $DIR/$tdir
25957
25958         prepare_remote_file || error "prepare remote file failed"
25959
25960         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25961         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25962         $CHECKSTAT -t file $remote_file || error "check file failed"
25963 }
25964 run_test 310b "unlink remote file with multiple links while open"
25965
25966 test_310c() {
25967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25968         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25969
25970         local remote_file=$DIR/$tdir/tgt_dir/b
25971
25972         mkdir -p $DIR/$tdir
25973
25974         prepare_remote_file || error "prepare remote file failed"
25975
25976         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25977         multiop_bg_pause $remote_file O_uc ||
25978                         error "mulitop failed for remote file"
25979         MULTIPID=$!
25980         $MULTIOP $DIR/$tfile Ouc
25981         kill -USR1 $MULTIPID
25982         wait $MULTIPID
25983 }
25984 run_test 310c "open-unlink remote file with multiple links"
25985
25986 #LU-4825
25987 test_311() {
25988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25989         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25990         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25991                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25992         remote_mds_nodsh && skip "remote MDS with nodsh"
25993
25994         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25995         local mdts=$(comma_list $(mdts_nodes))
25996
25997         mkdir -p $DIR/$tdir
25998         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25999         createmany -o $DIR/$tdir/$tfile. 1000
26000
26001         # statfs data is not real time, let's just calculate it
26002         old_iused=$((old_iused + 1000))
26003
26004         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26005                         osp.*OST0000*MDT0000.create_count")
26006         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26007                                 osp.*OST0000*MDT0000.max_create_count")
26008         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26009
26010         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26011         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26012         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26013
26014         unlinkmany $DIR/$tdir/$tfile. 1000
26015
26016         do_nodes $mdts "$LCTL set_param -n \
26017                         osp.*OST0000*.max_create_count=$max_count"
26018         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26019                 do_nodes $mdts "$LCTL set_param -n \
26020                                 osp.*OST0000*.create_count=$count"
26021         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26022                         grep "=0" && error "create_count is zero"
26023
26024         local new_iused
26025         for i in $(seq 120); do
26026                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26027                 # system may be too busy to destroy all objs in time, use
26028                 # a somewhat small value to not fail autotest
26029                 [ $((old_iused - new_iused)) -gt 400 ] && break
26030                 sleep 1
26031         done
26032
26033         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26034         [ $((old_iused - new_iused)) -gt 400 ] ||
26035                 error "objs not destroyed after unlink"
26036 }
26037 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26038
26039 zfs_get_objid()
26040 {
26041         local ost=$1
26042         local tf=$2
26043         local fid=($($LFS getstripe $tf | grep 0x))
26044         local seq=${fid[3]#0x}
26045         local objid=${fid[1]}
26046
26047         local vdevdir=$(dirname $(facet_vdevice $ost))
26048         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26049         local zfs_zapid=$(do_facet $ost $cmd |
26050                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26051                           awk '/Object/{getline; print $1}')
26052         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26053                           awk "/$objid = /"'{printf $3}')
26054
26055         echo $zfs_objid
26056 }
26057
26058 zfs_object_blksz() {
26059         local ost=$1
26060         local objid=$2
26061
26062         local vdevdir=$(dirname $(facet_vdevice $ost))
26063         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26064         local blksz=$(do_facet $ost $cmd $objid |
26065                       awk '/dblk/{getline; printf $4}')
26066
26067         case "${blksz: -1}" in
26068                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26069                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26070                 *) ;;
26071         esac
26072
26073         echo $blksz
26074 }
26075
26076 test_312() { # LU-4856
26077         remote_ost_nodsh && skip "remote OST with nodsh"
26078         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26079
26080         local max_blksz=$(do_facet ost1 \
26081                           $ZFS get -p recordsize $(facet_device ost1) |
26082                           awk '!/VALUE/{print $3}')
26083         local tf=$DIR/$tfile
26084
26085         $LFS setstripe -c1 $tf
26086         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26087
26088         # Get ZFS object id
26089         local zfs_objid=$(zfs_get_objid $facet $tf)
26090         # block size change by sequential overwrite
26091         local bs
26092
26093         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26094                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26095
26096                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26097                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26098         done
26099         rm -f $tf
26100
26101         $LFS setstripe -c1 $tf
26102         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26103
26104         # block size change by sequential append write
26105         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26106         zfs_objid=$(zfs_get_objid $facet $tf)
26107         local count
26108
26109         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26110                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26111                         oflag=sync conv=notrunc
26112
26113                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26114                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26115                         error "blksz error, actual $blksz, " \
26116                                 "expected: 2 * $count * $PAGE_SIZE"
26117         done
26118         rm -f $tf
26119
26120         # random write
26121         $LFS setstripe -c1 $tf
26122         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26123         zfs_objid=$(zfs_get_objid $facet $tf)
26124
26125         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26126         blksz=$(zfs_object_blksz $facet $zfs_objid)
26127         (( blksz == PAGE_SIZE )) ||
26128                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26129
26130         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26131         blksz=$(zfs_object_blksz $facet $zfs_objid)
26132         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26133
26134         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26135         blksz=$(zfs_object_blksz $facet $zfs_objid)
26136         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26137 }
26138 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26139
26140 test_313() {
26141         remote_ost_nodsh && skip "remote OST with nodsh"
26142
26143         local file=$DIR/$tfile
26144
26145         rm -f $file
26146         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26147
26148         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26149         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26150         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26151                 error "write should failed"
26152         do_facet ost1 "$LCTL set_param fail_loc=0"
26153         rm -f $file
26154 }
26155 run_test 313 "io should fail after last_rcvd update fail"
26156
26157 test_314() {
26158         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26159
26160         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26161         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26162         rm -f $DIR/$tfile
26163         wait_delete_completed
26164         do_facet ost1 "$LCTL set_param fail_loc=0"
26165 }
26166 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26167
26168 test_315() { # LU-618
26169         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26170
26171         local file=$DIR/$tfile
26172         rm -f $file
26173
26174         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26175                 error "multiop file write failed"
26176         $MULTIOP $file oO_RDONLY:r4063232_c &
26177         PID=$!
26178
26179         sleep 2
26180
26181         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26182         kill -USR1 $PID
26183
26184         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26185         rm -f $file
26186 }
26187 run_test 315 "read should be accounted"
26188
26189 test_316() {
26190         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26191         large_xattr_enabled || skip "ea_inode feature disabled"
26192
26193         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26194         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26195         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26196         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26197
26198         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26199 }
26200 run_test 316 "lfs migrate of file with large_xattr enabled"
26201
26202 test_317() {
26203         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26204                 skip "Need MDS version at least 2.11.53"
26205         if [ "$ost1_FSTYPE" == "zfs" ]; then
26206                 skip "LU-10370: no implementation for ZFS"
26207         fi
26208
26209         local trunc_sz
26210         local grant_blk_size
26211
26212         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26213                         awk '/grant_block_size:/ { print $2; exit; }')
26214         #
26215         # Create File of size 5M. Truncate it to below size's and verify
26216         # blocks count.
26217         #
26218         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26219                 error "Create file $DIR/$tfile failed"
26220         stack_trap "rm -f $DIR/$tfile" EXIT
26221
26222         for trunc_sz in 2097152 4097 4000 509 0; do
26223                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26224                         error "truncate $tfile to $trunc_sz failed"
26225                 local sz=$(stat --format=%s $DIR/$tfile)
26226                 local blk=$(stat --format=%b $DIR/$tfile)
26227                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26228                                      grant_blk_size) * 8))
26229
26230                 if [[ $blk -ne $trunc_blk ]]; then
26231                         $(which stat) $DIR/$tfile
26232                         error "Expected Block $trunc_blk got $blk for $tfile"
26233                 fi
26234
26235                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26236                         error "Expected Size $trunc_sz got $sz for $tfile"
26237         done
26238
26239         #
26240         # sparse file test
26241         # Create file with a hole and write actual 65536 bytes which aligned
26242         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26243         #
26244         local bs=65536
26245         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26246                 error "Create file : $DIR/$tfile"
26247
26248         #
26249         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26250         # blocks. The block count must drop to 8.
26251         #
26252         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26253                 ((bs - grant_blk_size) + 1)))
26254         $TRUNCATE $DIR/$tfile $trunc_sz ||
26255                 error "truncate $tfile to $trunc_sz failed"
26256
26257         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26258         sz=$(stat --format=%s $DIR/$tfile)
26259         blk=$(stat --format=%b $DIR/$tfile)
26260
26261         if [[ $blk -ne $trunc_bsz ]]; then
26262                 $(which stat) $DIR/$tfile
26263                 error "Expected Block $trunc_bsz got $blk for $tfile"
26264         fi
26265
26266         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26267                 error "Expected Size $trunc_sz got $sz for $tfile"
26268 }
26269 run_test 317 "Verify blocks get correctly update after truncate"
26270
26271 test_318() {
26272         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26273         local old_max_active=$($LCTL get_param -n \
26274                             ${llite_name}.max_read_ahead_async_active \
26275                             2>/dev/null)
26276
26277         $LCTL set_param llite.*.max_read_ahead_async_active=256
26278         local max_active=$($LCTL get_param -n \
26279                            ${llite_name}.max_read_ahead_async_active \
26280                            2>/dev/null)
26281         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26282
26283         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26284                 error "set max_read_ahead_async_active should succeed"
26285
26286         $LCTL set_param llite.*.max_read_ahead_async_active=512
26287         max_active=$($LCTL get_param -n \
26288                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26289         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26290
26291         # restore @max_active
26292         [ $old_max_active -ne 0 ] && $LCTL set_param \
26293                 llite.*.max_read_ahead_async_active=$old_max_active
26294
26295         local old_threshold=$($LCTL get_param -n \
26296                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26297         local max_per_file_mb=$($LCTL get_param -n \
26298                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26299
26300         local invalid=$(($max_per_file_mb + 1))
26301         $LCTL set_param \
26302                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26303                         && error "set $invalid should fail"
26304
26305         local valid=$(($invalid - 1))
26306         $LCTL set_param \
26307                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26308                         error "set $valid should succeed"
26309         local threshold=$($LCTL get_param -n \
26310                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26311         [ $threshold -eq $valid ] || error \
26312                 "expect threshold $valid got $threshold"
26313         $LCTL set_param \
26314                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26315 }
26316 run_test 318 "Verify async readahead tunables"
26317
26318 test_319() {
26319         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26320
26321         local before=$(date +%s)
26322         local evict
26323         local mdir=$DIR/$tdir
26324         local file=$mdir/xxx
26325
26326         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26327         touch $file
26328
26329 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26330         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26331         $LFS migrate -m1 $mdir &
26332
26333         sleep 1
26334         dd if=$file of=/dev/null
26335         wait
26336         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26337           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26338
26339         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26340 }
26341 run_test 319 "lost lease lock on migrate error"
26342
26343 test_398a() { # LU-4198
26344         local ost1_imp=$(get_osc_import_name client ost1)
26345         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26346                          cut -d'.' -f2)
26347
26348         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26349         stack_trap "rm -f $DIR/$tfile"
26350         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26351
26352         # request a new lock on client
26353         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26354
26355         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26356         local lock_count=$($LCTL get_param -n \
26357                            ldlm.namespaces.$imp_name.lru_size)
26358         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26359
26360         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26361
26362         # no lock cached, should use lockless DIO and not enqueue new lock
26363         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26364         lock_count=$($LCTL get_param -n \
26365                      ldlm.namespaces.$imp_name.lru_size)
26366         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26367
26368         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26369
26370         # no lock cached, should use locked DIO append
26371         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26372                 conv=notrunc || error "DIO append failed"
26373         lock_count=$($LCTL get_param -n \
26374                      ldlm.namespaces.$imp_name.lru_size)
26375         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26376 }
26377 run_test 398a "direct IO should cancel lock otherwise lockless"
26378
26379 test_398b() { # LU-4198
26380         local before=$(date +%s)
26381         local njobs=4
26382         local size=48
26383
26384         which fio || skip_env "no fio installed"
26385         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26386         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26387
26388         # Single page, multiple pages, stripe size, 4*stripe size
26389         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26390                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26391                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26392                         --numjobs=$njobs --fallocate=none \
26393                         --iodepth=16 --allow_file_create=0 \
26394                         --size=$((size/njobs))M \
26395                         --filename=$DIR/$tfile &
26396                 bg_pid=$!
26397
26398                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26399                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26400                         --numjobs=$njobs --fallocate=none \
26401                         --iodepth=16 --allow_file_create=0 \
26402                         --size=$((size/njobs))M \
26403                         --filename=$DIR/$tfile || true
26404                 wait $bg_pid
26405         done
26406
26407         evict=$(do_facet client $LCTL get_param \
26408                 osc.$FSNAME-OST*-osc-*/state |
26409             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26410
26411         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26412                 (do_facet client $LCTL get_param \
26413                         osc.$FSNAME-OST*-osc-*/state;
26414                     error "eviction happened: $evict before:$before")
26415
26416         rm -f $DIR/$tfile
26417 }
26418 run_test 398b "DIO and buffer IO race"
26419
26420 test_398c() { # LU-4198
26421         local ost1_imp=$(get_osc_import_name client ost1)
26422         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26423                          cut -d'.' -f2)
26424
26425         which fio || skip_env "no fio installed"
26426
26427         saved_debug=$($LCTL get_param -n debug)
26428         $LCTL set_param debug=0
26429
26430         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26431         ((size /= 1024)) # by megabytes
26432         ((size /= 2)) # write half of the OST at most
26433         [ $size -gt 40 ] && size=40 #reduce test time anyway
26434
26435         $LFS setstripe -c 1 $DIR/$tfile
26436
26437         # it seems like ldiskfs reserves more space than necessary if the
26438         # writing blocks are not mapped, so it extends the file firstly
26439         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26440         cancel_lru_locks osc
26441
26442         # clear and verify rpc_stats later
26443         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26444
26445         local njobs=4
26446         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26447         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26448                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26449                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26450                 --filename=$DIR/$tfile
26451         [ $? -eq 0 ] || error "fio write error"
26452
26453         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26454                 error "Locks were requested while doing AIO"
26455
26456         # get the percentage of 1-page I/O
26457         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26458                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26459                 awk '{print $7}')
26460         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26461
26462         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26463         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26464                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26465                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26466                 --filename=$DIR/$tfile
26467         [ $? -eq 0 ] || error "fio mixed read write error"
26468
26469         echo "AIO with large block size ${size}M"
26470         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26471                 --numjobs=1 --fallocate=none --ioengine=libaio \
26472                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26473                 --filename=$DIR/$tfile
26474         [ $? -eq 0 ] || error "fio large block size failed"
26475
26476         rm -f $DIR/$tfile
26477         $LCTL set_param debug="$saved_debug"
26478 }
26479 run_test 398c "run fio to test AIO"
26480
26481 test_398d() { #  LU-13846
26482         which aiocp || skip_env "no aiocp installed"
26483         local aio_file=$DIR/$tfile.aio
26484
26485         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26486
26487         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26488         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26489         stack_trap "rm -f $DIR/$tfile $aio_file"
26490
26491         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26492
26493         # make sure we don't crash and fail properly
26494         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26495                 error "aio not aligned with PAGE SIZE should fail"
26496
26497         rm -f $DIR/$tfile $aio_file
26498 }
26499 run_test 398d "run aiocp to verify block size > stripe size"
26500
26501 test_398e() {
26502         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26503         touch $DIR/$tfile.new
26504         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26505 }
26506 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26507
26508 test_398f() { #  LU-14687
26509         which aiocp || skip_env "no aiocp installed"
26510         local aio_file=$DIR/$tfile.aio
26511
26512         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26513
26514         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26515         stack_trap "rm -f $DIR/$tfile $aio_file"
26516
26517         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26518         $LCTL set_param fail_loc=0x1418
26519         # make sure we don't crash and fail properly
26520         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26521                 error "aio with page allocation failure succeeded"
26522         $LCTL set_param fail_loc=0
26523         diff $DIR/$tfile $aio_file
26524         [[ $? != 0 ]] || error "no diff after failed aiocp"
26525 }
26526 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26527
26528 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26529 # stripe and i/o size must be > stripe size
26530 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26531 # single RPC in flight.  This test shows async DIO submission is working by
26532 # showing multiple RPCs in flight.
26533 test_398g() { #  LU-13798
26534         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26535
26536         # We need to do some i/o first to acquire enough grant to put our RPCs
26537         # in flight; otherwise a new connection may not have enough grant
26538         # available
26539         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26540                 error "parallel dio failed"
26541         stack_trap "rm -f $DIR/$tfile"
26542
26543         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26544         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26545         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26546         stack_trap "$LCTL set_param -n $pages_per_rpc"
26547
26548         # Recreate file so it's empty
26549         rm -f $DIR/$tfile
26550         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26551         #Pause rpc completion to guarantee we see multiple rpcs in flight
26552         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26553         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26554         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26555
26556         # Clear rpc stats
26557         $LCTL set_param osc.*.rpc_stats=c
26558
26559         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26560                 error "parallel dio failed"
26561         stack_trap "rm -f $DIR/$tfile"
26562
26563         $LCTL get_param osc.*-OST0000-*.rpc_stats
26564         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26565                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26566                 grep "8:" | awk '{print $8}')
26567         # We look at the "8 rpcs in flight" field, and verify A) it is present
26568         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26569         # as expected for an 8M DIO to a file with 1M stripes.
26570         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26571
26572         # Verify turning off parallel dio works as expected
26573         # Clear rpc stats
26574         $LCTL set_param osc.*.rpc_stats=c
26575         $LCTL set_param llite.*.parallel_dio=0
26576         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26577
26578         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26579                 error "dio with parallel dio disabled failed"
26580
26581         # Ideally, we would see only one RPC in flight here, but there is an
26582         # unavoidable race between i/o completion and RPC in flight counting,
26583         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26584         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26585         # So instead we just verify it's always < 8.
26586         $LCTL get_param osc.*-OST0000-*.rpc_stats
26587         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26588                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26589                 grep '^$' -B1 | grep . | awk '{print $1}')
26590         [ $ret != "8:" ] ||
26591                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26592 }
26593 run_test 398g "verify parallel dio async RPC submission"
26594
26595 test_398h() { #  LU-13798
26596         local dio_file=$DIR/$tfile.dio
26597
26598         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26599
26600         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26601         stack_trap "rm -f $DIR/$tfile $dio_file"
26602
26603         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26604                 error "parallel dio failed"
26605         diff $DIR/$tfile $dio_file
26606         [[ $? == 0 ]] || error "file diff after aiocp"
26607 }
26608 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26609
26610 test_398i() { #  LU-13798
26611         local dio_file=$DIR/$tfile.dio
26612
26613         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26614
26615         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26616         stack_trap "rm -f $DIR/$tfile $dio_file"
26617
26618         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26619         $LCTL set_param fail_loc=0x1418
26620         # make sure we don't crash and fail properly
26621         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26622                 error "parallel dio page allocation failure succeeded"
26623         diff $DIR/$tfile $dio_file
26624         [[ $? != 0 ]] || error "no diff after failed aiocp"
26625 }
26626 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26627
26628 test_398j() { #  LU-13798
26629         # Stripe size > RPC size but less than i/o size tests split across
26630         # stripes and RPCs for individual i/o op
26631         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26632
26633         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26634         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26635         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26636         stack_trap "$LCTL set_param -n $pages_per_rpc"
26637
26638         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26639                 error "parallel dio write failed"
26640         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26641
26642         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26643                 error "parallel dio read failed"
26644         diff $DIR/$tfile $DIR/$tfile.2
26645         [[ $? == 0 ]] || error "file diff after parallel dio read"
26646 }
26647 run_test 398j "test parallel dio where stripe size > rpc_size"
26648
26649 test_398k() { #  LU-13798
26650         wait_delete_completed
26651         wait_mds_ost_sync
26652
26653         # 4 stripe file; we will cause out of space on OST0
26654         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26655
26656         # Fill OST0 (if it's not too large)
26657         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26658                    head -n1)
26659         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26660                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26661         fi
26662         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26663         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26664                 error "dd should fill OST0"
26665         stack_trap "rm -f $DIR/$tfile.1"
26666
26667         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26668         err=$?
26669
26670         ls -la $DIR/$tfile
26671         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26672                 error "file is not 0 bytes in size"
26673
26674         # dd above should not succeed, but don't error until here so we can
26675         # get debug info above
26676         [[ $err != 0 ]] ||
26677                 error "parallel dio write with enospc succeeded"
26678         stack_trap "rm -f $DIR/$tfile"
26679 }
26680 run_test 398k "test enospc on first stripe"
26681
26682 test_398l() { #  LU-13798
26683         wait_delete_completed
26684         wait_mds_ost_sync
26685
26686         # 4 stripe file; we will cause out of space on OST0
26687         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26688         # happens on the second i/o chunk we issue
26689         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26690
26691         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26692         stack_trap "rm -f $DIR/$tfile"
26693
26694         # Fill OST0 (if it's not too large)
26695         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26696                    head -n1)
26697         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26698                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26699         fi
26700         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26701         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26702                 error "dd should fill OST0"
26703         stack_trap "rm -f $DIR/$tfile.1"
26704
26705         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26706         err=$?
26707         stack_trap "rm -f $DIR/$tfile.2"
26708
26709         # Check that short write completed as expected
26710         ls -la $DIR/$tfile.2
26711         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26712                 error "file is not 1M in size"
26713
26714         # dd above should not succeed, but don't error until here so we can
26715         # get debug info above
26716         [[ $err != 0 ]] ||
26717                 error "parallel dio write with enospc succeeded"
26718
26719         # Truncate source file to same length as output file and diff them
26720         $TRUNCATE $DIR/$tfile 1048576
26721         diff $DIR/$tfile $DIR/$tfile.2
26722         [[ $? == 0 ]] || error "data incorrect after short write"
26723 }
26724 run_test 398l "test enospc on intermediate stripe/RPC"
26725
26726 test_398m() { #  LU-13798
26727         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26728
26729         # Set up failure on OST0, the first stripe:
26730         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26731         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26732         # OST0 is on ost1, OST1 is on ost2.
26733         # So this fail_val specifies OST0
26734         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26735         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26736
26737         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26738                 error "parallel dio write with failure on first stripe succeeded"
26739         stack_trap "rm -f $DIR/$tfile"
26740         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26741
26742         # Place data in file for read
26743         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26744                 error "parallel dio write failed"
26745
26746         # Fail read on OST0, first stripe
26747         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26748         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26749         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26750                 error "parallel dio read with error on first stripe succeeded"
26751         rm -f $DIR/$tfile.2
26752         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26753
26754         # Switch to testing on OST1, second stripe
26755         # Clear file contents, maintain striping
26756         echo > $DIR/$tfile
26757         # Set up failure on OST1, second stripe:
26758         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26759         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26760
26761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26762                 error "parallel dio write with failure on second stripe succeeded"
26763         stack_trap "rm -f $DIR/$tfile"
26764         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26765
26766         # Place data in file for read
26767         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26768                 error "parallel dio write failed"
26769
26770         # Fail read on OST1, second stripe
26771         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26772         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26773         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26774                 error "parallel dio read with error on second stripe succeeded"
26775         rm -f $DIR/$tfile.2
26776         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26777 }
26778 run_test 398m "test RPC failures with parallel dio"
26779
26780 # Parallel submission of DIO should not cause problems for append, but it's
26781 # important to verify.
26782 test_398n() { #  LU-13798
26783         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26784
26785         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26786                 error "dd to create source file failed"
26787         stack_trap "rm -f $DIR/$tfile"
26788
26789         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26790                 error "parallel dio write with failure on second stripe succeeded"
26791         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26792         diff $DIR/$tfile $DIR/$tfile.1
26793         [[ $? == 0 ]] || error "data incorrect after append"
26794
26795 }
26796 run_test 398n "test append with parallel DIO"
26797
26798 test_398o() {
26799         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26800 }
26801 run_test 398o "right kms with DIO"
26802
26803 test_398p()
26804 {
26805         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26806         which aiocp || skip_env "no aiocp installed"
26807
26808         local stripe_size=$((1024 * 1024)) #1 MiB
26809         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26810         local file_size=$((25 * stripe_size))
26811
26812         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26813         stack_trap "rm -f $DIR/$tfile*"
26814         # Just a bit bigger than the largest size in the test set below
26815         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26816                 error "buffered i/o to create file failed"
26817
26818         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26819                 $((stripe_size * 4)); do
26820
26821                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26822
26823                 echo "bs: $bs, file_size $file_size"
26824                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26825                         $DIR/$tfile.1 $DIR/$tfile.2 &
26826                 pid_dio1=$!
26827                 # Buffered I/O with similar but not the same block size
26828                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26829                         conv=notrunc &
26830                 pid_bio2=$!
26831                 wait $pid_dio1
26832                 rc1=$?
26833                 wait $pid_bio2
26834                 rc2=$?
26835                 if (( rc1 != 0 )); then
26836                         error "aio copy 1 w/bsize $bs failed: $rc1"
26837                 fi
26838                 if (( rc2 != 0 )); then
26839                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26840                 fi
26841
26842                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26843                         error "size incorrect"
26844                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26845                         error "files differ, bsize $bs"
26846                 rm -f $DIR/$tfile.2
26847         done
26848 }
26849 run_test 398p "race aio with buffered i/o"
26850
26851 test_398q()
26852 {
26853         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26854
26855         local stripe_size=$((1024 * 1024)) #1 MiB
26856         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26857         local file_size=$((25 * stripe_size))
26858
26859         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26860         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26861
26862         # Just a bit bigger than the largest size in the test set below
26863         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26864                 error "buffered i/o to create file failed"
26865
26866         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26867                 $((stripe_size * 4)); do
26868
26869                 echo "bs: $bs, file_size $file_size"
26870                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26871                         conv=notrunc oflag=direct iflag=direct &
26872                 pid_dio1=$!
26873                 # Buffered I/O with similar but not the same block size
26874                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26875                         conv=notrunc &
26876                 pid_bio2=$!
26877                 wait $pid_dio1
26878                 rc1=$?
26879                 wait $pid_bio2
26880                 rc2=$?
26881                 if (( rc1 != 0 )); then
26882                         error "dio copy 1 w/bsize $bs failed: $rc1"
26883                 fi
26884                 if (( rc2 != 0 )); then
26885                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26886                 fi
26887
26888                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26889                         error "size incorrect"
26890                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26891                         error "files differ, bsize $bs"
26892         done
26893
26894         rm -f $DIR/$tfile*
26895 }
26896 run_test 398q "race dio with buffered i/o"
26897
26898 test_fake_rw() {
26899         local read_write=$1
26900         if [ "$read_write" = "write" ]; then
26901                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26902         elif [ "$read_write" = "read" ]; then
26903                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26904         else
26905                 error "argument error"
26906         fi
26907
26908         # turn off debug for performance testing
26909         local saved_debug=$($LCTL get_param -n debug)
26910         $LCTL set_param debug=0
26911
26912         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26913
26914         # get ost1 size - $FSNAME-OST0000
26915         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26916         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26917         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26918
26919         if [ "$read_write" = "read" ]; then
26920                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26921         fi
26922
26923         local start_time=$(date +%s.%N)
26924         $dd_cmd bs=1M count=$blocks oflag=sync ||
26925                 error "real dd $read_write error"
26926         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26927
26928         if [ "$read_write" = "write" ]; then
26929                 rm -f $DIR/$tfile
26930         fi
26931
26932         # define OBD_FAIL_OST_FAKE_RW           0x238
26933         do_facet ost1 $LCTL set_param fail_loc=0x238
26934
26935         local start_time=$(date +%s.%N)
26936         $dd_cmd bs=1M count=$blocks oflag=sync ||
26937                 error "fake dd $read_write error"
26938         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26939
26940         if [ "$read_write" = "write" ]; then
26941                 # verify file size
26942                 cancel_lru_locks osc
26943                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26944                         error "$tfile size not $blocks MB"
26945         fi
26946         do_facet ost1 $LCTL set_param fail_loc=0
26947
26948         echo "fake $read_write $duration_fake vs. normal $read_write" \
26949                 "$duration in seconds"
26950         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26951                 error_not_in_vm "fake write is slower"
26952
26953         $LCTL set_param -n debug="$saved_debug"
26954         rm -f $DIR/$tfile
26955 }
26956 test_399a() { # LU-7655 for OST fake write
26957         remote_ost_nodsh && skip "remote OST with nodsh"
26958
26959         test_fake_rw write
26960 }
26961 run_test 399a "fake write should not be slower than normal write"
26962
26963 test_399b() { # LU-8726 for OST fake read
26964         remote_ost_nodsh && skip "remote OST with nodsh"
26965         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26966                 skip_env "ldiskfs only test"
26967         fi
26968
26969         test_fake_rw read
26970 }
26971 run_test 399b "fake read should not be slower than normal read"
26972
26973 test_400a() { # LU-1606, was conf-sanity test_74
26974         if ! which $CC > /dev/null 2>&1; then
26975                 skip_env "$CC is not installed"
26976         fi
26977
26978         local extra_flags=''
26979         local out=$TMP/$tfile
26980         local prefix=/usr/include/lustre
26981         local prog
26982
26983         # Oleg removes .c files in his test rig so test if any c files exist
26984         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26985                 skip_env "Needed .c test files are missing"
26986
26987         if ! [[ -d $prefix ]]; then
26988                 # Assume we're running in tree and fixup the include path.
26989                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26990                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26991                 extra_flags+=" -L$LUSTRE/utils/.libs"
26992         fi
26993
26994         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26995                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26996                         error "client api broken"
26997         done
26998         rm -f $out
26999 }
27000 run_test 400a "Lustre client api program can compile and link"
27001
27002 test_400b() { # LU-1606, LU-5011
27003         local header
27004         local out=$TMP/$tfile
27005         local prefix=/usr/include/linux/lustre
27006
27007         # We use a hard coded prefix so that this test will not fail
27008         # when run in tree. There are headers in lustre/include/lustre/
27009         # that are not packaged (like lustre_idl.h) and have more
27010         # complicated include dependencies (like config.h and lnet/types.h).
27011         # Since this test about correct packaging we just skip them when
27012         # they don't exist (see below) rather than try to fixup cppflags.
27013
27014         if ! which $CC > /dev/null 2>&1; then
27015                 skip_env "$CC is not installed"
27016         fi
27017
27018         for header in $prefix/*.h; do
27019                 if ! [[ -f "$header" ]]; then
27020                         continue
27021                 fi
27022
27023                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27024                         continue # lustre_ioctl.h is internal header
27025                 fi
27026
27027                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27028                         error "cannot compile '$header'"
27029         done
27030         rm -f $out
27031 }
27032 run_test 400b "packaged headers can be compiled"
27033
27034 test_401a() { #LU-7437
27035         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27036         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27037
27038         #count the number of parameters by "list_param -R"
27039         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27040         #count the number of parameters by listing proc files
27041         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27042         echo "proc_dirs='$proc_dirs'"
27043         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27044         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27045                       sort -u | wc -l)
27046
27047         [ $params -eq $procs ] ||
27048                 error "found $params parameters vs. $procs proc files"
27049
27050         # test the list_param -D option only returns directories
27051         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27052         #count the number of parameters by listing proc directories
27053         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27054                 sort -u | wc -l)
27055
27056         [ $params -eq $procs ] ||
27057                 error "found $params parameters vs. $procs proc files"
27058 }
27059 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27060
27061 test_401b() {
27062         # jobid_var may not allow arbitrary values, so use jobid_name
27063         # if available
27064         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27065                 local testname=jobid_name tmp='testing%p'
27066         else
27067                 local testname=jobid_var tmp=testing
27068         fi
27069
27070         local save=$($LCTL get_param -n $testname)
27071
27072         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27073                 error "no error returned when setting bad parameters"
27074
27075         local jobid_new=$($LCTL get_param -n foe $testname baz)
27076         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27077
27078         $LCTL set_param -n fog=bam $testname=$save bat=fog
27079         local jobid_old=$($LCTL get_param -n foe $testname bag)
27080         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27081 }
27082 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27083
27084 test_401c() {
27085         # jobid_var may not allow arbitrary values, so use jobid_name
27086         # if available
27087         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27088                 local testname=jobid_name
27089         else
27090                 local testname=jobid_var
27091         fi
27092
27093         local jobid_var_old=$($LCTL get_param -n $testname)
27094         local jobid_var_new
27095
27096         $LCTL set_param $testname= &&
27097                 error "no error returned for 'set_param a='"
27098
27099         jobid_var_new=$($LCTL get_param -n $testname)
27100         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27101                 error "$testname was changed by setting without value"
27102
27103         $LCTL set_param $testname &&
27104                 error "no error returned for 'set_param a'"
27105
27106         jobid_var_new=$($LCTL get_param -n $testname)
27107         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27108                 error "$testname was changed by setting without value"
27109 }
27110 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27111
27112 test_401d() {
27113         # jobid_var may not allow arbitrary values, so use jobid_name
27114         # if available
27115         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27116                 local testname=jobid_name new_value='foo=bar%p'
27117         else
27118                 local testname=jobid_var new_valuie=foo=bar
27119         fi
27120
27121         local jobid_var_old=$($LCTL get_param -n $testname)
27122         local jobid_var_new
27123
27124         $LCTL set_param $testname=$new_value ||
27125                 error "'set_param a=b' did not accept a value containing '='"
27126
27127         jobid_var_new=$($LCTL get_param -n $testname)
27128         [[ "$jobid_var_new" == "$new_value" ]] ||
27129                 error "'set_param a=b' failed on a value containing '='"
27130
27131         # Reset the $testname to test the other format
27132         $LCTL set_param $testname=$jobid_var_old
27133         jobid_var_new=$($LCTL get_param -n $testname)
27134         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27135                 error "failed to reset $testname"
27136
27137         $LCTL set_param $testname $new_value ||
27138                 error "'set_param a b' did not accept a value containing '='"
27139
27140         jobid_var_new=$($LCTL get_param -n $testname)
27141         [[ "$jobid_var_new" == "$new_value" ]] ||
27142                 error "'set_param a b' failed on a value containing '='"
27143
27144         $LCTL set_param $testname $jobid_var_old
27145         jobid_var_new=$($LCTL get_param -n $testname)
27146         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27147                 error "failed to reset $testname"
27148 }
27149 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27150
27151 test_401e() { # LU-14779
27152         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27153                 error "lctl list_param MGC* failed"
27154         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27155         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27156                 error "lctl get_param lru_size failed"
27157 }
27158 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27159
27160 test_402() {
27161         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27162         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27163                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27164         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27165                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27166                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27167         remote_mds_nodsh && skip "remote MDS with nodsh"
27168
27169         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27170 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27171         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27172         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27173                 echo "Touch failed - OK"
27174 }
27175 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27176
27177 test_403() {
27178         local file1=$DIR/$tfile.1
27179         local file2=$DIR/$tfile.2
27180         local tfile=$TMP/$tfile
27181
27182         rm -f $file1 $file2 $tfile
27183
27184         touch $file1
27185         ln $file1 $file2
27186
27187         # 30 sec OBD_TIMEOUT in ll_getattr()
27188         # right before populating st_nlink
27189         $LCTL set_param fail_loc=0x80001409
27190         stat -c %h $file1 > $tfile &
27191
27192         # create an alias, drop all locks and reclaim the dentry
27193         < $file2
27194         cancel_lru_locks mdc
27195         cancel_lru_locks osc
27196         sysctl -w vm.drop_caches=2
27197
27198         wait
27199
27200         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27201
27202         rm -f $tfile $file1 $file2
27203 }
27204 run_test 403 "i_nlink should not drop to zero due to aliasing"
27205
27206 test_404() { # LU-6601
27207         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27208                 skip "Need server version newer than 2.8.52"
27209         remote_mds_nodsh && skip "remote MDS with nodsh"
27210
27211         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27212                 awk '/osp .*-osc-MDT/ { print $4}')
27213
27214         local osp
27215         for osp in $mosps; do
27216                 echo "Deactivate: " $osp
27217                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27218                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27219                         awk -vp=$osp '$4 == p { print $2 }')
27220                 [ $stat = IN ] || {
27221                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27222                         error "deactivate error"
27223                 }
27224                 echo "Activate: " $osp
27225                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27226                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27227                         awk -vp=$osp '$4 == p { print $2 }')
27228                 [ $stat = UP ] || {
27229                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27230                         error "activate error"
27231                 }
27232         done
27233 }
27234 run_test 404 "validate manual {de}activated works properly for OSPs"
27235
27236 test_405() {
27237         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27238         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27239                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27240                         skip "Layout swap lock is not supported"
27241
27242         check_swap_layouts_support
27243         check_swap_layout_no_dom $DIR
27244
27245         test_mkdir $DIR/$tdir
27246         swap_lock_test -d $DIR/$tdir ||
27247                 error "One layout swap locked test failed"
27248 }
27249 run_test 405 "Various layout swap lock tests"
27250
27251 test_406() {
27252         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27253         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27254         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27256         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27257                 skip "Need MDS version at least 2.8.50"
27258
27259         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27260         local test_pool=$TESTNAME
27261
27262         pool_add $test_pool || error "pool_add failed"
27263         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27264                 error "pool_add_targets failed"
27265
27266         save_layout_restore_at_exit $MOUNT
27267
27268         # parent set default stripe count only, child will stripe from both
27269         # parent and fs default
27270         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27271                 error "setstripe $MOUNT failed"
27272         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27273         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27274         for i in $(seq 10); do
27275                 local f=$DIR/$tdir/$tfile.$i
27276                 touch $f || error "touch failed"
27277                 local count=$($LFS getstripe -c $f)
27278                 [ $count -eq $OSTCOUNT ] ||
27279                         error "$f stripe count $count != $OSTCOUNT"
27280                 local offset=$($LFS getstripe -i $f)
27281                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27282                 local size=$($LFS getstripe -S $f)
27283                 [ $size -eq $((def_stripe_size * 2)) ] ||
27284                         error "$f stripe size $size != $((def_stripe_size * 2))"
27285                 local pool=$($LFS getstripe -p $f)
27286                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27287         done
27288
27289         # change fs default striping, delete parent default striping, now child
27290         # will stripe from new fs default striping only
27291         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27292                 error "change $MOUNT default stripe failed"
27293         $LFS setstripe -c 0 $DIR/$tdir ||
27294                 error "delete $tdir default stripe failed"
27295         for i in $(seq 11 20); do
27296                 local f=$DIR/$tdir/$tfile.$i
27297                 touch $f || error "touch $f failed"
27298                 local count=$($LFS getstripe -c $f)
27299                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27300                 local offset=$($LFS getstripe -i $f)
27301                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27302                 local size=$($LFS getstripe -S $f)
27303                 [ $size -eq $def_stripe_size ] ||
27304                         error "$f stripe size $size != $def_stripe_size"
27305                 local pool=$($LFS getstripe -p $f)
27306                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27307         done
27308
27309         unlinkmany $DIR/$tdir/$tfile. 1 20
27310
27311         local f=$DIR/$tdir/$tfile
27312         pool_remove_all_targets $test_pool $f
27313         pool_remove $test_pool $f
27314 }
27315 run_test 406 "DNE support fs default striping"
27316
27317 test_407() {
27318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27319         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27320                 skip "Need MDS version at least 2.8.55"
27321         remote_mds_nodsh && skip "remote MDS with nodsh"
27322
27323         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27324                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27325         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27326                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27327         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27328
27329         #define OBD_FAIL_DT_TXN_STOP    0x2019
27330         for idx in $(seq $MDSCOUNT); do
27331                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27332         done
27333         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27334         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27335                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27336         true
27337 }
27338 run_test 407 "transaction fail should cause operation fail"
27339
27340 test_408() {
27341         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27342
27343         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27344         lctl set_param fail_loc=0x8000040a
27345         # let ll_prepare_partial_page() fail
27346         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27347
27348         rm -f $DIR/$tfile
27349
27350         # create at least 100 unused inodes so that
27351         # shrink_icache_memory(0) should not return 0
27352         touch $DIR/$tfile-{0..100}
27353         rm -f $DIR/$tfile-{0..100}
27354         sync
27355
27356         echo 2 > /proc/sys/vm/drop_caches
27357 }
27358 run_test 408 "drop_caches should not hang due to page leaks"
27359
27360 test_409()
27361 {
27362         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27363
27364         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27365         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27366         touch $DIR/$tdir/guard || error "(2) Fail to create"
27367
27368         local PREFIX=$(str_repeat 'A' 128)
27369         echo "Create 1K hard links start at $(date)"
27370         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27371                 error "(3) Fail to hard link"
27372
27373         echo "Links count should be right although linkEA overflow"
27374         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27375         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27376         [ $linkcount -eq 1001 ] ||
27377                 error "(5) Unexpected hard links count: $linkcount"
27378
27379         echo "List all links start at $(date)"
27380         ls -l $DIR/$tdir/foo > /dev/null ||
27381                 error "(6) Fail to list $DIR/$tdir/foo"
27382
27383         echo "Unlink hard links start at $(date)"
27384         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27385                 error "(7) Fail to unlink"
27386         echo "Unlink hard links finished at $(date)"
27387 }
27388 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27389
27390 test_410()
27391 {
27392         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27393                 skip "Need client version at least 2.9.59"
27394         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27395                 skip "Need MODULES build"
27396
27397         # Create a file, and stat it from the kernel
27398         local testfile=$DIR/$tfile
27399         touch $testfile
27400
27401         local run_id=$RANDOM
27402         local my_ino=$(stat --format "%i" $testfile)
27403
27404         # Try to insert the module. This will always fail as the
27405         # module is designed to not be inserted.
27406         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27407             &> /dev/null
27408
27409         # Anything but success is a test failure
27410         dmesg | grep -q \
27411             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27412             error "no inode match"
27413 }
27414 run_test 410 "Test inode number returned from kernel thread"
27415
27416 cleanup_test411_cgroup() {
27417         trap 0
27418         rmdir "$1"
27419 }
27420
27421 test_411() {
27422         local cg_basedir=/sys/fs/cgroup/memory
27423         # LU-9966
27424         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27425                 skip "no setup for cgroup"
27426
27427         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27428                 error "test file creation failed"
27429         cancel_lru_locks osc
27430
27431         # Create a very small memory cgroup to force a slab allocation error
27432         local cgdir=$cg_basedir/osc_slab_alloc
27433         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27434         trap "cleanup_test411_cgroup $cgdir" EXIT
27435         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27436         echo 1M > $cgdir/memory.limit_in_bytes
27437
27438         # Should not LBUG, just be killed by oom-killer
27439         # dd will return 0 even allocation failure in some environment.
27440         # So don't check return value
27441         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27442         cleanup_test411_cgroup $cgdir
27443
27444         return 0
27445 }
27446 run_test 411 "Slab allocation error with cgroup does not LBUG"
27447
27448 test_412() {
27449         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27450         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27451                 skip "Need server version at least 2.10.55"
27452
27453         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27454                 error "mkdir failed"
27455         $LFS getdirstripe $DIR/$tdir
27456         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27457         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27458                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27459         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27460         [ $stripe_count -eq 2 ] ||
27461                 error "expect 2 get $stripe_count"
27462
27463         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27464
27465         local index
27466         local index2
27467
27468         # subdirs should be on the same MDT as parent
27469         for i in $(seq 0 $((MDSCOUNT - 1))); do
27470                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27471                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27472                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27473                 (( index == i )) || error "mdt$i/sub on MDT$index"
27474         done
27475
27476         # stripe offset -1, ditto
27477         for i in {1..10}; do
27478                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27479                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27480                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27481                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27482                 (( index == index2 )) ||
27483                         error "qos$i on MDT$index, sub on MDT$index2"
27484         done
27485
27486         local testdir=$DIR/$tdir/inherit
27487
27488         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27489         # inherit 2 levels
27490         for i in 1 2; do
27491                 testdir=$testdir/s$i
27492                 mkdir $testdir || error "mkdir $testdir failed"
27493                 index=$($LFS getstripe -m $testdir)
27494                 (( index == 1 )) ||
27495                         error "$testdir on MDT$index"
27496         done
27497
27498         # not inherit any more
27499         testdir=$testdir/s3
27500         mkdir $testdir || error "mkdir $testdir failed"
27501         getfattr -d -m dmv $testdir | grep dmv &&
27502                 error "default LMV set on $testdir" || true
27503 }
27504 run_test 412 "mkdir on specific MDTs"
27505
27506 TEST413_COUNT=${TEST413_COUNT:-200}
27507
27508 #
27509 # set_maxage() is used by test_413 only.
27510 # This is a helper function to set maxage. Does not return any value.
27511 # Input: maxage to set
27512 #
27513 set_maxage() {
27514         local lmv_qos_maxage
27515         local lod_qos_maxage
27516         local new_maxage=$1
27517
27518         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27519         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27520         stack_trap "$LCTL set_param \
27521                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27522         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27523                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27524         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27525                 lod.*.mdt_qos_maxage=$new_maxage
27526         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27527                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27528 }
27529
27530 generate_uneven_mdts() {
27531         local threshold=$1
27532         local ffree
27533         local bavail
27534         local max
27535         local min
27536         local max_index
27537         local min_index
27538         local tmp
27539         local i
27540
27541         echo
27542         echo "Check for uneven MDTs: "
27543
27544         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27545         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27546         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27547
27548         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27549         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27550         max_index=0
27551         min_index=0
27552         for ((i = 1; i < ${#ffree[@]}; i++)); do
27553                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27554                 if [ $tmp -gt $max ]; then
27555                         max=$tmp
27556                         max_index=$i
27557                 fi
27558                 if [ $tmp -lt $min ]; then
27559                         min=$tmp
27560                         min_index=$i
27561                 fi
27562         done
27563
27564         (( min > 0 )) || skip "low space on MDT$min_index"
27565         (( ${ffree[min_index]} > 0 )) ||
27566                 skip "no free files on MDT$min_index"
27567         (( ${ffree[min_index]} < 10000000 )) ||
27568                 skip "too many free files on MDT$min_index"
27569
27570         # Check if we need to generate uneven MDTs
27571         local diff=$(((max - min) * 100 / min))
27572         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27573         local testdir # individual folder within $testdirp
27574         local start
27575         local cmd
27576
27577         # fallocate is faster to consume space on MDT, if available
27578         if check_fallocate_supported mds$((min_index + 1)); then
27579                 cmd="fallocate -l 128K "
27580         else
27581                 cmd="dd if=/dev/zero bs=128K count=1 of="
27582         fi
27583
27584         echo "using cmd $cmd"
27585         for (( i = 0; diff < threshold; i++ )); do
27586                 testdir=${testdirp}/$i
27587                 [ -d $testdir ] && continue
27588
27589                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27590
27591                 mkdir -p $testdirp
27592                 # generate uneven MDTs, create till $threshold% diff
27593                 echo -n "weight diff=$diff% must be > $threshold% ..."
27594                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27595                 $LFS mkdir -i $min_index $testdir ||
27596                         error "mkdir $testdir failed"
27597                 $LFS setstripe -E 1M -L mdt $testdir ||
27598                         error "setstripe $testdir failed"
27599                 start=$SECONDS
27600                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27601                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27602                 done
27603                 sync; sleep 1; sync
27604
27605                 # wait for QOS to update
27606                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27607
27608                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27609                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27610                 max=$(((${ffree[max_index]} >> 8) *
27611                         (${bavail[max_index]} * bsize >> 16)))
27612                 min=$(((${ffree[min_index]} >> 8) *
27613                         (${bavail[min_index]} * bsize >> 16)))
27614                 (( min > 0 )) || skip "low space on MDT$min_index"
27615                 diff=$(((max - min) * 100 / min))
27616         done
27617
27618         echo "MDT filesfree available: ${ffree[*]}"
27619         echo "MDT blocks available: ${bavail[*]}"
27620         echo "weight diff=$diff%"
27621 }
27622
27623 test_qos_mkdir() {
27624         local mkdir_cmd=$1
27625         local stripe_count=$2
27626         local mdts=$(comma_list $(mdts_nodes))
27627
27628         local testdir
27629         local lmv_qos_prio_free
27630         local lmv_qos_threshold_rr
27631         local lod_qos_prio_free
27632         local lod_qos_threshold_rr
27633         local total
27634         local count
27635         local i
27636
27637         # @total is total directories created if it's testing plain
27638         # directories, otherwise it's total stripe object count for
27639         # striped directories test.
27640         # remote/striped directory unlinking is slow on zfs and may
27641         # timeout, test with fewer directories
27642         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27643
27644         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27645         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27646         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27647                 head -n1)
27648         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27649         stack_trap "$LCTL set_param \
27650                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27651         stack_trap "$LCTL set_param \
27652                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27653
27654         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27655                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27656         lod_qos_prio_free=${lod_qos_prio_free%%%}
27657         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27658                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27659         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27660         stack_trap "do_nodes $mdts $LCTL set_param \
27661                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27662         stack_trap "do_nodes $mdts $LCTL set_param \
27663                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27664
27665         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27666         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27667
27668         testdir=$DIR/$tdir-s$stripe_count/rr
27669
27670         local stripe_index=$($LFS getstripe -m $testdir)
27671         local test_mkdir_rr=true
27672
27673         getfattr -d -m dmv -e hex $testdir | grep dmv
27674         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27675                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27676                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27677                         test_mkdir_rr=false
27678         fi
27679
27680         echo
27681         $test_mkdir_rr &&
27682                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27683                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27684
27685         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27686         for (( i = 0; i < total / stripe_count; i++ )); do
27687                 eval $mkdir_cmd $testdir/subdir$i ||
27688                         error "$mkdir_cmd subdir$i failed"
27689         done
27690
27691         for (( i = 0; i < $MDSCOUNT; i++ )); do
27692                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27693                 echo "$count directories created on MDT$i"
27694                 if $test_mkdir_rr; then
27695                         (( count == total / stripe_count / MDSCOUNT )) ||
27696                                 error "subdirs are not evenly distributed"
27697                 elif (( i == stripe_index )); then
27698                         (( count == total / stripe_count )) ||
27699                                 error "$count subdirs created on MDT$i"
27700                 else
27701                         (( count == 0 )) ||
27702                                 error "$count subdirs created on MDT$i"
27703                 fi
27704
27705                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27706                         count=$($LFS getdirstripe $testdir/* |
27707                                 grep -c -P "^\s+$i\t")
27708                         echo "$count stripes created on MDT$i"
27709                         # deviation should < 5% of average
27710                         delta=$((count - total / MDSCOUNT))
27711                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27712                                 error "stripes are not evenly distributed"
27713                 fi
27714         done
27715
27716         echo
27717         echo "Check for uneven MDTs: "
27718
27719         local ffree
27720         local bavail
27721         local max
27722         local min
27723         local max_index
27724         local min_index
27725         local tmp
27726
27727         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27728         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27729         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27730
27731         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27732         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27733         max_index=0
27734         min_index=0
27735         for ((i = 1; i < ${#ffree[@]}; i++)); do
27736                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27737                 if [ $tmp -gt $max ]; then
27738                         max=$tmp
27739                         max_index=$i
27740                 fi
27741                 if [ $tmp -lt $min ]; then
27742                         min=$tmp
27743                         min_index=$i
27744                 fi
27745         done
27746         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27747
27748         (( min > 0 )) || skip "low space on MDT$min_index"
27749         (( ${ffree[min_index]} < 10000000 )) ||
27750                 skip "too many free files on MDT$min_index"
27751
27752         generate_uneven_mdts 120
27753
27754         echo "MDT filesfree available: ${ffree[*]}"
27755         echo "MDT blocks available: ${bavail[*]}"
27756         echo "weight diff=$(((max - min) * 100 / min))%"
27757         echo
27758         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27759
27760         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27761         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27762         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27763         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27764         # decrease statfs age, so that it can be updated in time
27765         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27766         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27767
27768         sleep 1
27769
27770         testdir=$DIR/$tdir-s$stripe_count/qos
27771
27772         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27773         for (( i = 0; i < total / stripe_count; i++ )); do
27774                 eval $mkdir_cmd $testdir/subdir$i ||
27775                         error "$mkdir_cmd subdir$i failed"
27776         done
27777
27778         max=0
27779         for (( i = 0; i < $MDSCOUNT; i++ )); do
27780                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27781                 (( count > max )) && max=$count
27782                 echo "$count directories created on MDT$i : curmax=$max"
27783         done
27784
27785         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27786
27787         # D-value should > 10% of average
27788         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27789                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27790
27791         # ditto for stripes
27792         if (( stripe_count > 1 )); then
27793                 max=0
27794                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27795                         count=$($LFS getdirstripe $testdir/* |
27796                                 grep -c -P "^\s+$i\t")
27797                         (( count > max )) && max=$count
27798                         echo "$count stripes created on MDT$i"
27799                 done
27800
27801                 min=$($LFS getdirstripe $testdir/* |
27802                         grep -c -P "^\s+$min_index\t")
27803                 (( max - min > total / MDSCOUNT / 10 )) ||
27804                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27805         fi
27806 }
27807
27808 most_full_mdt() {
27809         local ffree
27810         local bavail
27811         local bsize
27812         local min
27813         local min_index
27814         local tmp
27815
27816         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27817         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27818         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27819
27820         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27821         min_index=0
27822         for ((i = 1; i < ${#ffree[@]}; i++)); do
27823                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27824                 (( tmp < min )) && min=$tmp && min_index=$i
27825         done
27826
27827         echo -n $min_index
27828 }
27829
27830 test_413a() {
27831         [ $MDSCOUNT -lt 2 ] &&
27832                 skip "We need at least 2 MDTs for this test"
27833
27834         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27835                 skip "Need server version at least 2.12.52"
27836
27837         local stripe_max=$((MDSCOUNT - 1))
27838         local stripe_count
27839
27840         # let caller set maxage for latest result
27841         set_maxage 1
27842
27843         # fill MDT unevenly
27844         generate_uneven_mdts 120
27845
27846         # test 4-stripe directory at most, otherwise it's too slow
27847         # We are being very defensive. Although Autotest uses 4 MDTs.
27848         # We make sure stripe_max does not go over 4.
27849         (( stripe_max > 4 )) && stripe_max=4
27850         # unlinking striped directory is slow on zfs, and may timeout, only test
27851         # plain directory
27852         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27853         for stripe_count in $(seq 1 $stripe_max); do
27854                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27855                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27856                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27857                         error "mkdir failed"
27858                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27859         done
27860 }
27861 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27862
27863 test_413b() {
27864         [ $MDSCOUNT -lt 2 ] &&
27865                 skip "We need at least 2 MDTs for this test"
27866
27867         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27868                 skip "Need server version at least 2.12.52"
27869
27870         local stripe_max=$((MDSCOUNT - 1))
27871         local testdir
27872         local stripe_count
27873
27874         # let caller set maxage for latest result
27875         set_maxage 1
27876
27877         # fill MDT unevenly
27878         generate_uneven_mdts 120
27879
27880         # test 4-stripe directory at most, otherwise it's too slow
27881         # We are being very defensive. Although Autotest uses 4 MDTs.
27882         # We make sure stripe_max does not go over 4.
27883         (( stripe_max > 4 )) && stripe_max=4
27884         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27885         for stripe_count in $(seq 1 $stripe_max); do
27886                 testdir=$DIR/$tdir-s$stripe_count
27887                 mkdir $testdir || error "mkdir $testdir failed"
27888                 mkdir $testdir/rr || error "mkdir rr failed"
27889                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27890                         error "mkdir qos failed"
27891                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27892                         $testdir/rr || error "setdirstripe rr failed"
27893                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27894                         error "setdirstripe failed"
27895                 test_qos_mkdir "mkdir" $stripe_count
27896         done
27897 }
27898 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27899
27900 test_413c() {
27901         (( $MDSCOUNT >= 2 )) ||
27902                 skip "We need at least 2 MDTs for this test"
27903
27904         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27905                 skip "Need server version at least 2.14.51"
27906
27907         local testdir
27908         local inherit
27909         local inherit_rr
27910         local lmv_qos_maxage
27911         local lod_qos_maxage
27912
27913         # let caller set maxage for latest result
27914         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27915         $LCTL set_param lmv.*.qos_maxage=1
27916         stack_trap "$LCTL set_param \
27917                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27918         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27919                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27920         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27921                 lod.*.mdt_qos_maxage=1
27922         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27923                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27924
27925         # fill MDT unevenly
27926         generate_uneven_mdts 120
27927
27928         testdir=$DIR/${tdir}-s1
27929         mkdir $testdir || error "mkdir $testdir failed"
27930         mkdir $testdir/rr || error "mkdir rr failed"
27931         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27932         # default max_inherit is -1, default max_inherit_rr is 0
27933         $LFS setdirstripe -D -c 1 $testdir/rr ||
27934                 error "setdirstripe rr failed"
27935         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27936                 error "setdirstripe qos failed"
27937         test_qos_mkdir "mkdir" 1
27938
27939         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27940         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27941         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27942         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27943         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27944
27945         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27946         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27947         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27948         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27949         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27950         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27951         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27952                 error "level2 shouldn't have default LMV" || true
27953 }
27954 run_test 413c "mkdir with default LMV max inherit rr"
27955
27956 test_413d() {
27957         (( MDSCOUNT >= 2 )) ||
27958                 skip "We need at least 2 MDTs for this test"
27959
27960         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27961                 skip "Need server version at least 2.14.51"
27962
27963         local lmv_qos_threshold_rr
27964
27965         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27966                 head -n1)
27967         stack_trap "$LCTL set_param \
27968                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27969
27970         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27971         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27972         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27973                 error "$tdir shouldn't have default LMV"
27974         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27975                 error "mkdir sub failed"
27976
27977         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27978
27979         (( count == 100 )) || error "$count subdirs on MDT0"
27980 }
27981 run_test 413d "inherit ROOT default LMV"
27982
27983 test_413e() {
27984         (( MDSCOUNT >= 2 )) ||
27985                 skip "We need at least 2 MDTs for this test"
27986         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27987                 skip "Need server version at least 2.14.55"
27988
27989         local testdir=$DIR/$tdir
27990         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27991         local max_inherit
27992         local sub_max_inherit
27993
27994         mkdir -p $testdir || error "failed to create $testdir"
27995
27996         # set default max-inherit to -1 if stripe count is 0 or 1
27997         $LFS setdirstripe -D -c 1 $testdir ||
27998                 error "failed to set default LMV"
27999         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28000         (( max_inherit == -1 )) ||
28001                 error "wrong max_inherit value $max_inherit"
28002
28003         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28004         $LFS setdirstripe -D -c -1 $testdir ||
28005                 error "failed to set default LMV"
28006         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28007         (( max_inherit > 0 )) ||
28008                 error "wrong max_inherit value $max_inherit"
28009
28010         # and the subdir will decrease the max_inherit by 1
28011         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28012         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28013         (( sub_max_inherit == max_inherit - 1)) ||
28014                 error "wrong max-inherit of subdir $sub_max_inherit"
28015
28016         # check specified --max-inherit and warning message
28017         stack_trap "rm -f $tmpfile"
28018         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28019                 error "failed to set default LMV"
28020         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28021         (( max_inherit == -1 )) ||
28022                 error "wrong max_inherit value $max_inherit"
28023
28024         # check the warning messages
28025         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28026                 error "failed to detect warning string"
28027         fi
28028 }
28029 run_test 413e "check default max-inherit value"
28030
28031 test_fs_dmv_inherit()
28032 {
28033         local testdir=$DIR/$tdir
28034
28035         local count
28036         local inherit
28037         local inherit_rr
28038
28039         for i in 1 2; do
28040                 mkdir $testdir || error "mkdir $testdir failed"
28041                 count=$($LFS getdirstripe -D -c $testdir)
28042                 (( count == 1 )) ||
28043                         error "$testdir default LMV count mismatch $count != 1"
28044                 inherit=$($LFS getdirstripe -D -X $testdir)
28045                 (( inherit == 3 - i )) ||
28046                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28047                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28048                 (( inherit_rr == 3 - i )) ||
28049                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28050                 testdir=$testdir/sub
28051         done
28052
28053         mkdir $testdir || error "mkdir $testdir failed"
28054         count=$($LFS getdirstripe -D -c $testdir)
28055         (( count == 0 )) ||
28056                 error "$testdir default LMV count not zero: $count"
28057 }
28058
28059 test_413f() {
28060         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28061
28062         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28063                 skip "Need server version at least 2.14.55"
28064
28065         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28066                 error "dump $DIR default LMV failed"
28067         stack_trap "setfattr --restore=$TMP/dmv.ea"
28068
28069         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28070                 error "set $DIR default LMV failed"
28071
28072         test_fs_dmv_inherit
28073 }
28074 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28075
28076 test_413g() {
28077         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28078
28079         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28080         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28081                 error "dump $DIR default LMV failed"
28082         stack_trap "setfattr --restore=$TMP/dmv.ea"
28083
28084         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28085                 error "set $DIR default LMV failed"
28086
28087         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28088                 error "mount $MOUNT2 failed"
28089         stack_trap "umount_client $MOUNT2"
28090
28091         local saved_DIR=$DIR
28092
28093         export DIR=$MOUNT2
28094
28095         stack_trap "export DIR=$saved_DIR"
28096
28097         # first check filesystem-wide default LMV inheritance
28098         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28099
28100         # then check subdirs are spread to all MDTs
28101         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28102
28103         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28104
28105         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28106 }
28107 run_test 413g "enforce ROOT default LMV on subdir mount"
28108
28109 test_413h() {
28110         (( MDSCOUNT >= 2 )) ||
28111                 skip "We need at least 2 MDTs for this test"
28112
28113         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28114                 skip "Need server version at least 2.15.50.6"
28115
28116         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28117
28118         stack_trap "$LCTL set_param \
28119                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28120         $LCTL set_param lmv.*.qos_maxage=1
28121
28122         local depth=5
28123         local rr_depth=4
28124         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28125         local count=$((MDSCOUNT * 20))
28126
28127         generate_uneven_mdts 50
28128
28129         mkdir -p $dir || error "mkdir $dir failed"
28130         stack_trap "rm -rf $dir"
28131         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28132                 --max-inherit-rr=$rr_depth $dir
28133
28134         for ((d=0; d < depth + 2; d++)); do
28135                 log "dir=$dir:"
28136                 for ((sub=0; sub < count; sub++)); do
28137                         mkdir $dir/d$sub
28138                 done
28139                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28140                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28141                 # subdirs within $rr_depth should be created round-robin
28142                 if (( d < rr_depth )); then
28143                         (( ${num[0]} != count )) ||
28144                                 error "all objects created on MDT ${num[1]}"
28145                 fi
28146
28147                 dir=$dir/d0
28148         done
28149 }
28150 run_test 413h "don't stick to parent for round-robin dirs"
28151
28152 test_413i() {
28153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28154
28155         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28156                 skip "Need server version at least 2.14.55"
28157
28158         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28159                 error "dump $DIR default LMV failed"
28160         stack_trap "setfattr --restore=$TMP/dmv.ea"
28161
28162         local testdir=$DIR/$tdir
28163         local def_max_rr=1
28164         local def_max=3
28165         local count
28166
28167         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28168                 --max-inherit-rr=$def_max_rr $DIR ||
28169                 error "set $DIR default LMV failed"
28170
28171         for i in $(seq 2 3); do
28172                 def_max=$((def_max - 1))
28173                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28174
28175                 mkdir $testdir
28176                 # RR is decremented and keeps zeroed once exhausted
28177                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28178                 (( count == def_max_rr )) ||
28179                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28180
28181                 # max-inherit is decremented
28182                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28183                 (( count == def_max )) ||
28184                         error_noexit "$testdir: max-inherit $count != $def_max"
28185
28186                 testdir=$testdir/d$i
28187         done
28188
28189         # d3 is the last inherited from ROOT, no inheritance anymore
28190         # i.e. no the default layout anymore
28191         mkdir -p $testdir/d4/d5
28192         count=$($LFS getdirstripe -D --max-inherit $testdir)
28193         (( count == -1 )) ||
28194                 error_noexit "$testdir: max-inherit $count != -1"
28195
28196         local p_count=$($LFS getdirstripe -i $testdir)
28197
28198         for i in $(seq 4 5); do
28199                 testdir=$testdir/d$i
28200
28201                 # the root default layout is not applied once exhausted
28202                 count=$($LFS getdirstripe -i $testdir)
28203                 (( count == p_count )) ||
28204                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28205         done
28206
28207         $LFS setdirstripe -i 0 $DIR/d2
28208         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28209         (( count == -1 )) ||
28210                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28211 }
28212 run_test 413i "check default layout inheritance"
28213
28214 test_413z() {
28215         local pids=""
28216         local subdir
28217         local pid
28218
28219         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28220                 unlinkmany $subdir/f. $TEST413_COUNT &
28221                 pids="$pids $!"
28222         done
28223
28224         for pid in $pids; do
28225                 wait $pid
28226         done
28227
28228         true
28229 }
28230 run_test 413z "413 test cleanup"
28231
28232 test_414() {
28233 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28234         $LCTL set_param fail_loc=0x80000521
28235         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28236         rm -f $DIR/$tfile
28237 }
28238 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28239
28240 test_415() {
28241         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28242         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28243                 skip "Need server version at least 2.11.52"
28244
28245         # LU-11102
28246         local total=500
28247         local max=120
28248
28249         # this test may be slow on ZFS
28250         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28251
28252         # though this test is designed for striped directory, let's test normal
28253         # directory too since lock is always saved as CoS lock.
28254         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28255         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28256         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28257         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28258         wait_delete_completed_mds
28259
28260         # run a loop without concurrent touch to measure rename duration.
28261         # only for test debug/robustness, NOT part of COS functional test.
28262         local start_time=$SECONDS
28263         for ((i = 0; i < total; i++)); do
28264                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28265                         > /dev/null
28266         done
28267         local baseline=$((SECONDS - start_time))
28268         echo "rename $total files without 'touch' took $baseline sec"
28269
28270         (
28271                 while true; do
28272                         touch $DIR/$tdir
28273                 done
28274         ) &
28275         local setattr_pid=$!
28276
28277         # rename files back to original name so unlinkmany works
28278         start_time=$SECONDS
28279         for ((i = 0; i < total; i++)); do
28280                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28281                         > /dev/null
28282         done
28283         local duration=$((SECONDS - start_time))
28284
28285         kill -9 $setattr_pid
28286
28287         echo "rename $total files with 'touch' took $duration sec"
28288         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28289         (( duration <= max )) ||
28290                 error_not_in_vm "rename took $duration > $max sec"
28291 }
28292 run_test 415 "lock revoke is not missing"
28293
28294 test_416() {
28295         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28296                 skip "Need server version at least 2.11.55"
28297
28298         # define OBD_FAIL_OSD_TXN_START    0x19a
28299         do_facet mds1 lctl set_param fail_loc=0x19a
28300
28301         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28302
28303         true
28304 }
28305 run_test 416 "transaction start failure won't cause system hung"
28306
28307 cleanup_417() {
28308         trap 0
28309         do_nodes $(comma_list $(mdts_nodes)) \
28310                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28311         do_nodes $(comma_list $(mdts_nodes)) \
28312                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28313         do_nodes $(comma_list $(mdts_nodes)) \
28314                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28315 }
28316
28317 test_417() {
28318         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28319         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28320                 skip "Need MDS version at least 2.11.56"
28321
28322         trap cleanup_417 RETURN EXIT
28323
28324         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28325         do_nodes $(comma_list $(mdts_nodes)) \
28326                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28327         $LFS migrate -m 0 $DIR/$tdir.1 &&
28328                 error "migrate dir $tdir.1 should fail"
28329
28330         do_nodes $(comma_list $(mdts_nodes)) \
28331                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28332         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28333                 error "create remote dir $tdir.2 should fail"
28334
28335         do_nodes $(comma_list $(mdts_nodes)) \
28336                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28337         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28338                 error "create striped dir $tdir.3 should fail"
28339         true
28340 }
28341 run_test 417 "disable remote dir, striped dir and dir migration"
28342
28343 # Checks that the outputs of df [-i] and lfs df [-i] match
28344 #
28345 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28346 check_lfs_df() {
28347         local dir=$2
28348         local inodes
28349         local df_out
28350         local lfs_df_out
28351         local count
28352         local passed=false
28353
28354         # blocks or inodes
28355         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28356
28357         for count in {1..100}; do
28358                 do_nodes "$CLIENTS" \
28359                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28360                 sync; sleep 0.2
28361
28362                 # read the lines of interest
28363                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28364                         error "df $inodes $dir | tail -n +2 failed"
28365                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28366                         error "lfs df $inodes $dir | grep summary: failed"
28367
28368                 # skip first substrings of each output as they are different
28369                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28370                 # compare the two outputs
28371                 passed=true
28372                 #  skip "available" on MDT until LU-13997 is fixed.
28373                 #for i in {1..5}; do
28374                 for i in 1 2 4 5; do
28375                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28376                 done
28377                 $passed && break
28378         done
28379
28380         if ! $passed; then
28381                 df -P $inodes $dir
28382                 echo
28383                 lfs df $inodes $dir
28384                 error "df and lfs df $1 output mismatch: "      \
28385                       "df ${inodes}: ${df_out[*]}, "            \
28386                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28387         fi
28388 }
28389
28390 test_418() {
28391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28392
28393         local dir=$DIR/$tdir
28394         local numfiles=$((RANDOM % 4096 + 2))
28395         local numblocks=$((RANDOM % 256 + 1))
28396
28397         wait_delete_completed
28398         test_mkdir $dir
28399
28400         # check block output
28401         check_lfs_df blocks $dir
28402         # check inode output
28403         check_lfs_df inodes $dir
28404
28405         # create a single file and retest
28406         echo "Creating a single file and testing"
28407         createmany -o $dir/$tfile- 1 &>/dev/null ||
28408                 error "creating 1 file in $dir failed"
28409         check_lfs_df blocks $dir
28410         check_lfs_df inodes $dir
28411
28412         # create a random number of files
28413         echo "Creating $((numfiles - 1)) files and testing"
28414         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28415                 error "creating $((numfiles - 1)) files in $dir failed"
28416
28417         # write a random number of blocks to the first test file
28418         echo "Writing $numblocks 4K blocks and testing"
28419         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28420                 count=$numblocks &>/dev/null ||
28421                 error "dd to $dir/${tfile}-0 failed"
28422
28423         # retest
28424         check_lfs_df blocks $dir
28425         check_lfs_df inodes $dir
28426
28427         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28428                 error "unlinking $numfiles files in $dir failed"
28429 }
28430 run_test 418 "df and lfs df outputs match"
28431
28432 test_419()
28433 {
28434         local dir=$DIR/$tdir
28435
28436         mkdir -p $dir
28437         touch $dir/file
28438
28439         cancel_lru_locks mdc
28440
28441         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28442         $LCTL set_param fail_loc=0x1410
28443         cat $dir/file
28444         $LCTL set_param fail_loc=0
28445         rm -rf $dir
28446 }
28447 run_test 419 "Verify open file by name doesn't crash kernel"
28448
28449 test_420()
28450 {
28451         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28452                 skip "Need MDS version at least 2.12.53"
28453
28454         local SAVE_UMASK=$(umask)
28455         local dir=$DIR/$tdir
28456         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28457
28458         mkdir -p $dir
28459         umask 0000
28460         mkdir -m03777 $dir/testdir
28461         ls -dn $dir/testdir
28462         # Need to remove trailing '.' when SELinux is enabled
28463         local dirperms=$(ls -dn $dir/testdir |
28464                          awk '{ sub(/\.$/, "", $1); print $1}')
28465         [ $dirperms == "drwxrwsrwt" ] ||
28466                 error "incorrect perms on $dir/testdir"
28467
28468         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28469                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28470         ls -n $dir/testdir/testfile
28471         local fileperms=$(ls -n $dir/testdir/testfile |
28472                           awk '{ sub(/\.$/, "", $1); print $1}')
28473         [ $fileperms == "-rwxr-xr-x" ] ||
28474                 error "incorrect perms on $dir/testdir/testfile"
28475
28476         umask $SAVE_UMASK
28477 }
28478 run_test 420 "clear SGID bit on non-directories for non-members"
28479
28480 test_421a() {
28481         local cnt
28482         local fid1
28483         local fid2
28484
28485         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28486                 skip "Need MDS version at least 2.12.54"
28487
28488         test_mkdir $DIR/$tdir
28489         createmany -o $DIR/$tdir/f 3
28490         cnt=$(ls -1 $DIR/$tdir | wc -l)
28491         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28492
28493         fid1=$(lfs path2fid $DIR/$tdir/f1)
28494         fid2=$(lfs path2fid $DIR/$tdir/f2)
28495         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28496
28497         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28498         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28499
28500         cnt=$(ls -1 $DIR/$tdir | wc -l)
28501         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28502
28503         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28504         createmany -o $DIR/$tdir/f 3
28505         cnt=$(ls -1 $DIR/$tdir | wc -l)
28506         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28507
28508         fid1=$(lfs path2fid $DIR/$tdir/f1)
28509         fid2=$(lfs path2fid $DIR/$tdir/f2)
28510         echo "remove using fsname $FSNAME"
28511         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28512
28513         cnt=$(ls -1 $DIR/$tdir | wc -l)
28514         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28515 }
28516 run_test 421a "simple rm by fid"
28517
28518 test_421b() {
28519         local cnt
28520         local FID1
28521         local FID2
28522
28523         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28524                 skip "Need MDS version at least 2.12.54"
28525
28526         test_mkdir $DIR/$tdir
28527         createmany -o $DIR/$tdir/f 3
28528         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28529         MULTIPID=$!
28530
28531         FID1=$(lfs path2fid $DIR/$tdir/f1)
28532         FID2=$(lfs path2fid $DIR/$tdir/f2)
28533         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28534
28535         kill -USR1 $MULTIPID
28536         wait
28537
28538         cnt=$(ls $DIR/$tdir | wc -l)
28539         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28540 }
28541 run_test 421b "rm by fid on open file"
28542
28543 test_421c() {
28544         local cnt
28545         local FIDS
28546
28547         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28548                 skip "Need MDS version at least 2.12.54"
28549
28550         test_mkdir $DIR/$tdir
28551         createmany -o $DIR/$tdir/f 3
28552         touch $DIR/$tdir/$tfile
28553         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28554         cnt=$(ls -1 $DIR/$tdir | wc -l)
28555         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28556
28557         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28558         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28559
28560         cnt=$(ls $DIR/$tdir | wc -l)
28561         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28562 }
28563 run_test 421c "rm by fid against hardlinked files"
28564
28565 test_421d() {
28566         local cnt
28567         local FIDS
28568
28569         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28570                 skip "Need MDS version at least 2.12.54"
28571
28572         test_mkdir $DIR/$tdir
28573         createmany -o $DIR/$tdir/f 4097
28574         cnt=$(ls -1 $DIR/$tdir | wc -l)
28575         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28576
28577         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28578         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28579
28580         cnt=$(ls $DIR/$tdir | wc -l)
28581         rm -rf $DIR/$tdir
28582         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28583 }
28584 run_test 421d "rmfid en masse"
28585
28586 test_421e() {
28587         local cnt
28588         local FID
28589
28590         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28591         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28592                 skip "Need MDS version at least 2.12.54"
28593
28594         mkdir -p $DIR/$tdir
28595         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28596         createmany -o $DIR/$tdir/striped_dir/f 512
28597         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28598         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28599
28600         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28601                 sed "s/[/][^:]*://g")
28602         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28603
28604         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28605         rm -rf $DIR/$tdir
28606         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28607 }
28608 run_test 421e "rmfid in DNE"
28609
28610 test_421f() {
28611         local cnt
28612         local FID
28613
28614         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28615                 skip "Need MDS version at least 2.12.54"
28616
28617         test_mkdir $DIR/$tdir
28618         touch $DIR/$tdir/f
28619         cnt=$(ls -1 $DIR/$tdir | wc -l)
28620         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28621
28622         FID=$(lfs path2fid $DIR/$tdir/f)
28623         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28624         # rmfid should fail
28625         cnt=$(ls -1 $DIR/$tdir | wc -l)
28626         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28627
28628         chmod a+rw $DIR/$tdir
28629         ls -la $DIR/$tdir
28630         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28631         # rmfid should fail
28632         cnt=$(ls -1 $DIR/$tdir | wc -l)
28633         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28634
28635         rm -f $DIR/$tdir/f
28636         $RUNAS touch $DIR/$tdir/f
28637         FID=$(lfs path2fid $DIR/$tdir/f)
28638         echo "rmfid as root"
28639         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28640         cnt=$(ls -1 $DIR/$tdir | wc -l)
28641         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28642
28643         rm -f $DIR/$tdir/f
28644         $RUNAS touch $DIR/$tdir/f
28645         cnt=$(ls -1 $DIR/$tdir | wc -l)
28646         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28647         FID=$(lfs path2fid $DIR/$tdir/f)
28648         # rmfid w/o user_fid2path mount option should fail
28649         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28650         cnt=$(ls -1 $DIR/$tdir | wc -l)
28651         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28652
28653         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28654         stack_trap "rmdir $tmpdir"
28655         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28656                 error "failed to mount client'"
28657         stack_trap "umount_client $tmpdir"
28658
28659         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28660         # rmfid should succeed
28661         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28662         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28663
28664         # rmfid shouldn't allow to remove files due to dir's permission
28665         chmod a+rwx $tmpdir/$tdir
28666         touch $tmpdir/$tdir/f
28667         ls -la $tmpdir/$tdir
28668         FID=$(lfs path2fid $tmpdir/$tdir/f)
28669         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28670         return 0
28671 }
28672 run_test 421f "rmfid checks permissions"
28673
28674 test_421g() {
28675         local cnt
28676         local FIDS
28677
28678         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28679         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28680                 skip "Need MDS version at least 2.12.54"
28681
28682         mkdir -p $DIR/$tdir
28683         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28684         createmany -o $DIR/$tdir/striped_dir/f 512
28685         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28686         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28687
28688         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28689                 sed "s/[/][^:]*://g")
28690
28691         rm -f $DIR/$tdir/striped_dir/f1*
28692         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28693         removed=$((512 - cnt))
28694
28695         # few files have been just removed, so we expect
28696         # rmfid to fail on their fids
28697         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28698         [ $removed != $errors ] && error "$errors != $removed"
28699
28700         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28701         rm -rf $DIR/$tdir
28702         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28703 }
28704 run_test 421g "rmfid to return errors properly"
28705
28706 test_421h() {
28707         local mount_other
28708         local mount_ret
28709         local rmfid_ret
28710         local old_fid
28711         local fidA
28712         local fidB
28713         local fidC
28714         local fidD
28715
28716         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28717                 skip "Need MDS version at least 2.15.53"
28718
28719         test_mkdir $DIR/$tdir
28720         test_mkdir $DIR/$tdir/subdir
28721         touch $DIR/$tdir/subdir/file0
28722         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28723         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28724         rm -f $DIR/$tdir/subdir/file0
28725         touch $DIR/$tdir/subdir/fileA
28726         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28727         echo File $DIR/$tdir/subdir/fileA FID $fidA
28728         touch $DIR/$tdir/subdir/fileB
28729         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28730         echo File $DIR/$tdir/subdir/fileB FID $fidB
28731         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28732         touch $DIR/$tdir/subdir/fileC
28733         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28734         echo File $DIR/$tdir/subdir/fileC FID $fidC
28735         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28736         touch $DIR/$tdir/fileD
28737         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28738         echo File $DIR/$tdir/fileD FID $fidD
28739
28740         # mount another client mount point with subdirectory mount
28741         export FILESET=/$tdir/subdir
28742         mount_other=${MOUNT}_other
28743         mount_client $mount_other ${MOUNT_OPTS}
28744         mount_ret=$?
28745         export FILESET=""
28746         (( mount_ret == 0 )) || error "mount $mount_other failed"
28747
28748         echo Removing FIDs:
28749         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28750         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28751         rmfid_ret=$?
28752
28753         umount_client $mount_other || error "umount $mount_other failed"
28754
28755         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28756
28757         # fileA should have been deleted
28758         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28759
28760         # fileB should have been deleted
28761         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28762
28763         # fileC should not have been deleted, fid also exists outside of fileset
28764         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28765
28766         # fileD should not have been deleted, it exists outside of fileset
28767         stat $DIR/$tdir/fileD || error "fileD deleted"
28768 }
28769 run_test 421h "rmfid with fileset mount"
28770
28771 test_422() {
28772         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28773         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28774         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28775         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28776         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28777
28778         local amc=$(at_max_get client)
28779         local amo=$(at_max_get mds1)
28780         local timeout=`lctl get_param -n timeout`
28781
28782         at_max_set 0 client
28783         at_max_set 0 mds1
28784
28785 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28786         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28787                         fail_val=$(((2*timeout + 10)*1000))
28788         touch $DIR/$tdir/d3/file &
28789         sleep 2
28790 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28791         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28792                         fail_val=$((2*timeout + 5))
28793         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28794         local pid=$!
28795         sleep 1
28796         kill -9 $pid
28797         sleep $((2 * timeout))
28798         echo kill $pid
28799         kill -9 $pid
28800         lctl mark touch
28801         touch $DIR/$tdir/d2/file3
28802         touch $DIR/$tdir/d2/file4
28803         touch $DIR/$tdir/d2/file5
28804
28805         wait
28806         at_max_set $amc client
28807         at_max_set $amo mds1
28808
28809         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28810         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28811                 error "Watchdog is always throttled"
28812 }
28813 run_test 422 "kill a process with RPC in progress"
28814
28815 stat_test() {
28816     df -h $MOUNT &
28817     df -h $MOUNT &
28818     df -h $MOUNT &
28819     df -h $MOUNT &
28820     df -h $MOUNT &
28821     df -h $MOUNT &
28822 }
28823
28824 test_423() {
28825     local _stats
28826     # ensure statfs cache is expired
28827     sleep 2;
28828
28829     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28830     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28831
28832     return 0
28833 }
28834 run_test 423 "statfs should return a right data"
28835
28836 test_424() {
28837 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28838         $LCTL set_param fail_loc=0x80000522
28839         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28840         rm -f $DIR/$tfile
28841 }
28842 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28843
28844 test_425() {
28845         test_mkdir -c -1 $DIR/$tdir
28846         $LFS setstripe -c -1 $DIR/$tdir
28847
28848         lru_resize_disable "" 100
28849         stack_trap "lru_resize_enable" EXIT
28850
28851         sleep 5
28852
28853         for i in $(seq $((MDSCOUNT * 125))); do
28854                 local t=$DIR/$tdir/$tfile_$i
28855
28856                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28857                         error_noexit "Create file $t"
28858         done
28859         stack_trap "rm -rf $DIR/$tdir" EXIT
28860
28861         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28862                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28863                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28864
28865                 [ $lock_count -le $lru_size ] ||
28866                         error "osc lock count $lock_count > lru size $lru_size"
28867         done
28868
28869         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28870                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28871                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28872
28873                 [ $lock_count -le $lru_size ] ||
28874                         error "mdc lock count $lock_count > lru size $lru_size"
28875         done
28876 }
28877 run_test 425 "lock count should not exceed lru size"
28878
28879 test_426() {
28880         splice-test -r $DIR/$tfile
28881         splice-test -rd $DIR/$tfile
28882         splice-test $DIR/$tfile
28883         splice-test -d $DIR/$tfile
28884 }
28885 run_test 426 "splice test on Lustre"
28886
28887 test_427() {
28888         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28889         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28890                 skip "Need MDS version at least 2.12.4"
28891         local log
28892
28893         mkdir $DIR/$tdir
28894         mkdir $DIR/$tdir/1
28895         mkdir $DIR/$tdir/2
28896         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28897         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28898
28899         $LFS getdirstripe $DIR/$tdir/1/dir
28900
28901         #first setfattr for creating updatelog
28902         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28903
28904 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28905         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28906         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28907         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28908
28909         sleep 2
28910         fail mds2
28911         wait_recovery_complete mds2 $((2*TIMEOUT))
28912
28913         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28914         echo $log | grep "get update log failed" &&
28915                 error "update log corruption is detected" || true
28916 }
28917 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28918
28919 test_428() {
28920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28921         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
28922                               awk '/^max_cached_mb/ { print $2 }')
28923         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
28924
28925         $LCTL set_param -n llite.*.max_cached_mb=64
28926
28927         mkdir $DIR/$tdir
28928         $LFS setstripe -c 1 $DIR/$tdir
28929         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28930         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28931         #test write
28932         for f in $(seq 4); do
28933                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28934         done
28935         wait
28936
28937         cancel_lru_locks osc
28938         # Test read
28939         for f in $(seq 4); do
28940                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28941         done
28942         wait
28943 }
28944 run_test 428 "large block size IO should not hang"
28945
28946 test_429() { # LU-7915 / LU-10948
28947         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28948         local testfile=$DIR/$tfile
28949         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28950         local new_flag=1
28951         local first_rpc
28952         local second_rpc
28953         local third_rpc
28954
28955         $LCTL get_param $ll_opencache_threshold_count ||
28956                 skip "client does not have opencache parameter"
28957
28958         set_opencache $new_flag
28959         stack_trap "restore_opencache"
28960         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28961                 error "enable opencache failed"
28962         touch $testfile
28963         # drop MDC DLM locks
28964         cancel_lru_locks mdc
28965         # clear MDC RPC stats counters
28966         $LCTL set_param $mdc_rpcstats=clear
28967
28968         # According to the current implementation, we need to run 3 times
28969         # open & close file to verify if opencache is enabled correctly.
28970         # 1st, RPCs are sent for lookup/open and open handle is released on
28971         #      close finally.
28972         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28973         #      so open handle won't be released thereafter.
28974         # 3rd, No RPC is sent out.
28975         $MULTIOP $testfile oc || error "multiop failed"
28976         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28977         echo "1st: $first_rpc RPCs in flight"
28978
28979         $MULTIOP $testfile oc || error "multiop failed"
28980         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28981         echo "2nd: $second_rpc RPCs in flight"
28982
28983         $MULTIOP $testfile oc || error "multiop failed"
28984         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28985         echo "3rd: $third_rpc RPCs in flight"
28986
28987         #verify no MDC RPC is sent
28988         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28989 }
28990 run_test 429 "verify if opencache flag on client side does work"
28991
28992 lseek_test_430() {
28993         local offset
28994         local file=$1
28995
28996         # data at [200K, 400K)
28997         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28998                 error "256K->512K dd fails"
28999         # data at [2M, 3M)
29000         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29001                 error "2M->3M dd fails"
29002         # data at [4M, 5M)
29003         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29004                 error "4M->5M dd fails"
29005         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29006         # start at first component hole #1
29007         printf "Seeking hole from 1000 ... "
29008         offset=$(lseek_test -l 1000 $file)
29009         echo $offset
29010         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29011         printf "Seeking data from 1000 ... "
29012         offset=$(lseek_test -d 1000 $file)
29013         echo $offset
29014         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29015
29016         # start at first component data block
29017         printf "Seeking hole from 300000 ... "
29018         offset=$(lseek_test -l 300000 $file)
29019         echo $offset
29020         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29021         printf "Seeking data from 300000 ... "
29022         offset=$(lseek_test -d 300000 $file)
29023         echo $offset
29024         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29025
29026         # start at the first component but beyond end of object size
29027         printf "Seeking hole from 1000000 ... "
29028         offset=$(lseek_test -l 1000000 $file)
29029         echo $offset
29030         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29031         printf "Seeking data from 1000000 ... "
29032         offset=$(lseek_test -d 1000000 $file)
29033         echo $offset
29034         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29035
29036         # start at second component stripe 2 (empty file)
29037         printf "Seeking hole from 1500000 ... "
29038         offset=$(lseek_test -l 1500000 $file)
29039         echo $offset
29040         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29041         printf "Seeking data from 1500000 ... "
29042         offset=$(lseek_test -d 1500000 $file)
29043         echo $offset
29044         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29045
29046         # start at second component stripe 1 (all data)
29047         printf "Seeking hole from 3000000 ... "
29048         offset=$(lseek_test -l 3000000 $file)
29049         echo $offset
29050         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29051         printf "Seeking data from 3000000 ... "
29052         offset=$(lseek_test -d 3000000 $file)
29053         echo $offset
29054         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29055
29056         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29057                 error "2nd dd fails"
29058         echo "Add data block at 640K...1280K"
29059
29060         # start at before new data block, in hole
29061         printf "Seeking hole from 600000 ... "
29062         offset=$(lseek_test -l 600000 $file)
29063         echo $offset
29064         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29065         printf "Seeking data from 600000 ... "
29066         offset=$(lseek_test -d 600000 $file)
29067         echo $offset
29068         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29069
29070         # start at the first component new data block
29071         printf "Seeking hole from 1000000 ... "
29072         offset=$(lseek_test -l 1000000 $file)
29073         echo $offset
29074         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29075         printf "Seeking data from 1000000 ... "
29076         offset=$(lseek_test -d 1000000 $file)
29077         echo $offset
29078         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29079
29080         # start at second component stripe 2, new data
29081         printf "Seeking hole from 1200000 ... "
29082         offset=$(lseek_test -l 1200000 $file)
29083         echo $offset
29084         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29085         printf "Seeking data from 1200000 ... "
29086         offset=$(lseek_test -d 1200000 $file)
29087         echo $offset
29088         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29089
29090         # start beyond file end
29091         printf "Using offset > filesize ... "
29092         lseek_test -l 4000000 $file && error "lseek should fail"
29093         printf "Using offset > filesize ... "
29094         lseek_test -d 4000000 $file && error "lseek should fail"
29095
29096         printf "Done\n\n"
29097 }
29098
29099 test_430a() {
29100         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29101                 skip "MDT does not support SEEK_HOLE"
29102
29103         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29104                 skip "OST does not support SEEK_HOLE"
29105
29106         local file=$DIR/$tdir/$tfile
29107
29108         mkdir -p $DIR/$tdir
29109
29110         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29111         # OST stripe #1 will have continuous data at [1M, 3M)
29112         # OST stripe #2 is empty
29113         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29114         lseek_test_430 $file
29115         rm $file
29116         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29117         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29118         lseek_test_430 $file
29119         rm $file
29120         $LFS setstripe -c2 -S 512K $file
29121         echo "Two stripes, stripe size 512K"
29122         lseek_test_430 $file
29123         rm $file
29124         # FLR with stale mirror
29125         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29126                        -N -c2 -S 1M $file
29127         echo "Mirrored file:"
29128         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29129         echo "Plain 2 stripes 1M"
29130         lseek_test_430 $file
29131         rm $file
29132 }
29133 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29134
29135 test_430b() {
29136         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29137                 skip "OST does not support SEEK_HOLE"
29138
29139         local offset
29140         local file=$DIR/$tdir/$tfile
29141
29142         mkdir -p $DIR/$tdir
29143         # Empty layout lseek should fail
29144         $MCREATE $file
29145         # seek from 0
29146         printf "Seeking hole from 0 ... "
29147         lseek_test -l 0 $file && error "lseek should fail"
29148         printf "Seeking data from 0 ... "
29149         lseek_test -d 0 $file && error "lseek should fail"
29150         rm $file
29151
29152         # 1M-hole file
29153         $LFS setstripe -E 1M -c2 -E eof $file
29154         $TRUNCATE $file 1048576
29155         printf "Seeking hole from 1000000 ... "
29156         offset=$(lseek_test -l 1000000 $file)
29157         echo $offset
29158         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29159         printf "Seeking data from 1000000 ... "
29160         lseek_test -d 1000000 $file && error "lseek should fail"
29161         rm $file
29162
29163         # full component followed by non-inited one
29164         $LFS setstripe -E 1M -c2 -E eof $file
29165         dd if=/dev/urandom of=$file bs=1M count=1
29166         printf "Seeking hole from 1000000 ... "
29167         offset=$(lseek_test -l 1000000 $file)
29168         echo $offset
29169         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29170         printf "Seeking hole from 1048576 ... "
29171         lseek_test -l 1048576 $file && error "lseek should fail"
29172         # init second component and truncate back
29173         echo "123" >> $file
29174         $TRUNCATE $file 1048576
29175         printf "Seeking hole from 1000000 ... "
29176         offset=$(lseek_test -l 1000000 $file)
29177         echo $offset
29178         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29179         printf "Seeking hole from 1048576 ... "
29180         lseek_test -l 1048576 $file && error "lseek should fail"
29181         # boundary checks for big values
29182         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29183         offset=$(lseek_test -d 0 $file.10g)
29184         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29185         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29186         offset=$(lseek_test -d 0 $file.100g)
29187         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29188         return 0
29189 }
29190 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29191
29192 test_430c() {
29193         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29194                 skip "OST does not support SEEK_HOLE"
29195
29196         local file=$DIR/$tdir/$tfile
29197         local start
29198
29199         mkdir -p $DIR/$tdir
29200         stack_trap "rm -f $file $file.tmp"
29201         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29202
29203         # cp version 8.33+ prefers lseek over fiemap
29204         local ver=$(cp --version | awk '{ print $4; exit; }')
29205
29206         echo "cp $ver installed"
29207         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29208                 start=$SECONDS
29209                 time cp -v $file $file.tmp || error "cp $file failed"
29210                 (( SECONDS - start < 5 )) || {
29211                         strace cp $file $file.tmp |&
29212                                 grep -E "open|read|seek|FIEMAP" |
29213                                 grep -A 100 $file
29214                         error "cp: too long runtime $((SECONDS - start))"
29215                 }
29216         else
29217                 echo "cp test skipped due to $ver < 8.33"
29218         fi
29219
29220         # tar version 1.29+ supports SEEK_HOLE/DATA
29221         ver=$(tar --version | awk '{ print $4; exit; }')
29222         echo "tar $ver installed"
29223         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29224                 start=$SECONDS
29225                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29226                 (( SECONDS - start < 5 )) || {
29227                         strace tar cf $file.tmp --sparse $file |&
29228                                 grep -E "open|read|seek|FIEMAP" |
29229                                 grep -A 100 $file
29230                         error "tar: too long runtime $((SECONDS - start))"
29231                 }
29232         else
29233                 echo "tar test skipped due to $ver < 1.29"
29234         fi
29235 }
29236 run_test 430c "lseek: external tools check"
29237
29238 test_431() { # LU-14187
29239         local file=$DIR/$tdir/$tfile
29240
29241         mkdir -p $DIR/$tdir
29242         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29243         dd if=/dev/urandom of=$file bs=4k count=1
29244         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29245         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29246         #define OBD_FAIL_OST_RESTART_IO 0x251
29247         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29248         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29249         cp $file $file.0
29250         cancel_lru_locks
29251         sync_all_data
29252         echo 3 > /proc/sys/vm/drop_caches
29253         diff  $file $file.0 || error "data diff"
29254 }
29255 run_test 431 "Restart transaction for IO"
29256
29257 cleanup_test_432() {
29258         do_facet mgs $LCTL nodemap_activate 0
29259         wait_nm_sync active
29260 }
29261
29262 test_432() {
29263         local tmpdir=$TMP/dir432
29264
29265         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29266                 skip "Need MDS version at least 2.14.52"
29267
29268         stack_trap cleanup_test_432 EXIT
29269         mkdir $DIR/$tdir
29270         mkdir $tmpdir
29271
29272         do_facet mgs $LCTL nodemap_activate 1
29273         wait_nm_sync active
29274         do_facet mgs $LCTL nodemap_modify --name default \
29275                 --property admin --value 1
29276         do_facet mgs $LCTL nodemap_modify --name default \
29277                 --property trusted --value 1
29278         cancel_lru_locks mdc
29279         wait_nm_sync default admin_nodemap
29280         wait_nm_sync default trusted_nodemap
29281
29282         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29283                grep -ci "Operation not permitted") -ne 0 ]; then
29284                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29285         fi
29286 }
29287 run_test 432 "mv dir from outside Lustre"
29288
29289 test_433() {
29290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29291
29292         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29293                 skip "inode cache not supported"
29294
29295         $LCTL set_param llite.*.inode_cache=0
29296         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29297
29298         local count=256
29299         local before
29300         local after
29301
29302         cancel_lru_locks mdc
29303         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29304         createmany -m $DIR/$tdir/f $count
29305         createmany -d $DIR/$tdir/d $count
29306         ls -l $DIR/$tdir > /dev/null
29307         stack_trap "rm -rf $DIR/$tdir"
29308
29309         before=$(num_objects)
29310         cancel_lru_locks mdc
29311         after=$(num_objects)
29312
29313         # sometimes even @before is less than 2 * count
29314         while (( before - after < count )); do
29315                 sleep 1
29316                 after=$(num_objects)
29317                 wait=$((wait + 1))
29318                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29319                 if (( wait > 60 )); then
29320                         error "inode slab grew from $before to $after"
29321                 fi
29322         done
29323
29324         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29325 }
29326 run_test 433 "ldlm lock cancel releases dentries and inodes"
29327
29328 test_434() {
29329         local file
29330         local getxattr_count
29331         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29332         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29333
29334         [[ $(getenforce) == "Disabled" ]] ||
29335                 skip "lsm selinux module have to be disabled for this test"
29336
29337         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29338                 error "fail to create $DIR/$tdir/ on MDT0000"
29339
29340         touch $DIR/$tdir/$tfile-{001..100}
29341
29342         # disable the xattr cache
29343         save_lustre_params client "llite.*.xattr_cache" > $p
29344         lctl set_param llite.*.xattr_cache=0
29345         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29346
29347         # clear clients mdc stats
29348         clear_stats $mdc_stat_param ||
29349                 error "fail to clear stats on mdc MDT0000"
29350
29351         for file in $DIR/$tdir/$tfile-{001..100}; do
29352                 getfattr -n security.selinux $file |&
29353                         grep -q "Operation not supported" ||
29354                         error "getxattr on security.selinux should return EOPNOTSUPP"
29355         done
29356
29357         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29358         (( getxattr_count < 100 )) ||
29359                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29360 }
29361 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29362
29363 test_440() {
29364         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29365                 source $LUSTRE/scripts/bash-completion/lustre
29366         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29367                 source /usr/share/bash-completion/completions/lustre
29368         else
29369                 skip "bash completion scripts not found"
29370         fi
29371
29372         local lctl_completions
29373         local lfs_completions
29374
29375         lctl_completions=$(_lustre_cmds lctl)
29376         if [[ ! $lctl_completions =~ "get_param" ]]; then
29377                 error "lctl bash completion failed"
29378         fi
29379
29380         lfs_completions=$(_lustre_cmds lfs)
29381         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29382                 error "lfs bash completion failed"
29383         fi
29384 }
29385 run_test 440 "bash completion for lfs, lctl"
29386
29387 prep_801() {
29388         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29389         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29390                 skip "Need server version at least 2.9.55"
29391
29392         start_full_debug_logging
29393 }
29394
29395 post_801() {
29396         stop_full_debug_logging
29397 }
29398
29399 barrier_stat() {
29400         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29401                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29402                            awk '/The barrier for/ { print $7 }')
29403                 echo $st
29404         else
29405                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29406                 echo \'$st\'
29407         fi
29408 }
29409
29410 barrier_expired() {
29411         local expired
29412
29413         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29414                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29415                           awk '/will be expired/ { print $7 }')
29416         else
29417                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29418         fi
29419
29420         echo $expired
29421 }
29422
29423 test_801a() {
29424         prep_801
29425
29426         echo "Start barrier_freeze at: $(date)"
29427         #define OBD_FAIL_BARRIER_DELAY          0x2202
29428         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29429         # Do not reduce barrier time - See LU-11873
29430         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29431
29432         sleep 2
29433         local b_status=$(barrier_stat)
29434         echo "Got barrier status at: $(date)"
29435         [ "$b_status" = "'freezing_p1'" ] ||
29436                 error "(1) unexpected barrier status $b_status"
29437
29438         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29439         wait
29440         b_status=$(barrier_stat)
29441         [ "$b_status" = "'frozen'" ] ||
29442                 error "(2) unexpected barrier status $b_status"
29443
29444         local expired=$(barrier_expired)
29445         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29446         sleep $((expired + 3))
29447
29448         b_status=$(barrier_stat)
29449         [ "$b_status" = "'expired'" ] ||
29450                 error "(3) unexpected barrier status $b_status"
29451
29452         # Do not reduce barrier time - See LU-11873
29453         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29454                 error "(4) fail to freeze barrier"
29455
29456         b_status=$(barrier_stat)
29457         [ "$b_status" = "'frozen'" ] ||
29458                 error "(5) unexpected barrier status $b_status"
29459
29460         echo "Start barrier_thaw at: $(date)"
29461         #define OBD_FAIL_BARRIER_DELAY          0x2202
29462         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29463         do_facet mgs $LCTL barrier_thaw $FSNAME &
29464
29465         sleep 2
29466         b_status=$(barrier_stat)
29467         echo "Got barrier status at: $(date)"
29468         [ "$b_status" = "'thawing'" ] ||
29469                 error "(6) unexpected barrier status $b_status"
29470
29471         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29472         wait
29473         b_status=$(barrier_stat)
29474         [ "$b_status" = "'thawed'" ] ||
29475                 error "(7) unexpected barrier status $b_status"
29476
29477         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29478         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29479         do_facet mgs $LCTL barrier_freeze $FSNAME
29480
29481         b_status=$(barrier_stat)
29482         [ "$b_status" = "'failed'" ] ||
29483                 error "(8) unexpected barrier status $b_status"
29484
29485         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29486         do_facet mgs $LCTL barrier_thaw $FSNAME
29487
29488         post_801
29489 }
29490 run_test 801a "write barrier user interfaces and stat machine"
29491
29492 test_801b() {
29493         prep_801
29494
29495         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29496         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29497         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29498         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29499         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29500
29501         cancel_lru_locks mdc
29502
29503         # 180 seconds should be long enough
29504         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29505
29506         local b_status=$(barrier_stat)
29507         [ "$b_status" = "'frozen'" ] ||
29508                 error "(6) unexpected barrier status $b_status"
29509
29510         mkdir $DIR/$tdir/d0/d10 &
29511         mkdir_pid=$!
29512
29513         touch $DIR/$tdir/d1/f13 &
29514         touch_pid=$!
29515
29516         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29517         ln_pid=$!
29518
29519         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29520         mv_pid=$!
29521
29522         rm -f $DIR/$tdir/d4/f12 &
29523         rm_pid=$!
29524
29525         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29526
29527         # To guarantee taht the 'stat' is not blocked
29528         b_status=$(barrier_stat)
29529         [ "$b_status" = "'frozen'" ] ||
29530                 error "(8) unexpected barrier status $b_status"
29531
29532         # let above commands to run at background
29533         sleep 5
29534
29535         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29536         ps -p $touch_pid || error "(10) touch should be blocked"
29537         ps -p $ln_pid || error "(11) link should be blocked"
29538         ps -p $mv_pid || error "(12) rename should be blocked"
29539         ps -p $rm_pid || error "(13) unlink should be blocked"
29540
29541         b_status=$(barrier_stat)
29542         [ "$b_status" = "'frozen'" ] ||
29543                 error "(14) unexpected barrier status $b_status"
29544
29545         do_facet mgs $LCTL barrier_thaw $FSNAME
29546         b_status=$(barrier_stat)
29547         [ "$b_status" = "'thawed'" ] ||
29548                 error "(15) unexpected barrier status $b_status"
29549
29550         wait $mkdir_pid || error "(16) mkdir should succeed"
29551         wait $touch_pid || error "(17) touch should succeed"
29552         wait $ln_pid || error "(18) link should succeed"
29553         wait $mv_pid || error "(19) rename should succeed"
29554         wait $rm_pid || error "(20) unlink should succeed"
29555
29556         post_801
29557 }
29558 run_test 801b "modification will be blocked by write barrier"
29559
29560 test_801c() {
29561         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29562
29563         prep_801
29564
29565         stop mds2 || error "(1) Fail to stop mds2"
29566
29567         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29568
29569         local b_status=$(barrier_stat)
29570         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29571                 do_facet mgs $LCTL barrier_thaw $FSNAME
29572                 error "(2) unexpected barrier status $b_status"
29573         }
29574
29575         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29576                 error "(3) Fail to rescan barrier bitmap"
29577
29578         # Do not reduce barrier time - See LU-11873
29579         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29580
29581         b_status=$(barrier_stat)
29582         [ "$b_status" = "'frozen'" ] ||
29583                 error "(4) unexpected barrier status $b_status"
29584
29585         do_facet mgs $LCTL barrier_thaw $FSNAME
29586         b_status=$(barrier_stat)
29587         [ "$b_status" = "'thawed'" ] ||
29588                 error "(5) unexpected barrier status $b_status"
29589
29590         local devname=$(mdsdevname 2)
29591
29592         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29593
29594         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29595                 error "(7) Fail to rescan barrier bitmap"
29596
29597         post_801
29598 }
29599 run_test 801c "rescan barrier bitmap"
29600
29601 test_802b() {
29602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29603         remote_mds_nodsh && skip "remote MDS with nodsh"
29604
29605         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29606                 skip "readonly option not available"
29607
29608         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29609
29610         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29611                 error "(2) Fail to copy"
29612
29613         # write back all cached data before setting MDT to readonly
29614         cancel_lru_locks
29615         sync_all_data
29616
29617         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29618         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29619
29620         echo "Modify should be refused"
29621         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29622
29623         echo "Read should be allowed"
29624         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29625                 error "(7) Read should succeed under ro mode"
29626
29627         # disable readonly
29628         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29629 }
29630 run_test 802b "be able to set MDTs to readonly"
29631
29632 test_803a() {
29633         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29634         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29635                 skip "MDS needs to be newer than 2.10.54"
29636
29637         mkdir_on_mdt0 $DIR/$tdir
29638         # Create some objects on all MDTs to trigger related logs objects
29639         for idx in $(seq $MDSCOUNT); do
29640                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29641                         $DIR/$tdir/dir${idx} ||
29642                         error "Fail to create $DIR/$tdir/dir${idx}"
29643         done
29644
29645         wait_delete_completed # ensure old test cleanups are finished
29646         sleep 3
29647         echo "before create:"
29648         $LFS df -i $MOUNT
29649         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29650
29651         for i in {1..10}; do
29652                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29653                         error "Fail to create $DIR/$tdir/foo$i"
29654         done
29655
29656         # sync ZFS-on-MDS to refresh statfs data
29657         wait_zfs_commit mds1
29658         sleep 3
29659         echo "after create:"
29660         $LFS df -i $MOUNT
29661         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29662
29663         # allow for an llog to be cleaned up during the test
29664         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29665                 error "before ($before_used) + 10 > after ($after_used)"
29666
29667         for i in {1..10}; do
29668                 rm -rf $DIR/$tdir/foo$i ||
29669                         error "Fail to remove $DIR/$tdir/foo$i"
29670         done
29671
29672         # sync ZFS-on-MDS to refresh statfs data
29673         wait_zfs_commit mds1
29674         wait_delete_completed
29675         sleep 3 # avoid MDT return cached statfs
29676         echo "after unlink:"
29677         $LFS df -i $MOUNT
29678         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29679
29680         # allow for an llog to be created during the test
29681         [ $after_used -le $((before_used + 1)) ] ||
29682                 error "after ($after_used) > before ($before_used) + 1"
29683 }
29684 run_test 803a "verify agent object for remote object"
29685
29686 test_803b() {
29687         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29688         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29689                 skip "MDS needs to be newer than 2.13.56"
29690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29691
29692         for i in $(seq 0 $((MDSCOUNT - 1))); do
29693                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29694         done
29695
29696         local before=0
29697         local after=0
29698
29699         local tmp
29700
29701         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29702         for i in $(seq 0 $((MDSCOUNT - 1))); do
29703                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29704                         awk '/getattr/ { print $2 }')
29705                 before=$((before + tmp))
29706         done
29707         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29708         for i in $(seq 0 $((MDSCOUNT - 1))); do
29709                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29710                         awk '/getattr/ { print $2 }')
29711                 after=$((after + tmp))
29712         done
29713
29714         [ $before -eq $after ] || error "getattr count $before != $after"
29715 }
29716 run_test 803b "remote object can getattr from cache"
29717
29718 test_804() {
29719         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29720         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29721                 skip "MDS needs to be newer than 2.10.54"
29722         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29723
29724         mkdir -p $DIR/$tdir
29725         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29726                 error "Fail to create $DIR/$tdir/dir0"
29727
29728         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29729         local dev=$(mdsdevname 2)
29730
29731         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29732                 grep ${fid} || error "NOT found agent entry for dir0"
29733
29734         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29735                 error "Fail to create $DIR/$tdir/dir1"
29736
29737         touch $DIR/$tdir/dir1/foo0 ||
29738                 error "Fail to create $DIR/$tdir/dir1/foo0"
29739         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29740         local rc=0
29741
29742         for idx in $(seq $MDSCOUNT); do
29743                 dev=$(mdsdevname $idx)
29744                 do_facet mds${idx} \
29745                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29746                         grep ${fid} && rc=$idx
29747         done
29748
29749         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29750                 error "Fail to rename foo0 to foo1"
29751         if [ $rc -eq 0 ]; then
29752                 for idx in $(seq $MDSCOUNT); do
29753                         dev=$(mdsdevname $idx)
29754                         do_facet mds${idx} \
29755                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29756                         grep ${fid} && rc=$idx
29757                 done
29758         fi
29759
29760         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29761                 error "Fail to rename foo1 to foo2"
29762         if [ $rc -eq 0 ]; then
29763                 for idx in $(seq $MDSCOUNT); do
29764                         dev=$(mdsdevname $idx)
29765                         do_facet mds${idx} \
29766                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29767                         grep ${fid} && rc=$idx
29768                 done
29769         fi
29770
29771         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29772
29773         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29774                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29775         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29776                 error "Fail to rename foo2 to foo0"
29777         unlink $DIR/$tdir/dir1/foo0 ||
29778                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29779         rm -rf $DIR/$tdir/dir0 ||
29780                 error "Fail to rm $DIR/$tdir/dir0"
29781
29782         for idx in $(seq $MDSCOUNT); do
29783                 rc=0
29784
29785                 stop mds${idx}
29786                 dev=$(mdsdevname $idx)
29787                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29788                         rc=$?
29789                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29790                         error "mount mds$idx failed"
29791                 df $MOUNT > /dev/null 2>&1
29792
29793                 # e2fsck should not return error
29794                 [ $rc -eq 0 ] ||
29795                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29796         done
29797 }
29798 run_test 804 "verify agent entry for remote entry"
29799
29800 cleanup_805() {
29801         do_facet $SINGLEMDS zfs set quota=$old $fsset
29802         unlinkmany $DIR/$tdir/f- 1000000
29803         trap 0
29804 }
29805
29806 test_805() {
29807         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29808         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29809         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29810                 skip "netfree not implemented before 0.7"
29811         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29812                 skip "Need MDS version at least 2.10.57"
29813
29814         local fsset
29815         local freekb
29816         local usedkb
29817         local old
29818         local quota
29819         local pref="osd-zfs.$FSNAME-MDT0000."
29820
29821         # limit available space on MDS dataset to meet nospace issue
29822         # quickly. then ZFS 0.7.2 can use reserved space if asked
29823         # properly (using netfree flag in osd_declare_destroy()
29824         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29825         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29826                 gawk '{print $3}')
29827         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29828         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29829         let "usedkb=usedkb-freekb"
29830         let "freekb=freekb/2"
29831         if let "freekb > 5000"; then
29832                 let "freekb=5000"
29833         fi
29834         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29835         trap cleanup_805 EXIT
29836         mkdir_on_mdt0 $DIR/$tdir
29837         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29838                 error "Can't set PFL layout"
29839         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29840         rm -rf $DIR/$tdir || error "not able to remove"
29841         do_facet $SINGLEMDS zfs set quota=$old $fsset
29842         trap 0
29843 }
29844 run_test 805 "ZFS can remove from full fs"
29845
29846 # Size-on-MDS test
29847 check_lsom_data()
29848 {
29849         local file=$1
29850         local expect=$(stat -c %s $file)
29851
29852         check_lsom_size $1 $expect
29853
29854         local blocks=$($LFS getsom -b $file)
29855         expect=$(stat -c %b $file)
29856         [[ $blocks == $expect ]] ||
29857                 error "$file expected blocks: $expect, got: $blocks"
29858 }
29859
29860 check_lsom_size()
29861 {
29862         local size
29863         local expect=$2
29864
29865         cancel_lru_locks mdc
29866
29867         size=$($LFS getsom -s $1)
29868         [[ $size == $expect ]] ||
29869                 error "$file expected size: $expect, got: $size"
29870 }
29871
29872 test_806() {
29873         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29874                 skip "Need MDS version at least 2.11.52"
29875
29876         local bs=1048576
29877
29878         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29879
29880         disable_opencache
29881         stack_trap "restore_opencache"
29882
29883         # single-threaded write
29884         echo "Test SOM for single-threaded write"
29885         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29886                 error "write $tfile failed"
29887         check_lsom_size $DIR/$tfile $bs
29888
29889         local num=32
29890         local size=$(($num * $bs))
29891         local offset=0
29892         local i
29893
29894         echo "Test SOM for single client multi-threaded($num) write"
29895         $TRUNCATE $DIR/$tfile 0
29896         for ((i = 0; i < $num; i++)); do
29897                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29898                 local pids[$i]=$!
29899                 offset=$((offset + $bs))
29900         done
29901         for (( i=0; i < $num; i++ )); do
29902                 wait ${pids[$i]}
29903         done
29904         check_lsom_size $DIR/$tfile $size
29905
29906         $TRUNCATE $DIR/$tfile 0
29907         for ((i = 0; i < $num; i++)); do
29908                 offset=$((offset - $bs))
29909                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29910                 local pids[$i]=$!
29911         done
29912         for (( i=0; i < $num; i++ )); do
29913                 wait ${pids[$i]}
29914         done
29915         check_lsom_size $DIR/$tfile $size
29916
29917         # multi-client writes
29918         num=$(get_node_count ${CLIENTS//,/ })
29919         size=$(($num * $bs))
29920         offset=0
29921         i=0
29922
29923         echo "Test SOM for multi-client ($num) writes"
29924         $TRUNCATE $DIR/$tfile 0
29925         for client in ${CLIENTS//,/ }; do
29926                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29927                 local pids[$i]=$!
29928                 i=$((i + 1))
29929                 offset=$((offset + $bs))
29930         done
29931         for (( i=0; i < $num; i++ )); do
29932                 wait ${pids[$i]}
29933         done
29934         check_lsom_size $DIR/$tfile $offset
29935
29936         i=0
29937         $TRUNCATE $DIR/$tfile 0
29938         for client in ${CLIENTS//,/ }; do
29939                 offset=$((offset - $bs))
29940                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29941                 local pids[$i]=$!
29942                 i=$((i + 1))
29943         done
29944         for (( i=0; i < $num; i++ )); do
29945                 wait ${pids[$i]}
29946         done
29947         check_lsom_size $DIR/$tfile $size
29948
29949         # verify SOM blocks count
29950         echo "Verify SOM block count"
29951         $TRUNCATE $DIR/$tfile 0
29952         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29953                 error "failed to write file $tfile with fdatasync and fstat"
29954         check_lsom_data $DIR/$tfile
29955
29956         $TRUNCATE $DIR/$tfile 0
29957         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29958                 error "failed to write file $tfile with fdatasync"
29959         check_lsom_data $DIR/$tfile
29960
29961         $TRUNCATE $DIR/$tfile 0
29962         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29963                 error "failed to write file $tfile with sync IO"
29964         check_lsom_data $DIR/$tfile
29965
29966         # verify truncate
29967         echo "Test SOM for truncate"
29968         # use ftruncate to sync blocks on close request
29969         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29970         check_lsom_size $DIR/$tfile 16384
29971         check_lsom_data $DIR/$tfile
29972
29973         $TRUNCATE $DIR/$tfile 1234
29974         check_lsom_size $DIR/$tfile 1234
29975         # sync blocks on the MDT
29976         $MULTIOP $DIR/$tfile oc
29977         check_lsom_data $DIR/$tfile
29978 }
29979 run_test 806 "Verify Lazy Size on MDS"
29980
29981 test_807() {
29982         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29983         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29984                 skip "Need MDS version at least 2.11.52"
29985
29986         # Registration step
29987         changelog_register || error "changelog_register failed"
29988         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29989         changelog_users $SINGLEMDS | grep -q $cl_user ||
29990                 error "User $cl_user not found in changelog_users"
29991
29992         rm -rf $DIR/$tdir || error "rm $tdir failed"
29993         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29994         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29995         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29996         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29997                 error "truncate $tdir/trunc failed"
29998
29999         local bs=1048576
30000         echo "Test SOM for single-threaded write with fsync"
30001         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30002                 error "write $tfile failed"
30003         sync;sync;sync
30004
30005         # multi-client wirtes
30006         local num=$(get_node_count ${CLIENTS//,/ })
30007         local offset=0
30008         local i=0
30009
30010         echo "Test SOM for multi-client ($num) writes"
30011         touch $DIR/$tfile || error "touch $tfile failed"
30012         $TRUNCATE $DIR/$tfile 0
30013         for client in ${CLIENTS//,/ }; do
30014                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30015                 local pids[$i]=$!
30016                 i=$((i + 1))
30017                 offset=$((offset + $bs))
30018         done
30019         for (( i=0; i < $num; i++ )); do
30020                 wait ${pids[$i]}
30021         done
30022
30023         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30024         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30025         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30026         check_lsom_data $DIR/$tdir/trunc
30027         check_lsom_data $DIR/$tdir/single_dd
30028         check_lsom_data $DIR/$tfile
30029
30030         rm -rf $DIR/$tdir
30031         # Deregistration step
30032         changelog_deregister || error "changelog_deregister failed"
30033 }
30034 run_test 807 "verify LSOM syncing tool"
30035
30036 check_som_nologged()
30037 {
30038         local lines=$($LFS changelog $FSNAME-MDT0000 |
30039                 grep 'x=trusted.som' | wc -l)
30040         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30041 }
30042
30043 test_808() {
30044         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30045                 skip "Need MDS version at least 2.11.55"
30046
30047         # Registration step
30048         changelog_register || error "changelog_register failed"
30049
30050         touch $DIR/$tfile || error "touch $tfile failed"
30051         check_som_nologged
30052
30053         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30054                 error "write $tfile failed"
30055         check_som_nologged
30056
30057         $TRUNCATE $DIR/$tfile 1234
30058         check_som_nologged
30059
30060         $TRUNCATE $DIR/$tfile 1048576
30061         check_som_nologged
30062
30063         # Deregistration step
30064         changelog_deregister || error "changelog_deregister failed"
30065 }
30066 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30067
30068 check_som_nodata()
30069 {
30070         $LFS getsom $1
30071         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30072 }
30073
30074 test_809() {
30075         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30076                 skip "Need MDS version at least 2.11.56"
30077
30078         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30079                 error "failed to create DoM-only file $DIR/$tfile"
30080         touch $DIR/$tfile || error "touch $tfile failed"
30081         check_som_nodata $DIR/$tfile
30082
30083         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30084                 error "write $tfile failed"
30085         check_som_nodata $DIR/$tfile
30086
30087         $TRUNCATE $DIR/$tfile 1234
30088         check_som_nodata $DIR/$tfile
30089
30090         $TRUNCATE $DIR/$tfile 4097
30091         check_som_nodata $DIR/$file
30092 }
30093 run_test 809 "Verify no SOM xattr store for DoM-only files"
30094
30095 test_810() {
30096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30097         $GSS && skip_env "could not run with gss"
30098         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30099                 skip "OST < 2.12.58 doesn't align checksum"
30100
30101         set_checksums 1
30102         stack_trap "set_checksums $ORIG_CSUM" EXIT
30103         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30104
30105         local csum
30106         local before
30107         local after
30108         for csum in $CKSUM_TYPES; do
30109                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30110                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30111                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30112                         eval set -- $i
30113                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30114                         before=$(md5sum $DIR/$tfile)
30115                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30116                         after=$(md5sum $DIR/$tfile)
30117                         [ "$before" == "$after" ] ||
30118                                 error "$csum: $before != $after bs=$1 seek=$2"
30119                 done
30120         done
30121 }
30122 run_test 810 "partial page writes on ZFS (LU-11663)"
30123
30124 test_812a() {
30125         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30126                 skip "OST < 2.12.51 doesn't support this fail_loc"
30127
30128         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30129         # ensure ost1 is connected
30130         stat $DIR/$tfile >/dev/null || error "can't stat"
30131         wait_osc_import_state client ost1 FULL
30132         # no locks, no reqs to let the connection idle
30133         cancel_lru_locks osc
30134
30135         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30136 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30137         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30138         wait_osc_import_state client ost1 CONNECTING
30139         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30140
30141         stat $DIR/$tfile >/dev/null || error "can't stat file"
30142 }
30143 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30144
30145 test_812b() { # LU-12378
30146         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30147                 skip "OST < 2.12.51 doesn't support this fail_loc"
30148
30149         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30150         # ensure ost1 is connected
30151         stat $DIR/$tfile >/dev/null || error "can't stat"
30152         wait_osc_import_state client ost1 FULL
30153         # no locks, no reqs to let the connection idle
30154         cancel_lru_locks osc
30155
30156         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30157 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30158         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30159         wait_osc_import_state client ost1 CONNECTING
30160         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30161
30162         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30163         wait_osc_import_state client ost1 IDLE
30164 }
30165 run_test 812b "do not drop no resend request for idle connect"
30166
30167 test_812c() {
30168         local old
30169
30170         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30171
30172         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30173         $LFS getstripe $DIR/$tfile
30174         $LCTL set_param osc.*.idle_timeout=10
30175         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30176         # ensure ost1 is connected
30177         stat $DIR/$tfile >/dev/null || error "can't stat"
30178         wait_osc_import_state client ost1 FULL
30179         # no locks, no reqs to let the connection idle
30180         cancel_lru_locks osc
30181
30182 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30183         $LCTL set_param fail_loc=0x80000533
30184         sleep 15
30185         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30186 }
30187 run_test 812c "idle import vs lock enqueue race"
30188
30189 test_813() {
30190         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30191         [ -z "$file_heat_sav" ] && skip "no file heat support"
30192
30193         local readsample
30194         local writesample
30195         local readbyte
30196         local writebyte
30197         local readsample1
30198         local writesample1
30199         local readbyte1
30200         local writebyte1
30201
30202         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30203         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30204
30205         $LCTL set_param -n llite.*.file_heat=1
30206         echo "Turn on file heat"
30207         echo "Period second: $period_second, Decay percentage: $decay_pct"
30208
30209         echo "QQQQ" > $DIR/$tfile
30210         echo "QQQQ" > $DIR/$tfile
30211         echo "QQQQ" > $DIR/$tfile
30212         cat $DIR/$tfile > /dev/null
30213         cat $DIR/$tfile > /dev/null
30214         cat $DIR/$tfile > /dev/null
30215         cat $DIR/$tfile > /dev/null
30216
30217         local out=$($LFS heat_get $DIR/$tfile)
30218
30219         $LFS heat_get $DIR/$tfile
30220         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30221         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30222         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30223         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30224
30225         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30226         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30227         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30228         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30229
30230         sleep $((period_second + 3))
30231         echo "Sleep $((period_second + 3)) seconds..."
30232         # The recursion formula to calculate the heat of the file f is as
30233         # follow:
30234         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30235         # Where Hi is the heat value in the period between time points i*I and
30236         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30237         # to the weight of Ci.
30238         out=$($LFS heat_get $DIR/$tfile)
30239         $LFS heat_get $DIR/$tfile
30240         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30241         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30242         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30243         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30244
30245         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30246                 error "read sample ($readsample) is wrong"
30247         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30248                 error "write sample ($writesample) is wrong"
30249         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30250                 error "read bytes ($readbyte) is wrong"
30251         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30252                 error "write bytes ($writebyte) is wrong"
30253
30254         echo "QQQQ" > $DIR/$tfile
30255         echo "QQQQ" > $DIR/$tfile
30256         echo "QQQQ" > $DIR/$tfile
30257         cat $DIR/$tfile > /dev/null
30258         cat $DIR/$tfile > /dev/null
30259         cat $DIR/$tfile > /dev/null
30260         cat $DIR/$tfile > /dev/null
30261
30262         sleep $((period_second + 3))
30263         echo "Sleep $((period_second + 3)) seconds..."
30264
30265         out=$($LFS heat_get $DIR/$tfile)
30266         $LFS heat_get $DIR/$tfile
30267         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30268         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30269         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30270         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30271
30272         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30273                 4 * $decay_pct) / 100") -eq 1 ] ||
30274                 error "read sample ($readsample1) is wrong"
30275         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30276                 3 * $decay_pct) / 100") -eq 1 ] ||
30277                 error "write sample ($writesample1) is wrong"
30278         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30279                 20 * $decay_pct) / 100") -eq 1 ] ||
30280                 error "read bytes ($readbyte1) is wrong"
30281         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30282                 15 * $decay_pct) / 100") -eq 1 ] ||
30283                 error "write bytes ($writebyte1) is wrong"
30284
30285         echo "Turn off file heat for the file $DIR/$tfile"
30286         $LFS heat_set -o $DIR/$tfile
30287
30288         echo "QQQQ" > $DIR/$tfile
30289         echo "QQQQ" > $DIR/$tfile
30290         echo "QQQQ" > $DIR/$tfile
30291         cat $DIR/$tfile > /dev/null
30292         cat $DIR/$tfile > /dev/null
30293         cat $DIR/$tfile > /dev/null
30294         cat $DIR/$tfile > /dev/null
30295
30296         out=$($LFS heat_get $DIR/$tfile)
30297         $LFS heat_get $DIR/$tfile
30298         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30299         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30300         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30301         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30302
30303         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30304         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30305         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30306         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30307
30308         echo "Trun on file heat for the file $DIR/$tfile"
30309         $LFS heat_set -O $DIR/$tfile
30310
30311         echo "QQQQ" > $DIR/$tfile
30312         echo "QQQQ" > $DIR/$tfile
30313         echo "QQQQ" > $DIR/$tfile
30314         cat $DIR/$tfile > /dev/null
30315         cat $DIR/$tfile > /dev/null
30316         cat $DIR/$tfile > /dev/null
30317         cat $DIR/$tfile > /dev/null
30318
30319         out=$($LFS heat_get $DIR/$tfile)
30320         $LFS heat_get $DIR/$tfile
30321         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30322         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30323         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30324         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30325
30326         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30327         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30328         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30329         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30330
30331         $LFS heat_set -c $DIR/$tfile
30332         $LCTL set_param -n llite.*.file_heat=0
30333         echo "Turn off file heat support for the Lustre filesystem"
30334
30335         echo "QQQQ" > $DIR/$tfile
30336         echo "QQQQ" > $DIR/$tfile
30337         echo "QQQQ" > $DIR/$tfile
30338         cat $DIR/$tfile > /dev/null
30339         cat $DIR/$tfile > /dev/null
30340         cat $DIR/$tfile > /dev/null
30341         cat $DIR/$tfile > /dev/null
30342
30343         out=$($LFS heat_get $DIR/$tfile)
30344         $LFS heat_get $DIR/$tfile
30345         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30346         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30347         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30348         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30349
30350         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30351         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30352         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30353         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30354
30355         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30356         rm -f $DIR/$tfile
30357 }
30358 run_test 813 "File heat verfication"
30359
30360 test_814()
30361 {
30362         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30363         echo -n y >> $DIR/$tfile
30364         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30365         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30366 }
30367 run_test 814 "sparse cp works as expected (LU-12361)"
30368
30369 test_815()
30370 {
30371         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30372         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30373 }
30374 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30375
30376 test_816() {
30377         local ost1_imp=$(get_osc_import_name client ost1)
30378         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30379                          cut -d'.' -f2)
30380
30381         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30382         # ensure ost1 is connected
30383
30384         stat $DIR/$tfile >/dev/null || error "can't stat"
30385         wait_osc_import_state client ost1 FULL
30386         # no locks, no reqs to let the connection idle
30387         cancel_lru_locks osc
30388         lru_resize_disable osc
30389         local before
30390         local now
30391         before=$($LCTL get_param -n \
30392                  ldlm.namespaces.$imp_name.lru_size)
30393
30394         wait_osc_import_state client ost1 IDLE
30395         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30396         now=$($LCTL get_param -n \
30397               ldlm.namespaces.$imp_name.lru_size)
30398         [ $before == $now ] || error "lru_size changed $before != $now"
30399 }
30400 run_test 816 "do not reset lru_resize on idle reconnect"
30401
30402 cleanup_817() {
30403         umount $tmpdir
30404         exportfs -u localhost:$DIR/nfsexp
30405         rm -rf $DIR/nfsexp
30406 }
30407
30408 test_817() {
30409         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30410
30411         mkdir -p $DIR/nfsexp
30412         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30413                 error "failed to export nfs"
30414
30415         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30416         stack_trap cleanup_817 EXIT
30417
30418         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30419                 error "failed to mount nfs to $tmpdir"
30420
30421         cp /bin/true $tmpdir
30422         $DIR/nfsexp/true || error "failed to execute 'true' command"
30423 }
30424 run_test 817 "nfsd won't cache write lock for exec file"
30425
30426 test_818() {
30427         test_mkdir -i0 -c1 $DIR/$tdir
30428         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30429         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30430         stop $SINGLEMDS
30431
30432         # restore osp-syn threads
30433         stack_trap "fail $SINGLEMDS"
30434
30435         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30436         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30437         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30438                 error "start $SINGLEMDS failed"
30439         rm -rf $DIR/$tdir
30440
30441         local testid=$(echo $TESTNAME | tr '_' ' ')
30442
30443         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30444                 grep "run LFSCK" || error "run LFSCK is not suggested"
30445 }
30446 run_test 818 "unlink with failed llog"
30447
30448 test_819a() {
30449         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30450         cancel_lru_locks osc
30451         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30452         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30453         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30454         rm -f $TDIR/$tfile
30455 }
30456 run_test 819a "too big niobuf in read"
30457
30458 test_819b() {
30459         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30460         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30461         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30462         cancel_lru_locks osc
30463         sleep 1
30464         rm -f $TDIR/$tfile
30465 }
30466 run_test 819b "too big niobuf in write"
30467
30468
30469 function test_820_start_ost() {
30470         sleep 5
30471
30472         for num in $(seq $OSTCOUNT); do
30473                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30474         done
30475 }
30476
30477 test_820() {
30478         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30479
30480         mkdir $DIR/$tdir
30481         umount_client $MOUNT || error "umount failed"
30482         for num in $(seq $OSTCOUNT); do
30483                 stop ost$num
30484         done
30485
30486         # mount client with no active OSTs
30487         # so that the client can't initialize max LOV EA size
30488         # from OSC notifications
30489         mount_client $MOUNT || error "mount failed"
30490         # delay OST starting to keep this 0 max EA size for a while
30491         test_820_start_ost &
30492
30493         # create a directory on MDS2
30494         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30495                 error "Failed to create directory"
30496         # open intent should update default EA size
30497         # see mdc_update_max_ea_from_body()
30498         # notice this is the very first RPC to MDS2
30499         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30500         ret=$?
30501         echo $out
30502         # With SSK, this situation can lead to -EPERM being returned.
30503         # In that case, simply retry.
30504         if [ $ret -ne 0 ] && $SHARED_KEY; then
30505                 if echo "$out" | grep -q "not permitted"; then
30506                         cp /etc/services $DIR/$tdir/mds2
30507                         ret=$?
30508                 fi
30509         fi
30510         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30511 }
30512 run_test 820 "update max EA from open intent"
30513
30514 test_823() {
30515         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30516         local OST_MAX_PRECREATE=20000
30517
30518         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30519                 skip "Need MDS version at least 2.14.56"
30520
30521         save_lustre_params mds1 \
30522                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30523         do_facet $SINGLEMDS "$LCTL set_param -n \
30524                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30525         do_facet $SINGLEMDS "$LCTL set_param -n \
30526                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30527
30528         stack_trap "restore_lustre_params < $p; rm $p"
30529
30530         do_facet $SINGLEMDS "$LCTL set_param -n \
30531                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30532
30533         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30534                       osp.$FSNAME-OST0000*MDT0000.create_count")
30535         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30536                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30537         local expect_count=$(((($max/2)/256) * 256))
30538
30539         log "setting create_count to 100200:"
30540         log " -result- count: $count with max: $max, expecting: $expect_count"
30541
30542         [[ $count -eq expect_count ]] ||
30543                 error "Create count not set to max precreate."
30544 }
30545 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30546
30547 test_831() {
30548         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30549                 skip "Need MDS version 2.14.56"
30550
30551         local sync_changes=$(do_facet $SINGLEMDS \
30552                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30553
30554         [ "$sync_changes" -gt 100 ] &&
30555                 skip "Sync changes $sync_changes > 100 already"
30556
30557         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30558
30559         $LFS mkdir -i 0 $DIR/$tdir
30560         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30561
30562         save_lustre_params mds1 \
30563                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30564         save_lustre_params mds1 \
30565                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30566
30567         do_facet mds1 "$LCTL set_param -n \
30568                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30569                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30570         stack_trap "restore_lustre_params < $p" EXIT
30571
30572         createmany -o $DIR/$tdir/f- 1000
30573         unlinkmany $DIR/$tdir/f- 1000 &
30574         local UNLINK_PID=$!
30575
30576         while sleep 1; do
30577                 sync_changes=$(do_facet mds1 \
30578                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30579                 # the check in the code is racy, fail the test
30580                 # if the value above the limit by 10.
30581                 [ $sync_changes -gt 110 ] && {
30582                         kill -2 $UNLINK_PID
30583                         wait
30584                         error "osp changes throttling failed, $sync_changes>110"
30585                 }
30586                 kill -0 $UNLINK_PID 2> /dev/null || break
30587         done
30588         wait
30589 }
30590 run_test 831 "throttling unlink/setattr queuing on OSP"
30591
30592 test_832() {
30593         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30594         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30595                 skip "Need MDS version 2.15.52+"
30596         is_rmentry_supported || skip "rm_entry not supported"
30597
30598         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30599         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30600         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30601                 error "mkdir remote_dir failed"
30602         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30603                 error "mkdir striped_dir failed"
30604         touch $DIR/$tdir/file || error "touch file failed"
30605         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30606         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30607 }
30608 run_test 832 "lfs rm_entry"
30609
30610 test_833() {
30611         local file=$DIR/$tfile
30612
30613         stack_trap "rm -f $file" EXIT
30614         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30615
30616         local wpid
30617         local rpid
30618         local rpid2
30619
30620         # Buffered I/O write
30621         (
30622                 while [ ! -e $DIR/sanity.833.lck ]; do
30623                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30624                                 error "failed to write $file"
30625                         sleep 0.$((RANDOM % 4 + 1))
30626                 done
30627         )&
30628         wpid=$!
30629
30630         # Buffered I/O read
30631         (
30632                 while [ ! -e $DIR/sanity.833.lck ]; do
30633                         dd if=$file of=/dev/null bs=1M count=50 ||
30634                                 error "failed to read $file"
30635                         sleep 0.$((RANDOM % 4 + 1))
30636                 done
30637         )&
30638         rpid=$!
30639
30640         # Direct I/O read
30641         (
30642                 while [ ! -e $DIR/sanity.833.lck ]; do
30643                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30644                                 error "failed to read $file in direct I/O mode"
30645                         sleep 0.$((RANDOM % 4 + 1))
30646                 done
30647         )&
30648         rpid2=$!
30649
30650         sleep 30
30651         touch $DIR/sanity.833.lck
30652         wait $wpid || error "$?: buffered write failed"
30653         wait $rpid || error "$?: buffered read failed"
30654         wait $rpid2 || error "$?: direct read failed"
30655 }
30656 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30657
30658 #
30659 # tests that do cleanup/setup should be run at the end
30660 #
30661
30662 test_900() {
30663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30664         local ls
30665
30666         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30667         $LCTL set_param fail_loc=0x903
30668
30669         cancel_lru_locks MGC
30670
30671         FAIL_ON_ERROR=true cleanup
30672         FAIL_ON_ERROR=true setup
30673 }
30674 run_test 900 "umount should not race with any mgc requeue thread"
30675
30676 # LUS-6253/LU-11185
30677 test_901() {
30678         local old
30679         local count
30680         local oldc
30681         local newc
30682         local olds
30683         local news
30684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30685
30686         # some get_param have a bug to handle dot in param name
30687         cancel_lru_locks MGC
30688         old=$(mount -t lustre | wc -l)
30689         # 1 config+sptlrpc
30690         # 2 params
30691         # 3 nodemap
30692         # 4 IR
30693         old=$((old * 4))
30694         oldc=0
30695         count=0
30696         while [ $old -ne $oldc ]; do
30697                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30698                 sleep 1
30699                 ((count++))
30700                 if [ $count -ge $TIMEOUT ]; then
30701                         error "too large timeout"
30702                 fi
30703         done
30704         umount_client $MOUNT || error "umount failed"
30705         mount_client $MOUNT || error "mount failed"
30706         cancel_lru_locks MGC
30707         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30708
30709         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30710
30711         return 0
30712 }
30713 run_test 901 "don't leak a mgc lock on client umount"
30714
30715 # LU-13377
30716 test_902() {
30717         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30718                 skip "client does not have LU-13377 fix"
30719         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30720         $LCTL set_param fail_loc=0x1415
30721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30722         cancel_lru_locks osc
30723         rm -f $DIR/$tfile
30724 }
30725 run_test 902 "test short write doesn't hang lustre"
30726
30727 # LU-14711
30728 test_903() {
30729         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30730         echo "blah" > $DIR/${tfile}-2
30731         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30732         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30733         $LCTL set_param fail_loc=0x417 fail_val=20
30734
30735         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30736         sleep 1 # To start the destroy
30737         wait_destroy_complete 150 || error "Destroy taking too long"
30738         cat $DIR/$tfile > /dev/null || error "Evicted"
30739 }
30740 run_test 903 "Test long page discard does not cause evictions"
30741
30742 test_904() {
30743         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30744         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30745                 grep -q project || skip "skip project quota not supported"
30746
30747         local testfile="$DIR/$tdir/$tfile"
30748         local xattr="trusted.projid"
30749         local projid
30750         local mdts=$(comma_list $(mdts_nodes))
30751         local saved=$(do_facet mds1 $LCTL get_param -n \
30752                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30753
30754         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30755         stack_trap "do_nodes $mdts $LCTL set_param \
30756                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30757
30758         mkdir -p $DIR/$tdir
30759         touch $testfile
30760         #hide projid xattr on server
30761         $LFS project -p 1 $testfile ||
30762                 error "set $testfile project id failed"
30763         getfattr -m - $testfile | grep $xattr &&
30764                 error "do not show trusted.projid when disabled on server"
30765         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30766         #should be hidden when projid is 0
30767         $LFS project -p 0 $testfile ||
30768                 error "set $testfile project id failed"
30769         getfattr -m - $testfile | grep $xattr &&
30770                 error "do not show trusted.projid with project ID 0"
30771
30772         #still can getxattr explicitly
30773         projid=$(getfattr -n $xattr $testfile |
30774                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30775         [ $projid == "0" ] ||
30776                 error "projid expected 0 not $projid"
30777
30778         #set the projid via setxattr
30779         setfattr -n $xattr -v "1000" $testfile ||
30780                 error "setattr failed with $?"
30781         projid=($($LFS project $testfile))
30782         [ ${projid[0]} == "1000" ] ||
30783                 error "projid expected 1000 not $projid"
30784
30785         #check the new projid via getxattr
30786         $LFS project -p 1001 $testfile ||
30787                 error "set $testfile project id failed"
30788         getfattr -m - $testfile | grep $xattr ||
30789                 error "should show trusted.projid when project ID != 0"
30790         projid=$(getfattr -n $xattr $testfile |
30791                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30792         [ $projid == "1001" ] ||
30793                 error "projid expected 1001 not $projid"
30794
30795         #try to set invalid projid
30796         setfattr -n $xattr -v "4294967295" $testfile &&
30797                 error "set invalid projid should fail"
30798
30799         #remove the xattr means setting projid to 0
30800         setfattr -x $xattr $testfile ||
30801                 error "setfattr failed with $?"
30802         projid=($($LFS project $testfile))
30803         [ ${projid[0]} == "0" ] ||
30804                 error "projid expected 0 not $projid"
30805
30806         #should be hidden when parent has inherit flag and same projid
30807         $LFS project -srp 1002 $DIR/$tdir ||
30808                 error "set $tdir project id failed"
30809         getfattr -m - $testfile | grep $xattr &&
30810                 error "do not show trusted.projid with inherit flag"
30811
30812         #still can getxattr explicitly
30813         projid=$(getfattr -n $xattr $testfile |
30814                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30815         [ $projid == "1002" ] ||
30816                 error "projid expected 1002 not $projid"
30817 }
30818 run_test 904 "virtual project ID xattr"
30819
30820 # LU-8582
30821 test_905() {
30822         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30823                 skip "need OST version >= 2.15.50.220 for fail_loc"
30824
30825         remote_ost_nodsh && skip "remote OST with nodsh"
30826         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30827
30828         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30829
30830         #define OBD_FAIL_OST_OPCODE 0x253
30831         # OST_LADVISE = 21
30832         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30833         $LFS ladvise -a willread $DIR/$tfile &&
30834                 error "unexpected success of ladvise with fault injection"
30835         $LFS ladvise -a willread $DIR/$tfile |&
30836                 grep -q "Operation not supported"
30837         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30838 }
30839 run_test 905 "bad or new opcode should not stuck client"
30840
30841 test_906() {
30842         grep -q io_uring_setup /proc/kallsyms ||
30843                 skip "Client OS does not support io_uring I/O engine"
30844         io_uring_probe || skip "kernel does not support io_uring fully"
30845         which fio || skip_env "no fio installed"
30846         fio --enghelp | grep -q io_uring ||
30847                 skip_env "fio does not support io_uring I/O engine"
30848
30849         local file=$DIR/$tfile
30850         local ioengine="io_uring"
30851         local numjobs=2
30852         local size=50M
30853
30854         fio --name=seqwrite --ioengine=$ioengine        \
30855                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30856                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30857                 error "fio seqwrite $file failed"
30858
30859         fio --name=seqread --ioengine=$ioengine \
30860                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30861                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30862                 error "fio seqread $file failed"
30863
30864         rm -f $file || error "rm -f $file failed"
30865 }
30866 run_test 906 "Simple test for io_uring I/O engine via fio"
30867
30868 test_907() {
30869         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
30870
30871         # set stripe size to max rpc size
30872         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
30873         $LFS getstripe $DIR/$tfile
30874 #define OBD_FAIL_OST_EROFS               0x216
30875         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
30876
30877         local bs=$((max_pages * PAGE_SIZE / 16))
30878
30879         # write full one stripe and one block
30880         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
30881
30882         rm $DIR/$tfile || error "rm failed"
30883 }
30884 run_test 907 "write rpc error during unlink"
30885
30886 complete_test $SECONDS
30887 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30888 check_and_cleanup_lustre
30889 if [ "$I_MOUNTED" != "yes" ]; then
30890         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30891 fi
30892 exit_status