Whamcloud - gitweb
LU-15496 tests: add debugging to sanity/398c
[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         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 #                                  5              12     8   12  15   (min)"
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         (( $sles_version >= $(version_code 11.4.0) )) ||
103                 always_except LU-4341 170
104
105         (( $sles_version >= $(version_code 12.0.0) )) ||
106                 always_except LU-3703 234
107 elif [ -r /etc/redhat-release ]; then
108         rhel_version=$(cat /etc/redhat-release |
109                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
110         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
111                 # disable test_906 temporarily until rhel9.3 solves the
112                 # failure on fio io_uring I/O engine.
113                 always_except LU-17289 906
114         fi
115 elif [ -r /etc/os-release ]; then
116         if grep -qi ubuntu /etc/os-release; then
117                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
118                                                 -e 's/^VERSION=//p' \
119                                                 /etc/os-release |
120                                                 awk '{ print $1 }'))
121
122                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
123                         always_except LU-10366 410
124                 fi
125         fi
126 fi
127
128 build_test_filter
129 FAIL_ON_ERROR=false
130
131 cleanup() {
132         echo -n "cln.."
133         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
134         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
135 }
136 setup() {
137         echo -n "mnt.."
138         load_modules
139         setupall || exit 10
140         echo "done"
141 }
142
143 check_swap_layouts_support()
144 {
145         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
146                 skip "Does not support layout lock."
147 }
148
149 check_swap_layout_no_dom()
150 {
151         local FOLDER=$1
152         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
153         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
154 }
155
156 check_and_setup_lustre
157 DIR=${DIR:-$MOUNT}
158 assert_DIR
159
160 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
161
162 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
163 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
164 rm -rf $DIR/[Rdfs][0-9]*
165
166 # $RUNAS_ID may get set incorrectly somewhere else
167 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
168         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
169
170 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
171
172 if [ "${ONLY}" = "MOUNT" ] ; then
173         echo "Lustre is up, please go on"
174         exit
175 fi
176
177 echo "preparing for tests involving mounts"
178 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
179 touch $EXT2_DEV
180 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
181 echo # add a newline after mke2fs.
182
183 umask 077
184
185 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
186
187 # ensure all internal functions know we want full debug
188 export PTLDEBUG=all
189 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
190
191 test_0a() {
192         touch $DIR/$tfile
193         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
194         rm $DIR/$tfile
195         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
196 }
197 run_test 0a "touch; rm ====================="
198
199 test_0b() {
200         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
201         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
202 }
203 run_test 0b "chmod 0755 $DIR ============================="
204
205 test_0c() {
206         $LCTL get_param mdc.*.import | grep "state: FULL" ||
207                 error "import not FULL"
208         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
209                 error "bad target"
210 }
211 run_test 0c "check import proc"
212
213 test_0d() { # LU-3397
214         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
215                 skip "proc exports not supported before 2.10.57"
216
217         local mgs_exp="mgs.MGS.exports"
218         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
219         local exp_client_nid
220         local exp_client_version
221         local exp_val
222         local imp_val
223         local temp_imp=$DIR/$tfile.import
224         local temp_exp=$DIR/$tfile.export
225
226         # save mgc import file to $temp_imp
227         $LCTL get_param mgc.*.import | tee $temp_imp
228         # Check if client uuid is found in MGS export
229         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
230                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
231                         $client_uuid ] &&
232                         break;
233         done
234         # save mgs export file to $temp_exp
235         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
236
237         # Compare the value of field "connect_flags"
238         imp_val=$(grep "connect_flags" $temp_imp)
239         exp_val=$(grep "connect_flags" $temp_exp)
240         [ "$exp_val" == "$imp_val" ] ||
241                 error "export flags '$exp_val' != import flags '$imp_val'"
242
243         # Compare client versions.  Only compare top-3 fields for compatibility
244         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
245         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
246         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "exp version '$exp_client_version'($exp_val) != " \
249                         "'$(lustre_build_version client)'($imp_val)"
250 }
251 run_test 0d "check export proc ============================="
252
253 test_0e() { # LU-13417
254         (( $MDSCOUNT > 1 )) ||
255                 skip "We need at least 2 MDTs for this test"
256
257         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
258                 skip "Need server version at least 2.14.51"
259
260         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
261         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
262
263         [ $default_lmv_count -eq 1 ] ||
264                 error "$MOUNT default stripe count $default_lmv_count"
265
266         [ $default_lmv_index -eq -1 ] ||
267                 error "$MOUNT default stripe index $default_lmv_index"
268
269         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
270         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
271
272         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
273         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
274
275         [ $mdt_index1 -eq $mdt_index2 ] &&
276                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
277
278         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
279 }
280 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
281
282 test_1() {
283         test_mkdir $DIR/$tdir
284         test_mkdir $DIR/$tdir/d2
285         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
286         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
287         rmdir $DIR/$tdir/d2
288         rmdir $DIR/$tdir
289         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
290 }
291 run_test 1 "mkdir; remkdir; rmdir"
292
293 test_2() {
294         test_mkdir $DIR/$tdir
295         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
296         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
297         rm -r $DIR/$tdir
298         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
299 }
300 run_test 2 "mkdir; touch; rmdir; check file"
301
302 test_3() {
303         test_mkdir $DIR/$tdir
304         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
305         touch $DIR/$tdir/$tfile
306         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
307         rm -r $DIR/$tdir
308         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
309 }
310 run_test 3 "mkdir; touch; rmdir; check dir"
311
312 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
313 test_4() {
314         test_mkdir -i 1 $DIR/$tdir
315
316         touch $DIR/$tdir/$tfile ||
317                 error "Create file under remote directory failed"
318
319         rmdir $DIR/$tdir &&
320                 error "Expect error removing in-use dir $DIR/$tdir"
321
322         test -d $DIR/$tdir || error "Remote directory disappeared"
323
324         rm -rf $DIR/$tdir || error "remove remote dir error"
325 }
326 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
327
328 test_5() {
329         test_mkdir $DIR/$tdir
330         test_mkdir $DIR/$tdir/d2
331         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
332         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
333         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
334 }
335 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
336
337 test_6a() {
338         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
339         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
340         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
341                 error "$tfile does not have perm 0666 or UID $UID"
342         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile should be 0666 and owned by UID $UID"
345 }
346 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
347
348 test_6c() {
349         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
350
351         touch $DIR/$tfile
352         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
353         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
354                 error "$tfile should be owned by UID $RUNAS_ID"
355         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358 }
359 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
360
361 test_6e() {
362         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
363
364         touch $DIR/$tfile
365         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
366         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
367                 error "$tfile should be owned by GID $UID"
368         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
371 }
372 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
373
374 test_6g() {
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         test_mkdir $DIR/$tdir
378         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
379         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
380         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
381         test_mkdir $DIR/$tdir/d/subdir
382         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
383                 error "$tdir/d/subdir should be GID $RUNAS_GID"
384         if [[ $MDSCOUNT -gt 1 ]]; then
385                 # check remote dir sgid inherite
386                 $LFS mkdir -i 0 $DIR/$tdir.local ||
387                         error "mkdir $tdir.local failed"
388                 chmod g+s $DIR/$tdir.local ||
389                         error "chmod $tdir.local failed"
390                 chgrp $RUNAS_GID $DIR/$tdir.local ||
391                         error "chgrp $tdir.local failed"
392                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
393                         error "mkdir $tdir.remote failed"
394                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
395                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
396                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
397                         error "$tdir.remote should be mode 02755"
398         fi
399 }
400 run_test 6g "verify new dir in sgid dir inherits group"
401
402 test_6h() { # bug 7331
403         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
404
405         touch $DIR/$tfile || error "touch failed"
406         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
407         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
408                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
409         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
410                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
411 }
412 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
413
414 test_7a() {
415         test_mkdir $DIR/$tdir
416         $MCREATE $DIR/$tdir/$tfile
417         chmod 0666 $DIR/$tdir/$tfile
418         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
419                 error "$tdir/$tfile should be mode 0666"
420 }
421 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
422
423 test_7b() {
424         if [ ! -d $DIR/$tdir ]; then
425                 test_mkdir $DIR/$tdir
426         fi
427         $MCREATE $DIR/$tdir/$tfile
428         echo -n foo > $DIR/$tdir/$tfile
429         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
430         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
431 }
432 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
433
434 test_8() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         chmod 0666 $DIR/$tdir/$tfile
438         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
439                 error "$tfile mode not 0666"
440 }
441 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
442
443 test_9() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         test_mkdir $DIR/$tdir/d2/d3
447         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
448 }
449 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
450
451 test_10() {
452         test_mkdir $DIR/$tdir
453         test_mkdir $DIR/$tdir/d2
454         touch $DIR/$tdir/d2/$tfile
455         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
456                 error "$tdir/d2/$tfile not a file"
457 }
458 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
459
460 test_11() {
461         test_mkdir $DIR/$tdir
462         test_mkdir $DIR/$tdir/d2
463         chmod 0666 $DIR/$tdir/d2
464         chmod 0705 $DIR/$tdir/d2
465         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
466                 error "$tdir/d2 mode not 0705"
467 }
468 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
469
470 test_12() {
471         test_mkdir $DIR/$tdir
472         touch $DIR/$tdir/$tfile
473         chmod 0666 $DIR/$tdir/$tfile
474         chmod 0654 $DIR/$tdir/$tfile
475         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
476                 error "$tdir/d2 mode not 0654"
477 }
478 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
479
480 test_13() {
481         test_mkdir $DIR/$tdir
482         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
483         >  $DIR/$tdir/$tfile
484         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
485                 error "$tdir/$tfile size not 0 after truncate"
486 }
487 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
488
489 test_14() {
490         test_mkdir $DIR/$tdir
491         touch $DIR/$tdir/$tfile
492         rm $DIR/$tdir/$tfile
493         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
494 }
495 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
496
497 test_15() {
498         test_mkdir $DIR/$tdir
499         touch $DIR/$tdir/$tfile
500         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
501         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
502                 error "$tdir/${tfile_2} not a file after rename"
503         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
504 }
505 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
506
507 test_16() {
508         test_mkdir $DIR/$tdir
509         touch $DIR/$tdir/$tfile
510         rm -rf $DIR/$tdir/$tfile
511         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
512 }
513 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
514
515 test_17a() {
516         test_mkdir $DIR/$tdir
517         touch $DIR/$tdir/$tfile
518         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
519         ls -l $DIR/$tdir
520         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
521                 error "$tdir/l-exist not a symlink"
522         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
523                 error "$tdir/l-exist not referencing a file"
524         rm -f $DIR/$tdir/l-exist
525         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
526 }
527 run_test 17a "symlinks: create, remove (real)"
528
529 test_17b() {
530         test_mkdir $DIR/$tdir
531         ln -s no-such-file $DIR/$tdir/l-dangle
532         ls -l $DIR/$tdir
533         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
534                 error "$tdir/l-dangle not referencing no-such-file"
535         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
536                 error "$tdir/l-dangle not referencing non-existent file"
537         rm -f $DIR/$tdir/l-dangle
538         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
539 }
540 run_test 17b "symlinks: create, remove (dangling)"
541
542 test_17c() { # bug 3440 - don't save failed open RPC for replay
543         test_mkdir $DIR/$tdir
544         ln -s foo $DIR/$tdir/$tfile
545         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
546 }
547 run_test 17c "symlinks: open dangling (should return error)"
548
549 test_17d() {
550         test_mkdir $DIR/$tdir
551         ln -s foo $DIR/$tdir/$tfile
552         touch $DIR/$tdir/$tfile || error "creating to new symlink"
553 }
554 run_test 17d "symlinks: create dangling"
555
556 test_17e() {
557         test_mkdir $DIR/$tdir
558         local foo=$DIR/$tdir/$tfile
559         ln -s $foo $foo || error "create symlink failed"
560         ls -l $foo || error "ls -l failed"
561         ls $foo && error "ls not failed" || true
562 }
563 run_test 17e "symlinks: create recursive symlink (should return error)"
564
565 test_17f() {
566         test_mkdir $DIR/$tdir
567         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
568         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
569         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
570         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
572         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
573         ls -l  $DIR/$tdir
574 }
575 run_test 17f "symlinks: long and very long symlink name"
576
577 # str_repeat(S, N) generate a string that is string S repeated N times
578 str_repeat() {
579         local s=$1
580         local n=$2
581         local ret=''
582         while [ $((n -= 1)) -ge 0 ]; do
583                 ret=$ret$s
584         done
585         echo $ret
586 }
587
588 # Long symlinks and LU-2241
589 test_17g() {
590         test_mkdir $DIR/$tdir
591         local TESTS="59 60 61 4094 4095"
592
593         # Fix for inode size boundary in 2.1.4
594         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
595                 TESTS="4094 4095"
596
597         # Patch not applied to 2.2 or 2.3 branches
598         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
599         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
600                 TESTS="4094 4095"
601
602         for i in $TESTS; do
603                 local SYMNAME=$(str_repeat 'x' $i)
604                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
605                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
606         done
607 }
608 run_test 17g "symlinks: really long symlink name and inode boundaries"
609
610 test_17h() { #bug 17378
611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
612         remote_mds_nodsh && skip "remote MDS with nodsh"
613
614         local mdt_idx
615
616         test_mkdir $DIR/$tdir
617         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
618         $LFS setstripe -c -1 $DIR/$tdir
619         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
620         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
621         touch $DIR/$tdir/$tfile || true
622 }
623 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
624
625 test_17i() { #bug 20018
626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
627         remote_mds_nodsh && skip "remote MDS with nodsh"
628
629         local foo=$DIR/$tdir/$tfile
630         local mdt_idx
631
632         test_mkdir -c1 $DIR/$tdir
633         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
634         ln -s $foo $foo || error "create symlink failed"
635 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
636         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
637         ls -l $foo && error "error not detected"
638         return 0
639 }
640 run_test 17i "don't panic on short symlink (should return error)"
641
642 test_17k() { #bug 22301
643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
644         [[ -z "$(which rsync 2>/dev/null)" ]] &&
645                 skip "no rsync command"
646         rsync --help | grep -q xattr ||
647                 skip_env "$(rsync --version | head -n1) does not support xattrs"
648         test_mkdir $DIR/$tdir
649         test_mkdir $DIR/$tdir.new
650         touch $DIR/$tdir/$tfile
651         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
652         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
653                 error "rsync failed with xattrs enabled"
654 }
655 run_test 17k "symlinks: rsync with xattrs enabled"
656
657 test_17l() { # LU-279
658         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
659                 skip "no getfattr command"
660
661         test_mkdir $DIR/$tdir
662         touch $DIR/$tdir/$tfile
663         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
664         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
665                 # -h to not follow symlinks. -m '' to list all the xattrs.
666                 # grep to remove first line: '# file: $path'.
667                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
668                 do
669                         lgetxattr_size_check $path $xattr ||
670                                 error "lgetxattr_size_check $path $xattr failed"
671                 done
672         done
673 }
674 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
675
676 # LU-1540
677 test_17m() {
678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
679         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
680         remote_mds_nodsh && skip "remote MDS with nodsh"
681         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
682         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
683                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
684
685         local short_sym="0123456789"
686         local wdir=$DIR/$tdir
687         local i
688
689         test_mkdir $wdir
690         long_sym=$short_sym
691         # create a long symlink file
692         for ((i = 0; i < 4; ++i)); do
693                 long_sym=${long_sym}${long_sym}
694         done
695
696         echo "create 512 short and long symlink files under $wdir"
697         for ((i = 0; i < 256; ++i)); do
698                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
699                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
700         done
701
702         echo "erase them"
703         rm -f $wdir/*
704         sync
705         wait_delete_completed
706
707         echo "recreate the 512 symlink files with a shorter string"
708         for ((i = 0; i < 512; ++i)); do
709                 # rewrite the symlink file with a shorter string
710                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
711                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
712         done
713
714         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
715
716         echo "stop and checking mds${mds_index}:"
717         # e2fsck should not return error
718         stop mds${mds_index}
719         local devname=$(mdsdevname $mds_index)
720         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
721         rc=$?
722
723         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
724                 error "start mds${mds_index} failed"
725         df $MOUNT > /dev/null 2>&1
726         [ $rc -eq 0 ] ||
727                 error "e2fsck detected error for short/long symlink: rc=$rc"
728         rm -f $wdir/*
729 }
730 run_test 17m "run e2fsck against MDT which contains short/long symlink"
731
732 check_fs_consistency_17n() {
733         local mdt_index
734         local rc=0
735
736         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
737         # so it only check MDT1/MDT2 instead of all of MDTs.
738         for mdt_index in 1 2; do
739                 # e2fsck should not return error
740                 stop mds${mdt_index}
741                 local devname=$(mdsdevname $mdt_index)
742                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
743                         rc=$((rc + $?))
744
745                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
746                         error "mount mds$mdt_index failed"
747                 df $MOUNT > /dev/null 2>&1
748         done
749         return $rc
750 }
751
752 test_17n() {
753         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
755         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
756         remote_mds_nodsh && skip "remote MDS with nodsh"
757         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
758         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
759                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
760
761         local i
762
763         test_mkdir $DIR/$tdir
764         for ((i=0; i<10; i++)); do
765                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
766                         error "create remote dir error $i"
767                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
768                         error "create files under remote dir failed $i"
769         done
770
771         check_fs_consistency_17n ||
772                 error "e2fsck report error after create files under remote dir"
773
774         for ((i = 0; i < 10; i++)); do
775                 rm -rf $DIR/$tdir/remote_dir_${i} ||
776                         error "destroy remote dir error $i"
777         done
778
779         check_fs_consistency_17n ||
780                 error "e2fsck report error after unlink files under remote dir"
781
782         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
783                 skip "lustre < 2.4.50 does not support migrate mv"
784
785         for ((i = 0; i < 10; i++)); do
786                 mkdir -p $DIR/$tdir/remote_dir_${i}
787                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
788                         error "create files under remote dir failed $i"
789                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
790                         error "migrate remote dir error $i"
791         done
792         check_fs_consistency_17n || error "e2fsck report error after migration"
793
794         for ((i = 0; i < 10; i++)); do
795                 rm -rf $DIR/$tdir/remote_dir_${i} ||
796                         error "destroy remote dir error $i"
797         done
798
799         check_fs_consistency_17n || error "e2fsck report error after unlink"
800 }
801 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
802
803 test_17o() {
804         remote_mds_nodsh && skip "remote MDS with nodsh"
805         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
806                 skip "Need MDS version at least 2.3.64"
807
808         local wdir=$DIR/${tdir}o
809         local mdt_index
810         local rc=0
811
812         test_mkdir $wdir
813         touch $wdir/$tfile
814         mdt_index=$($LFS getstripe -m $wdir/$tfile)
815         mdt_index=$((mdt_index + 1))
816
817         cancel_lru_locks mdc
818         #fail mds will wait the failover finish then set
819         #following fail_loc to avoid interfer the recovery process.
820         fail mds${mdt_index}
821
822         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
823         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
824         ls -l $wdir/$tfile && rc=1
825         do_facet mds${mdt_index} lctl set_param fail_loc=0
826         [[ $rc -eq 0 ]] || error "stat file should fail"
827 }
828 run_test 17o "stat file with incompat LMA feature"
829
830 test_18() {
831         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
832         ls $DIR || error "Failed to ls $DIR: $?"
833 }
834 run_test 18 "touch .../f ; ls ... =============================="
835
836 test_19a() {
837         touch $DIR/$tfile
838         ls -l $DIR
839         rm $DIR/$tfile
840         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
841 }
842 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
843
844 test_19b() {
845         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
846 }
847 run_test 19b "ls -l .../f19 (should return error) =============="
848
849 test_19c() {
850         [ $RUNAS_ID -eq $UID ] &&
851                 skip_env "RUNAS_ID = UID = $UID -- skipping"
852
853         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
854 }
855 run_test 19c "$RUNAS touch .../f19 (should return error) =="
856
857 test_19d() {
858         cat $DIR/f19 && error || true
859 }
860 run_test 19d "cat .../f19 (should return error) =============="
861
862 test_20() {
863         touch $DIR/$tfile
864         rm $DIR/$tfile
865         touch $DIR/$tfile
866         rm $DIR/$tfile
867         touch $DIR/$tfile
868         rm $DIR/$tfile
869         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
870 }
871 run_test 20 "touch .../f ; ls -l ..."
872
873 test_21() {
874         test_mkdir $DIR/$tdir
875         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
876         ln -s dangle $DIR/$tdir/link
877         echo foo >> $DIR/$tdir/link
878         cat $DIR/$tdir/dangle
879         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
880         $CHECKSTAT -f -t file $DIR/$tdir/link ||
881                 error "$tdir/link not linked to a file"
882 }
883 run_test 21 "write to dangling link"
884
885 test_22() {
886         local wdir=$DIR/$tdir
887         test_mkdir $wdir
888         chown $RUNAS_ID:$RUNAS_GID $wdir
889         (cd $wdir || error "cd $wdir failed";
890                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
891                 $RUNAS tar xf -)
892         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
893         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
894         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
895                 error "checkstat -u failed"
896 }
897 run_test 22 "unpack tar archive as non-root user"
898
899 # was test_23
900 test_23a() {
901         test_mkdir $DIR/$tdir
902         local file=$DIR/$tdir/$tfile
903
904         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
905         openfile -f O_CREAT:O_EXCL $file &&
906                 error "$file recreate succeeded" || true
907 }
908 run_test 23a "O_CREAT|O_EXCL in subdir"
909
910 test_23b() { # bug 18988
911         test_mkdir $DIR/$tdir
912         local file=$DIR/$tdir/$tfile
913
914         rm -f $file
915         echo foo > $file || error "write filed"
916         echo bar >> $file || error "append filed"
917         $CHECKSTAT -s 8 $file || error "wrong size"
918         rm $file
919 }
920 run_test 23b "O_APPEND check"
921
922 # LU-9409, size with O_APPEND and tiny writes
923 test_23c() {
924         local file=$DIR/$tfile
925
926         # single dd
927         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
928         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
929         rm -f $file
930
931         # racing tiny writes
932         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
934         wait
935         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
936         rm -f $file
937
938         #racing tiny & normal writes
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
941         wait
942         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
943         rm -f $file
944
945         #racing tiny & normal writes 2, ugly numbers
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
948         wait
949         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
950         rm -f $file
951 }
952 run_test 23c "O_APPEND size checks for tiny writes"
953
954 # LU-11069 file offset is correct after appending writes
955 test_23d() {
956         local file=$DIR/$tfile
957         local offset
958
959         echo CentaurHauls > $file
960         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
961         if ((offset != 26)); then
962                 error "wrong offset, expected 26, got '$offset'"
963         fi
964 }
965 run_test 23d "file offset is correct after appending writes"
966
967 # rename sanity
968 test_24a() {
969         echo '-- same directory rename'
970         test_mkdir $DIR/$tdir
971         touch $DIR/$tdir/$tfile.1
972         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
973         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
974 }
975 run_test 24a "rename file to non-existent target"
976
977 test_24b() {
978         test_mkdir $DIR/$tdir
979         touch $DIR/$tdir/$tfile.{1,2}
980         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
981         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
982         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
983 }
984 run_test 24b "rename file to existing target"
985
986 test_24c() {
987         test_mkdir $DIR/$tdir
988         test_mkdir $DIR/$tdir/d$testnum.1
989         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
990         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
991         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
992 }
993 run_test 24c "rename directory to non-existent target"
994
995 test_24d() {
996         test_mkdir -c1 $DIR/$tdir
997         test_mkdir -c1 $DIR/$tdir/d$testnum.1
998         test_mkdir -c1 $DIR/$tdir/d$testnum.2
999         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1000         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1001         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1002 }
1003 run_test 24d "rename directory to existing target"
1004
1005 test_24e() {
1006         echo '-- cross directory renames --'
1007         test_mkdir $DIR/R5a
1008         test_mkdir $DIR/R5b
1009         touch $DIR/R5a/f
1010         mv $DIR/R5a/f $DIR/R5b/g
1011         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1012         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1013 }
1014 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1015
1016 test_24f() {
1017         test_mkdir $DIR/R6a
1018         test_mkdir $DIR/R6b
1019         touch $DIR/R6a/f $DIR/R6b/g
1020         mv $DIR/R6a/f $DIR/R6b/g
1021         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1022         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1023 }
1024 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1025
1026 test_24g() {
1027         test_mkdir $DIR/R7a
1028         test_mkdir $DIR/R7b
1029         test_mkdir $DIR/R7a/d
1030         mv $DIR/R7a/d $DIR/R7b/e
1031         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1032         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1033 }
1034 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1035
1036 test_24h() {
1037         test_mkdir -c1 $DIR/R8a
1038         test_mkdir -c1 $DIR/R8b
1039         test_mkdir -c1 $DIR/R8a/d
1040         test_mkdir -c1 $DIR/R8b/e
1041         mrename $DIR/R8a/d $DIR/R8b/e
1042         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1043         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1044 }
1045 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1046
1047 test_24i() {
1048         echo "-- rename error cases"
1049         test_mkdir $DIR/R9
1050         test_mkdir $DIR/R9/a
1051         touch $DIR/R9/f
1052         mrename $DIR/R9/f $DIR/R9/a
1053         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1054         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1055         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1056 }
1057 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1058
1059 test_24j() {
1060         test_mkdir $DIR/R10
1061         mrename $DIR/R10/f $DIR/R10/g
1062         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1063         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1064         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1065 }
1066 run_test 24j "source does not exist ============================"
1067
1068 test_24k() {
1069         test_mkdir $DIR/R11a
1070         test_mkdir $DIR/R11a/d
1071         touch $DIR/R11a/f
1072         mv $DIR/R11a/f $DIR/R11a/d
1073         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1074         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1075 }
1076 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1077
1078 # bug 2429 - rename foo foo foo creates invalid file
1079 test_24l() {
1080         f="$DIR/f24l"
1081         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1082 }
1083 run_test 24l "Renaming a file to itself ========================"
1084
1085 test_24m() {
1086         f="$DIR/f24m"
1087         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1088         # on ext3 this does not remove either the source or target files
1089         # though the "expected" operation would be to remove the source
1090         $CHECKSTAT -t file ${f} || error "${f} missing"
1091         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1092 }
1093 run_test 24m "Renaming a file to a hard link to itself ========="
1094
1095 test_24n() {
1096     f="$DIR/f24n"
1097     # this stats the old file after it was renamed, so it should fail
1098     touch ${f}
1099     $CHECKSTAT ${f} || error "${f} missing"
1100     mv ${f} ${f}.rename
1101     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1102     $CHECKSTAT -a ${f} || error "${f} exists"
1103 }
1104 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1105
1106 test_24o() {
1107         test_mkdir $DIR/$tdir
1108         rename_many -s random -v -n 10 $DIR/$tdir
1109 }
1110 run_test 24o "rename of files during htree split"
1111
1112 test_24p() {
1113         test_mkdir $DIR/R12a
1114         test_mkdir $DIR/R12b
1115         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1116         mrename $DIR/R12a $DIR/R12b
1117         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1118         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1119         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1120         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1121 }
1122 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1123
1124 cleanup_multiop_pause() {
1125         trap 0
1126         kill -USR1 $MULTIPID
1127 }
1128
1129 test_24q() {
1130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1131
1132         test_mkdir $DIR/R13a
1133         test_mkdir $DIR/R13b
1134         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1135         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1136         MULTIPID=$!
1137
1138         trap cleanup_multiop_pause EXIT
1139         mrename $DIR/R13a $DIR/R13b
1140         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1141         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1142         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1143         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1144         cleanup_multiop_pause
1145         wait $MULTIPID || error "multiop close failed"
1146 }
1147 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1148
1149 test_24r() { #bug 3789
1150         test_mkdir $DIR/R14a
1151         test_mkdir $DIR/R14a/b
1152         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1153         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1154         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1155 }
1156 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1157
1158 test_24s() {
1159         test_mkdir $DIR/R15a
1160         test_mkdir $DIR/R15a/b
1161         test_mkdir $DIR/R15a/b/c
1162         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1163         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1164         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1165 }
1166 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1167
1168 test_24t() {
1169         test_mkdir $DIR/R16a
1170         test_mkdir $DIR/R16a/b
1171         test_mkdir $DIR/R16a/b/c
1172         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1173         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1174         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1175 }
1176 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1177
1178 test_24u() { # bug12192
1179         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1180         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1181 }
1182 run_test 24u "create stripe file"
1183
1184 simple_cleanup_common() {
1185         local createmany=$1
1186         local rc=0
1187
1188         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1189
1190         local start=$SECONDS
1191
1192         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1193         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1194         rc=$?
1195         wait_delete_completed
1196         echo "cleanup time $((SECONDS - start))"
1197         return $rc
1198 }
1199
1200 max_pages_per_rpc() {
1201         local mdtname="$(printf "MDT%04x" ${1:-0})"
1202         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1203 }
1204
1205 test_24v() {
1206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1207
1208         local nrfiles=${COUNT:-100000}
1209         local fname="$DIR/$tdir/$tfile"
1210
1211         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1212         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1213
1214         test_mkdir "$(dirname $fname)"
1215         # assume MDT0000 has the fewest inodes
1216         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1217         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1218         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1219
1220         stack_trap "simple_cleanup_common $nrfiles"
1221
1222         createmany -m "$fname" $nrfiles
1223
1224         cancel_lru_locks mdc
1225         lctl set_param mdc.*.stats clear
1226
1227         # was previously test_24D: LU-6101
1228         # readdir() returns correct number of entries after cursor reload
1229         local num_ls=$(ls $DIR/$tdir | wc -l)
1230         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1231         local num_all=$(ls -a $DIR/$tdir | wc -l)
1232         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1233                 [ $num_all -ne $((nrfiles + 2)) ]; then
1234                         error "Expected $nrfiles files, got $num_ls " \
1235                                 "($num_uniq unique $num_all .&..)"
1236         fi
1237         # LU-5 large readdir
1238         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1239         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1240         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1241         # take into account of overhead in lu_dirpage header and end mark in
1242         # each page, plus one in rpc_num calculation.
1243         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1244         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1245         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1246         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1247         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1248         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1249         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1250         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1251                 error "large readdir doesn't take effect: " \
1252                       "$mds_readpage should be about $rpc_max"
1253 }
1254 run_test 24v "list large directory (test hash collision, b=17560)"
1255
1256 test_24w() { # bug21506
1257         SZ1=234852
1258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1259         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1260         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1261         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1262         [[ "$SZ1" -eq "$SZ2" ]] ||
1263                 error "Error reading at the end of the file $tfile"
1264 }
1265 run_test 24w "Reading a file larger than 4Gb"
1266
1267 test_24x() {
1268         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1270         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1271                 skip "Need MDS version at least 2.7.56"
1272
1273         local MDTIDX=1
1274         local remote_dir=$DIR/$tdir/remote_dir
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $MDTIDX $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $DIR/$tdir/src_dir
1281         touch $DIR/$tdir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename dir cross MDT failed!"
1287
1288         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1289                 error "rename file cross MDT failed!"
1290
1291         touch $DIR/$tdir/ln_file
1292         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1293                 error "ln file cross MDT failed"
1294
1295         rm -rf $DIR/$tdir || error "Can not delete directories"
1296 }
1297 run_test 24x "cross MDT rename/link"
1298
1299 test_24y() {
1300         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1302
1303         local remote_dir=$DIR/$tdir/remote_dir
1304         local mdtidx=1
1305
1306         test_mkdir $DIR/$tdir
1307         $LFS mkdir -i $mdtidx $remote_dir ||
1308                 error "create remote directory failed"
1309
1310         test_mkdir $remote_dir/src_dir
1311         touch $remote_dir/src_file
1312         test_mkdir $remote_dir/tgt_dir
1313         touch $remote_dir/tgt_file
1314
1315         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1316                 error "rename subdir in the same remote dir failed!"
1317
1318         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1319                 error "rename files in the same remote dir failed!"
1320
1321         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1322                 error "link files in the same remote dir failed!"
1323
1324         rm -rf $DIR/$tdir || error "Can not delete directories"
1325 }
1326 run_test 24y "rename/link on the same dir should succeed"
1327
1328 test_24z() {
1329         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1330         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1331                 skip "Need MDS version at least 2.12.51"
1332
1333         local index
1334
1335         for index in 0 1; do
1336                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1337                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1338         done
1339
1340         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1341
1342         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1343         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1344
1345         local mdts=$(comma_list $(mdts_nodes))
1346
1347         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1348         stack_trap "do_nodes $mdts $LCTL \
1349                 set_param mdt.*.enable_remote_rename=1" EXIT
1350
1351         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1352
1353         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1354         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1355 }
1356 run_test 24z "cross-MDT rename is done as cp"
1357
1358 test_24A() { # LU-3182
1359         local NFILES=5000
1360
1361         test_mkdir $DIR/$tdir
1362         stack_trap "simple_cleanup_common $NFILES"
1363         createmany -m $DIR/$tdir/$tfile $NFILES
1364         local t=$(ls $DIR/$tdir | wc -l)
1365         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1366         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1367
1368         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1369                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1370 }
1371 run_test 24A "readdir() returns correct number of entries."
1372
1373 test_24B() { # LU-4805
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         local count
1377
1378         test_mkdir $DIR/$tdir
1379         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1380                 error "create striped dir failed"
1381
1382         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1383         [ $count -eq 2 ] || error "Expected 2, got $count"
1384
1385         touch $DIR/$tdir/striped_dir/a
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 3 ] || error "Expected 3, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/.f
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 4 ] || error "Expected 4, got $count"
1394
1395         rm -rf $DIR/$tdir || error "Can not delete directories"
1396 }
1397 run_test 24B "readdir for striped dir return correct number of entries"
1398
1399 test_24C() {
1400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1401
1402         mkdir $DIR/$tdir
1403         mkdir $DIR/$tdir/d0
1404         mkdir $DIR/$tdir/d1
1405
1406         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1407                 error "create striped dir failed"
1408
1409         cd $DIR/$tdir/d0/striped_dir
1410
1411         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1412         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1413         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1414
1415         [ "$d0_ino" = "$parent_ino" ] ||
1416                 error ".. wrong, expect $d0_ino, get $parent_ino"
1417
1418         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1419                 error "mv striped dir failed"
1420
1421         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1422
1423         [ "$d1_ino" = "$parent_ino" ] ||
1424                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1425 }
1426 run_test 24C "check .. in striped dir"
1427
1428 test_24E() {
1429         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1431
1432         mkdir -p $DIR/$tdir
1433         mkdir $DIR/$tdir/src_dir
1434         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1435                 error "create remote source failed"
1436
1437         touch $DIR/$tdir/src_dir/src_child/a
1438
1439         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1440                 error "create remote target dir failed"
1441
1442         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1443                 error "create remote target child failed"
1444
1445         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1446                 error "rename dir cross MDT failed!"
1447
1448         find $DIR/$tdir
1449
1450         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1451                 error "src_child still exists after rename"
1452
1453         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1454                 error "missing file(a) after rename"
1455
1456         rm -rf $DIR/$tdir || error "Can not delete directories"
1457 }
1458 run_test 24E "cross MDT rename/link"
1459
1460 test_24F () {
1461         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1462
1463         local repeats=1000
1464         [ "$SLOW" = "no" ] && repeats=100
1465
1466         mkdir -p $DIR/$tdir
1467
1468         echo "$repeats repeats"
1469         for ((i = 0; i < repeats; i++)); do
1470                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1471                 touch $DIR/$tdir/test/a || error "touch fails"
1472                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1473                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1474         done
1475
1476         true
1477 }
1478 run_test 24F "hash order vs readdir (LU-11330)"
1479
1480 test_24G () {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482
1483         local ino1
1484         local ino2
1485
1486         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1487         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1488         touch $DIR/$tdir-0/f1 || error "touch f1"
1489         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1490         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1491         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1492         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1493         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1494 }
1495 run_test 24G "migrate symlink in rename"
1496
1497 test_24H() {
1498         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1499         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1500                 skip "MDT1 should be on another node"
1501
1502         test_mkdir -i 1 -c 1 $DIR/$tdir
1503 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1504         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1505         touch $DIR/$tdir/$tfile || error "touch failed"
1506 }
1507 run_test 24H "repeat FLD_QUERY rpc"
1508
1509 test_25a() {
1510         echo '== symlink sanity ============================================='
1511
1512         test_mkdir $DIR/d25
1513         ln -s d25 $DIR/s25
1514         touch $DIR/s25/foo ||
1515                 error "File creation in symlinked directory failed"
1516 }
1517 run_test 25a "create file in symlinked directory ==============="
1518
1519 test_25b() {
1520         [ ! -d $DIR/d25 ] && test_25a
1521         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1522 }
1523 run_test 25b "lookup file in symlinked directory ==============="
1524
1525 test_26a() {
1526         test_mkdir $DIR/d26
1527         test_mkdir $DIR/d26/d26-2
1528         ln -s d26/d26-2 $DIR/s26
1529         touch $DIR/s26/foo || error "File creation failed"
1530 }
1531 run_test 26a "multiple component symlink ======================="
1532
1533 test_26b() {
1534         test_mkdir -p $DIR/$tdir/d26-2
1535         ln -s $tdir/d26-2/foo $DIR/s26-2
1536         touch $DIR/s26-2 || error "File creation failed"
1537 }
1538 run_test 26b "multiple component symlink at end of lookup ======"
1539
1540 test_26c() {
1541         test_mkdir $DIR/d26.2
1542         touch $DIR/d26.2/foo
1543         ln -s d26.2 $DIR/s26.2-1
1544         ln -s s26.2-1 $DIR/s26.2-2
1545         ln -s s26.2-2 $DIR/s26.2-3
1546         chmod 0666 $DIR/s26.2-3/foo
1547 }
1548 run_test 26c "chain of symlinks"
1549
1550 # recursive symlinks (bug 439)
1551 test_26d() {
1552         ln -s d26-3/foo $DIR/d26-3
1553 }
1554 run_test 26d "create multiple component recursive symlink"
1555
1556 test_26e() {
1557         [ ! -h $DIR/d26-3 ] && test_26d
1558         rm $DIR/d26-3
1559 }
1560 run_test 26e "unlink multiple component recursive symlink"
1561
1562 # recursive symlinks (bug 7022)
1563 test_26f() {
1564         test_mkdir $DIR/$tdir
1565         test_mkdir $DIR/$tdir/$tfile
1566         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1567         test_mkdir -p lndir/bar1
1568         test_mkdir $DIR/$tdir/$tfile/$tfile
1569         cd $tfile                || error "cd $tfile failed"
1570         ln -s .. dotdot          || error "ln dotdot failed"
1571         ln -s dotdot/lndir lndir || error "ln lndir failed"
1572         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1573         output=`ls $tfile/$tfile/lndir/bar1`
1574         [ "$output" = bar1 ] && error "unexpected output"
1575         rm -r $tfile             || error "rm $tfile failed"
1576         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1577 }
1578 run_test 26f "rm -r of a directory which has recursive symlink"
1579
1580 test_27a() {
1581         test_mkdir $DIR/$tdir
1582         $LFS getstripe $DIR/$tdir
1583         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1584         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1585         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1586 }
1587 run_test 27a "one stripe file"
1588
1589 test_27b() {
1590         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1591
1592         test_mkdir $DIR/$tdir
1593         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1594         $LFS getstripe -c $DIR/$tdir/$tfile
1595         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1596                 error "two-stripe file doesn't have two stripes"
1597
1598         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1599 }
1600 run_test 27b "create and write to two stripe file"
1601
1602 # 27c family tests specific striping, setstripe -o
1603 test_27ca() {
1604         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1605         test_mkdir -p $DIR/$tdir
1606         local osts="1"
1607
1608         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1609         $LFS getstripe -i $DIR/$tdir/$tfile
1610         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1611                 error "stripe not on specified OST"
1612
1613         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1614 }
1615 run_test 27ca "one stripe on specified OST"
1616
1617 test_27cb() {
1618         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1619         test_mkdir -p $DIR/$tdir
1620         local osts="1,0"
1621         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1622         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1623         echo "$getstripe"
1624
1625         # Strip getstripe output to a space separated list of OSTs
1626         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1627                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1628         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1629                 error "stripes not on specified OSTs"
1630
1631         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1632 }
1633 run_test 27cb "two stripes on specified OSTs"
1634
1635 test_27cc() {
1636         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1637         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1638                 skip "server does not support overstriping"
1639
1640         test_mkdir -p $DIR/$tdir
1641         local osts="0,0"
1642         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1643         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1644         echo "$getstripe"
1645
1646         # Strip getstripe output to a space separated list of OSTs
1647         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1648                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1649         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1650                 error "stripes not on specified OSTs"
1651
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1653 }
1654 run_test 27cc "two stripes on the same OST"
1655
1656 test_27cd() {
1657         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1658         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1659                 skip "server does not support overstriping"
1660         test_mkdir -p $DIR/$tdir
1661         local osts="0,1,1,0"
1662         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1663         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1664         echo "$getstripe"
1665
1666         # Strip getstripe output to a space separated list of OSTs
1667         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1668                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1669         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1670                 error "stripes not on specified OSTs"
1671
1672         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1673 }
1674 run_test 27cd "four stripes on two OSTs"
1675
1676 test_27ce() {
1677         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1678                 skip_env "too many osts, skipping"
1679         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1680                 skip "server does not support overstriping"
1681         # We do one more stripe than we have OSTs
1682         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1683                 skip_env "ea_inode feature disabled"
1684
1685         test_mkdir -p $DIR/$tdir
1686         local osts=""
1687         for i in $(seq 0 $OSTCOUNT);
1688         do
1689                 osts=$osts"0"
1690                 if [ $i -ne $OSTCOUNT ]; then
1691                         osts=$osts","
1692                 fi
1693         done
1694         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1695         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1696         echo "$getstripe"
1697
1698         # Strip getstripe output to a space separated list of OSTs
1699         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1700                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1701         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1702                 error "stripes not on specified OSTs"
1703
1704         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1705 }
1706 run_test 27ce "more stripes than OSTs with -o"
1707
1708 test_27cf() {
1709         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1710         local pid=0
1711
1712         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1713         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1714         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1716                 error "failed to set $osp_proc=0"
1717
1718         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1719         pid=$!
1720         sleep 1
1721         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1722         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1723                 error "failed to set $osp_proc=1"
1724         wait $pid
1725         [[ $pid -ne 0 ]] ||
1726                 error "should return error due to $osp_proc=0"
1727 }
1728 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1729
1730 test_27cg() {
1731         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1732                 skip "server does not support overstriping"
1733         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1734         large_xattr_enabled || skip_env "ea_inode feature disabled"
1735
1736         local osts="0"
1737
1738         for ((i=1;i<1000;i++)); do
1739                 osts+=",$((i % OSTCOUNT))"
1740         done
1741
1742         local mdts=$(comma_list $(mdts_nodes))
1743         local before=$(do_nodes $mdts \
1744                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1745                 awk '/many credits/{print $3}' |
1746                 calc_sum)
1747
1748         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1749         $LFS getstripe $DIR/$tfile | grep stripe
1750
1751         rm -f $DIR/$tfile || error "can't unlink"
1752
1753         after=$(do_nodes $mdts \
1754                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1755                 awk '/many credits/{print $3}' |
1756                 calc_sum)
1757
1758         (( before == after )) ||
1759                 error "too many credits happened: $after > $before"
1760 }
1761 run_test 27cg "1000 shouldn't cause too many credits"
1762
1763 test_27d() {
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1766                 error "setstripe failed"
1767         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1768         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1769 }
1770 run_test 27d "create file with default settings"
1771
1772 test_27e() {
1773         # LU-5839 adds check for existed layout before setting it
1774         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1775                 skip "Need MDS version at least 2.7.56"
1776
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1779         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1780         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1781 }
1782 run_test 27e "setstripe existing file (should return error)"
1783
1784 test_27f() {
1785         test_mkdir $DIR/$tdir
1786         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1787                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1788         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1789                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1790         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1791         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1792 }
1793 run_test 27f "setstripe with bad stripe size (should return error)"
1794
1795 test_27g() {
1796         test_mkdir $DIR/$tdir
1797         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1798         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1799                 error "$DIR/$tdir/$tfile has object"
1800 }
1801 run_test 27g "$LFS getstripe with no objects"
1802
1803 test_27ga() {
1804         test_mkdir $DIR/$tdir
1805         touch $DIR/$tdir/$tfile || error "touch failed"
1806         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1807         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1808         local rc=$?
1809         (( rc == 2 )) || error "getstripe did not return ENOENT"
1810
1811         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1812                         2>&1 > /dev/null)
1813         [[ $err_msg =~ "typo" ]] ||
1814                 error "expected message with correct filename, got '$err_msg'"
1815 }
1816 run_test 27ga "$LFS getstripe with missing file (should return error)"
1817
1818 test_27i() {
1819         test_mkdir $DIR/$tdir
1820         touch $DIR/$tdir/$tfile || error "touch failed"
1821         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1822                 error "missing objects"
1823 }
1824 run_test 27i "$LFS getstripe with some objects"
1825
1826 test_27j() {
1827         test_mkdir $DIR/$tdir
1828         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1829                 error "setstripe failed" || true
1830 }
1831 run_test 27j "setstripe with bad stripe offset (should return error)"
1832
1833 test_27k() { # bug 2844
1834         test_mkdir $DIR/$tdir
1835         local file=$DIR/$tdir/$tfile
1836         local ll_max_blksize=$((4 * 1024 * 1024))
1837         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1838         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1839         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1840         dd if=/dev/zero of=$file bs=4k count=1
1841         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1842         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1843 }
1844 run_test 27k "limit i_blksize for broken user apps"
1845
1846 test_27l() {
1847         mcreate $DIR/$tfile || error "creating file"
1848         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1849                 error "setstripe should have failed" || true
1850 }
1851 run_test 27l "check setstripe permissions (should return error)"
1852
1853 test_27m() {
1854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1855
1856         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1857                 skip_env "multiple clients -- skipping"
1858
1859         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1860                    head -n1)
1861         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1862                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1863         fi
1864         stack_trap simple_cleanup_common
1865         test_mkdir $DIR/$tdir
1866         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1867         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1868                 error "dd should fill OST0"
1869         i=2
1870         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1871                 i=$((i + 1))
1872                 [ $i -gt 256 ] && break
1873         done
1874         i=$((i + 1))
1875         touch $DIR/$tdir/$tfile.$i
1876         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1877             awk '{print $1}'| grep -w "0") ] &&
1878                 error "OST0 was full but new created file still use it"
1879         i=$((i + 1))
1880         touch $DIR/$tdir/$tfile.$i
1881         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1882             awk '{print $1}'| grep -w "0") ] &&
1883                 error "OST0 was full but new created file still use it" || true
1884 }
1885 run_test 27m "create file while OST0 was full"
1886
1887 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1888 # if the OST isn't full anymore.
1889 reset_enospc() {
1890         local ostidx=${1:-""}
1891         local delay
1892         local ready
1893         local get_prealloc
1894
1895         local list=$(comma_list $(osts_nodes))
1896         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1897
1898         do_nodes $list lctl set_param fail_loc=0
1899         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1900         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1901                 awk '{print $1 * 2;exit;}')
1902         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1903                         grep -v \"^0$\""
1904         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1905 }
1906
1907 test_27n() {
1908         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1910         remote_mds_nodsh && skip "remote MDS with nodsh"
1911         remote_ost_nodsh && skip "remote OST with nodsh"
1912
1913         reset_enospc
1914         rm -f $DIR/$tdir/$tfile
1915         exhaust_precreations 0 0x80000215
1916         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1917         touch $DIR/$tdir/$tfile || error "touch failed"
1918         $LFS getstripe $DIR/$tdir/$tfile
1919         reset_enospc
1920 }
1921 run_test 27n "create file with some full OSTs"
1922
1923 test_27o() {
1924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1926         remote_mds_nodsh && skip "remote MDS with nodsh"
1927         remote_ost_nodsh && skip "remote OST with nodsh"
1928
1929         reset_enospc
1930         rm -f $DIR/$tdir/$tfile
1931         exhaust_all_precreations 0x215
1932
1933         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1934
1935         reset_enospc
1936         rm -rf $DIR/$tdir/*
1937 }
1938 run_test 27o "create file with all full OSTs (should error)"
1939
1940 function create_and_checktime() {
1941         local fname=$1
1942         local loops=$2
1943         local i
1944
1945         for ((i=0; i < $loops; i++)); do
1946                 local start=$SECONDS
1947                 multiop $fname-$i Oc
1948                 ((SECONDS-start < TIMEOUT)) ||
1949                         error "creation took " $((SECONDS-$start)) && return 1
1950         done
1951 }
1952
1953 test_27oo() {
1954         local mdts=$(comma_list $(mdts_nodes))
1955
1956         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1957                 skip "Need MDS version at least 2.13.57"
1958
1959         local f0=$DIR/${tfile}-0
1960         local f1=$DIR/${tfile}-1
1961
1962         wait_delete_completed
1963
1964         # refill precreated objects
1965         $LFS setstripe -i0 -c1 $f0
1966
1967         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1968         # force QoS allocation policy
1969         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1970         stack_trap "do_nodes $mdts $LCTL set_param \
1971                 lov.*.qos_threshold_rr=$saved" EXIT
1972         sleep_maxage
1973
1974         # one OST is unavailable, but still have few objects preallocated
1975         stop ost1
1976         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1977                 rm -rf $f1 $DIR/$tdir*" EXIT
1978
1979         for ((i=0; i < 7; i++)); do
1980                 mkdir $DIR/$tdir$i || error "can't create dir"
1981                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1982                         error "can't set striping"
1983         done
1984         for ((i=0; i < 7; i++)); do
1985                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1986         done
1987         wait
1988 }
1989 run_test 27oo "don't let few threads to reserve too many objects"
1990
1991 test_27p() {
1992         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1994         remote_mds_nodsh && skip "remote MDS with nodsh"
1995         remote_ost_nodsh && skip "remote OST with nodsh"
1996
1997         reset_enospc
1998         rm -f $DIR/$tdir/$tfile
1999         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
2000
2001         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2002         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2004
2005         exhaust_precreations 0 0x80000215
2006         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2007         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2008         $LFS getstripe $DIR/$tdir/$tfile
2009
2010         reset_enospc
2011 }
2012 run_test 27p "append to a truncated file with some full OSTs"
2013
2014 test_27q() {
2015         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2017         remote_mds_nodsh && skip "remote MDS with nodsh"
2018         remote_ost_nodsh && skip "remote OST with nodsh"
2019
2020         reset_enospc
2021         rm -f $DIR/$tdir/$tfile
2022
2023         mkdir_on_mdt0 $DIR/$tdir
2024         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2025         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2026                 error "truncate $DIR/$tdir/$tfile failed"
2027         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2028
2029         exhaust_all_precreations 0x215
2030
2031         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2032         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2033
2034         reset_enospc
2035 }
2036 run_test 27q "append to truncated file with all OSTs full (should error)"
2037
2038 test_27r() {
2039         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2041         remote_mds_nodsh && skip "remote MDS with nodsh"
2042         remote_ost_nodsh && skip "remote OST with nodsh"
2043
2044         reset_enospc
2045         rm -f $DIR/$tdir/$tfile
2046         exhaust_precreations 0 0x80000215
2047
2048         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2049
2050         reset_enospc
2051 }
2052 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2053
2054 test_27s() { # bug 10725
2055         test_mkdir $DIR/$tdir
2056         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2057         local stripe_count=0
2058         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2059         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2060                 error "stripe width >= 2^32 succeeded" || true
2061
2062 }
2063 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2064
2065 test_27t() { # bug 10864
2066         WDIR=$(pwd)
2067         WLFS=$(which lfs)
2068         cd $DIR
2069         touch $tfile
2070         $WLFS getstripe $tfile
2071         cd $WDIR
2072 }
2073 run_test 27t "check that utils parse path correctly"
2074
2075 test_27u() { # bug 4900
2076         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2077         remote_mds_nodsh && skip "remote MDS with nodsh"
2078
2079         local index
2080         local list=$(comma_list $(mdts_nodes))
2081
2082 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2083         do_nodes $list $LCTL set_param fail_loc=0x139
2084         test_mkdir -p $DIR/$tdir
2085         stack_trap "simple_cleanup_common 1000"
2086         createmany -o $DIR/$tdir/$tfile 1000
2087         do_nodes $list $LCTL set_param fail_loc=0
2088
2089         TLOG=$TMP/$tfile.getstripe
2090         $LFS getstripe $DIR/$tdir > $TLOG
2091         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2092         [[ $OBJS -gt 0 ]] &&
2093                 error "$OBJS objects created on OST-0. See $TLOG" ||
2094                 rm -f $TLOG
2095 }
2096 run_test 27u "skip object creation on OSC w/o objects"
2097
2098 test_27v() { # bug 4900
2099         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2101         remote_mds_nodsh && skip "remote MDS with nodsh"
2102         remote_ost_nodsh && skip "remote OST with nodsh"
2103
2104         exhaust_all_precreations 0x215
2105         reset_enospc
2106
2107         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2108
2109         touch $DIR/$tdir/$tfile
2110         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2111         # all except ost1
2112         for (( i=1; i < OSTCOUNT; i++ )); do
2113                 do_facet ost$i lctl set_param fail_loc=0x705
2114         done
2115         local START=`date +%s`
2116         createmany -o $DIR/$tdir/$tfile 32
2117
2118         local FINISH=`date +%s`
2119         local TIMEOUT=`lctl get_param -n timeout`
2120         local PROCESS=$((FINISH - START))
2121         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2122                error "$FINISH - $START >= $TIMEOUT / 2"
2123         sleep $((TIMEOUT / 2 - PROCESS))
2124         reset_enospc
2125 }
2126 run_test 27v "skip object creation on slow OST"
2127
2128 test_27w() { # bug 10997
2129         test_mkdir $DIR/$tdir
2130         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2131         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2132                 error "stripe size $size != 65536" || true
2133         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2134                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2135 }
2136 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2137
2138 test_27wa() {
2139         [[ $OSTCOUNT -lt 2 ]] &&
2140                 skip_env "skipping multiple stripe count/offset test"
2141
2142         test_mkdir $DIR/$tdir
2143         for i in $(seq 1 $OSTCOUNT); do
2144                 offset=$((i - 1))
2145                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2146                         error "setstripe -c $i -i $offset failed"
2147                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2148                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2149                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2150                 [ $index -ne $offset ] &&
2151                         error "stripe offset $index != $offset" || true
2152         done
2153 }
2154 run_test 27wa "check $LFS setstripe -c -i options"
2155
2156 test_27x() {
2157         remote_ost_nodsh && skip "remote OST with nodsh"
2158         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2160
2161         OFFSET=$(($OSTCOUNT - 1))
2162         OSTIDX=0
2163         local OST=$(ostname_from_index $OSTIDX)
2164
2165         test_mkdir $DIR/$tdir
2166         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2167         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2168         sleep_maxage
2169         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2170         for i in $(seq 0 $OFFSET); do
2171                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2172                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2173                 error "OST0 was degraded but new created file still use it"
2174         done
2175         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2176 }
2177 run_test 27x "create files while OST0 is degraded"
2178
2179 test_27y() {
2180         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2181         remote_mds_nodsh && skip "remote MDS with nodsh"
2182         remote_ost_nodsh && skip "remote OST with nodsh"
2183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2184
2185         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2186         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2187                 osp.$mdtosc.prealloc_last_id)
2188         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2189                 osp.$mdtosc.prealloc_next_id)
2190         local fcount=$((last_id - next_id))
2191         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2192         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2193
2194         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2195                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2196         local OST_DEACTIVE_IDX=-1
2197         local OSC
2198         local OSTIDX
2199         local OST
2200
2201         for OSC in $MDS_OSCS; do
2202                 OST=$(osc_to_ost $OSC)
2203                 OSTIDX=$(index_from_ostuuid $OST)
2204                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2205                         OST_DEACTIVE_IDX=$OSTIDX
2206                 fi
2207                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2208                         echo $OSC "is Deactivated:"
2209                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2210                 fi
2211         done
2212
2213         OSTIDX=$(index_from_ostuuid $OST)
2214         test_mkdir $DIR/$tdir
2215         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2216
2217         for OSC in $MDS_OSCS; do
2218                 OST=$(osc_to_ost $OSC)
2219                 OSTIDX=$(index_from_ostuuid $OST)
2220                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2221                         echo $OST "is degraded:"
2222                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2223                                                 obdfilter.$OST.degraded=1
2224                 fi
2225         done
2226
2227         sleep_maxage
2228         createmany -o $DIR/$tdir/$tfile $fcount
2229
2230         for OSC in $MDS_OSCS; do
2231                 OST=$(osc_to_ost $OSC)
2232                 OSTIDX=$(index_from_ostuuid $OST)
2233                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2234                         echo $OST "is recovered from degraded:"
2235                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2236                                                 obdfilter.$OST.degraded=0
2237                 else
2238                         do_facet $SINGLEMDS lctl --device %$OSC activate
2239                 fi
2240         done
2241
2242         # all osp devices get activated, hence -1 stripe count restored
2243         local stripe_count=0
2244
2245         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2246         # devices get activated.
2247         sleep_maxage
2248         $LFS setstripe -c -1 $DIR/$tfile
2249         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2250         rm -f $DIR/$tfile
2251         [ $stripe_count -ne $OSTCOUNT ] &&
2252                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2253         return 0
2254 }
2255 run_test 27y "create files while OST0 is degraded and the rest inactive"
2256
2257 check_seq_oid()
2258 {
2259         log "check file $1"
2260
2261         lmm_count=$($LFS getstripe -c $1)
2262         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2263         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2264
2265         local old_ifs="$IFS"
2266         IFS=$'[:]'
2267         fid=($($LFS path2fid $1))
2268         IFS="$old_ifs"
2269
2270         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2271         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2272
2273         # compare lmm_seq and lu_fid->f_seq
2274         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2275         # compare lmm_object_id and lu_fid->oid
2276         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2277
2278         # check the trusted.fid attribute of the OST objects of the file
2279         local have_obdidx=false
2280         local stripe_nr=0
2281         $LFS getstripe $1 | while read obdidx oid hex seq; do
2282                 # skip lines up to and including "obdidx"
2283                 [ -z "$obdidx" ] && break
2284                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2285                 $have_obdidx || continue
2286
2287                 local ost=$((obdidx + 1))
2288                 local dev=$(ostdevname $ost)
2289                 local oid_hex
2290
2291                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2292
2293                 seq=$(echo $seq | sed -e "s/^0x//g")
2294                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2295                         oid_hex=$(echo $oid)
2296                 else
2297                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2298                 fi
2299                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2300
2301                 local ff=""
2302                 #
2303                 # Don't unmount/remount the OSTs if we don't need to do that.
2304                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2305                 # update too, until that use mount/ll_decode_filter_fid/mount.
2306                 # Re-enable when debugfs will understand new filter_fid.
2307                 #
2308                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2309                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2310                                 $dev 2>/dev/null" | grep "parent=")
2311                 fi
2312                 if [ -z "$ff" ]; then
2313                         stop ost$ost
2314                         mount_fstype ost$ost
2315                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2316                                 $(facet_mntpt ost$ost)/$obj_file)
2317                         unmount_fstype ost$ost
2318                         start ost$ost $dev $OST_MOUNT_OPTS
2319                         clients_up
2320                 fi
2321
2322                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2323
2324                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2325
2326                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2327                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2328                 #
2329                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2330                 #       stripe_size=1048576 component_id=1 component_start=0 \
2331                 #       component_end=33554432
2332                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2333                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2334                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2335                 local ff_pstripe
2336                 if grep -q 'stripe=' <<<$ff; then
2337                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2338                 else
2339                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2340                         # into f_ver in this case.  See comment on ff_parent.
2341                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2342                 fi
2343
2344                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2345                 [ $ff_pseq = $lmm_seq ] ||
2346                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2347                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2348                 [ $ff_poid = $lmm_oid ] ||
2349                         error "FF parent OID $ff_poid != $lmm_oid"
2350                 (($ff_pstripe == $stripe_nr)) ||
2351                         error "FF stripe $ff_pstripe != $stripe_nr"
2352
2353                 stripe_nr=$((stripe_nr + 1))
2354                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2355                         continue
2356                 if grep -q 'stripe_count=' <<<$ff; then
2357                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2358                                             -e 's/ .*//' <<<$ff)
2359                         [ $lmm_count = $ff_scnt ] ||
2360                                 error "FF stripe count $lmm_count != $ff_scnt"
2361                 fi
2362         done
2363 }
2364
2365 test_27z() {
2366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2367         remote_ost_nodsh && skip "remote OST with nodsh"
2368
2369         test_mkdir $DIR/$tdir
2370         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2371                 { error "setstripe -c -1 failed"; return 1; }
2372         # We need to send a write to every object to get parent FID info set.
2373         # This _should_ also work for setattr, but does not currently.
2374         # touch $DIR/$tdir/$tfile-1 ||
2375         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2376                 { error "dd $tfile-1 failed"; return 2; }
2377         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2378                 { error "setstripe -c -1 failed"; return 3; }
2379         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2380                 { error "dd $tfile-2 failed"; return 4; }
2381
2382         # make sure write RPCs have been sent to OSTs
2383         sync; sleep 5; sync
2384
2385         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2386         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2387 }
2388 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2389
2390 test_27A() { # b=19102
2391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2392
2393         save_layout_restore_at_exit $MOUNT
2394         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2395         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2396                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2397         local default_size=$($LFS getstripe -S $MOUNT)
2398         local default_offset=$($LFS getstripe -i $MOUNT)
2399         local dsize=$(do_facet $SINGLEMDS \
2400                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2401         [ $default_size -eq $dsize ] ||
2402                 error "stripe size $default_size != $dsize"
2403         [ $default_offset -eq -1 ] ||
2404                 error "stripe offset $default_offset != -1"
2405 }
2406 run_test 27A "check filesystem-wide default LOV EA values"
2407
2408 test_27B() { # LU-2523
2409         test_mkdir $DIR/$tdir
2410         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2411         touch $DIR/$tdir/f0
2412         # open f1 with O_LOV_DELAY_CREATE
2413         # rename f0 onto f1
2414         # call setstripe ioctl on open file descriptor for f1
2415         # close
2416         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2417                 $DIR/$tdir/f0
2418
2419         rm -f $DIR/$tdir/f1
2420         # open f1 with O_LOV_DELAY_CREATE
2421         # unlink f1
2422         # call setstripe ioctl on open file descriptor for f1
2423         # close
2424         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2425
2426         # Allow multiop to fail in imitation of NFS's busted semantics.
2427         true
2428 }
2429 run_test 27B "call setstripe on open unlinked file/rename victim"
2430
2431 # 27C family tests full striping and overstriping
2432 test_27Ca() { #LU-2871
2433         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2434
2435         declare -a ost_idx
2436         local index
2437         local found
2438         local i
2439         local j
2440
2441         test_mkdir $DIR/$tdir
2442         cd $DIR/$tdir
2443         for i in $(seq 0 $((OSTCOUNT - 1))); do
2444                 # set stripe across all OSTs starting from OST$i
2445                 $LFS setstripe -i $i -c -1 $tfile$i
2446                 # get striping information
2447                 ost_idx=($($LFS getstripe $tfile$i |
2448                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2449                 echo "OST Index: ${ost_idx[*]}"
2450
2451                 # check the layout
2452                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2453                         error "${#ost_idx[@]} != $OSTCOUNT"
2454
2455                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2456                         found=0
2457                         for j in "${ost_idx[@]}"; do
2458                                 if [ $index -eq $j ]; then
2459                                         found=1
2460                                         break
2461                                 fi
2462                         done
2463                         [ $found = 1 ] ||
2464                                 error "Can not find $index in ${ost_idx[*]}"
2465                 done
2466         done
2467 }
2468 run_test 27Ca "check full striping across all OSTs"
2469
2470 test_27Cb() {
2471         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2472                 skip "server does not support overstriping"
2473         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2474                 skip_env "too many osts, skipping"
2475
2476         test_mkdir -p $DIR/$tdir
2477         local setcount=$(($OSTCOUNT * 2))
2478         [ $setcount -lt 160 ] || large_xattr_enabled ||
2479                 skip_env "ea_inode feature disabled"
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493 }
2494 run_test 27Cb "more stripes than OSTs with -C"
2495
2496 test_27Cc() {
2497         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2498                 skip "server does not support overstriping"
2499         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$(($OSTCOUNT - 1))
2503
2504         [ $setcount -lt 160 ] || large_xattr_enabled ||
2505                 skip_env "ea_inode feature disabled"
2506
2507         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2508                 error "setstripe failed"
2509
2510         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2511         [ $count -eq $setcount ] ||
2512                 error "stripe count $count, should be $setcount"
2513
2514         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2515                 error "overstriped should not be set in pattern"
2516
2517         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2518                 error "dd failed"
2519 }
2520 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2521
2522 test_27Cd() {
2523         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2524                 skip "server does not support overstriping"
2525         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2526         large_xattr_enabled || skip_env "ea_inode feature disabled"
2527
2528         force_new_seq_all
2529
2530         test_mkdir -p $DIR/$tdir
2531         local setcount=$LOV_MAX_STRIPE_COUNT
2532
2533         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2534                 error "setstripe failed"
2535
2536         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2537         [ $count -eq $setcount ] ||
2538                 error "stripe count $count, should be $setcount"
2539
2540         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2541                 error "overstriped should be set in pattern"
2542
2543         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2544                 error "dd failed"
2545
2546         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2547 }
2548 run_test 27Cd "test maximum stripe count"
2549
2550 test_27Ce() {
2551         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2552                 skip "server does not support overstriping"
2553         test_mkdir -p $DIR/$tdir
2554
2555         pool_add $TESTNAME || error "Pool creation failed"
2556         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2557
2558         local setcount=8
2559
2560         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2561                 error "setstripe failed"
2562
2563         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2564         [ $count -eq $setcount ] ||
2565                 error "stripe count $count, should be $setcount"
2566
2567         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2568                 error "overstriped should be set in pattern"
2569
2570         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2571                 error "dd failed"
2572
2573         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2574 }
2575 run_test 27Ce "test pool with overstriping"
2576
2577 test_27Cf() {
2578         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2579                 skip "server does not support overstriping"
2580         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2581                 skip_env "too many osts, skipping"
2582
2583         test_mkdir -p $DIR/$tdir
2584
2585         local setcount=$(($OSTCOUNT * 2))
2586         [ $setcount -lt 160 ] || large_xattr_enabled ||
2587                 skip_env "ea_inode feature disabled"
2588
2589         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2590                 error "setstripe failed"
2591
2592         echo 1 > $DIR/$tdir/$tfile
2593
2594         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2595         [ $count -eq $setcount ] ||
2596                 error "stripe count $count, should be $setcount"
2597
2598         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2599                 error "overstriped should be set in pattern"
2600
2601         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2602                 error "dd failed"
2603
2604         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2605 }
2606 run_test 27Cf "test default inheritance with overstriping"
2607
2608 test_27Cg() {
2609         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2610                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2611
2612         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2613         (( $? != 0 )) || error "must be an error for not existent OST#"
2614 }
2615 run_test 27Cg "test setstripe with wrong OST idx"
2616
2617 test_27D() {
2618         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2619         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2620         remote_mds_nodsh && skip "remote MDS with nodsh"
2621
2622         local POOL=${POOL:-testpool}
2623         local first_ost=0
2624         local last_ost=$(($OSTCOUNT - 1))
2625         local ost_step=1
2626         local ost_list=$(seq $first_ost $ost_step $last_ost)
2627         local ost_range="$first_ost $last_ost $ost_step"
2628
2629         test_mkdir $DIR/$tdir
2630         pool_add $POOL || error "pool_add failed"
2631         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2632
2633         local skip27D
2634         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2635                 skip27D+="-s 29"
2636         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2637                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2638                         skip27D+=" -s 30,31"
2639         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2640           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2641                 skip27D+=" -s 32,33"
2642         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2643                 skip27D+=" -s 34"
2644         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2645                 error "llapi_layout_test failed"
2646
2647         destroy_test_pools || error "destroy test pools failed"
2648 }
2649 run_test 27D "validate llapi_layout API"
2650
2651 # Verify that default_easize is increased from its initial value after
2652 # accessing a widely striped file.
2653 test_27E() {
2654         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2655         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2656                 skip "client does not have LU-3338 fix"
2657
2658         # 72 bytes is the minimum space required to store striping
2659         # information for a file striped across one OST:
2660         # (sizeof(struct lov_user_md_v3) +
2661         #  sizeof(struct lov_user_ost_data_v1))
2662         local min_easize=72
2663         $LCTL set_param -n llite.*.default_easize $min_easize ||
2664                 error "lctl set_param failed"
2665         local easize=$($LCTL get_param -n llite.*.default_easize)
2666
2667         [ $easize -eq $min_easize ] ||
2668                 error "failed to set default_easize"
2669
2670         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2671                 error "setstripe failed"
2672         # In order to ensure stat() call actually talks to MDS we need to
2673         # do something drastic to this file to shake off all lock, e.g.
2674         # rename it (kills lookup lock forcing cache cleaning)
2675         mv $DIR/$tfile $DIR/${tfile}-1
2676         ls -l $DIR/${tfile}-1
2677         rm $DIR/${tfile}-1
2678
2679         easize=$($LCTL get_param -n llite.*.default_easize)
2680
2681         [ $easize -gt $min_easize ] ||
2682                 error "default_easize not updated"
2683 }
2684 run_test 27E "check that default extended attribute size properly increases"
2685
2686 test_27F() { # LU-5346/LU-7975
2687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2688         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2689         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2690                 skip "Need MDS version at least 2.8.51"
2691         remote_ost_nodsh && skip "remote OST with nodsh"
2692
2693         test_mkdir $DIR/$tdir
2694         rm -f $DIR/$tdir/f0
2695         $LFS setstripe -c 2 $DIR/$tdir
2696
2697         # stop all OSTs to reproduce situation for LU-7975 ticket
2698         for num in $(seq $OSTCOUNT); do
2699                 stop ost$num
2700         done
2701
2702         # open/create f0 with O_LOV_DELAY_CREATE
2703         # truncate f0 to a non-0 size
2704         # close
2705         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2706
2707         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2708         # open/write it again to force delayed layout creation
2709         cat /etc/hosts > $DIR/$tdir/f0 &
2710         catpid=$!
2711
2712         # restart OSTs
2713         for num in $(seq $OSTCOUNT); do
2714                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2715                         error "ost$num failed to start"
2716         done
2717
2718         wait $catpid || error "cat failed"
2719
2720         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2721         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2722                 error "wrong stripecount"
2723
2724 }
2725 run_test 27F "Client resend delayed layout creation with non-zero size"
2726
2727 test_27G() { #LU-10629
2728         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2729                 skip "Need MDS version at least 2.11.51"
2730         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2731         remote_mds_nodsh && skip "remote MDS with nodsh"
2732         local POOL=${POOL:-testpool}
2733         local ostrange="0 0 1"
2734
2735         test_mkdir $DIR/$tdir
2736         touch $DIR/$tdir/$tfile.nopool
2737         pool_add $POOL || error "pool_add failed"
2738         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2739         $LFS setstripe -p $POOL $DIR/$tdir
2740
2741         local pool=$($LFS getstripe -p $DIR/$tdir)
2742
2743         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2744         touch $DIR/$tdir/$tfile.default
2745         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2746         $LFS find $DIR/$tdir -type f --pool $POOL
2747         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2748         [[ "$found" == "2" ]] ||
2749                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2750
2751         $LFS setstripe -d $DIR/$tdir
2752
2753         pool=$($LFS getstripe -p -d $DIR/$tdir)
2754
2755         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2756 }
2757 run_test 27G "Clear OST pool from stripe"
2758
2759 test_27H() {
2760         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2761                 skip "Need MDS version newer than 2.11.54"
2762         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2763         test_mkdir $DIR/$tdir
2764         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2765         touch $DIR/$tdir/$tfile
2766         $LFS getstripe -c $DIR/$tdir/$tfile
2767         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2768                 error "two-stripe file doesn't have two stripes"
2769
2770         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2771         $LFS getstripe -y $DIR/$tdir/$tfile
2772         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2773              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2774                 error "expected l_ost_idx: [02]$ not matched"
2775
2776         # make sure ost list has been cleared
2777         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2778         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2779                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2780         touch $DIR/$tdir/f3
2781         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2782 }
2783 run_test 27H "Set specific OSTs stripe"
2784
2785 test_27I() {
2786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2787         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2788         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2789                 skip "Need MDS version newer than 2.12.52"
2790         local pool=$TESTNAME
2791         local ostrange="1 1 1"
2792
2793         save_layout_restore_at_exit $MOUNT
2794         $LFS setstripe -c 2 -i 0 $MOUNT
2795         pool_add $pool || error "pool_add failed"
2796         pool_add_targets $pool $ostrange ||
2797                 error "pool_add_targets failed"
2798         test_mkdir $DIR/$tdir
2799         $LFS setstripe -p $pool $DIR/$tdir
2800         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2801         $LFS getstripe $DIR/$tdir/$tfile
2802 }
2803 run_test 27I "check that root dir striping does not break parent dir one"
2804
2805 test_27J() {
2806         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2807                 skip "Need MDS version newer than 2.12.51"
2808
2809         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2810         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2811         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2812            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2813                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2814
2815         test_mkdir $DIR/$tdir
2816         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2817         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2818
2819         # create foreign file (raw way)
2820         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2821                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2822
2823         ! $LFS setstripe --foreign --flags foo \
2824                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2825                         error "creating $tfile with '--flags foo' should fail"
2826
2827         ! $LFS setstripe --foreign --flags 0xffffffff \
2828                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2829                         error "creating $tfile w/ 0xffffffff flags should fail"
2830
2831         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2832                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2833
2834         # verify foreign file (raw way)
2835         parse_foreign_file -f $DIR/$tdir/$tfile |
2836                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2837                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2838         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2839                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2840         parse_foreign_file -f $DIR/$tdir/$tfile |
2841                 grep "lov_foreign_size: 73" ||
2842                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2843         parse_foreign_file -f $DIR/$tdir/$tfile |
2844                 grep "lov_foreign_type: 1" ||
2845                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2846         parse_foreign_file -f $DIR/$tdir/$tfile |
2847                 grep "lov_foreign_flags: 0x0000DA08" ||
2848                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2849         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2850                 grep "lov_foreign_value: 0x" |
2851                 sed -e 's/lov_foreign_value: 0x//')
2852         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2853         [[ $lov = ${lov2// /} ]] ||
2854                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2855
2856         # create foreign file (lfs + API)
2857         $LFS setstripe --foreign=none --flags 0xda08 \
2858                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2859                 error "$DIR/$tdir/${tfile}2: create failed"
2860
2861         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2862                 grep "lfm_magic:.*0x0BD70BD0" ||
2863                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2864         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2865         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2866                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2867         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2868                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2869         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2870                 grep "lfm_flags:.*0x0000DA08" ||
2871                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2872         $LFS getstripe $DIR/$tdir/${tfile}2 |
2873                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2874                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2875
2876         # modify striping should fail
2877         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2878                 error "$DIR/$tdir/$tfile: setstripe should fail"
2879         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2880                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2881
2882         # R/W should fail
2883         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2884         cat $DIR/$tdir/${tfile}2 &&
2885                 error "$DIR/$tdir/${tfile}2: read should fail"
2886         cat /etc/passwd > $DIR/$tdir/$tfile &&
2887                 error "$DIR/$tdir/$tfile: write should fail"
2888         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2889                 error "$DIR/$tdir/${tfile}2: write should fail"
2890
2891         # chmod should work
2892         chmod 222 $DIR/$tdir/$tfile ||
2893                 error "$DIR/$tdir/$tfile: chmod failed"
2894         chmod 222 $DIR/$tdir/${tfile}2 ||
2895                 error "$DIR/$tdir/${tfile}2: chmod failed"
2896
2897         # chown should work
2898         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2899                 error "$DIR/$tdir/$tfile: chown failed"
2900         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2901                 error "$DIR/$tdir/${tfile}2: chown failed"
2902
2903         # rename should work
2904         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2905                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2906         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2907                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2908
2909         #remove foreign file
2910         rm $DIR/$tdir/${tfile}.new ||
2911                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2912         rm $DIR/$tdir/${tfile}2.new ||
2913                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2914 }
2915 run_test 27J "basic ops on file with foreign LOV"
2916
2917 test_27K() {
2918         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2919                 skip "Need MDS version newer than 2.12.49"
2920
2921         test_mkdir $DIR/$tdir
2922         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2923         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2924
2925         # create foreign dir (raw way)
2926         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2927                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2928
2929         ! $LFS setdirstripe --foreign --flags foo \
2930                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2931                         error "creating $tdir with '--flags foo' should fail"
2932
2933         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2934                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2935                         error "creating $tdir w/ 0xffffffff flags should fail"
2936
2937         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2938                 error "create_foreign_dir FAILED"
2939
2940         # verify foreign dir (raw way)
2941         parse_foreign_dir -d $DIR/$tdir/$tdir |
2942                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2943                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2944         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2945                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2946         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2947                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2948         parse_foreign_dir -d $DIR/$tdir/$tdir |
2949                 grep "lmv_foreign_flags: 55813$" ||
2950                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2951         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2952                 grep "lmv_foreign_value: 0x" |
2953                 sed 's/lmv_foreign_value: 0x//')
2954         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2955                 sed 's/ //g')
2956         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2957
2958         # create foreign dir (lfs + API)
2959         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2960                 $DIR/$tdir/${tdir}2 ||
2961                 error "$DIR/$tdir/${tdir}2: create failed"
2962
2963         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2964
2965         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2966                 grep "lfm_magic:.*0x0CD50CD0" ||
2967                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2968         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2969         # - sizeof(lfm_type) - sizeof(lfm_flags)
2970         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2971                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2972         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2973                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2974         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2975                 grep "lfm_flags:.*0x0000DA05" ||
2976                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2977         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2978                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2979                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2980
2981         # file create in dir should fail
2982         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2983         touch $DIR/$tdir/${tdir}2/$tfile &&
2984                 error "$DIR/${tdir}2: file create should fail"
2985
2986         # chmod should work
2987         chmod 777 $DIR/$tdir/$tdir ||
2988                 error "$DIR/$tdir: chmod failed"
2989         chmod 777 $DIR/$tdir/${tdir}2 ||
2990                 error "$DIR/${tdir}2: chmod failed"
2991
2992         # chown should work
2993         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2994                 error "$DIR/$tdir: chown failed"
2995         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2996                 error "$DIR/${tdir}2: chown failed"
2997
2998         # rename should work
2999         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3000                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3001         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3002                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3003
3004         #remove foreign dir
3005         rmdir $DIR/$tdir/${tdir}.new ||
3006                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3007         rmdir $DIR/$tdir/${tdir}2.new ||
3008                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3009 }
3010 run_test 27K "basic ops on dir with foreign LMV"
3011
3012 test_27L() {
3013         remote_mds_nodsh && skip "remote MDS with nodsh"
3014
3015         local POOL=${POOL:-$TESTNAME}
3016
3017         pool_add $POOL || error "pool_add failed"
3018
3019         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3020                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3021                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3022 }
3023 run_test 27L "lfs pool_list gives correct pool name"
3024
3025 test_27M() {
3026         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3027                 skip "Need MDS version >= than 2.12.57"
3028         remote_mds_nodsh && skip "remote MDS with nodsh"
3029         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3030
3031         # Set default striping on directory
3032         local setcount=4
3033         local stripe_opt
3034         local mdts=$(comma_list $(mdts_nodes))
3035
3036         # if we run against a 2.12 server which lacks overstring support
3037         # then the connect_flag will not report overstriping, even if client
3038         # is 2.14+
3039         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3040                 stripe_opt="-C $setcount"
3041         elif (( $OSTCOUNT >= $setcount )); then
3042                 stripe_opt="-c $setcount"
3043         else
3044                 skip "server does not support overstriping"
3045         fi
3046
3047         test_mkdir $DIR/$tdir
3048
3049         # Validate existing append_* params and ensure restore
3050         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3051         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3052         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3053
3054         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3055         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3056         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3057
3058         $LFS setstripe $stripe_opt $DIR/$tdir
3059
3060         echo 1 > $DIR/$tdir/${tfile}.1
3061         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3062         (( $count == $setcount )) ||
3063                 error "(1) stripe count $count, should be $setcount"
3064
3065         local appendcount=$orig_count
3066         echo 1 >> $DIR/$tdir/${tfile}.2_append
3067         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3068         (( $count == $appendcount )) ||
3069                 error "(2)stripe count $count, should be $appendcount for append"
3070
3071         # Disable O_APPEND striping, verify it works
3072         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3073
3074         # Should now get the default striping, which is 4
3075         setcount=4
3076         echo 1 >> $DIR/$tdir/${tfile}.3_append
3077         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3078         (( $count == $setcount )) ||
3079                 error "(3) stripe count $count, should be $setcount"
3080
3081         # Try changing the stripe count for append files
3082         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3083
3084         # Append striping is now 2 (directory default is still 4)
3085         appendcount=2
3086         echo 1 >> $DIR/$tdir/${tfile}.4_append
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3088         (( $count == $appendcount )) ||
3089                 error "(4) stripe count $count, should be $appendcount for append"
3090
3091         # Test append stripe count of -1
3092         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3093         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3094                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3095                 touch $DIR/$tdir/$tfile.specific.{1..128}
3096         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3097
3098         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3099         appendcount=$OSTCOUNT
3100         echo 1 >> $DIR/$tdir/${tfile}.5
3101         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3102         (( $count == $appendcount )) ||
3103                 error "(5) stripe count $count, should be $appendcount for append"
3104
3105         # Set append striping back to default of 1
3106         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3107
3108         # Try a new default striping, PFL + DOM
3109         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3110
3111         # Create normal DOM file, DOM returns stripe count == 0
3112         setcount=0
3113         touch $DIR/$tdir/${tfile}.6
3114         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3115         (( $count == $setcount )) ||
3116                 error "(6) stripe count $count, should be $setcount"
3117
3118         # Show
3119         appendcount=1
3120         echo 1 >> $DIR/$tdir/${tfile}.7_append
3121         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3122         (( $count == $appendcount )) ||
3123                 error "(7) stripe count $count, should be $appendcount for append"
3124
3125         # Clean up DOM layout
3126         $LFS setstripe -d $DIR/$tdir
3127
3128         save_layout_restore_at_exit $MOUNT
3129         # Now test that append striping works when layout is from root
3130         $LFS setstripe -c 2 $MOUNT
3131         # Make a special directory for this
3132         mkdir $DIR/${tdir}/${tdir}.2
3133
3134         # Verify for normal file
3135         setcount=2
3136         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3137         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3138         (( $count == $setcount )) ||
3139                 error "(8) stripe count $count, should be $setcount"
3140
3141         appendcount=1
3142         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3143         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3144         (( $count == $appendcount )) ||
3145                 error "(9) stripe count $count, should be $appendcount for append"
3146
3147         # Now test O_APPEND striping with pools
3148         pool_add $TESTNAME || error "pool creation failed"
3149         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3150         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3151
3152         echo 1 >> $DIR/$tdir/${tfile}.10_append
3153
3154         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3155         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3156
3157         # Check that count is still correct
3158         appendcount=1
3159         echo 1 >> $DIR/$tdir/${tfile}.11_append
3160         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3161         (( $count == $appendcount )) ||
3162                 error "(11) stripe count $count, should be $appendcount for append"
3163
3164         # Disable O_APPEND stripe count, verify pool works separately
3165         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3166
3167         echo 1 >> $DIR/$tdir/${tfile}.12_append
3168
3169         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3170         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3171
3172         # Remove pool setting, verify it's not applied
3173         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3174
3175         echo 1 >> $DIR/$tdir/${tfile}.13_append
3176
3177         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3178         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3179 }
3180 run_test 27M "test O_APPEND striping"
3181
3182 test_27N() {
3183         combined_mgs_mds && skip "needs separate MGS/MDT"
3184
3185         pool_add $TESTNAME || error "pool_add failed"
3186         do_facet mgs "$LCTL pool_list $FSNAME" |
3187                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3188                 error "lctl pool_list on MGS failed"
3189 }
3190 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3191
3192 clean_foreign_symlink() {
3193         trap 0
3194         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3195         for i in $DIR/$tdir/* ; do
3196                 $LFS unlink_foreign $i || true
3197         done
3198 }
3199
3200 test_27O() {
3201         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3202                 skip "Need MDS version newer than 2.12.51"
3203
3204         test_mkdir $DIR/$tdir
3205         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3206         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3207
3208         trap clean_foreign_symlink EXIT
3209
3210         # enable foreign_symlink behaviour
3211         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3212
3213         # foreign symlink LOV format is a partial path by default
3214
3215         # create foreign file (lfs + API)
3216         $LFS setstripe --foreign=symlink --flags 0xda05 \
3217                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3218                 error "$DIR/$tdir/${tfile}: create failed"
3219
3220         $LFS getstripe -v $DIR/$tdir/${tfile} |
3221                 grep "lfm_magic:.*0x0BD70BD0" ||
3222                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3223         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3224                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3225         $LFS getstripe -v $DIR/$tdir/${tfile} |
3226                 grep "lfm_flags:.*0x0000DA05" ||
3227                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3228         $LFS getstripe $DIR/$tdir/${tfile} |
3229                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3230                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3231
3232         # modify striping should fail
3233         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3234                 error "$DIR/$tdir/$tfile: setstripe should fail"
3235
3236         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3237         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3238         cat /etc/passwd > $DIR/$tdir/$tfile &&
3239                 error "$DIR/$tdir/$tfile: write should fail"
3240
3241         # rename should succeed
3242         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3243                 error "$DIR/$tdir/$tfile: rename has failed"
3244
3245         #remove foreign_symlink file should fail
3246         rm $DIR/$tdir/${tfile}.new &&
3247                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3248
3249         #test fake symlink
3250         mkdir /tmp/${uuid1} ||
3251                 error "/tmp/${uuid1}: mkdir has failed"
3252         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3253                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3254         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3255         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3256                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3257         #read should succeed now
3258         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3259                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3260         #write should succeed now
3261         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3262                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3263         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3264                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3265         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3266                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3267
3268         #check that getstripe still works
3269         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3270                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3271
3272         # chmod should still succeed
3273         chmod 644 $DIR/$tdir/${tfile}.new ||
3274                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3275
3276         # chown should still succeed
3277         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3278                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3279
3280         # rename should still succeed
3281         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3282                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3283
3284         #remove foreign_symlink file should still fail
3285         rm $DIR/$tdir/${tfile} &&
3286                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3287
3288         #use special ioctl() to unlink foreign_symlink file
3289         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3290                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3291
3292 }
3293 run_test 27O "basic ops on foreign file of symlink type"
3294
3295 test_27P() {
3296         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3297                 skip "Need MDS version newer than 2.12.49"
3298
3299         test_mkdir $DIR/$tdir
3300         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3301         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3302
3303         trap clean_foreign_symlink EXIT
3304
3305         # enable foreign_symlink behaviour
3306         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3307
3308         # foreign symlink LMV format is a partial path by default
3309
3310         # create foreign dir (lfs + API)
3311         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3312                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3313                 error "$DIR/$tdir/${tdir}: create failed"
3314
3315         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3316
3317         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3318                 grep "lfm_magic:.*0x0CD50CD0" ||
3319                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3320         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3321                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3322         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3323                 grep "lfm_flags:.*0x0000DA05" ||
3324                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3325         $LFS getdirstripe $DIR/$tdir/${tdir} |
3326                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3327                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3328
3329         # file create in dir should fail
3330         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3331         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3332
3333         # rename should succeed
3334         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3335                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3336
3337         #remove foreign_symlink dir should fail
3338         rmdir $DIR/$tdir/${tdir}.new &&
3339                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3340
3341         #test fake symlink
3342         mkdir -p /tmp/${uuid1}/${uuid2} ||
3343                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3344         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3345                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3346         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3347         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3348                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3349         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3350                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3351
3352         #check that getstripe fails now that foreign_symlink enabled
3353         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3354                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3355
3356         # file create in dir should work now
3357         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3358                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3359         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3360                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3361         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3362                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3363
3364         # chmod should still succeed
3365         chmod 755 $DIR/$tdir/${tdir}.new ||
3366                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3367
3368         # chown should still succeed
3369         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3370                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3371
3372         # rename should still succeed
3373         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3374                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3375
3376         #remove foreign_symlink dir should still fail
3377         rmdir $DIR/$tdir/${tdir} &&
3378                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3379
3380         #use special ioctl() to unlink foreign_symlink file
3381         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3382                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3383
3384         #created file should still exist
3385         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3386                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3387         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3388                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3389 }
3390 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3391
3392 test_27Q() {
3393         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3394         stack_trap "rm -f $TMP/$tfile*"
3395
3396         test_mkdir $DIR/$tdir-1
3397         test_mkdir $DIR/$tdir-2
3398
3399         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3400         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3401
3402         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3403         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3404
3405         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3406         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3407
3408         # Create some bad symlinks and ensure that we don't loop
3409         # forever or something. These should return ELOOP (40) and
3410         # ENOENT (2) but I don't want to test for that because there's
3411         # always some weirdo architecture that needs to ruin
3412         # everything by defining these error numbers differently.
3413
3414         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3415         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3416
3417         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3418         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3419
3420         return 0
3421 }
3422 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3423
3424 test_27R() {
3425         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3426                 skip "need MDS 2.14.55 or later"
3427         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3428
3429         local testdir="$DIR/$tdir"
3430         test_mkdir -p $testdir
3431         stack_trap "rm -rf $testdir"
3432         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3433
3434         local f1="$testdir/f1"
3435         touch $f1 || error "failed to touch $f1"
3436         local count=$($LFS getstripe -c $f1)
3437         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3438
3439         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3440         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3441
3442         local maxcount=$(($OSTCOUNT - 1))
3443         local mdts=$(comma_list $(mdts_nodes))
3444         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3445         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3446
3447         local f2="$testdir/f2"
3448         touch $f2 || error "failed to touch $f2"
3449         local count=$($LFS getstripe -c $f2)
3450         (( $count == $maxcount )) || error "wrong stripe count"
3451 }
3452 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3453
3454 test_27T() {
3455         [ $(facet_host client) == $(facet_host ost1) ] &&
3456                 skip "need ost1 and client on different nodes"
3457
3458 #define OBD_FAIL_OSC_NO_GRANT            0x411
3459         $LCTL set_param fail_loc=0x20000411 fail_val=1
3460 #define OBD_FAIL_OST_ENOSPC              0x215
3461         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3462         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3463         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3464                 error "multiop failed"
3465 }
3466 run_test 27T "no eio on close on partial write due to enosp"
3467
3468 test_27U() {
3469         local dir=$DIR/$tdir
3470         local file=$dir/$tfile
3471         local append_pool=${TESTNAME}-append
3472         local normal_pool=${TESTNAME}-normal
3473         local pool
3474         local stripe_count
3475         local stripe_count2
3476         local mdts=$(comma_list $(mdts_nodes))
3477
3478         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3479                 skip "Need MDS version at least 2.15.51 for append pool feature"
3480
3481         # Validate existing append_* params and ensure restore
3482         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3483         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3484         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3485
3486         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3487         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3488         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3489
3490         pool_add $append_pool || error "pool creation failed"
3491         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3492
3493         pool_add $normal_pool || error "pool creation failed"
3494         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3495
3496         test_mkdir $dir
3497         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3498
3499         echo XXX >> $file.1
3500         $LFS getstripe $file.1
3501
3502         pool=$($LFS getstripe -p $file.1)
3503         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3504
3505         stripe_count2=$($LFS getstripe -c $file.1)
3506         ((stripe_count2 == stripe_count)) ||
3507                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3508
3509         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3510
3511         echo XXX >> $file.2
3512         $LFS getstripe $file.2
3513
3514         pool=$($LFS getstripe -p $file.2)
3515         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3516
3517         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3518
3519         echo XXX >> $file.3
3520         $LFS getstripe $file.3
3521
3522         stripe_count2=$($LFS getstripe -c $file.3)
3523         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3524 }
3525 run_test 27U "append pool and stripe count work with composite default layout"
3526
3527 test_27V() {
3528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3529         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3530
3531         local dir=$DIR/$tdir
3532         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3533         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3534         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3535         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3536         local pid
3537
3538         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3539
3540         do_facet mds1 $LCTL set_param $lod_param=0
3541         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3542
3543         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3544         stack_trap "rm -rf $dir"
3545
3546         # exercise race in LU-16981 with deactivating OST while creating a file
3547         (
3548                 while true; do
3549                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3550                         sleep 0.1
3551                         do_facet mds1 \
3552                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3553                 done
3554         ) &
3555
3556         pid=$!
3557         stack_trap "kill -9 $pid"
3558
3559         # errors here are OK so ignore them (just don't want to crash)
3560         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3561
3562         return 0
3563 }
3564 run_test 27V "creating widely striped file races with deactivating OST"
3565
3566 # createtest also checks that device nodes are created and
3567 # then visible correctly (#2091)
3568 test_28() { # bug 2091
3569         test_mkdir $DIR/d28
3570         $CREATETEST $DIR/d28/ct || error "createtest failed"
3571 }
3572 run_test 28 "create/mknod/mkdir with bad file types ============"
3573
3574 test_29() {
3575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3576
3577         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3578                 disable_opencache
3579                 stack_trap "restore_opencache"
3580         }
3581
3582         sync; sleep 1; sync # flush out any dirty pages from previous tests
3583         cancel_lru_locks
3584         test_mkdir $DIR/d29
3585         touch $DIR/d29/foo
3586         log 'first d29'
3587         ls -l $DIR/d29
3588
3589         local locks_orig=$(total_used_locks mdc)
3590         (( $locks_orig != 0 )) || error "No mdc lock count"
3591
3592         local locks_unused_orig=$(total_unused_locks mdc)
3593
3594         log 'second d29'
3595         ls -l $DIR/d29
3596         log 'done'
3597
3598         local locks_current=$(total_used_locks mdc)
3599
3600         local locks_unused_current=$(total_unused_locks mdc)
3601
3602         if (( $locks_current > $locks_orig )); then
3603                 $LCTL set_param -n ldlm.dump_namespaces ""
3604                 error "CURRENT: $locks_current > $locks_orig"
3605         fi
3606         if (( $locks_unused_current > $locks_unused_orig )); then
3607                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3608         fi
3609 }
3610 run_test 29 "IT_GETATTR regression  ============================"
3611
3612 test_30a() { # was test_30
3613         cp $(which ls) $DIR || cp /bin/ls $DIR
3614         $DIR/ls / || error "Can't execute binary from lustre"
3615         rm $DIR/ls
3616 }
3617 run_test 30a "execute binary from Lustre (execve) =============="
3618
3619 test_30b() {
3620         cp `which ls` $DIR || cp /bin/ls $DIR
3621         chmod go+rx $DIR/ls
3622         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3623         rm $DIR/ls
3624 }
3625 run_test 30b "execute binary from Lustre as non-root ==========="
3626
3627 test_30c() { # b=22376
3628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3629
3630         cp $(which ls) $DIR || cp /bin/ls $DIR
3631         chmod a-rw $DIR/ls
3632         cancel_lru_locks mdc
3633         cancel_lru_locks osc
3634         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3635         rm -f $DIR/ls
3636 }
3637 run_test 30c "execute binary from Lustre without read perms ===="
3638
3639 test_30d() {
3640         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3641
3642         for i in {1..10}; do
3643                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3644                 local PID=$!
3645                 sleep 1
3646                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3647                 wait $PID || error "executing dd from Lustre failed"
3648                 rm -f $DIR/$tfile
3649         done
3650
3651         rm -f $DIR/dd
3652 }
3653 run_test 30d "execute binary from Lustre while clear locks"
3654
3655 test_31a() {
3656         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3657         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3658 }
3659 run_test 31a "open-unlink file =================================="
3660
3661 test_31b() {
3662         touch $DIR/f31 || error "touch $DIR/f31 failed"
3663         ln $DIR/f31 $DIR/f31b || error "ln failed"
3664         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3665         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3666 }
3667 run_test 31b "unlink file with multiple links while open ======="
3668
3669 test_31c() {
3670         touch $DIR/f31 || error "touch $DIR/f31 failed"
3671         ln $DIR/f31 $DIR/f31c || error "ln failed"
3672         multiop_bg_pause $DIR/f31 O_uc ||
3673                 error "multiop_bg_pause for $DIR/f31 failed"
3674         MULTIPID=$!
3675         $MULTIOP $DIR/f31c Ouc
3676         kill -USR1 $MULTIPID
3677         wait $MULTIPID
3678 }
3679 run_test 31c "open-unlink file with multiple links ============="
3680
3681 test_31d() {
3682         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3683         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3684 }
3685 run_test 31d "remove of open directory ========================="
3686
3687 test_31e() { # bug 2904
3688         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3689 }
3690 run_test 31e "remove of open non-empty directory ==============="
3691
3692 test_31f() { # bug 4554
3693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3694
3695         set -vx
3696         test_mkdir $DIR/d31f
3697         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3698         cp /etc/hosts $DIR/d31f
3699         ls -l $DIR/d31f
3700         $LFS getstripe $DIR/d31f/hosts
3701         multiop_bg_pause $DIR/d31f D_c || return 1
3702         MULTIPID=$!
3703
3704         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3705         test_mkdir $DIR/d31f
3706         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3707         cp /etc/hosts $DIR/d31f
3708         ls -l $DIR/d31f
3709         $LFS getstripe $DIR/d31f/hosts
3710         multiop_bg_pause $DIR/d31f D_c || return 1
3711         MULTIPID2=$!
3712
3713         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3714         wait $MULTIPID || error "first opendir $MULTIPID failed"
3715
3716         sleep 6
3717
3718         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3719         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3720         set +vx
3721 }
3722 run_test 31f "remove of open directory with open-unlink file ==="
3723
3724 test_31g() {
3725         echo "-- cross directory link --"
3726         test_mkdir -c1 $DIR/${tdir}ga
3727         test_mkdir -c1 $DIR/${tdir}gb
3728         touch $DIR/${tdir}ga/f
3729         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3730         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3731         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3732         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3733         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3734 }
3735 run_test 31g "cross directory link==============="
3736
3737 test_31h() {
3738         echo "-- cross directory link --"
3739         test_mkdir -c1 $DIR/${tdir}
3740         test_mkdir -c1 $DIR/${tdir}/dir
3741         touch $DIR/${tdir}/f
3742         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3743         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3744         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3745         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3746         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3747 }
3748 run_test 31h "cross directory link under child==============="
3749
3750 test_31i() {
3751         echo "-- cross directory link --"
3752         test_mkdir -c1 $DIR/$tdir
3753         test_mkdir -c1 $DIR/$tdir/dir
3754         touch $DIR/$tdir/dir/f
3755         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3756         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3757         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3758         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3759         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3760 }
3761 run_test 31i "cross directory link under parent==============="
3762
3763 test_31j() {
3764         test_mkdir -c1 -p $DIR/$tdir
3765         test_mkdir -c1 -p $DIR/$tdir/dir1
3766         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3767         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3768         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3769         return 0
3770 }
3771 run_test 31j "link for directory"
3772
3773 test_31k() {
3774         test_mkdir -c1 -p $DIR/$tdir
3775         touch $DIR/$tdir/s
3776         touch $DIR/$tdir/exist
3777         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3778         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3779         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3780         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3781         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3782         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3783         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3784         return 0
3785 }
3786 run_test 31k "link to file: the same, non-existing, dir"
3787
3788 test_31l() {
3789         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3790
3791         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3792         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3793                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3794
3795         touch $DIR/$tfile || error "create failed"
3796         mkdir $DIR/$tdir || error "mkdir failed"
3797         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3798 }
3799 run_test 31l "link to file: target dir has trailing slash"
3800
3801 test_31m() {
3802         mkdir $DIR/d31m
3803         touch $DIR/d31m/s
3804         mkdir $DIR/d31m2
3805         touch $DIR/d31m2/exist
3806         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3807         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3808         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3809         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3810         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3811         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3812         return 0
3813 }
3814 run_test 31m "link to file: the same, non-existing, dir"
3815
3816 test_31n() {
3817         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3818         nlink=$(stat --format=%h $DIR/$tfile)
3819         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3820         local fd=$(free_fd)
3821         local cmd="exec $fd<$DIR/$tfile"
3822         eval $cmd
3823         cmd="exec $fd<&-"
3824         trap "eval $cmd" EXIT
3825         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3826         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3827         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3828         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3829         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3830         eval $cmd
3831 }
3832 run_test 31n "check link count of unlinked file"
3833
3834 link_one() {
3835         local tempfile=$(mktemp $1_XXXXXX)
3836         link $tempfile $1 2> /dev/null &&
3837                 echo "$BASHPID: link $tempfile to $1 succeeded"
3838         unlink $tempfile
3839 }
3840
3841 test_31o() { # LU-2901
3842         test_mkdir $DIR/$tdir
3843         for LOOP in $(seq 100); do
3844                 rm -f $DIR/$tdir/$tfile*
3845                 for THREAD in $(seq 8); do
3846                         link_one $DIR/$tdir/$tfile.$LOOP &
3847                 done
3848                 wait
3849                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3850                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3851                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3852                         break || true
3853         done
3854 }
3855 run_test 31o "duplicate hard links with same filename"
3856
3857 test_31p() {
3858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3859
3860         test_mkdir $DIR/$tdir
3861         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3862         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3863
3864         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3865                 error "open unlink test1 failed"
3866         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3867                 error "open unlink test2 failed"
3868
3869         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3870                 error "test1 still exists"
3871         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3872                 error "test2 still exists"
3873 }
3874 run_test 31p "remove of open striped directory"
3875
3876 test_31q() {
3877         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3878
3879         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3880         index=$($LFS getdirstripe -i $DIR/$tdir)
3881         [ $index -eq 3 ] || error "first stripe index $index != 3"
3882         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3883         [ $index -eq 1 ] || error "second stripe index $index != 1"
3884
3885         # when "-c <stripe_count>" is set, the number of MDTs specified after
3886         # "-i" should equal to the stripe count
3887         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3888 }
3889 run_test 31q "create striped directory on specific MDTs"
3890
3891 #LU-14949
3892 test_31r() {
3893         touch $DIR/$tfile.target
3894         touch $DIR/$tfile.source
3895
3896         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3897         $LCTL set_param fail_loc=0x1419 fail_val=3
3898         cat $DIR/$tfile.target &
3899         CATPID=$!
3900
3901         # Guarantee open is waiting before we get here
3902         sleep 1
3903         mv $DIR/$tfile.source $DIR/$tfile.target
3904
3905         wait $CATPID
3906         RC=$?
3907         if [[ $RC -ne 0 ]]; then
3908                 error "open with cat failed, rc=$RC"
3909         fi
3910 }
3911 run_test 31r "open-rename(replace) race"
3912
3913 cleanup_test32_mount() {
3914         local rc=0
3915         trap 0
3916         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3917         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3918         losetup -d $loopdev || true
3919         rm -rf $DIR/$tdir
3920         return $rc
3921 }
3922
3923 test_32a() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         echo "== more mountpoints and symlinks ================="
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3933                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3934         cleanup_test32_mount
3935 }
3936 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3937
3938 test_32b() {
3939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3940
3941         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3942         trap cleanup_test32_mount EXIT
3943         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3944         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3945                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3946         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3947                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3948         cleanup_test32_mount
3949 }
3950 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3951
3952 test_32c() {
3953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3954
3955         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3956         trap cleanup_test32_mount EXIT
3957         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3958         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3959                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3960         test_mkdir -p $DIR/$tdir/d2/test_dir
3961         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3962                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3963         cleanup_test32_mount
3964 }
3965 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3966
3967 test_32d() {
3968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3969
3970         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3971         trap cleanup_test32_mount EXIT
3972         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3973         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3974                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3975         test_mkdir -p $DIR/$tdir/d2/test_dir
3976         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3977                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3978         cleanup_test32_mount
3979 }
3980 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3981
3982 test_32e() {
3983         rm -fr $DIR/$tdir
3984         test_mkdir -p $DIR/$tdir/tmp
3985         local tmp_dir=$DIR/$tdir/tmp
3986         ln -s $DIR/$tdir $tmp_dir/symlink11
3987         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3988         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3989         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3990 }
3991 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3992
3993 test_32f() {
3994         rm -fr $DIR/$tdir
3995         test_mkdir -p $DIR/$tdir/tmp
3996         local tmp_dir=$DIR/$tdir/tmp
3997         ln -s $DIR/$tdir $tmp_dir/symlink11
3998         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3999         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4000         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4001 }
4002 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4003
4004 test_32g() {
4005         local tmp_dir=$DIR/$tdir/tmp
4006         test_mkdir -p $tmp_dir
4007         test_mkdir $DIR/${tdir}2
4008         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4009         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4010         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4011         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4012         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4013         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4014 }
4015 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4016
4017 test_32h() {
4018         rm -fr $DIR/$tdir $DIR/${tdir}2
4019         tmp_dir=$DIR/$tdir/tmp
4020         test_mkdir -p $tmp_dir
4021         test_mkdir $DIR/${tdir}2
4022         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4023         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4024         ls $tmp_dir/symlink12 || error "listing symlink12"
4025         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4026 }
4027 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4028
4029 test_32i() {
4030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4031
4032         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4033         trap cleanup_test32_mount EXIT
4034         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4035         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4036                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4037         touch $DIR/$tdir/test_file
4038         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4039                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4040         cleanup_test32_mount
4041 }
4042 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4043
4044 test_32j() {
4045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4046
4047         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4048         trap cleanup_test32_mount EXIT
4049         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4050         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4051                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4052         touch $DIR/$tdir/test_file
4053         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4054                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4055         cleanup_test32_mount
4056 }
4057 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4058
4059 test_32k() {
4060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4061
4062         rm -fr $DIR/$tdir
4063         trap cleanup_test32_mount EXIT
4064         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4065         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4066                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4067         test_mkdir -p $DIR/$tdir/d2
4068         touch $DIR/$tdir/d2/test_file || error "touch failed"
4069         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4070                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4071         cleanup_test32_mount
4072 }
4073 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4074
4075 test_32l() {
4076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4077
4078         rm -fr $DIR/$tdir
4079         trap cleanup_test32_mount EXIT
4080         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4081         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4082                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4083         test_mkdir -p $DIR/$tdir/d2
4084         touch $DIR/$tdir/d2/test_file || error "touch failed"
4085         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4086                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4087         cleanup_test32_mount
4088 }
4089 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4090
4091 test_32m() {
4092         rm -fr $DIR/d32m
4093         test_mkdir -p $DIR/d32m/tmp
4094         TMP_DIR=$DIR/d32m/tmp
4095         ln -s $DIR $TMP_DIR/symlink11
4096         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4097         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4098                 error "symlink11 not a link"
4099         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4100                 error "symlink01 not a link"
4101 }
4102 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4103
4104 test_32n() {
4105         rm -fr $DIR/d32n
4106         test_mkdir -p $DIR/d32n/tmp
4107         TMP_DIR=$DIR/d32n/tmp
4108         ln -s $DIR $TMP_DIR/symlink11
4109         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4110         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4111         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4112 }
4113 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4114
4115 test_32o() {
4116         touch $DIR/$tfile
4117         test_mkdir -p $DIR/d32o/tmp
4118         TMP_DIR=$DIR/d32o/tmp
4119         ln -s $DIR/$tfile $TMP_DIR/symlink12
4120         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4121         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4122                 error "symlink12 not a link"
4123         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4124         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4125                 error "$DIR/d32o/tmp/symlink12 not file type"
4126         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4127                 error "$DIR/d32o/symlink02 not file type"
4128 }
4129 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4130
4131 test_32p() {
4132         log 32p_1
4133         rm -fr $DIR/d32p
4134         log 32p_2
4135         rm -f $DIR/$tfile
4136         log 32p_3
4137         touch $DIR/$tfile
4138         log 32p_4
4139         test_mkdir -p $DIR/d32p/tmp
4140         log 32p_5
4141         TMP_DIR=$DIR/d32p/tmp
4142         log 32p_6
4143         ln -s $DIR/$tfile $TMP_DIR/symlink12
4144         log 32p_7
4145         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4146         log 32p_8
4147         cat $DIR/d32p/tmp/symlink12 ||
4148                 error "Can't open $DIR/d32p/tmp/symlink12"
4149         log 32p_9
4150         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4151         log 32p_10
4152 }
4153 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4154
4155 test_32q() {
4156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4157
4158         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4159         trap cleanup_test32_mount EXIT
4160         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4161         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4162         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4163                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4164         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4165         cleanup_test32_mount
4166 }
4167 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4168
4169 test_32r() {
4170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4171
4172         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4173         trap cleanup_test32_mount EXIT
4174         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4175         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4176         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4177                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4178         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4179         cleanup_test32_mount
4180 }
4181 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4182
4183 test_33aa() {
4184         rm -f $DIR/$tfile
4185         touch $DIR/$tfile
4186         chmod 444 $DIR/$tfile
4187         chown $RUNAS_ID $DIR/$tfile
4188         log 33_1
4189         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4190         log 33_2
4191 }
4192 run_test 33aa "write file with mode 444 (should return error)"
4193
4194 test_33a() {
4195         rm -fr $DIR/$tdir
4196         test_mkdir $DIR/$tdir
4197         chown $RUNAS_ID $DIR/$tdir
4198         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4199                 error "$RUNAS create $tdir/$tfile failed"
4200         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4201                 error "open RDWR" || true
4202 }
4203 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4204
4205 test_33b() {
4206         rm -fr $DIR/$tdir
4207         test_mkdir $DIR/$tdir
4208         chown $RUNAS_ID $DIR/$tdir
4209         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4210 }
4211 run_test 33b "test open file with malformed flags (No panic)"
4212
4213 test_33c() {
4214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4215         remote_ost_nodsh && skip "remote OST with nodsh"
4216
4217         local ostnum
4218         local ostname
4219         local write_bytes
4220         local all_zeros
4221
4222         all_zeros=true
4223         test_mkdir $DIR/$tdir
4224         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4225
4226         sync
4227         for ostnum in $(seq $OSTCOUNT); do
4228                 # test-framework's OST numbering is one-based, while Lustre's
4229                 # is zero-based
4230                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4231                 # check if at least some write_bytes stats are counted
4232                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4233                               obdfilter.$ostname.stats |
4234                               awk '/^write_bytes/ {print $7}' )
4235                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4236                 if (( ${write_bytes:-0} > 0 )); then
4237                         all_zeros=false
4238                         break
4239                 fi
4240         done
4241
4242         $all_zeros || return 0
4243
4244         # Write four bytes
4245         echo foo > $DIR/$tdir/bar
4246         # Really write them
4247         sync
4248
4249         # Total up write_bytes after writing.  We'd better find non-zeros.
4250         for ostnum in $(seq $OSTCOUNT); do
4251                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4252                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4253                               obdfilter/$ostname/stats |
4254                               awk '/^write_bytes/ {print $7}' )
4255                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4256                 if (( ${write_bytes:-0} > 0 )); then
4257                         all_zeros=false
4258                         break
4259                 fi
4260         done
4261
4262         if $all_zeros; then
4263                 for ostnum in $(seq $OSTCOUNT); do
4264                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4265                         echo "Check write_bytes is in obdfilter.*.stats:"
4266                         do_facet ost$ostnum lctl get_param -n \
4267                                 obdfilter.$ostname.stats
4268                 done
4269                 error "OST not keeping write_bytes stats (b=22312)"
4270         fi
4271 }
4272 run_test 33c "test write_bytes stats"
4273
4274 test_33d() {
4275         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4277
4278         local MDTIDX=1
4279         local remote_dir=$DIR/$tdir/remote_dir
4280
4281         test_mkdir $DIR/$tdir
4282         $LFS mkdir -i $MDTIDX $remote_dir ||
4283                 error "create remote directory failed"
4284
4285         touch $remote_dir/$tfile
4286         chmod 444 $remote_dir/$tfile
4287         chown $RUNAS_ID $remote_dir/$tfile
4288
4289         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4290
4291         chown $RUNAS_ID $remote_dir
4292         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4293                                         error "create" || true
4294         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4295                                     error "open RDWR" || true
4296         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4297 }
4298 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4299
4300 test_33e() {
4301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4302
4303         mkdir $DIR/$tdir
4304
4305         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4306         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4307         mkdir $DIR/$tdir/local_dir
4308
4309         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4310         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4311         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4312
4313         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4314                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4315
4316         rmdir $DIR/$tdir/* || error "rmdir failed"
4317
4318         umask 777
4319         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4320         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4321         mkdir $DIR/$tdir/local_dir
4322
4323         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4324         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4325         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4326
4327         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4328                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4329
4330         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4331
4332         umask 000
4333         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4334         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4335         mkdir $DIR/$tdir/local_dir
4336
4337         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4338         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4339         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4340
4341         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4342                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4343 }
4344 run_test 33e "mkdir and striped directory should have same mode"
4345
4346 cleanup_33f() {
4347         trap 0
4348         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4349 }
4350
4351 test_33f() {
4352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4353         remote_mds_nodsh && skip "remote MDS with nodsh"
4354
4355         mkdir $DIR/$tdir
4356         chmod go+rwx $DIR/$tdir
4357         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4358         trap cleanup_33f EXIT
4359
4360         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4361                 error "cannot create striped directory"
4362
4363         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4364                 error "cannot create files in striped directory"
4365
4366         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4367                 error "cannot remove files in striped directory"
4368
4369         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4370                 error "cannot remove striped directory"
4371
4372         cleanup_33f
4373 }
4374 run_test 33f "nonroot user can create, access, and remove a striped directory"
4375
4376 test_33g() {
4377         mkdir -p $DIR/$tdir/dir2
4378
4379         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4380         echo $err
4381         [[ $err =~ "exists" ]] || error "Not exists error"
4382 }
4383 run_test 33g "nonroot user create already existing root created file"
4384
4385 sub_33h() {
4386         local hash_type=$1
4387         local count=250
4388
4389         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4390                 error "lfs mkdir -H $hash_type $tdir failed"
4391         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4392
4393         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4394         local index2
4395         local fname
4396
4397         for fname in $DIR/$tdir/$tfile.bak \
4398                      $DIR/$tdir/$tfile.SAV \
4399                      $DIR/$tdir/$tfile.orig \
4400                      $DIR/$tdir/$tfile~; do
4401                 touch $fname || error "touch $fname failed"
4402                 index2=$($LFS getstripe -m $fname)
4403                 (( $index == $index2 )) ||
4404                         error "$fname MDT index mismatch $index != $index2"
4405         done
4406
4407         local failed=0
4408         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4409         local pattern
4410
4411         for pattern in ${patterns[*]}; do
4412                 echo "pattern $pattern"
4413                 fname=$DIR/$tdir/$pattern
4414                 for (( i = 0; i < $count; i++ )); do
4415                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4416                                 error "mktemp $DIR/$tdir/$pattern failed"
4417                         index2=$($LFS getstripe -m $fname)
4418                         (( $index == $index2 )) && continue
4419
4420                         failed=$((failed + 1))
4421                         echo "$fname MDT index mismatch $index != $index2"
4422                 done
4423         done
4424
4425         echo "$failed/$count MDT index mismatches, expect ~2-4"
4426         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4427
4428         local same=0
4429         local expect
4430
4431         # verify that "crush" is still broken with all files on same MDT,
4432         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4433         [[ "$hash_type" == "crush" ]] && expect=$count ||
4434                 expect=$((count / MDSCOUNT))
4435
4436         # crush2 doesn't put all-numeric suffixes on the same MDT,
4437         # filename like $tfile.12345678 should *not* be considered temp
4438         for pattern in ${patterns[*]}; do
4439                 local base=${pattern%%X*}
4440                 local suff=${pattern#$base}
4441
4442                 echo "pattern $pattern"
4443                 for (( i = 0; i < $count; i++ )); do
4444                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4445                         touch $fname || error "touch $fname failed"
4446                         index2=$($LFS getstripe -m $fname)
4447                         (( $index != $index2 )) && continue
4448
4449                         same=$((same + 1))
4450                 done
4451         done
4452
4453         # the number of "bad" hashes is random, as it depends on the random
4454         # filenames generated by "mktemp".  Allow some margin in the results.
4455         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4456         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4457            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4458                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4459         same=0
4460
4461         # crush2 doesn't put suffixes with special characters on the same MDT
4462         # filename like $tfile.txt.1234 should *not* be considered temp
4463         for pattern in ${patterns[*]}; do
4464                 local base=${pattern%%X*}
4465                 local suff=${pattern#$base}
4466
4467                 pattern=$base...${suff/XXX}
4468                 echo "pattern=$pattern"
4469                 for (( i = 0; i < $count; i++ )); do
4470                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4471                                 error "touch $fname failed"
4472                         index2=$($LFS getstripe -m $fname)
4473                         (( $index != $index2 )) && continue
4474
4475                         same=$((same + 1))
4476                 done
4477         done
4478
4479         # the number of "bad" hashes is random, as it depends on the random
4480         # filenames generated by "mktemp".  Allow some margin in the results.
4481         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4482         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4483            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4484                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4485 }
4486
4487 test_33h() {
4488         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4489         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4490                 skip "Need MDS version at least 2.13.50"
4491
4492         sub_33h crush
4493 }
4494 run_test 33h "temp file is located on the same MDT as target (crush)"
4495
4496 test_33hh() {
4497         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4498         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4499         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4500                 skip "Need MDS version at least 2.15.0 for crush2"
4501
4502         sub_33h crush2
4503 }
4504 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4505
4506 test_33i()
4507 {
4508         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4509
4510         local FNAME=$(str_repeat 'f' 250)
4511
4512         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4513         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4514
4515         local count
4516         local total
4517
4518         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4519
4520         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4521
4522         lctl --device %$MDC deactivate
4523         stack_trap "lctl --device %$MDC activate"
4524         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4525         total=$(\ls -l $DIR/$tdir | wc -l)
4526         # "ls -l" will list total in the first line
4527         total=$((total - 1))
4528         (( total + count == 1000 )) ||
4529                 error "ls list $total files, $count files on MDT1"
4530 }
4531 run_test 33i "striped directory can be accessed when one MDT is down"
4532
4533 test_33j() {
4534         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4535
4536         mkdir -p $DIR/$tdir/
4537
4538         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4539                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4540
4541         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4542                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4543
4544         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4545                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4546
4547         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4548                 error "-D was not specified, but still failed"
4549 }
4550 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4551
4552 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4553 test_34a() {
4554         rm -f $DIR/f34
4555         $MCREATE $DIR/f34 || error "mcreate failed"
4556         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4557                 error "getstripe failed"
4558         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4559         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4560                 error "getstripe failed"
4561         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4562                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4563 }
4564 run_test 34a "truncate file that has not been opened ==========="
4565
4566 test_34b() {
4567         [ ! -f $DIR/f34 ] && test_34a
4568         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4569                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4570         $OPENFILE -f O_RDONLY $DIR/f34
4571         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4572                 error "getstripe failed"
4573         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4574                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4575 }
4576 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4577
4578 test_34c() {
4579         [ ! -f $DIR/f34 ] && test_34a
4580         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4581                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4582         $OPENFILE -f O_RDWR $DIR/f34
4583         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4584                 error "$LFS getstripe failed"
4585         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4586                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4587 }
4588 run_test 34c "O_RDWR opening file-with-size works =============="
4589
4590 test_34d() {
4591         [ ! -f $DIR/f34 ] && test_34a
4592         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4593                 error "dd failed"
4594         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4595                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4596         rm $DIR/f34
4597 }
4598 run_test 34d "write to sparse file ============================="
4599
4600 test_34e() {
4601         rm -f $DIR/f34e
4602         $MCREATE $DIR/f34e || error "mcreate failed"
4603         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4604         $CHECKSTAT -s 1000 $DIR/f34e ||
4605                 error "Size of $DIR/f34e not equal to 1000 bytes"
4606         $OPENFILE -f O_RDWR $DIR/f34e
4607         $CHECKSTAT -s 1000 $DIR/f34e ||
4608                 error "Size of $DIR/f34e not equal to 1000 bytes"
4609 }
4610 run_test 34e "create objects, some with size and some without =="
4611
4612 test_34f() { # bug 6242, 6243
4613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4614
4615         SIZE34F=48000
4616         rm -f $DIR/f34f
4617         $MCREATE $DIR/f34f || error "mcreate failed"
4618         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4619         dd if=$DIR/f34f of=$TMP/f34f
4620         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4621         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4622         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4623         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4624         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4625 }
4626 run_test 34f "read from a file with no objects until EOF ======="
4627
4628 test_34g() {
4629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4630
4631         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4632                 error "dd failed"
4633         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4634         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4635                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4636         cancel_lru_locks osc
4637         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4638                 error "wrong size after lock cancel"
4639
4640         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4641         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4642                 error "expanding truncate failed"
4643         cancel_lru_locks osc
4644         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4645                 error "wrong expanded size after lock cancel"
4646 }
4647 run_test 34g "truncate long file ==============================="
4648
4649 test_34h() {
4650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4651
4652         local gid=10
4653         local sz=1000
4654
4655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4656         sync # Flush the cache so that multiop below does not block on cache
4657              # flush when getting the group lock
4658         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4659         MULTIPID=$!
4660
4661         # Since just timed wait is not good enough, let's do a sync write
4662         # that way we are sure enough time for a roundtrip + processing
4663         # passed + 2 seconds of extra margin.
4664         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4665         rm $DIR/${tfile}-1
4666         sleep 2
4667
4668         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4669                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4670                 kill -9 $MULTIPID
4671         fi
4672         wait $MULTIPID
4673         local nsz=`stat -c %s $DIR/$tfile`
4674         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4675 }
4676 run_test 34h "ftruncate file under grouplock should not block"
4677
4678 test_35a() {
4679         cp /bin/sh $DIR/f35a
4680         chmod 444 $DIR/f35a
4681         chown $RUNAS_ID $DIR/f35a
4682         $RUNAS $DIR/f35a && error || true
4683         rm $DIR/f35a
4684 }
4685 run_test 35a "exec file with mode 444 (should return and not leak)"
4686
4687 test_36a() {
4688         rm -f $DIR/f36
4689         utime $DIR/f36 || error "utime failed for MDS"
4690 }
4691 run_test 36a "MDS utime check (mknod, utime)"
4692
4693 test_36b() {
4694         echo "" > $DIR/f36
4695         utime $DIR/f36 || error "utime failed for OST"
4696 }
4697 run_test 36b "OST utime check (open, utime)"
4698
4699 test_36c() {
4700         rm -f $DIR/d36/f36
4701         test_mkdir $DIR/d36
4702         chown $RUNAS_ID $DIR/d36
4703         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4704 }
4705 run_test 36c "non-root MDS utime check (mknod, utime)"
4706
4707 test_36d() {
4708         [ ! -d $DIR/d36 ] && test_36c
4709         echo "" > $DIR/d36/f36
4710         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4711 }
4712 run_test 36d "non-root OST utime check (open, utime)"
4713
4714 test_36e() {
4715         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4716
4717         test_mkdir $DIR/$tdir
4718         touch $DIR/$tdir/$tfile
4719         $RUNAS utime $DIR/$tdir/$tfile &&
4720                 error "utime worked, expected failure" || true
4721 }
4722 run_test 36e "utime on non-owned file (should return error)"
4723
4724 subr_36fh() {
4725         local fl="$1"
4726         local LANG_SAVE=$LANG
4727         local LC_LANG_SAVE=$LC_LANG
4728         export LANG=C LC_LANG=C # for date language
4729
4730         DATESTR="Dec 20  2000"
4731         test_mkdir $DIR/$tdir
4732         lctl set_param fail_loc=$fl
4733         date; date +%s
4734         cp /etc/hosts $DIR/$tdir/$tfile
4735         sync & # write RPC generated with "current" inode timestamp, but delayed
4736         sleep 1
4737         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4738         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4739         cancel_lru_locks $OSC
4740         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4741         date; date +%s
4742         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4743                 echo "BEFORE: $LS_BEFORE" && \
4744                 echo "AFTER : $LS_AFTER" && \
4745                 echo "WANT  : $DATESTR" && \
4746                 error "$DIR/$tdir/$tfile timestamps changed" || true
4747
4748         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4749 }
4750
4751 test_36f() {
4752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4753
4754         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4755         subr_36fh "0x80000214"
4756 }
4757 run_test 36f "utime on file racing with OST BRW write =========="
4758
4759 test_36g() {
4760         remote_ost_nodsh && skip "remote OST with nodsh"
4761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4762         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4763                 skip "Need MDS version at least 2.12.51"
4764
4765         local fmd_max_age
4766         local fmd
4767         local facet="ost1"
4768         local tgt="obdfilter"
4769
4770         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4771
4772         test_mkdir $DIR/$tdir
4773         fmd_max_age=$(do_facet $facet \
4774                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4775                 head -n 1")
4776
4777         echo "FMD max age: ${fmd_max_age}s"
4778         touch $DIR/$tdir/$tfile
4779         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4780                 gawk '{cnt=cnt+$1}  END{print cnt}')
4781         echo "FMD before: $fmd"
4782         [[ $fmd == 0 ]] &&
4783                 error "FMD wasn't create by touch"
4784         sleep $((fmd_max_age + 12))
4785         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4786                 gawk '{cnt=cnt+$1}  END{print cnt}')
4787         echo "FMD after: $fmd"
4788         [[ $fmd == 0 ]] ||
4789                 error "FMD wasn't expired by ping"
4790 }
4791 run_test 36g "FMD cache expiry ====================="
4792
4793 test_36h() {
4794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4795
4796         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4797         subr_36fh "0x80000227"
4798 }
4799 run_test 36h "utime on file racing with OST BRW write =========="
4800
4801 test_36i() {
4802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4803
4804         test_mkdir $DIR/$tdir
4805         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4806
4807         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4808         local new_mtime=$((mtime + 200))
4809
4810         #change Modify time of striped dir
4811         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4812                         error "change mtime failed"
4813
4814         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4815
4816         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4817 }
4818 run_test 36i "change mtime on striped directory"
4819
4820 # test_37 - duplicate with tests 32q 32r
4821
4822 test_38() {
4823         local file=$DIR/$tfile
4824         touch $file
4825         openfile -f O_DIRECTORY $file
4826         local RC=$?
4827         local ENOTDIR=20
4828         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4829         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4830 }
4831 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4832
4833 test_39a() { # was test_39
4834         touch $DIR/$tfile
4835         touch $DIR/${tfile}2
4836 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4837 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4838 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4839         sleep 2
4840         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4841         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4842                 echo "mtime"
4843                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4844                 echo "atime"
4845                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4846                 echo "ctime"
4847                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4848                 error "O_TRUNC didn't change timestamps"
4849         fi
4850 }
4851 run_test 39a "mtime changed on create"
4852
4853 test_39b() {
4854         test_mkdir -c1 $DIR/$tdir
4855         cp -p /etc/passwd $DIR/$tdir/fopen
4856         cp -p /etc/passwd $DIR/$tdir/flink
4857         cp -p /etc/passwd $DIR/$tdir/funlink
4858         cp -p /etc/passwd $DIR/$tdir/frename
4859         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4860
4861         sleep 1
4862         echo "aaaaaa" >> $DIR/$tdir/fopen
4863         echo "aaaaaa" >> $DIR/$tdir/flink
4864         echo "aaaaaa" >> $DIR/$tdir/funlink
4865         echo "aaaaaa" >> $DIR/$tdir/frename
4866
4867         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4868         local link_new=`stat -c %Y $DIR/$tdir/flink`
4869         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4870         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4871
4872         cat $DIR/$tdir/fopen > /dev/null
4873         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4874         rm -f $DIR/$tdir/funlink2
4875         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4876
4877         for (( i=0; i < 2; i++ )) ; do
4878                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4879                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4880                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4881                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4882
4883                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4884                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4885                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4886                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4887
4888                 cancel_lru_locks $OSC
4889                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4890         done
4891 }
4892 run_test 39b "mtime change on open, link, unlink, rename  ======"
4893
4894 # this should be set to past
4895 TEST_39_MTIME=`date -d "1 year ago" +%s`
4896
4897 # bug 11063
4898 test_39c() {
4899         touch $DIR1/$tfile
4900         sleep 2
4901         local mtime0=`stat -c %Y $DIR1/$tfile`
4902
4903         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4904         local mtime1=`stat -c %Y $DIR1/$tfile`
4905         [ "$mtime1" = $TEST_39_MTIME ] || \
4906                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4907
4908         local d1=`date +%s`
4909         echo hello >> $DIR1/$tfile
4910         local d2=`date +%s`
4911         local mtime2=`stat -c %Y $DIR1/$tfile`
4912         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4913                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4914
4915         mv $DIR1/$tfile $DIR1/$tfile-1
4916
4917         for (( i=0; i < 2; i++ )) ; do
4918                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4919                 [ "$mtime2" = "$mtime3" ] || \
4920                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4921
4922                 cancel_lru_locks $OSC
4923                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4924         done
4925 }
4926 run_test 39c "mtime change on rename ==========================="
4927
4928 # bug 21114
4929 test_39d() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         touch $DIR1/$tfile
4933         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4934
4935         for (( i=0; i < 2; i++ )) ; do
4936                 local mtime=`stat -c %Y $DIR1/$tfile`
4937                 [ $mtime = $TEST_39_MTIME ] || \
4938                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4939
4940                 cancel_lru_locks $OSC
4941                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4942         done
4943 }
4944 run_test 39d "create, utime, stat =============================="
4945
4946 # bug 21114
4947 test_39e() {
4948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4949
4950         touch $DIR1/$tfile
4951         local mtime1=`stat -c %Y $DIR1/$tfile`
4952
4953         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4954
4955         for (( i=0; i < 2; i++ )) ; do
4956                 local mtime2=`stat -c %Y $DIR1/$tfile`
4957                 [ $mtime2 = $TEST_39_MTIME ] || \
4958                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4959
4960                 cancel_lru_locks $OSC
4961                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4962         done
4963 }
4964 run_test 39e "create, stat, utime, stat ========================"
4965
4966 # bug 21114
4967 test_39f() {
4968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4969
4970         touch $DIR1/$tfile
4971         mtime1=`stat -c %Y $DIR1/$tfile`
4972
4973         sleep 2
4974         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4975
4976         for (( i=0; i < 2; i++ )) ; do
4977                 local mtime2=`stat -c %Y $DIR1/$tfile`
4978                 [ $mtime2 = $TEST_39_MTIME ] || \
4979                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4980
4981                 cancel_lru_locks $OSC
4982                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4983         done
4984 }
4985 run_test 39f "create, stat, sleep, utime, stat ================="
4986
4987 # bug 11063
4988 test_39g() {
4989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4990
4991         echo hello >> $DIR1/$tfile
4992         local mtime1=`stat -c %Y $DIR1/$tfile`
4993
4994         sleep 2
4995         chmod o+r $DIR1/$tfile
4996
4997         for (( i=0; i < 2; i++ )) ; do
4998                 local mtime2=`stat -c %Y $DIR1/$tfile`
4999                 [ "$mtime1" = "$mtime2" ] || \
5000                         error "lost mtime: $mtime2, should be $mtime1"
5001
5002                 cancel_lru_locks $OSC
5003                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5004         done
5005 }
5006 run_test 39g "write, chmod, stat ==============================="
5007
5008 # bug 11063
5009 test_39h() {
5010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5011
5012         touch $DIR1/$tfile
5013         sleep 1
5014
5015         local d1=`date`
5016         echo hello >> $DIR1/$tfile
5017         local mtime1=`stat -c %Y $DIR1/$tfile`
5018
5019         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5020         local d2=`date`
5021         if [ "$d1" != "$d2" ]; then
5022                 echo "write and touch not within one second"
5023         else
5024                 for (( i=0; i < 2; i++ )) ; do
5025                         local mtime2=`stat -c %Y $DIR1/$tfile`
5026                         [ "$mtime2" = $TEST_39_MTIME ] || \
5027                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5028
5029                         cancel_lru_locks $OSC
5030                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5031                 done
5032         fi
5033 }
5034 run_test 39h "write, utime within one second, stat ============="
5035
5036 test_39i() {
5037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5038
5039         touch $DIR1/$tfile
5040         sleep 1
5041
5042         echo hello >> $DIR1/$tfile
5043         local mtime1=`stat -c %Y $DIR1/$tfile`
5044
5045         mv $DIR1/$tfile $DIR1/$tfile-1
5046
5047         for (( i=0; i < 2; i++ )) ; do
5048                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5049
5050                 [ "$mtime1" = "$mtime2" ] || \
5051                         error "lost mtime: $mtime2, should be $mtime1"
5052
5053                 cancel_lru_locks $OSC
5054                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5055         done
5056 }
5057 run_test 39i "write, rename, stat =============================="
5058
5059 test_39j() {
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         start_full_debug_logging
5063         touch $DIR1/$tfile
5064         sleep 1
5065
5066         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5067         lctl set_param fail_loc=0x80000412
5068         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5069                 error "multiop failed"
5070         local multipid=$!
5071         local mtime1=`stat -c %Y $DIR1/$tfile`
5072
5073         mv $DIR1/$tfile $DIR1/$tfile-1
5074
5075         kill -USR1 $multipid
5076         wait $multipid || error "multiop close failed"
5077
5078         for (( i=0; i < 2; i++ )) ; do
5079                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5080                 [ "$mtime1" = "$mtime2" ] ||
5081                         error "mtime is lost on close: $mtime2, " \
5082                               "should be $mtime1"
5083
5084                 cancel_lru_locks
5085                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5086         done
5087         lctl set_param fail_loc=0
5088         stop_full_debug_logging
5089 }
5090 run_test 39j "write, rename, close, stat ======================="
5091
5092 test_39k() {
5093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5094
5095         touch $DIR1/$tfile
5096         sleep 1
5097
5098         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5099         local multipid=$!
5100         local mtime1=`stat -c %Y $DIR1/$tfile`
5101
5102         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5103
5104         kill -USR1 $multipid
5105         wait $multipid || error "multiop close failed"
5106
5107         for (( i=0; i < 2; i++ )) ; do
5108                 local mtime2=`stat -c %Y $DIR1/$tfile`
5109
5110                 [ "$mtime2" = $TEST_39_MTIME ] || \
5111                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5112
5113                 cancel_lru_locks
5114                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5115         done
5116 }
5117 run_test 39k "write, utime, close, stat ========================"
5118
5119 # this should be set to future
5120 TEST_39_ATIME=`date -d "1 year" +%s`
5121
5122 test_39l() {
5123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5124         remote_mds_nodsh && skip "remote MDS with nodsh"
5125
5126         local atime_diff=$(do_facet $SINGLEMDS \
5127                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5128         rm -rf $DIR/$tdir
5129         mkdir_on_mdt0 $DIR/$tdir
5130
5131         # test setting directory atime to future
5132         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5133         local atime=$(stat -c %X $DIR/$tdir)
5134         [ "$atime" = $TEST_39_ATIME ] ||
5135                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5136
5137         # test setting directory atime from future to now
5138         local now=$(date +%s)
5139         touch -a -d @$now $DIR/$tdir
5140
5141         atime=$(stat -c %X $DIR/$tdir)
5142         [ "$atime" -eq "$now"  ] ||
5143                 error "atime is not updated from future: $atime, $now"
5144
5145         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5146         sleep 3
5147
5148         # test setting directory atime when now > dir atime + atime_diff
5149         local d1=$(date +%s)
5150         ls $DIR/$tdir
5151         local d2=$(date +%s)
5152         cancel_lru_locks mdc
5153         atime=$(stat -c %X $DIR/$tdir)
5154         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5155                 error "atime is not updated  : $atime, should be $d2"
5156
5157         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5158         sleep 3
5159
5160         # test not setting directory atime when now < dir atime + atime_diff
5161         ls $DIR/$tdir
5162         cancel_lru_locks mdc
5163         atime=$(stat -c %X $DIR/$tdir)
5164         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5165                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5166
5167         do_facet $SINGLEMDS \
5168                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5169 }
5170 run_test 39l "directory atime update ==========================="
5171
5172 test_39m() {
5173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5174
5175         touch $DIR1/$tfile
5176         sleep 2
5177         local far_past_mtime=$(date -d "May 29 1953" +%s)
5178         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5179
5180         touch -m -d @$far_past_mtime $DIR1/$tfile
5181         touch -a -d @$far_past_atime $DIR1/$tfile
5182
5183         for (( i=0; i < 2; i++ )) ; do
5184                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5185                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5186                         error "atime or mtime set incorrectly"
5187
5188                 cancel_lru_locks $OSC
5189                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5190         done
5191 }
5192 run_test 39m "test atime and mtime before 1970"
5193
5194 test_39n() { # LU-3832
5195         remote_mds_nodsh && skip "remote MDS with nodsh"
5196
5197         local atime_diff=$(do_facet $SINGLEMDS \
5198                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5199         local atime0
5200         local atime1
5201         local atime2
5202
5203         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5204
5205         rm -rf $DIR/$tfile
5206         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5207         atime0=$(stat -c %X $DIR/$tfile)
5208
5209         sleep 5
5210         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5211         atime1=$(stat -c %X $DIR/$tfile)
5212
5213         sleep 5
5214         cancel_lru_locks mdc
5215         cancel_lru_locks osc
5216         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5217         atime2=$(stat -c %X $DIR/$tfile)
5218
5219         do_facet $SINGLEMDS \
5220                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5221
5222         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5223         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5224 }
5225 run_test 39n "check that O_NOATIME is honored"
5226
5227 test_39o() {
5228         TESTDIR=$DIR/$tdir/$tfile
5229         [ -e $TESTDIR ] && rm -rf $TESTDIR
5230         mkdir -p $TESTDIR
5231         cd $TESTDIR
5232         links1=2
5233         ls
5234         mkdir a b
5235         ls
5236         links2=$(stat -c %h .)
5237         [ $(($links1 + 2)) != $links2 ] &&
5238                 error "wrong links count $(($links1 + 2)) != $links2"
5239         rmdir b
5240         links3=$(stat -c %h .)
5241         [ $(($links1 + 1)) != $links3 ] &&
5242                 error "wrong links count $links1 != $links3"
5243         return 0
5244 }
5245 run_test 39o "directory cached attributes updated after create"
5246
5247 test_39p() {
5248         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5249
5250         local MDTIDX=1
5251         TESTDIR=$DIR/$tdir/$tdir
5252         [ -e $TESTDIR ] && rm -rf $TESTDIR
5253         test_mkdir -p $TESTDIR
5254         cd $TESTDIR
5255         links1=2
5256         ls
5257         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5258         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5259         ls
5260         links2=$(stat -c %h .)
5261         [ $(($links1 + 2)) != $links2 ] &&
5262                 error "wrong links count $(($links1 + 2)) != $links2"
5263         rmdir remote_dir2
5264         links3=$(stat -c %h .)
5265         [ $(($links1 + 1)) != $links3 ] &&
5266                 error "wrong links count $links1 != $links3"
5267         return 0
5268 }
5269 run_test 39p "remote directory cached attributes updated after create ========"
5270
5271 test_39r() {
5272         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5273                 skip "no atime update on old OST"
5274         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5275                 skip_env "ldiskfs only test"
5276         fi
5277
5278         local saved_adiff
5279         local ahost=$(facet_active_host ost1)
5280         saved_adiff=$(do_facet ost1 \
5281                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5282         stack_trap "do_facet ost1 \
5283                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5284
5285         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5286
5287         $LFS setstripe -i 0 $DIR/$tfile
5288         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5289                 error "can't write initial file"
5290         cancel_lru_locks osc
5291
5292         # exceed atime_diff and access file
5293         sleep 10
5294         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5295                 error "can't udpate atime"
5296
5297         # atime_cli value is in decimal
5298         local atime_cli=$(stat -c %X $DIR/$tfile)
5299         echo "client atime: $atime_cli"
5300
5301         local ostdev=$(ostdevname 1)
5302         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5303         local seq=${fid[3]#0x}
5304         local oid=${fid[1]}
5305         local oid_hex
5306
5307         if [ $seq == 0 ]; then
5308                 oid_hex=${fid[1]}
5309         else
5310                 oid_hex=${fid[2]#0x}
5311         fi
5312         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5313         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5314
5315         # allow atime update to be written to device
5316         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5317         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5318
5319         # Give enough time for server to get updated. Until then
5320         # the value read is defaulted to "0x00000000:00000000"
5321         # Wait until atime read via debugfs is not equal to zero.
5322         # Max limit to wait is 30 seconds.
5323         wait_update_cond $ahost                                         \
5324                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5325                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5326         # atime_ost value is in hex
5327         local atime_ost=$(do_facet ost1 "$cmd" |&
5328                           awk -F'[: ]' '/atime:/ { print $4 }')
5329         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5330         # convert Hex to decimal before comparing
5331         local atime_ost_dec=$((atime_ost))
5332
5333         # The test pass criteria is that the client time and server should
5334         # be same (2s gap accepted). This gap could arise due to VFS updating
5335         # the atime after the read(dd), stat and the updated time from the
5336         # inode
5337         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5338                 error "atime on client $atime_cli != ost $atime_ost_dec"
5339 }
5340 run_test 39r "lazy atime update on OST"
5341
5342 test_39q() { # LU-8041
5343         local testdir=$DIR/$tdir
5344         mkdir -p $testdir
5345         multiop_bg_pause $testdir D_c || error "multiop failed"
5346         local multipid=$!
5347         cancel_lru_locks mdc
5348         kill -USR1 $multipid
5349         local atime=$(stat -c %X $testdir)
5350         [ "$atime" -ne 0 ] || error "atime is zero"
5351 }
5352 run_test 39q "close won't zero out atime"
5353
5354 test_39s() {
5355         local atime0
5356         local atime1
5357         local atime2
5358         local atime3
5359         local atime4
5360
5361         umount_client $MOUNT
5362         mount_client $MOUNT relatime
5363
5364         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5365         atime0=$(stat -c %X $DIR/$tfile)
5366
5367         # First read updates atime
5368         sleep 1
5369         cat $DIR/$tfile >/dev/null
5370         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5371
5372         # Next reads do not update atime
5373         sleep 1
5374         cat $DIR/$tfile >/dev/null
5375         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5376
5377         # If mtime is greater than atime, atime is updated
5378         sleep 1
5379         touch -m $DIR/$tfile # (mtime = now)
5380         sleep 1
5381         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5382         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5383
5384         # Next reads do not update atime
5385         sleep 1
5386         cat $DIR/$tfile >/dev/null
5387         atime4=$(stat -c %X $DIR/$tfile)
5388
5389         # Remount the client to clear 'relatime' option
5390         remount_client $MOUNT
5391
5392         (( atime0 < atime1 )) ||
5393                 error "atime $atime0 should be smaller than $atime1"
5394         (( atime1 == atime2 )) ||
5395                 error "atime $atime1 was updated to $atime2"
5396         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5397         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5398 }
5399 run_test 39s "relatime is supported"
5400
5401 test_40() {
5402         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5403         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5404                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5405         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5406                 error "$tfile is not 4096 bytes in size"
5407 }
5408 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5409
5410 test_41() {
5411         # bug 1553
5412         small_write $DIR/f41 18
5413 }
5414 run_test 41 "test small file write + fstat ====================="
5415
5416 count_ost_writes() {
5417         lctl get_param -n ${OSC}.*.stats |
5418                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5419                         END { printf("%0.0f", writes) }'
5420 }
5421
5422 # decent default
5423 WRITEBACK_SAVE=500
5424 DIRTY_RATIO_SAVE=40
5425 MAX_DIRTY_RATIO=50
5426 BG_DIRTY_RATIO_SAVE=10
5427 MAX_BG_DIRTY_RATIO=25
5428
5429 start_writeback() {
5430         trap 0
5431         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5432         # dirty_ratio, dirty_background_ratio
5433         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5434                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5435                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5436                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5437         else
5438                 # if file not here, we are a 2.4 kernel
5439                 kill -CONT `pidof kupdated`
5440         fi
5441 }
5442
5443 stop_writeback() {
5444         # setup the trap first, so someone cannot exit the test at the
5445         # exact wrong time and mess up a machine
5446         trap start_writeback EXIT
5447         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5448         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5449                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5450                 sysctl -w vm.dirty_writeback_centisecs=0
5451                 sysctl -w vm.dirty_writeback_centisecs=0
5452                 # save and increase /proc/sys/vm/dirty_ratio
5453                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5454                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5455                 # save and increase /proc/sys/vm/dirty_background_ratio
5456                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5457                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5458         else
5459                 # if file not here, we are a 2.4 kernel
5460                 kill -STOP `pidof kupdated`
5461         fi
5462 }
5463
5464 # ensure that all stripes have some grant before we test client-side cache
5465 setup_test42() {
5466         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5467                 dd if=/dev/zero of=$i bs=4k count=1
5468                 rm $i
5469         done
5470 }
5471
5472 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5473 # file truncation, and file removal.
5474 test_42a() {
5475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5476
5477         setup_test42
5478         cancel_lru_locks $OSC
5479         stop_writeback
5480         sync; sleep 1; sync # just to be safe
5481         BEFOREWRITES=`count_ost_writes`
5482         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5483         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5484         AFTERWRITES=`count_ost_writes`
5485         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5486                 error "$BEFOREWRITES < $AFTERWRITES"
5487         start_writeback
5488 }
5489 run_test 42a "ensure that we don't flush on close"
5490
5491 test_42b() {
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493
5494         setup_test42
5495         cancel_lru_locks $OSC
5496         stop_writeback
5497         sync
5498         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5499         BEFOREWRITES=$(count_ost_writes)
5500         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5501         AFTERWRITES=$(count_ost_writes)
5502         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5503                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5504         fi
5505         BEFOREWRITES=$(count_ost_writes)
5506         sync || error "sync: $?"
5507         AFTERWRITES=$(count_ost_writes)
5508         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5509                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5510         fi
5511         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5512         start_writeback
5513         return 0
5514 }
5515 run_test 42b "test destroy of file with cached dirty data ======"
5516
5517 # if these tests just want to test the effect of truncation,
5518 # they have to be very careful.  consider:
5519 # - the first open gets a {0,EOF}PR lock
5520 # - the first write conflicts and gets a {0, count-1}PW
5521 # - the rest of the writes are under {count,EOF}PW
5522 # - the open for truncate tries to match a {0,EOF}PR
5523 #   for the filesize and cancels the PWs.
5524 # any number of fixes (don't get {0,EOF} on open, match
5525 # composite locks, do smarter file size management) fix
5526 # this, but for now we want these tests to verify that
5527 # the cancellation with truncate intent works, so we
5528 # start the file with a full-file pw lock to match against
5529 # until the truncate.
5530 trunc_test() {
5531         test=$1
5532         file=$DIR/$test
5533         offset=$2
5534         cancel_lru_locks $OSC
5535         stop_writeback
5536         # prime the file with 0,EOF PW to match
5537         touch $file
5538         $TRUNCATE $file 0
5539         sync; sync
5540         # now the real test..
5541         dd if=/dev/zero of=$file bs=1024 count=100
5542         BEFOREWRITES=`count_ost_writes`
5543         $TRUNCATE $file $offset
5544         cancel_lru_locks $OSC
5545         AFTERWRITES=`count_ost_writes`
5546         start_writeback
5547 }
5548
5549 test_42c() {
5550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5551
5552         trunc_test 42c 1024
5553         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5554                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5555         rm $file
5556 }
5557 run_test 42c "test partial truncate of file with cached dirty data"
5558
5559 test_42d() {
5560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5561
5562         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5563         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5564         $LCTL set_param debug=+cache
5565
5566         trunc_test 42d 0
5567         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5568                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5569         rm $file
5570 }
5571 run_test 42d "test complete truncate of file with cached dirty data"
5572
5573 test_42e() { # bug22074
5574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5575
5576         local TDIR=$DIR/${tdir}e
5577         local pages=16 # hardcoded 16 pages, don't change it.
5578         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5579         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5580         local max_dirty_mb
5581         local warmup_files
5582
5583         test_mkdir $DIR/${tdir}e
5584         $LFS setstripe -c 1 $TDIR
5585         createmany -o $TDIR/f $files
5586
5587         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5588
5589         # we assume that with $OSTCOUNT files, at least one of them will
5590         # be allocated on OST0.
5591         warmup_files=$((OSTCOUNT * max_dirty_mb))
5592         createmany -o $TDIR/w $warmup_files
5593
5594         # write a large amount of data into one file and sync, to get good
5595         # avail_grant number from OST.
5596         for ((i=0; i<$warmup_files; i++)); do
5597                 idx=$($LFS getstripe -i $TDIR/w$i)
5598                 [ $idx -ne 0 ] && continue
5599                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5600                 break
5601         done
5602         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5603         sync
5604         $LCTL get_param $proc_osc0/cur_dirty_bytes
5605         $LCTL get_param $proc_osc0/cur_grant_bytes
5606
5607         # create as much dirty pages as we can while not to trigger the actual
5608         # RPCs directly. but depends on the env, VFS may trigger flush during this
5609         # period, hopefully we are good.
5610         for ((i=0; i<$warmup_files; i++)); do
5611                 idx=$($LFS getstripe -i $TDIR/w$i)
5612                 [ $idx -ne 0 ] && continue
5613                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5614         done
5615         $LCTL get_param $proc_osc0/cur_dirty_bytes
5616         $LCTL get_param $proc_osc0/cur_grant_bytes
5617
5618         # perform the real test
5619         $LCTL set_param $proc_osc0/rpc_stats 0
5620         for ((;i<$files; i++)); do
5621                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5622                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5623         done
5624         sync
5625         $LCTL get_param $proc_osc0/rpc_stats
5626
5627         local percent=0
5628         local have_ppr=false
5629         $LCTL get_param $proc_osc0/rpc_stats |
5630                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5631                         # skip lines until we are at the RPC histogram data
5632                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5633                         $have_ppr || continue
5634
5635                         # we only want the percent stat for < 16 pages
5636                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5637
5638                         percent=$((percent + WPCT))
5639                         if [[ $percent -gt 15 ]]; then
5640                                 error "less than 16-pages write RPCs" \
5641                                       "$percent% > 15%"
5642                                 break
5643                         fi
5644                 done
5645         rm -rf $TDIR
5646 }
5647 run_test 42e "verify sub-RPC writes are not done synchronously"
5648
5649 test_43A() { # was test_43
5650         test_mkdir $DIR/$tdir
5651         cp -p /bin/ls $DIR/$tdir/$tfile
5652         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5653         pid=$!
5654         # give multiop a chance to open
5655         sleep 1
5656
5657         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5658         kill -USR1 $pid
5659         # Wait for multiop to exit
5660         wait $pid
5661 }
5662 run_test 43A "execution of file opened for write should return -ETXTBSY"
5663
5664 test_43a() {
5665         test_mkdir $DIR/$tdir
5666         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5667         $DIR/$tdir/sleep 60 &
5668         SLEEP_PID=$!
5669         # Make sure exec of $tdir/sleep wins race with truncate
5670         sleep 1
5671         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5672         kill $SLEEP_PID
5673 }
5674 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5675
5676 test_43b() {
5677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5678
5679         test_mkdir $DIR/$tdir
5680         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5681         $DIR/$tdir/sleep 60 &
5682         SLEEP_PID=$!
5683         # Make sure exec of $tdir/sleep wins race with truncate
5684         sleep 1
5685         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5686         kill $SLEEP_PID
5687 }
5688 run_test 43b "truncate of file being executed should return -ETXTBSY"
5689
5690 test_43c() {
5691         local testdir="$DIR/$tdir"
5692         test_mkdir $testdir
5693         cp $SHELL $testdir/
5694         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5695                 ( cd $testdir && md5sum -c )
5696 }
5697 run_test 43c "md5sum of copy into lustre"
5698
5699 test_44A() { # was test_44
5700         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5701
5702         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5703         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5704 }
5705 run_test 44A "zero length read from a sparse stripe"
5706
5707 test_44a() {
5708         local nstripe=$($LFS getstripe -c -d $DIR)
5709         [ -z "$nstripe" ] && skip "can't get stripe info"
5710         [[ $nstripe -gt $OSTCOUNT ]] &&
5711                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5712
5713         local stride=$($LFS getstripe -S -d $DIR)
5714         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5715                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5716         fi
5717
5718         OFFSETS="0 $((stride/2)) $((stride-1))"
5719         for offset in $OFFSETS; do
5720                 for i in $(seq 0 $((nstripe-1))); do
5721                         local GLOBALOFFSETS=""
5722                         # size in Bytes
5723                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5724                         local myfn=$DIR/d44a-$size
5725                         echo "--------writing $myfn at $size"
5726                         ll_sparseness_write $myfn $size ||
5727                                 error "ll_sparseness_write"
5728                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5729                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5730                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5731
5732                         for j in $(seq 0 $((nstripe-1))); do
5733                                 # size in Bytes
5734                                 size=$((((j + $nstripe )*$stride + $offset)))
5735                                 ll_sparseness_write $myfn $size ||
5736                                         error "ll_sparseness_write"
5737                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5738                         done
5739                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5740                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5741                         rm -f $myfn
5742                 done
5743         done
5744 }
5745 run_test 44a "test sparse pwrite ==============================="
5746
5747 dirty_osc_total() {
5748         tot=0
5749         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5750                 tot=$(($tot + $d))
5751         done
5752         echo $tot
5753 }
5754 do_dirty_record() {
5755         before=`dirty_osc_total`
5756         echo executing "\"$*\""
5757         eval $*
5758         after=`dirty_osc_total`
5759         echo before $before, after $after
5760 }
5761 test_45() {
5762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5763
5764         f="$DIR/f45"
5765         # Obtain grants from OST if it supports it
5766         echo blah > ${f}_grant
5767         stop_writeback
5768         sync
5769         do_dirty_record "echo blah > $f"
5770         [[ $before -eq $after ]] && error "write wasn't cached"
5771         do_dirty_record "> $f"
5772         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5773         do_dirty_record "echo blah > $f"
5774         [[ $before -eq $after ]] && error "write wasn't cached"
5775         do_dirty_record "sync"
5776         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5777         do_dirty_record "echo blah > $f"
5778         [[ $before -eq $after ]] && error "write wasn't cached"
5779         do_dirty_record "cancel_lru_locks osc"
5780         [[ $before -gt $after ]] ||
5781                 error "lock cancellation didn't lower dirty count"
5782         start_writeback
5783 }
5784 run_test 45 "osc io page accounting ============================"
5785
5786 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5787 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5788 # objects offset and an assert hit when an rpc was built with 1023's mapped
5789 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5790 test_46() {
5791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5792
5793         f="$DIR/f46"
5794         stop_writeback
5795         sync
5796         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5797         sync
5798         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5799         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5800         sync
5801         start_writeback
5802 }
5803 run_test 46 "dirtying a previously written page ================"
5804
5805 # test_47 is removed "Device nodes check" is moved to test_28
5806
5807 test_48a() { # bug 2399
5808         [ "$mds1_FSTYPE" = "zfs" ] &&
5809         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5810                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5811
5812         test_mkdir $DIR/$tdir
5813         cd $DIR/$tdir
5814         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5815         test_mkdir $DIR/$tdir
5816         touch foo || error "'touch foo' failed after recreating cwd"
5817         test_mkdir bar
5818         touch .foo || error "'touch .foo' failed after recreating cwd"
5819         test_mkdir .bar
5820         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5821         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5822         cd . || error "'cd .' failed after recreating cwd"
5823         mkdir . && error "'mkdir .' worked after recreating cwd"
5824         rmdir . && error "'rmdir .' worked after recreating cwd"
5825         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5826         cd .. || error "'cd ..' failed after recreating cwd"
5827 }
5828 run_test 48a "Access renamed working dir (should return errors)="
5829
5830 test_48b() { # bug 2399
5831         rm -rf $DIR/$tdir
5832         test_mkdir $DIR/$tdir
5833         cd $DIR/$tdir
5834         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5835         touch foo && error "'touch foo' worked after removing cwd"
5836         mkdir foo && error "'mkdir foo' worked after removing cwd"
5837         touch .foo && error "'touch .foo' worked after removing cwd"
5838         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5839         ls . > /dev/null && error "'ls .' worked after removing cwd"
5840         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5841         mkdir . && error "'mkdir .' worked after removing cwd"
5842         rmdir . && error "'rmdir .' worked after removing cwd"
5843         ln -s . foo && error "'ln -s .' worked after removing cwd"
5844         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5845 }
5846 run_test 48b "Access removed working dir (should return errors)="
5847
5848 test_48c() { # bug 2350
5849         #lctl set_param debug=-1
5850         #set -vx
5851         rm -rf $DIR/$tdir
5852         test_mkdir -p $DIR/$tdir/dir
5853         cd $DIR/$tdir/dir
5854         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5855         $TRACE touch foo && error "touch foo worked after removing cwd"
5856         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5857         touch .foo && error "touch .foo worked after removing cwd"
5858         mkdir .foo && error "mkdir .foo worked after removing cwd"
5859         $TRACE ls . && error "'ls .' worked after removing cwd"
5860         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5861         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5862         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5863         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5864         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5865 }
5866 run_test 48c "Access removed working subdir (should return errors)"
5867
5868 test_48d() { # bug 2350
5869         #lctl set_param debug=-1
5870         #set -vx
5871         rm -rf $DIR/$tdir
5872         test_mkdir -p $DIR/$tdir/dir
5873         cd $DIR/$tdir/dir
5874         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5875         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5876         $TRACE touch foo && error "'touch foo' worked after removing parent"
5877         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5878         touch .foo && error "'touch .foo' worked after removing parent"
5879         mkdir .foo && error "mkdir .foo worked after removing parent"
5880         $TRACE ls . && error "'ls .' worked after removing parent"
5881         $TRACE ls .. && error "'ls ..' worked after removing parent"
5882         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5883         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5884         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5885         true
5886 }
5887 run_test 48d "Access removed parent subdir (should return errors)"
5888
5889 test_48e() { # bug 4134
5890         #lctl set_param debug=-1
5891         #set -vx
5892         rm -rf $DIR/$tdir
5893         test_mkdir -p $DIR/$tdir/dir
5894         cd $DIR/$tdir/dir
5895         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5896         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5897         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5898         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5899         # On a buggy kernel addition of "touch foo" after cd .. will
5900         # produce kernel oops in lookup_hash_it
5901         touch ../foo && error "'cd ..' worked after recreate parent"
5902         cd $DIR
5903         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5904 }
5905 run_test 48e "Access to recreated parent subdir (should return errors)"
5906
5907 test_48f() {
5908         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5909                 skip "need MDS >= 2.13.55"
5910         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5911         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5912                 skip "needs different host for mdt1 mdt2"
5913         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5914
5915         $LFS mkdir -i0 $DIR/$tdir
5916         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5917
5918         for d in sub1 sub2 sub3; do
5919                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5920                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5921                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5922         done
5923
5924         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5925 }
5926 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5927
5928 test_49() { # LU-1030
5929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5930         remote_ost_nodsh && skip "remote OST with nodsh"
5931
5932         # get ost1 size - $FSNAME-OST0000
5933         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5934                 awk '{ print $4 }')
5935         # write 800M at maximum
5936         [[ $ost1_size -lt 2 ]] && ost1_size=2
5937         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5938
5939         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5940         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5941         local dd_pid=$!
5942
5943         # change max_pages_per_rpc while writing the file
5944         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5945         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5946         # loop until dd process exits
5947         while ps ax -opid | grep -wq $dd_pid; do
5948                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5949                 sleep $((RANDOM % 5 + 1))
5950         done
5951         # restore original max_pages_per_rpc
5952         $LCTL set_param $osc1_mppc=$orig_mppc
5953         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5954 }
5955 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5956
5957 test_50() {
5958         # bug 1485
5959         test_mkdir $DIR/$tdir
5960         cd $DIR/$tdir
5961         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5962 }
5963 run_test 50 "special situations: /proc symlinks  ==============="
5964
5965 test_51a() {    # was test_51
5966         # bug 1516 - create an empty entry right after ".." then split dir
5967         test_mkdir -c1 $DIR/$tdir
5968         touch $DIR/$tdir/foo
5969         $MCREATE $DIR/$tdir/bar
5970         rm $DIR/$tdir/foo
5971         createmany -m $DIR/$tdir/longfile 201
5972         FNUM=202
5973         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5974                 $MCREATE $DIR/$tdir/longfile$FNUM
5975                 FNUM=$(($FNUM + 1))
5976                 echo -n "+"
5977         done
5978         echo
5979         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5980 }
5981 run_test 51a "special situations: split htree with empty entry =="
5982
5983 cleanup_print_lfs_df () {
5984         trap 0
5985         $LFS df
5986         $LFS df -i
5987 }
5988
5989 test_51b() {
5990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5991
5992         local dir=$DIR/$tdir
5993         local nrdirs=$((65536 + 100))
5994
5995         # cleanup the directory
5996         rm -fr $dir
5997
5998         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5999
6000         $LFS df
6001         $LFS df -i
6002         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6003         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6004         [[ $numfree -lt $nrdirs ]] &&
6005                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6006
6007         # need to check free space for the directories as well
6008         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6009         numfree=$(( blkfree / $(fs_inode_ksize) ))
6010         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6011
6012         trap cleanup_print_lfs_df EXIT
6013
6014         # create files
6015         createmany -d $dir/d $nrdirs || {
6016                 unlinkmany $dir/d $nrdirs
6017                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6018         }
6019
6020         # really created :
6021         nrdirs=$(ls -U $dir | wc -l)
6022
6023         # unlink all but 100 subdirectories, then check it still works
6024         local left=100
6025         local delete=$((nrdirs - left))
6026
6027         $LFS df
6028         $LFS df -i
6029
6030         # for ldiskfs the nlink count should be 1, but this is OSD specific
6031         # and so this is listed for informational purposes only
6032         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6033         unlinkmany -d $dir/d $delete ||
6034                 error "unlink of first $delete subdirs failed"
6035
6036         echo "nlink between: $(stat -c %h $dir)"
6037         local found=$(ls -U $dir | wc -l)
6038         [ $found -ne $left ] &&
6039                 error "can't find subdirs: found only $found, expected $left"
6040
6041         unlinkmany -d $dir/d $delete $left ||
6042                 error "unlink of second $left subdirs failed"
6043         # regardless of whether the backing filesystem tracks nlink accurately
6044         # or not, the nlink count shouldn't be more than "." and ".." here
6045         local after=$(stat -c %h $dir)
6046         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6047                 echo "nlink after: $after"
6048
6049         cleanup_print_lfs_df
6050 }
6051 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6052
6053 test_51d_sub() {
6054         local stripecount=$1
6055         local nfiles=$2
6056
6057         log "create files with stripecount=$stripecount"
6058         $LFS setstripe -C $stripecount $DIR/$tdir
6059         createmany -o $DIR/$tdir/t- $nfiles
6060         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6061         for ((n = 0; n < $OSTCOUNT; n++)); do
6062                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6063                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6064                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6065                             '($1 == '$n') { objs += 1 } \
6066                             END { printf("%0.0f", objs) }')
6067                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6068         done
6069         unlinkmany $DIR/$tdir/t- $nfiles
6070         rm  -f $TMP/$tfile
6071
6072         local nlast
6073         local min=4
6074         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6075
6076         # For some combinations of stripecount and OSTCOUNT current code
6077         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6078         # than others. Rather than skipping this test entirely, check that
6079         # and keep testing to ensure imbalance does not get worse. LU-15282
6080         (( (OSTCOUNT == 6 && stripecount == 4) ||
6081            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6082            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6083         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6084                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6085                         { $LFS df && $LFS df -i &&
6086                         error "stripecount=$stripecount: " \
6087                               "OST $n has fewer objects vs. OST $nlast " \
6088                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6089                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6090                         { $LFS df && $LFS df -i &&
6091                         error "stripecount=$stripecount: " \
6092                               "OST $n has more objects vs. OST $nlast " \
6093                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6094
6095                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6096                         { $LFS df && $LFS df -i &&
6097                         error "stripecount=$stripecount: " \
6098                               "OST $n has fewer #0 objects vs. OST $nlast " \
6099                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6100                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6101                         { $LFS df && $LFS df -i &&
6102                         error "stripecount=$stripecount: " \
6103                               "OST $n has more #0 objects vs. OST $nlast " \
6104                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6105         done
6106 }
6107
6108 test_51d() {
6109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6110         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6111
6112         local stripecount
6113         local per_ost=100
6114         local nfiles=$((per_ost * OSTCOUNT))
6115         local mdts=$(comma_list $(mdts_nodes))
6116         local param="osp.*.create_count"
6117         local qos_old=$(do_facet mds1 \
6118                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6119
6120         do_nodes $mdts \
6121                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6122         stack_trap "do_nodes $mdts \
6123                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6124
6125         test_mkdir $DIR/$tdir
6126         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6127         (( dirstripes > 0 )) || dirstripes=1
6128
6129         # Ensure enough OST objects precreated for tests to pass without
6130         # running out of objects.  This is an LOV r-r OST algorithm test,
6131         # not an OST object precreation test.
6132         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6133         (( old >= nfiles )) ||
6134         {
6135                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6136
6137                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6138                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6139
6140                 # trigger precreation from all MDTs for all OSTs
6141                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6142                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6143                 done
6144         }
6145
6146         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6147                 sleep 8  # allow object precreation to catch up
6148                 test_51d_sub $stripecount $nfiles
6149         done
6150 }
6151 run_test 51d "check LOV round-robin OST object distribution"
6152
6153 test_51e() {
6154         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6155                 skip_env "ldiskfs only test"
6156         fi
6157
6158         test_mkdir -c1 $DIR/$tdir
6159         test_mkdir -c1 $DIR/$tdir/d0
6160
6161         touch $DIR/$tdir/d0/foo
6162         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6163                 error "file exceed 65000 nlink limit!"
6164         unlinkmany $DIR/$tdir/d0/f- 65001
6165         return 0
6166 }
6167 run_test 51e "check file nlink limit"
6168
6169 test_51f() {
6170         test_mkdir $DIR/$tdir
6171
6172         local max=100000
6173         local ulimit_old=$(ulimit -n)
6174         local spare=20 # number of spare fd's for scripts/libraries, etc.
6175         local mdt=$($LFS getstripe -m $DIR/$tdir)
6176         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6177
6178         echo "MDT$mdt numfree=$numfree, max=$max"
6179         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6180         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6181                 while ! ulimit -n $((numfree + spare)); do
6182                         numfree=$((numfree * 3 / 4))
6183                 done
6184                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6185         else
6186                 echo "left ulimit at $ulimit_old"
6187         fi
6188
6189         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6190                 unlinkmany $DIR/$tdir/f $numfree
6191                 error "create+open $numfree files in $DIR/$tdir failed"
6192         }
6193         ulimit -n $ulimit_old
6194
6195         # if createmany exits at 120s there will be fewer than $numfree files
6196         unlinkmany $DIR/$tdir/f $numfree || true
6197 }
6198 run_test 51f "check many open files limit"
6199
6200 test_52a() {
6201         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6202         test_mkdir $DIR/$tdir
6203         touch $DIR/$tdir/foo
6204         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6205         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6206         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6207         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6208         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6209                                         error "link worked"
6210         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6211         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6212         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6213                                                      error "lsattr"
6214         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6215         cp -r $DIR/$tdir $TMP/
6216         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6217 }
6218 run_test 52a "append-only flag test (should return errors)"
6219
6220 test_52b() {
6221         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6222         test_mkdir $DIR/$tdir
6223         touch $DIR/$tdir/foo
6224         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6225         cat test > $DIR/$tdir/foo && error "cat test worked"
6226         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6227         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6228         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6229                                         error "link worked"
6230         echo foo >> $DIR/$tdir/foo && error "echo worked"
6231         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6232         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6233         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6234         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6235                                                         error "lsattr"
6236         chattr -i $DIR/$tdir/foo || error "chattr failed"
6237
6238         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6239 }
6240 run_test 52b "immutable flag test (should return errors) ======="
6241
6242 test_53() {
6243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6244         remote_mds_nodsh && skip "remote MDS with nodsh"
6245         remote_ost_nodsh && skip "remote OST with nodsh"
6246
6247         local param
6248         local param_seq
6249         local ostname
6250         local mds_last
6251         local mds_last_seq
6252         local ost_last
6253         local ost_last_seq
6254         local ost_last_id
6255         local ostnum
6256         local node
6257         local found=false
6258         local support_last_seq=true
6259
6260         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6261                 support_last_seq=false
6262
6263         # only test MDT0000
6264         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6265         local value
6266         for value in $(do_facet $SINGLEMDS \
6267                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6268                 param=$(echo ${value[0]} | cut -d "=" -f1)
6269                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6270
6271                 if $support_last_seq; then
6272                         param_seq=$(echo $param |
6273                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6274                         mds_last_seq=$(do_facet $SINGLEMDS \
6275                                        $LCTL get_param -n $param_seq)
6276                 fi
6277                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6278
6279                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6280                 node=$(facet_active_host ost$((ostnum+1)))
6281                 param="obdfilter.$ostname.last_id"
6282                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6283                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6284                         ost_last_id=$ost_last
6285
6286                         if $support_last_seq; then
6287                                 ost_last_id=$(echo $ost_last |
6288                                               awk -F':' '{print $2}' |
6289                                               sed -e "s/^0x//g")
6290                                 ost_last_seq=$(echo $ost_last |
6291                                                awk -F':' '{print $1}')
6292                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6293                         fi
6294
6295                         if [[ $ost_last_id != $mds_last ]]; then
6296                                 error "$ost_last_id != $mds_last"
6297                         else
6298                                 found=true
6299                                 break
6300                         fi
6301                 done
6302         done
6303         $found || error "can not match last_seq/last_id for $mdtosc"
6304         return 0
6305 }
6306 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6307
6308 test_54a() {
6309         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6310
6311         LANG=C $SOCKETSERVER $DIR/socket ||
6312                 error "$SOCKETSERVER $DIR/socket failed: $?"
6313         LANG=C $SOCKETCLIENT $DIR/socket ||
6314                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6315         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6316 }
6317 run_test 54a "unix domain socket test =========================="
6318
6319 test_54b() {
6320         f="$DIR/f54b"
6321         mknod $f c 1 3
6322         chmod 0666 $f
6323         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6324 }
6325 run_test 54b "char device works in lustre ======================"
6326
6327 find_loop_dev() {
6328         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6329         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6330         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6331
6332         for i in $(seq 3 7); do
6333                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6334                 LOOPDEV=$LOOPBASE$i
6335                 LOOPNUM=$i
6336                 break
6337         done
6338 }
6339
6340 cleanup_54c() {
6341         local rc=0
6342         loopdev="$DIR/loop54c"
6343
6344         trap 0
6345         $UMOUNT $DIR/$tdir || rc=$?
6346         losetup -d $loopdev || true
6347         losetup -d $LOOPDEV || true
6348         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6349         return $rc
6350 }
6351
6352 test_54c() {
6353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6354
6355         loopdev="$DIR/loop54c"
6356
6357         find_loop_dev
6358         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6359         trap cleanup_54c EXIT
6360         mknod $loopdev b 7 $LOOPNUM
6361         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6362         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6363         losetup $loopdev $DIR/$tfile ||
6364                 error "can't set up $loopdev for $DIR/$tfile"
6365         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6366         test_mkdir $DIR/$tdir
6367         mount -t ext2 $loopdev $DIR/$tdir ||
6368                 error "error mounting $loopdev on $DIR/$tdir"
6369         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6370                 error "dd write"
6371         df $DIR/$tdir
6372         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6373                 error "dd read"
6374         cleanup_54c
6375 }
6376 run_test 54c "block device works in lustre ====================="
6377
6378 test_54d() {
6379         local pipe="$DIR/$tfile.pipe"
6380         local string="aaaaaa"
6381
6382         mknod $pipe p
6383         echo -n "$string" > $pipe &
6384         local result=$(cat $pipe)
6385         [[ "$result" == "$string" ]] || error "$result != $string"
6386 }
6387 run_test 54d "fifo device works in lustre ======================"
6388
6389 test_54e() {
6390         f="$DIR/f54e"
6391         string="aaaaaa"
6392         cp -aL /dev/console $f
6393         echo $string > $f || error "echo $string to $f failed"
6394 }
6395 run_test 54e "console/tty device works in lustre ======================"
6396
6397 test_55a() {
6398         local dev_path="/sys/kernel/debug/lustre/devices"
6399
6400         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6401
6402         # This must be run in iteractive mode, since attach and setup
6403         # are stateful
6404         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6405                 attach obd_test obd_name obd_uuid
6406                 setup obd_test
6407         EOF"
6408
6409         echo "Devices:"
6410         cat "$dev_path" | tail -n 10
6411
6412         $LCTL --device "obd_name" cleanup
6413         $LCTL --device "obd_name" detach
6414
6415         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6416                 error "OBD unit test failed"
6417
6418         rmmod -v obd_test ||
6419                 error "rmmod failed (may trigger a failure in a later test)"
6420 }
6421 run_test 55a "OBD device life cycle unit tests"
6422
6423 test_55b() {
6424         local dev_path="/sys/kernel/debug/lustre/devices"
6425         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6426
6427         # Set up a large number of devices, using the number
6428         # that can be set up in about a minute (based on prior
6429         # testing). We don't want to run this test forever.
6430         local num_dev_to_create="$(( 24000 - $dev_count))"
6431
6432         load_module obdclass/obd_test || error "load_module failed"
6433
6434         local start=$SECONDS
6435
6436         # This must be run in iteractive mode, since attach and setup
6437         # are stateful
6438         for ((i = 1; i <= num_dev_to_create; i++)); do
6439                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6440                 echo "setup obd_test_$i"
6441         done | $LCTL || error "OBD device creation failed"
6442
6443         echo "Load time: $((SECONDS - start))"
6444         echo "Devices:"
6445         cat "$dev_path" | tail -n 10
6446
6447         for ((i = 1; i <= num_dev_to_create; i++)); do
6448                 echo "--device obd_name_$i cleanup"
6449                 echo "--device obd_name_$i detach"
6450         done | $LCTL || error "OBD device cleanup failed"
6451
6452         echo "Unload time: $((SECONDS - start))"
6453
6454         rmmod -v obd_test ||
6455                 error "rmmod failed (may trigger a failure in a later test)"
6456 }
6457 run_test 55b "Load and unload max OBD devices"
6458
6459 test_56a() {
6460         local numfiles=3
6461         local numdirs=2
6462         local dir=$DIR/$tdir
6463
6464         rm -rf $dir
6465         test_mkdir -p $dir/dir
6466         for i in $(seq $numfiles); do
6467                 touch $dir/file$i
6468                 touch $dir/dir/file$i
6469         done
6470
6471         local numcomp=$($LFS getstripe --component-count $dir)
6472
6473         [[ $numcomp == 0 ]] && numcomp=1
6474
6475         # test lfs getstripe with --recursive
6476         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6477
6478         [[ $filenum -eq $((numfiles * 2)) ]] ||
6479                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6480         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6481         [[ $filenum -eq $numfiles ]] ||
6482                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6483         echo "$LFS getstripe showed obdidx or l_ost_idx"
6484
6485         # test lfs getstripe with file instead of dir
6486         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6487         [[ $filenum -eq 1 ]] ||
6488                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6489         echo "$LFS getstripe file1 passed"
6490
6491         #test lfs getstripe with --verbose
6492         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6493         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6494                 error "$LFS getstripe --verbose $dir: "\
6495                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6496         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6497                 error "$LFS getstripe $dir: showed lmm_magic"
6498
6499         #test lfs getstripe with -v prints lmm_fid
6500         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6501         local countfids=$((numdirs + numfiles * numcomp))
6502         [[ $filenum -eq $countfids ]] ||
6503                 error "$LFS getstripe -v $dir: "\
6504                       "got $filenum want $countfids lmm_fid"
6505         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6506                 error "$LFS getstripe $dir: showed lmm_fid by default"
6507         echo "$LFS getstripe --verbose passed"
6508
6509         #check for FID information
6510         local fid1=$($LFS getstripe --fid $dir/file1)
6511         local fid2=$($LFS getstripe --verbose $dir/file1 |
6512                      awk '/lmm_fid: / { print $2; exit; }')
6513         local fid3=$($LFS path2fid $dir/file1)
6514
6515         [ "$fid1" != "$fid2" ] &&
6516                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6517         [ "$fid1" != "$fid3" ] &&
6518                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6519         echo "$LFS getstripe --fid passed"
6520
6521         #test lfs getstripe with --obd
6522         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6523                 error "$LFS getstripe --obd wrong_uuid: should return error"
6524
6525         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6526
6527         local ostidx=1
6528         local obduuid=$(ostuuid_from_index $ostidx)
6529         local found=$($LFS getstripe -r --obd $obduuid $dir |
6530                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6531
6532         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6533         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6534                 ((filenum--))
6535         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6536                 ((filenum--))
6537
6538         [[ $found -eq $filenum ]] ||
6539                 error "$LFS getstripe --obd: found $found expect $filenum"
6540         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6541                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6542                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6543                 error "$LFS getstripe --obd: should not show file on other obd"
6544         echo "$LFS getstripe --obd passed"
6545 }
6546 run_test 56a "check $LFS getstripe"
6547
6548 test_56b() {
6549         local dir=$DIR/$tdir
6550         local numdirs=3
6551
6552         test_mkdir $dir
6553         for i in $(seq $numdirs); do
6554                 test_mkdir $dir/dir$i
6555         done
6556
6557         # test lfs getdirstripe default mode is non-recursion, which is
6558         # different from lfs getstripe
6559         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6560
6561         [[ $dircnt -eq 1 ]] ||
6562                 error "$LFS getdirstripe: found $dircnt, not 1"
6563         dircnt=$($LFS getdirstripe --recursive $dir |
6564                 grep -c lmv_stripe_count)
6565         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6566                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6567 }
6568 run_test 56b "check $LFS getdirstripe"
6569
6570 test_56bb() {
6571         verify_yaml_available || skip_env "YAML verification not installed"
6572         local output_file=$DIR/$tfile.out
6573
6574         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6575
6576         cat $output_file
6577         cat $output_file | verify_yaml || error "layout is not valid YAML"
6578 }
6579 run_test 56bb "check $LFS getdirstripe layout is YAML"
6580
6581 test_56c() {
6582         remote_ost_nodsh && skip "remote OST with nodsh"
6583
6584         local ost_idx=0
6585         local ost_name=$(ostname_from_index $ost_idx)
6586         local old_status=$(ost_dev_status $ost_idx)
6587         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6588
6589         [[ -z "$old_status" ]] ||
6590                 skip_env "OST $ost_name is in $old_status status"
6591
6592         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6593         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6594                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6595         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6596                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6597                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6598         fi
6599
6600         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6601                 error "$LFS df -v showing inactive devices"
6602         sleep_maxage
6603
6604         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6605
6606         [[ "$new_status" =~ "D" ]] ||
6607                 error "$ost_name status is '$new_status', missing 'D'"
6608         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6609                 [[ "$new_status" =~ "N" ]] ||
6610                         error "$ost_name status is '$new_status', missing 'N'"
6611         fi
6612         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6613                 [[ "$new_status" =~ "f" ]] ||
6614                         error "$ost_name status is '$new_status', missing 'f'"
6615         fi
6616
6617         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6618         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6619                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6620         [[ -z "$p" ]] && restore_lustre_params < $p || true
6621         sleep_maxage
6622
6623         new_status=$(ost_dev_status $ost_idx)
6624         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6625                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6626         # can't check 'f' as devices may actually be on flash
6627 }
6628 run_test 56c "check 'lfs df' showing device status"
6629
6630 test_56d() {
6631         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6632         local osts=$($LFS df -v $MOUNT | grep -c OST)
6633
6634         $LFS df $MOUNT
6635
6636         (( mdts == MDSCOUNT )) ||
6637                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6638         (( osts == OSTCOUNT )) ||
6639                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6640 }
6641 run_test 56d "'lfs df -v' prints only configured devices"
6642
6643 test_56e() {
6644         err_enoent=2 # No such file or directory
6645         err_eopnotsupp=95 # Operation not supported
6646
6647         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6648         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6649
6650         # Check for handling of path not exists
6651         output=$($LFS df $enoent_mnt 2>&1)
6652         ret=$?
6653
6654         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6655         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6656                 error "expect failure $err_enoent, not $ret"
6657
6658         # Check for handling of non-Lustre FS
6659         output=$($LFS df $notsup_mnt)
6660         ret=$?
6661
6662         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6663         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6664                 error "expect success $err_eopnotsupp, not $ret"
6665
6666         # Check for multiple LustreFS argument
6667         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6668         ret=$?
6669
6670         [[ $output -eq 3 && $ret -eq 0 ]] ||
6671                 error "expect success 3, not $output, rc = $ret"
6672
6673         # Check for correct non-Lustre FS handling among multiple
6674         # LustreFS argument
6675         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6676                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6677         ret=$?
6678
6679         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6680                 error "expect success 2, not $output, rc = $ret"
6681 }
6682 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6683
6684 NUMFILES=3
6685 NUMDIRS=3
6686 setup_56() {
6687         local local_tdir="$1"
6688         local local_numfiles="$2"
6689         local local_numdirs="$3"
6690         local dir_params="$4"
6691         local dir_stripe_params="$5"
6692
6693         if [ ! -d "$local_tdir" ] ; then
6694                 test_mkdir -p $dir_stripe_params $local_tdir
6695                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6696                 for i in $(seq $local_numfiles) ; do
6697                         touch $local_tdir/file$i
6698                 done
6699                 for i in $(seq $local_numdirs) ; do
6700                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6701                         for j in $(seq $local_numfiles) ; do
6702                                 touch $local_tdir/dir$i/file$j
6703                         done
6704                 done
6705         fi
6706 }
6707
6708 setup_56_special() {
6709         local local_tdir=$1
6710         local local_numfiles=$2
6711         local local_numdirs=$3
6712
6713         setup_56 $local_tdir $local_numfiles $local_numdirs
6714
6715         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6716                 for i in $(seq $local_numfiles) ; do
6717                         mknod $local_tdir/loop${i}b b 7 $i
6718                         mknod $local_tdir/null${i}c c 1 3
6719                         ln -s $local_tdir/file1 $local_tdir/link${i}
6720                 done
6721                 for i in $(seq $local_numdirs) ; do
6722                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6723                         mknod $local_tdir/dir$i/null${i}c c 1 3
6724                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6725                 done
6726         fi
6727 }
6728
6729 test_56g() {
6730         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6731         local expected=$(($NUMDIRS + 2))
6732
6733         setup_56 $dir $NUMFILES $NUMDIRS
6734
6735         # test lfs find with -name
6736         for i in $(seq $NUMFILES) ; do
6737                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6738
6739                 [ $nums -eq $expected ] ||
6740                         error "lfs find -name '*$i' $dir wrong: "\
6741                               "found $nums, expected $expected"
6742         done
6743 }
6744 run_test 56g "check lfs find -name"
6745
6746 test_56h() {
6747         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6748         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6749
6750         setup_56 $dir $NUMFILES $NUMDIRS
6751
6752         # test lfs find with ! -name
6753         for i in $(seq $NUMFILES) ; do
6754                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6755
6756                 [ $nums -eq $expected ] ||
6757                         error "lfs find ! -name '*$i' $dir wrong: "\
6758                               "found $nums, expected $expected"
6759         done
6760 }
6761 run_test 56h "check lfs find ! -name"
6762
6763 test_56i() {
6764         local dir=$DIR/$tdir
6765
6766         test_mkdir $dir
6767
6768         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6769         local out=$($cmd)
6770
6771         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6772 }
6773 run_test 56i "check 'lfs find -ost UUID' skips directories"
6774
6775 test_56j() {
6776         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6777
6778         setup_56_special $dir $NUMFILES $NUMDIRS
6779
6780         local expected=$((NUMDIRS + 1))
6781         local cmd="$LFS find -type d $dir"
6782         local nums=$($cmd | wc -l)
6783
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786 }
6787 run_test 56j "check lfs find -type d"
6788
6789 test_56k() {
6790         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6791
6792         setup_56_special $dir $NUMFILES $NUMDIRS
6793
6794         local expected=$(((NUMDIRS + 1) * NUMFILES))
6795         local cmd="$LFS find -type f $dir"
6796         local nums=$($cmd | wc -l)
6797
6798         [ $nums -eq $expected ] ||
6799                 error "'$cmd' wrong: found $nums, expected $expected"
6800 }
6801 run_test 56k "check lfs find -type f"
6802
6803 test_56l() {
6804         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6805
6806         setup_56_special $dir $NUMFILES $NUMDIRS
6807
6808         local expected=$((NUMDIRS + NUMFILES))
6809         local cmd="$LFS find -type b $dir"
6810         local nums=$($cmd | wc -l)
6811
6812         [ $nums -eq $expected ] ||
6813                 error "'$cmd' wrong: found $nums, expected $expected"
6814 }
6815 run_test 56l "check lfs find -type b"
6816
6817 test_56m() {
6818         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6819
6820         setup_56_special $dir $NUMFILES $NUMDIRS
6821
6822         local expected=$((NUMDIRS + NUMFILES))
6823         local cmd="$LFS find -type c $dir"
6824         local nums=$($cmd | wc -l)
6825         [ $nums -eq $expected ] ||
6826                 error "'$cmd' wrong: found $nums, expected $expected"
6827 }
6828 run_test 56m "check lfs find -type c"
6829
6830 test_56n() {
6831         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6832         setup_56_special $dir $NUMFILES $NUMDIRS
6833
6834         local expected=$((NUMDIRS + NUMFILES))
6835         local cmd="$LFS find -type l $dir"
6836         local nums=$($cmd | wc -l)
6837
6838         [ $nums -eq $expected ] ||
6839                 error "'$cmd' wrong: found $nums, expected $expected"
6840 }
6841 run_test 56n "check lfs find -type l"
6842
6843 test_56o() {
6844         local dir=$DIR/$tdir
6845
6846         setup_56 $dir $NUMFILES $NUMDIRS
6847         utime $dir/file1 > /dev/null || error "utime (1)"
6848         utime $dir/file2 > /dev/null || error "utime (2)"
6849         utime $dir/dir1 > /dev/null || error "utime (3)"
6850         utime $dir/dir2 > /dev/null || error "utime (4)"
6851         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6852         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6853
6854         local expected=4
6855         local nums=$($LFS find -mtime +0 $dir | wc -l)
6856
6857         [ $nums -eq $expected ] ||
6858                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6859
6860         expected=12
6861         cmd="$LFS find -mtime 0 $dir"
6862         nums=$($cmd | wc -l)
6863         [ $nums -eq $expected ] ||
6864                 error "'$cmd' wrong: found $nums, expected $expected"
6865 }
6866 run_test 56o "check lfs find -mtime for old files"
6867
6868 test_56ob() {
6869         local dir=$DIR/$tdir
6870         local expected=1
6871         local count=0
6872
6873         # just to make sure there is something that won't be found
6874         test_mkdir $dir
6875         touch $dir/$tfile.now
6876
6877         for age in year week day hour min; do
6878                 count=$((count + 1))
6879
6880                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6881                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6882                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6883
6884                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6885                 local nums=$($cmd | wc -l)
6886                 [ $nums -eq $expected ] ||
6887                         error "'$cmd' wrong: found $nums, expected $expected"
6888
6889                 cmd="$LFS find $dir -atime $count${age:0:1}"
6890                 nums=$($cmd | wc -l)
6891                 [ $nums -eq $expected ] ||
6892                         error "'$cmd' wrong: found $nums, expected $expected"
6893         done
6894
6895         sleep 2
6896         cmd="$LFS find $dir -ctime +1s -type f"
6897         nums=$($cmd | wc -l)
6898         (( $nums == $count * 2 + 1)) ||
6899                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6900 }
6901 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6902
6903 test_newerXY_base() {
6904         local x=$1
6905         local y=$2
6906         local dir=$DIR/$tdir
6907         local ref
6908         local negref
6909
6910         if [ $y == "t" ]; then
6911                 if [ $x == "b" ]; then
6912                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6913                 else
6914                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6915                 fi
6916         else
6917                 ref=$DIR/$tfile.newer.$x$y
6918                 touch $ref || error "touch $ref failed"
6919         fi
6920
6921         echo "before = $ref"
6922         sleep 2
6923         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6924         sleep 2
6925         if [ $y == "t" ]; then
6926                 if [ $x == "b" ]; then
6927                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6928                 else
6929                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6930                 fi
6931         else
6932                 negref=$DIR/$tfile.negnewer.$x$y
6933                 touch $negref || error "touch $negref failed"
6934         fi
6935
6936         echo "after = $negref"
6937         local cmd="$LFS find $dir -newer$x$y $ref"
6938         local nums=$(eval $cmd | wc -l)
6939         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6940
6941         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6942                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6943
6944         cmd="$LFS find $dir ! -newer$x$y $negref"
6945         nums=$(eval $cmd | wc -l)
6946         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6947                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6948
6949         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6950         nums=$(eval $cmd | wc -l)
6951         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6952                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6953
6954         rm -rf $DIR/*
6955 }
6956
6957 test_56oc() {
6958         test_newerXY_base "a" "a"
6959         test_newerXY_base "a" "m"
6960         test_newerXY_base "a" "c"
6961         test_newerXY_base "m" "a"
6962         test_newerXY_base "m" "m"
6963         test_newerXY_base "m" "c"
6964         test_newerXY_base "c" "a"
6965         test_newerXY_base "c" "m"
6966         test_newerXY_base "c" "c"
6967
6968         test_newerXY_base "a" "t"
6969         test_newerXY_base "m" "t"
6970         test_newerXY_base "c" "t"
6971
6972         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6973            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6974                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6975
6976         test_newerXY_base "b" "b"
6977         test_newerXY_base "b" "t"
6978 }
6979 run_test 56oc "check lfs find -newerXY work"
6980
6981 test_56od() {
6982         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6983                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6984
6985         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6986                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6987
6988         local dir=$DIR/$tdir
6989         local ref=$DIR/$tfile.ref
6990         local negref=$DIR/$tfile.negref
6991
6992         mkdir $dir || error "mkdir $dir failed"
6993         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6994         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6995         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6996         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6997         touch $ref || error "touch $ref failed"
6998         # sleep 3 seconds at least
6999         sleep 3
7000
7001         local before=$(do_facet mds1 date +%s)
7002         local skew=$(($(date +%s) - before + 1))
7003
7004         if (( skew < 0 && skew > -5 )); then
7005                 sleep $((0 - skew + 1))
7006                 skew=0
7007         fi
7008
7009         # Set the dir stripe params to limit files all on MDT0,
7010         # otherwise we need to calc the max clock skew between
7011         # the client and MDTs.
7012         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7013         sleep 2
7014         touch $negref || error "touch $negref failed"
7015
7016         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7017         local nums=$($cmd | wc -l)
7018         local expected=$(((NUMFILES + 1) * NUMDIRS))
7019
7020         [ $nums -eq $expected ] ||
7021                 error "'$cmd' wrong: found $nums, expected $expected"
7022
7023         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7024         nums=$($cmd | wc -l)
7025         expected=$((NUMFILES + 1))
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         [ $skew -lt 0 ] && return
7030
7031         local after=$(do_facet mds1 date +%s)
7032         local age=$((after - before + 1 + skew))
7033
7034         cmd="$LFS find $dir -btime -${age}s -type f"
7035         nums=$($cmd | wc -l)
7036         expected=$(((NUMFILES + 1) * NUMDIRS))
7037
7038         echo "Clock skew between client and server: $skew, age:$age"
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041
7042         expected=$(($NUMDIRS + 1))
7043         cmd="$LFS find $dir -btime -${age}s -type d"
7044         nums=$($cmd | wc -l)
7045         [ $nums -eq $expected ] ||
7046                 error "'$cmd' wrong: found $nums, expected $expected"
7047         rm -f $ref $negref || error "Failed to remove $ref $negref"
7048 }
7049 run_test 56od "check lfs find -btime with units"
7050
7051 test_56p() {
7052         [ $RUNAS_ID -eq $UID ] &&
7053                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7054
7055         local dir=$DIR/$tdir
7056
7057         setup_56 $dir $NUMFILES $NUMDIRS
7058         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7059
7060         local expected=$NUMFILES
7061         local cmd="$LFS find -uid $RUNAS_ID $dir"
7062         local nums=$($cmd | wc -l)
7063
7064         [ $nums -eq $expected ] ||
7065                 error "'$cmd' wrong: found $nums, expected $expected"
7066
7067         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7068         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7069         nums=$($cmd | wc -l)
7070         [ $nums -eq $expected ] ||
7071                 error "'$cmd' wrong: found $nums, expected $expected"
7072 }
7073 run_test 56p "check lfs find -uid and ! -uid"
7074
7075 test_56q() {
7076         [ $RUNAS_ID -eq $UID ] &&
7077                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7078
7079         local dir=$DIR/$tdir
7080
7081         setup_56 $dir $NUMFILES $NUMDIRS
7082         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7083
7084         local expected=$NUMFILES
7085         local cmd="$LFS find -gid $RUNAS_GID $dir"
7086         local nums=$($cmd | wc -l)
7087
7088         [ $nums -eq $expected ] ||
7089                 error "'$cmd' wrong: found $nums, expected $expected"
7090
7091         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7092         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7093         nums=$($cmd | wc -l)
7094         [ $nums -eq $expected ] ||
7095                 error "'$cmd' wrong: found $nums, expected $expected"
7096 }
7097 run_test 56q "check lfs find -gid and ! -gid"
7098
7099 test_56r() {
7100         local dir=$DIR/$tdir
7101
7102         setup_56 $dir $NUMFILES $NUMDIRS
7103
7104         local expected=12
7105         local cmd="$LFS find -size 0 -type f -lazy $dir"
7106         local nums=$($cmd | wc -l)
7107
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110         cmd="$LFS find -size 0 -type f $dir"
7111         nums=$($cmd | wc -l)
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114
7115         expected=0
7116         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7117         nums=$($cmd | wc -l)
7118         [ $nums -eq $expected ] ||
7119                 error "'$cmd' wrong: found $nums, expected $expected"
7120         cmd="$LFS find ! -size 0 -type f $dir"
7121         nums=$($cmd | wc -l)
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124
7125         echo "test" > $dir/$tfile
7126         echo "test2" > $dir/$tfile.2 && sync
7127         expected=1
7128         cmd="$LFS find -size 5c -type f -lazy $dir"
7129         nums=$($cmd | wc -l)
7130         [ $nums -eq $expected ] ||
7131                 error "'$cmd' wrong: found $nums, expected $expected"
7132         cmd="$LFS find -size 5c -type f $dir"
7133         nums=$($cmd | wc -l)
7134         [ $nums -eq $expected ] ||
7135                 error "'$cmd' wrong: found $nums, expected $expected"
7136
7137         expected=1
7138         cmd="$LFS find -size +5c -type f -lazy $dir"
7139         nums=$($cmd | wc -l)
7140         [ $nums -eq $expected ] ||
7141                 error "'$cmd' wrong: found $nums, expected $expected"
7142         cmd="$LFS find -size +5c -type f $dir"
7143         nums=$($cmd | wc -l)
7144         [ $nums -eq $expected ] ||
7145                 error "'$cmd' wrong: found $nums, expected $expected"
7146
7147         expected=2
7148         cmd="$LFS find -size +0 -type f -lazy $dir"
7149         nums=$($cmd | wc -l)
7150         [ $nums -eq $expected ] ||
7151                 error "'$cmd' wrong: found $nums, expected $expected"
7152         cmd="$LFS find -size +0 -type f $dir"
7153         nums=$($cmd | wc -l)
7154         [ $nums -eq $expected ] ||
7155                 error "'$cmd' wrong: found $nums, expected $expected"
7156
7157         expected=2
7158         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7159         nums=$($cmd | wc -l)
7160         [ $nums -eq $expected ] ||
7161                 error "'$cmd' wrong: found $nums, expected $expected"
7162         cmd="$LFS find ! -size -5c -type f $dir"
7163         nums=$($cmd | wc -l)
7164         [ $nums -eq $expected ] ||
7165                 error "'$cmd' wrong: found $nums, expected $expected"
7166
7167         expected=12
7168         cmd="$LFS find -size -5c -type f -lazy $dir"
7169         nums=$($cmd | wc -l)
7170         [ $nums -eq $expected ] ||
7171                 error "'$cmd' wrong: found $nums, expected $expected"
7172         cmd="$LFS find -size -5c -type f $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] ||
7175                 error "'$cmd' wrong: found $nums, expected $expected"
7176 }
7177 run_test 56r "check lfs find -size works"
7178
7179 test_56ra_sub() {
7180         local expected=$1
7181         local glimpses=$2
7182         local cmd="$3"
7183
7184         cancel_lru_locks $OSC
7185
7186         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7187         local nums=$($cmd | wc -l)
7188
7189         [ $nums -eq $expected ] ||
7190                 error "'$cmd' wrong: found $nums, expected $expected"
7191
7192         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7193
7194         if (( rpcs_before + glimpses != rpcs_after )); then
7195                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7196                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7197
7198                 if [[ $glimpses == 0 ]]; then
7199                         error "'$cmd' should not send glimpse RPCs to OST"
7200                 else
7201                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7202                 fi
7203         fi
7204 }
7205
7206 test_56ra() {
7207         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7208                 skip "MDS < 2.12.58 doesn't return LSOM data"
7209         local dir=$DIR/$tdir
7210         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7211
7212         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7213
7214         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7215         $LCTL set_param -n llite.*.statahead_agl=0
7216         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7217
7218         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7219         # open and close all files to ensure LSOM is updated
7220         cancel_lru_locks $OSC
7221         find $dir -type f | xargs cat > /dev/null
7222
7223         #   expect_found  glimpse_rpcs  command_to_run
7224         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7225         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7226         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7227         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7228
7229         echo "test" > $dir/$tfile
7230         echo "test2" > $dir/$tfile.2 && sync
7231         cancel_lru_locks $OSC
7232         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7233
7234         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7235         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7236         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7237         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7238
7239         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7240         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7241         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7242         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7243         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7244         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7245 }
7246 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7247
7248 test_56rb() {
7249         local dir=$DIR/$tdir
7250         local tmp=$TMP/$tfile.log
7251         local mdt_idx;
7252
7253         test_mkdir -p $dir || error "failed to mkdir $dir"
7254         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7255                 error "failed to setstripe $dir/$tfile"
7256         mdt_idx=$($LFS getdirstripe -i $dir)
7257         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7258
7259         stack_trap "rm -f $tmp" EXIT
7260         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7261         ! grep -q obd_uuid $tmp ||
7262                 error "failed to find --size +100K --ost 0 $dir"
7263         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7264         ! grep -q obd_uuid $tmp ||
7265                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7266 }
7267 run_test 56rb "check lfs find --size --ost/--mdt works"
7268
7269 test_56rc() {
7270         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7271         local dir=$DIR/$tdir
7272         local found
7273
7274         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7275         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7276         (( $MDSCOUNT > 2 )) &&
7277                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7278         mkdir $dir/$tdir-{1..10}
7279         touch $dir/$tfile-{1..10}
7280
7281         found=$($LFS find $dir --mdt-count 2 | wc -l)
7282         expect=11
7283         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7284
7285         found=$($LFS find $dir -T +1 | wc -l)
7286         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7287         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7288
7289         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7290         expect=11
7291         (( $found == $expect )) || error "found $found all_char, expect $expect"
7292
7293         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7294         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7295         (( $found == $expect )) || error "found $found all_char, expect $expect"
7296 }
7297 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7298
7299 test_56rd() {
7300         local dir=$DIR/$tdir
7301
7302         test_mkdir $dir
7303         rm -f $dir/*
7304
7305         mkfifo $dir/fifo || error "failed to create fifo file"
7306         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7307                 error "should not fail even cannot get projid from pipe file"
7308         found=$($LFS find $dir -t p --printf "%y")
7309         [[ "p" == $found ]] || error "found $found, expect p"
7310
7311         mknod $dir/chardev c 1 5 ||
7312                 error "failed to create character device file"
7313         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7314                 error "should not fail even cannot get projid from chardev file"
7315         found=$($LFS find $dir -t c --printf "%y")
7316         [[ "c" == $found ]] || error "found $found, expect c"
7317
7318         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7319         (( found == 2 )) || error "unable to list all files"
7320 }
7321 run_test 56rd "check lfs find --printf special files"
7322
7323 test_56s() { # LU-611 #LU-9369
7324         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7325
7326         local dir=$DIR/$tdir
7327         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7328
7329         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7330         for i in $(seq $NUMDIRS); do
7331                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7332         done
7333
7334         local expected=$NUMDIRS
7335         local cmd="$LFS find -c $OSTCOUNT $dir"
7336         local nums=$($cmd | wc -l)
7337
7338         [ $nums -eq $expected ] || {
7339                 $LFS getstripe -R $dir
7340                 error "'$cmd' wrong: found $nums, expected $expected"
7341         }
7342
7343         expected=$((NUMDIRS + onestripe))
7344         cmd="$LFS find -stripe-count +0 -type f $dir"
7345         nums=$($cmd | wc -l)
7346         [ $nums -eq $expected ] || {
7347                 $LFS getstripe -R $dir
7348                 error "'$cmd' wrong: found $nums, expected $expected"
7349         }
7350
7351         expected=$onestripe
7352         cmd="$LFS find -stripe-count 1 -type f $dir"
7353         nums=$($cmd | wc -l)
7354         [ $nums -eq $expected ] || {
7355                 $LFS getstripe -R $dir
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357         }
7358
7359         cmd="$LFS find -stripe-count -2 -type f $dir"
7360         nums=$($cmd | wc -l)
7361         [ $nums -eq $expected ] || {
7362                 $LFS getstripe -R $dir
7363                 error "'$cmd' wrong: found $nums, expected $expected"
7364         }
7365
7366         expected=0
7367         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7368         nums=$($cmd | wc -l)
7369         [ $nums -eq $expected ] || {
7370                 $LFS getstripe -R $dir
7371                 error "'$cmd' wrong: found $nums, expected $expected"
7372         }
7373 }
7374 run_test 56s "check lfs find -stripe-count works"
7375
7376 test_56t() { # LU-611 #LU-9369
7377         local dir=$DIR/$tdir
7378
7379         setup_56 $dir 0 $NUMDIRS
7380         for i in $(seq $NUMDIRS); do
7381                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7382         done
7383
7384         local expected=$NUMDIRS
7385         local cmd="$LFS find -S 8M $dir"
7386         local nums=$($cmd | wc -l)
7387
7388         [ $nums -eq $expected ] || {
7389                 $LFS getstripe -R $dir
7390                 error "'$cmd' wrong: found $nums, expected $expected"
7391         }
7392         rm -rf $dir
7393
7394         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7395
7396         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7397
7398         expected=$(((NUMDIRS + 1) * NUMFILES))
7399         cmd="$LFS find -stripe-size 512k -type f $dir"
7400         nums=$($cmd | wc -l)
7401         [ $nums -eq $expected ] ||
7402                 error "'$cmd' wrong: found $nums, expected $expected"
7403
7404         cmd="$LFS find -stripe-size +320k -type f $dir"
7405         nums=$($cmd | wc -l)
7406         [ $nums -eq $expected ] ||
7407                 error "'$cmd' wrong: found $nums, expected $expected"
7408
7409         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7410         cmd="$LFS find -stripe-size +200k -type f $dir"
7411         nums=$($cmd | wc -l)
7412         [ $nums -eq $expected ] ||
7413                 error "'$cmd' wrong: found $nums, expected $expected"
7414
7415         cmd="$LFS find -stripe-size -640k -type f $dir"
7416         nums=$($cmd | wc -l)
7417         [ $nums -eq $expected ] ||
7418                 error "'$cmd' wrong: found $nums, expected $expected"
7419
7420         expected=4
7421         cmd="$LFS find -stripe-size 256k -type f $dir"
7422         nums=$($cmd | wc -l)
7423         [ $nums -eq $expected ] ||
7424                 error "'$cmd' wrong: found $nums, expected $expected"
7425
7426         cmd="$LFS find -stripe-size -320k -type f $dir"
7427         nums=$($cmd | wc -l)
7428         [ $nums -eq $expected ] ||
7429                 error "'$cmd' wrong: found $nums, expected $expected"
7430
7431         expected=0
7432         cmd="$LFS find -stripe-size 1024k -type f $dir"
7433         nums=$($cmd | wc -l)
7434         [ $nums -eq $expected ] ||
7435                 error "'$cmd' wrong: found $nums, expected $expected"
7436 }
7437 run_test 56t "check lfs find -stripe-size works"
7438
7439 test_56u() { # LU-611
7440         local dir=$DIR/$tdir
7441
7442         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7443
7444         if [[ $OSTCOUNT -gt 1 ]]; then
7445                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7446                 onestripe=4
7447         else
7448                 onestripe=0
7449         fi
7450
7451         local expected=$(((NUMDIRS + 1) * NUMFILES))
7452         local cmd="$LFS find -stripe-index 0 -type f $dir"
7453         local nums=$($cmd | wc -l)
7454
7455         [ $nums -eq $expected ] ||
7456                 error "'$cmd' wrong: found $nums, expected $expected"
7457
7458         expected=$onestripe
7459         cmd="$LFS find -stripe-index 1 -type f $dir"
7460         nums=$($cmd | wc -l)
7461         [ $nums -eq $expected ] ||
7462                 error "'$cmd' wrong: found $nums, expected $expected"
7463
7464         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7465         nums=$($cmd | wc -l)
7466         [ $nums -eq $expected ] ||
7467                 error "'$cmd' wrong: found $nums, expected $expected"
7468
7469         expected=0
7470         # This should produce an error and not return any files
7471         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7472         nums=$($cmd 2>/dev/null | wc -l)
7473         [ $nums -eq $expected ] ||
7474                 error "'$cmd' wrong: found $nums, expected $expected"
7475
7476         if [[ $OSTCOUNT -gt 1 ]]; then
7477                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7478                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7479                 nums=$($cmd | wc -l)
7480                 [ $nums -eq $expected ] ||
7481                         error "'$cmd' wrong: found $nums, expected $expected"
7482         fi
7483 }
7484 run_test 56u "check lfs find -stripe-index works"
7485
7486 test_56v() {
7487         local mdt_idx=0
7488         local dir=$DIR/$tdir
7489
7490         setup_56 $dir $NUMFILES $NUMDIRS
7491
7492         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7493         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7494
7495         for file in $($LFS find -m $UUID $dir); do
7496                 file_midx=$($LFS getstripe -m $file)
7497                 [ $file_midx -eq $mdt_idx ] ||
7498                         error "lfs find -m $UUID != getstripe -m $file_midx"
7499         done
7500 }
7501 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7502
7503 test_56wa() {
7504         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7506
7507         local dir=$DIR/$tdir
7508
7509         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7510         stack_trap "rm -rf $dir"
7511
7512         local stripe_size=$($LFS getstripe -S -d $dir) ||
7513                 error "$LFS getstripe -S -d $dir failed"
7514         stripe_size=${stripe_size%% *}
7515
7516         local file_size=$((stripe_size * OSTCOUNT))
7517         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7518         local required_space=$((file_num * file_size))
7519         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7520                            head -n1)
7521         (( free_space >= required_space / 1024 )) ||
7522                 skip_env "need $required_space, have $free_space kbytes"
7523
7524         local dd_bs=65536
7525         local dd_count=$((file_size / dd_bs))
7526
7527         # write data into the files
7528         local i
7529         local j
7530         local file
7531
7532         for ((i = 1; i <= NUMFILES; i++ )); do
7533                 file=$dir/file$i
7534                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7535                         error "write data into $file failed"
7536         done
7537         for ((i = 1; i <= NUMDIRS; i++ )); do
7538                 for ((j = 1; j <= NUMFILES; j++ )); do
7539                         file=$dir/dir$i/file$j
7540                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7541                                 error "write data into $file failed"
7542                 done
7543         done
7544
7545         # $LFS_MIGRATE will fail if hard link migration is unsupported
7546         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7547                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7548                         error "creating links to $dir/dir1/file1 failed"
7549         fi
7550
7551         local expected=-1
7552
7553         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7554
7555         # lfs_migrate file
7556         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7557
7558         echo "$cmd"
7559         eval $cmd || error "$cmd failed"
7560
7561         check_stripe_count $dir/file1 $expected
7562
7563         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7564                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7565                 # OST 1 if it is on OST 0. This file is small enough to
7566                 # be on only one stripe.
7567                 file=$dir/migr_1_ost
7568                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7569                         error "write data into $file failed"
7570                 local obdidx=$($LFS getstripe -i $file)
7571                 local oldmd5=$(md5sum $file)
7572                 local newobdidx=0
7573
7574                 (( obdidx != 0 )) || newobdidx=1
7575                 cmd="$LFS migrate -i $newobdidx $file"
7576                 echo $cmd
7577                 eval $cmd || error "$cmd failed"
7578
7579                 local realobdix=$($LFS getstripe -i $file)
7580                 local newmd5=$(md5sum $file)
7581
7582                 (( $newobdidx == $realobdix )) ||
7583                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7584                 [[ "$oldmd5" == "$newmd5" ]] ||
7585                         error "md5sum differ: $oldmd5, $newmd5"
7586         fi
7587
7588         # lfs_migrate dir
7589         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7590         echo "$cmd"
7591         eval $cmd || error "$cmd failed"
7592
7593         for (( j = 1; j <= NUMFILES; j++ )); do
7594                 check_stripe_count $dir/dir1/file$j $expected
7595         done
7596
7597         # lfs_migrate works with lfs find
7598         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7599              $LFS_MIGRATE -y -c $expected"
7600         echo "$cmd"
7601         eval $cmd || error "$cmd failed"
7602
7603         for (( i = 2; i <= NUMFILES; i++ )); do
7604                 check_stripe_count $dir/file$i $expected
7605         done
7606         for (( i = 2; i <= NUMDIRS; i++ )); do
7607                 for (( j = 1; j <= NUMFILES; j++ )); do
7608                         check_stripe_count $dir/dir$i/file$j $expected
7609                 done
7610         done
7611 }
7612 run_test 56wa "check lfs_migrate -c stripe_count works"
7613
7614 test_56wb() {
7615         local file1=$DIR/$tdir/file1
7616         local create_pool=false
7617         local initial_pool=$($LFS getstripe -p $DIR)
7618         local pool_list=()
7619         local pool=""
7620
7621         echo -n "Creating test dir..."
7622         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7623         echo "done."
7624
7625         echo -n "Creating test file..."
7626         touch $file1 || error "cannot create file"
7627         echo "done."
7628
7629         echo -n "Detecting existing pools..."
7630         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7631
7632         if [ ${#pool_list[@]} -gt 0 ]; then
7633                 echo "${pool_list[@]}"
7634                 for thispool in "${pool_list[@]}"; do
7635                         if [[ -z "$initial_pool" ||
7636                               "$initial_pool" != "$thispool" ]]; then
7637                                 pool="$thispool"
7638                                 echo "Using existing pool '$pool'"
7639                                 break
7640                         fi
7641                 done
7642         else
7643                 echo "none detected."
7644         fi
7645         if [ -z "$pool" ]; then
7646                 pool=${POOL:-testpool}
7647                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7648                 echo -n "Creating pool '$pool'..."
7649                 create_pool=true
7650                 pool_add $pool &> /dev/null ||
7651                         error "pool_add failed"
7652                 echo "done."
7653
7654                 echo -n "Adding target to pool..."
7655                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7656                         error "pool_add_targets failed"
7657                 echo "done."
7658         fi
7659
7660         echo -n "Setting pool using -p option..."
7661         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7662                 error "migrate failed rc = $?"
7663         echo "done."
7664
7665         echo -n "Verifying test file is in pool after migrating..."
7666         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7667                 error "file was not migrated to pool $pool"
7668         echo "done."
7669
7670         echo -n "Removing test file from pool '$pool'..."
7671         # "lfs migrate $file" won't remove the file from the pool
7672         # until some striping information is changed.
7673         $LFS migrate -c 1 $file1 &> /dev/null ||
7674                 error "cannot remove from pool"
7675         [ "$($LFS getstripe -p $file1)" ] &&
7676                 error "pool still set"
7677         echo "done."
7678
7679         echo -n "Setting pool using --pool option..."
7680         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7681                 error "migrate failed rc = $?"
7682         echo "done."
7683
7684         # Clean up
7685         rm -f $file1
7686         if $create_pool; then
7687                 destroy_test_pools 2> /dev/null ||
7688                         error "destroy test pools failed"
7689         fi
7690 }
7691 run_test 56wb "check lfs_migrate pool support"
7692
7693 test_56wc() {
7694         local file1="$DIR/$tdir/$tfile"
7695         local md5
7696         local parent_ssize
7697         local parent_scount
7698         local cur_ssize
7699         local cur_scount
7700         local orig_ssize
7701         local new_scount
7702         local cur_comp
7703
7704         echo -n "Creating test dir..."
7705         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7706         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7707                 error "cannot set stripe by '-S 1M -c 1'"
7708         echo "done"
7709
7710         echo -n "Setting initial stripe for test file..."
7711         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7712                 error "cannot set stripe"
7713         cur_ssize=$($LFS getstripe -S "$file1")
7714         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7715         echo "done."
7716
7717         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7718         stack_trap "rm -f $file1"
7719         md5="$(md5sum $file1)"
7720
7721         # File currently set to -S 512K -c 1
7722
7723         # Ensure -c and -S options are rejected when -R is set
7724         echo -n "Verifying incompatible options are detected..."
7725         $LFS_MIGRATE -R -c 1 "$file1" &&
7726                 error "incompatible -R and -c options not detected"
7727         $LFS_MIGRATE -R -S 1M "$file1" &&
7728                 error "incompatible -R and -S options not detected"
7729         $LFS_MIGRATE -R -p pool "$file1" &&
7730                 error "incompatible -R and -p options not detected"
7731         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7732                 error "incompatible -R and -E options not detected"
7733         $LFS_MIGRATE -R -A "$file1" &&
7734                 error "incompatible -R and -A options not detected"
7735         $LFS_MIGRATE -A -c 1 "$file1" &&
7736                 error "incompatible -A and -c options not detected"
7737         $LFS_MIGRATE -A -S 1M "$file1" &&
7738                 error "incompatible -A and -S options not detected"
7739         $LFS_MIGRATE -A -p pool "$file1" &&
7740                 error "incompatible -A and -p options not detected"
7741         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7742                 error "incompatible -A and -E options not detected"
7743         echo "done."
7744
7745         # Ensure unrecognized options are passed through to 'lfs migrate'
7746         echo -n "Verifying -S option is passed through to lfs migrate..."
7747         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7748         cur_ssize=$($LFS getstripe -S "$file1")
7749         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7750         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7751         echo "done."
7752
7753         # File currently set to -S 1M -c 1
7754
7755         # Ensure long options are supported
7756         echo -n "Verifying long options supported..."
7757         $LFS_MIGRATE --non-block "$file1" ||
7758                 error "long option without argument not supported"
7759         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7760                 error "long option with argument not supported"
7761         cur_ssize=$($LFS getstripe -S "$file1")
7762         (( cur_ssize == 524288 )) ||
7763                 error "migrate --stripe-size $cur_ssize != 524288"
7764         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7765         echo "done."
7766
7767         # File currently set to -S 512K -c 1
7768
7769         if (( OSTCOUNT > 1 )); then
7770                 echo -n "Verifying explicit stripe count can be set..."
7771                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7772                 cur_scount=$($LFS getstripe -c "$file1")
7773                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7774                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7775                         error "file data has changed (3)"
7776                 echo "done."
7777         fi
7778
7779         # File currently set to -S 512K -c 1 or -S 512K -c 2
7780
7781         # Ensure parent striping is used if -R is set, and no stripe
7782         # count or size is specified
7783         echo -n "Setting stripe for parent directory..."
7784         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7785                 error "cannot set stripe '-S 2M -c 1'"
7786         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7787         echo "done."
7788
7789         echo -n "Verifying restripe option uses parent stripe settings..."
7790         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7791         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7792         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7793         cur_ssize=$($LFS getstripe -S "$file1")
7794         (( cur_ssize == parent_ssize )) ||
7795                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7796         cur_scount=$($LFS getstripe -c "$file1")
7797         (( cur_scount == parent_scount )) ||
7798                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7799         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7800         echo "done."
7801
7802         # File currently set to -S 1M -c 1
7803
7804         # Ensure striping is preserved if -R is not set, and no stripe
7805         # count or size is specified
7806         echo -n "Verifying striping size preserved when not specified..."
7807         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7808         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7809                 error "cannot set stripe on parent directory"
7810         $LFS_MIGRATE "$file1" || error "migrate failed"
7811         cur_ssize=$($LFS getstripe -S "$file1")
7812         (( cur_ssize == orig_ssize )) ||
7813                 error "migrate by default $cur_ssize != $orig_ssize"
7814         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7815         echo "done."
7816
7817         # Ensure file name properly detected when final option has no argument
7818         echo -n "Verifying file name properly detected..."
7819         $LFS_MIGRATE "$file1" ||
7820                 error "file name interpreted as option argument"
7821         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7822         echo "done."
7823
7824         # Ensure PFL arguments are passed through properly
7825         echo -n "Verifying PFL options passed through..."
7826         new_scount=$(((OSTCOUNT + 1) / 2))
7827         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7828                 error "migrate PFL arguments failed"
7829         cur_comp=$($LFS getstripe --comp-count $file1)
7830         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7831         cur_scount=$($LFS getstripe --stripe-count $file1)
7832         (( cur_scount == new_scount)) ||
7833                 error "PFL stripe count $cur_scount != $new_scount"
7834         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7835         echo "done."
7836 }
7837 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7838
7839 test_56wd() {
7840         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7841
7842         local file1=$DIR/$tdir/$tfile
7843
7844         echo -n "Creating test dir..."
7845         test_mkdir $DIR/$tdir || error "cannot create dir"
7846         echo "done."
7847
7848         echo -n "Creating test file..."
7849         echo "$tfile" > $file1
7850         echo "done."
7851
7852         # Ensure 'lfs migrate' will fail by using a non-existent option,
7853         # and make sure rsync is not called to recover
7854         echo -n "Make sure --no-rsync option works..."
7855         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7856                 grep -q 'refusing to fall back to rsync' ||
7857                 error "rsync was called with --no-rsync set"
7858         echo "done."
7859
7860         # Ensure rsync is called without trying 'lfs migrate' first
7861         echo -n "Make sure --rsync option works..."
7862         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7863                 grep -q 'falling back to rsync' &&
7864                 error "lfs migrate was called with --rsync set"
7865         echo "done."
7866 }
7867 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7868
7869 test_56we() {
7870         local td=$DIR/$tdir
7871         local tf=$td/$tfile
7872
7873         test_mkdir $td || error "cannot create $td"
7874         touch $tf || error "cannot touch $tf"
7875
7876         echo -n "Make sure --non-direct|-D works..."
7877         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7878                 grep -q "lfs migrate --non-direct" ||
7879                 error "--non-direct option cannot work correctly"
7880         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7881                 grep -q "lfs migrate -D" ||
7882                 error "-D option cannot work correctly"
7883         echo "done."
7884 }
7885 run_test 56we "check lfs_migrate --non-direct|-D support"
7886
7887 test_56x() {
7888         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7889         check_swap_layouts_support
7890
7891         local dir=$DIR/$tdir
7892         local ref1=/etc/passwd
7893         local file1=$dir/file1
7894
7895         test_mkdir $dir || error "creating dir $dir"
7896         $LFS setstripe -c 2 $file1
7897         cp $ref1 $file1
7898         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7899         stripe=$($LFS getstripe -c $file1)
7900         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7901         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7902
7903         # clean up
7904         rm -f $file1
7905 }
7906 run_test 56x "lfs migration support"
7907
7908 test_56xa() {
7909         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7910         check_swap_layouts_support
7911
7912         local dir=$DIR/$tdir/$testnum
7913
7914         test_mkdir -p $dir
7915
7916         local ref1=/etc/passwd
7917         local file1=$dir/file1
7918
7919         $LFS setstripe -c 2 $file1
7920         cp $ref1 $file1
7921         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7922
7923         local stripe=$($LFS getstripe -c $file1)
7924
7925         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7926         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7927
7928         # clean up
7929         rm -f $file1
7930 }
7931 run_test 56xa "lfs migration --block support"
7932
7933 check_migrate_links() {
7934         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7935         local dir="$1"
7936         local file1="$dir/file1"
7937         local begin="$2"
7938         local count="$3"
7939         local runas="$4"
7940         local total_count=$(($begin + $count - 1))
7941         local symlink_count=10
7942         local uniq_count=10
7943
7944         if [ ! -f "$file1" ]; then
7945                 echo -n "creating initial file..."
7946                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7947                         error "cannot setstripe initial file"
7948                 echo "done"
7949
7950                 echo -n "creating symlinks..."
7951                 for s in $(seq 1 $symlink_count); do
7952                         ln -s "$file1" "$dir/slink$s" ||
7953                                 error "cannot create symlinks"
7954                 done
7955                 echo "done"
7956
7957                 echo -n "creating nonlinked files..."
7958                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7959                         error "cannot create nonlinked files"
7960                 echo "done"
7961         fi
7962
7963         # create hard links
7964         if [ ! -f "$dir/file$total_count" ]; then
7965                 echo -n "creating hard links $begin:$total_count..."
7966                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7967                         /dev/null || error "cannot create hard links"
7968                 echo "done"
7969         fi
7970
7971         echo -n "checking number of hard links listed in xattrs..."
7972         local fid=$($LFS getstripe -F "$file1")
7973         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7974
7975         echo "${#paths[*]}"
7976         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7977                         skip "hard link list has unexpected size, skipping test"
7978         fi
7979         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7980                         error "link names should exceed xattrs size"
7981         fi
7982
7983         echo -n "migrating files..."
7984         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7985         local rc=$?
7986         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7987         echo "done"
7988
7989         # make sure all links have been properly migrated
7990         echo -n "verifying files..."
7991         fid=$($LFS getstripe -F "$file1") ||
7992                 error "cannot get fid for file $file1"
7993         for i in $(seq 2 $total_count); do
7994                 local fid2=$($LFS getstripe -F $dir/file$i)
7995
7996                 [ "$fid2" == "$fid" ] ||
7997                         error "migrated hard link has mismatched FID"
7998         done
7999
8000         # make sure hard links were properly detected, and migration was
8001         # performed only once for the entire link set; nonlinked files should
8002         # also be migrated
8003         local actual=$(grep -c 'done' <<< "$migrate_out")
8004         local expected=$(($uniq_count + 1))
8005
8006         [ "$actual" -eq  "$expected" ] ||
8007                 error "hard links individually migrated ($actual != $expected)"
8008
8009         # make sure the correct number of hard links are present
8010         local hardlinks=$(stat -c '%h' "$file1")
8011
8012         [ $hardlinks -eq $total_count ] ||
8013                 error "num hard links $hardlinks != $total_count"
8014         echo "done"
8015
8016         return 0
8017 }
8018
8019 test_56xb() {
8020         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8021                 skip "Need MDS version at least 2.10.55"
8022
8023         local dir="$DIR/$tdir"
8024
8025         test_mkdir "$dir" || error "cannot create dir $dir"
8026
8027         echo "testing lfs migrate mode when all links fit within xattrs"
8028         check_migrate_links "$dir" 2 99
8029
8030         echo "testing rsync mode when all links fit within xattrs"
8031         check_migrate_links --rsync "$dir" 2 99
8032
8033         echo "testing lfs migrate mode when all links do not fit within xattrs"
8034         check_migrate_links "$dir" 101 100
8035
8036         echo "testing rsync mode when all links do not fit within xattrs"
8037         check_migrate_links --rsync "$dir" 101 100
8038
8039         chown -R $RUNAS_ID $dir
8040         echo "testing non-root lfs migrate mode when not all links are in xattr"
8041         check_migrate_links "$dir" 101 100 "$RUNAS"
8042
8043         # clean up
8044         rm -rf $dir
8045 }
8046 run_test 56xb "lfs migration hard link support"
8047
8048 test_56xc() {
8049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8050
8051         local dir="$DIR/$tdir"
8052
8053         test_mkdir "$dir" || error "cannot create dir $dir"
8054
8055         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8056         echo -n "Setting initial stripe for 20MB test file..."
8057         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8058                 error "cannot setstripe 20MB file"
8059         echo "done"
8060         echo -n "Sizing 20MB test file..."
8061         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8062         echo "done"
8063         echo -n "Verifying small file autostripe count is 1..."
8064         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8065                 error "cannot migrate 20MB file"
8066         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8067                 error "cannot get stripe for $dir/20mb"
8068         [ $stripe_count -eq 1 ] ||
8069                 error "unexpected stripe count $stripe_count for 20MB file"
8070         rm -f "$dir/20mb"
8071         echo "done"
8072
8073         # Test 2: File is small enough to fit within the available space on
8074         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8075         # have at least an additional 1KB for each desired stripe for test 3
8076         echo -n "Setting stripe for 1GB test file..."
8077         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8078         echo "done"
8079         echo -n "Sizing 1GB test file..."
8080         # File size is 1GB + 3KB
8081         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8082         echo "done"
8083
8084         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8085         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8086         if (( avail > 524288 * OSTCOUNT )); then
8087                 echo -n "Migrating 1GB file..."
8088                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8089                         error "cannot migrate 1GB file"
8090                 echo "done"
8091                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8092                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8093                         error "cannot getstripe for 1GB file"
8094                 [ $stripe_count -eq 2 ] ||
8095                         error "unexpected stripe count $stripe_count != 2"
8096                 echo "done"
8097         fi
8098
8099         # Test 3: File is too large to fit within the available space on
8100         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8101         if [ $OSTCOUNT -ge 3 ]; then
8102                 # The required available space is calculated as
8103                 # file size (1GB + 3KB) / OST count (3).
8104                 local kb_per_ost=349526
8105
8106                 echo -n "Migrating 1GB file with limit..."
8107                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8108                         error "cannot migrate 1GB file with limit"
8109                 echo "done"
8110
8111                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8112                 echo -n "Verifying 1GB autostripe count with limited space..."
8113                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8114                         error "unexpected stripe count $stripe_count (min 3)"
8115                 echo "done"
8116         fi
8117
8118         # clean up
8119         rm -rf $dir
8120 }
8121 run_test 56xc "lfs migration autostripe"
8122
8123 test_56xd() {
8124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8125
8126         local dir=$DIR/$tdir
8127         local f_mgrt=$dir/$tfile.mgrt
8128         local f_yaml=$dir/$tfile.yaml
8129         local f_copy=$dir/$tfile.copy
8130         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8131         local layout_copy="-c 2 -S 2M -i 1"
8132         local yamlfile=$dir/yamlfile
8133         local layout_before;
8134         local layout_after;
8135
8136         test_mkdir "$dir" || error "cannot create dir $dir"
8137         stack_trap "rm -rf $dir"
8138         $LFS setstripe $layout_yaml $f_yaml ||
8139                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8140         $LFS getstripe --yaml $f_yaml > $yamlfile
8141         $LFS setstripe $layout_copy $f_copy ||
8142                 error "cannot setstripe $f_copy with layout $layout_copy"
8143         touch $f_mgrt
8144         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8145
8146         # 1. test option --yaml
8147         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8148                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8149         layout_before=$(get_layout_param $f_yaml)
8150         layout_after=$(get_layout_param $f_mgrt)
8151         [ "$layout_after" == "$layout_before" ] ||
8152                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8153
8154         # 2. test option --copy
8155         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8156                 error "cannot migrate $f_mgrt with --copy $f_copy"
8157         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8158         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8159         [ "$layout_after" == "$layout_before" ] ||
8160                 error "lfs_migrate --copy: $layout_after != $layout_before"
8161 }
8162 run_test 56xd "check lfs_migrate --yaml and --copy support"
8163
8164 test_56xe() {
8165         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8166
8167         local dir=$DIR/$tdir
8168         local f_comp=$dir/$tfile
8169         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8170         local layout_before=""
8171         local layout_after=""
8172
8173         test_mkdir "$dir" || error "cannot create dir $dir"
8174         stack_trap "rm -rf $dir"
8175         $LFS setstripe $layout $f_comp ||
8176                 error "cannot setstripe $f_comp with layout $layout"
8177         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8178         dd if=/dev/zero of=$f_comp bs=1M count=4
8179
8180         # 1. migrate a comp layout file by lfs_migrate
8181         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8182         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8183         [ "$layout_before" == "$layout_after" ] ||
8184                 error "lfs_migrate: $layout_before != $layout_after"
8185
8186         # 2. migrate a comp layout file by lfs migrate
8187         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8188         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8189         [ "$layout_before" == "$layout_after" ] ||
8190                 error "lfs migrate: $layout_before != $layout_after"
8191 }
8192 run_test 56xe "migrate a composite layout file"
8193
8194 test_56xf() {
8195         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8196
8197         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8198                 skip "Need server version at least 2.13.53"
8199
8200         local dir=$DIR/$tdir
8201         local f_comp=$dir/$tfile
8202         local layout="-E 1M -c1 -E -1 -c2"
8203         local fid_before=""
8204         local fid_after=""
8205
8206         test_mkdir "$dir" || error "cannot create dir $dir"
8207         stack_trap "rm -rf $dir"
8208         $LFS setstripe $layout $f_comp ||
8209                 error "cannot setstripe $f_comp with layout $layout"
8210         fid_before=$($LFS getstripe --fid $f_comp)
8211         dd if=/dev/zero of=$f_comp bs=1M count=4
8212
8213         # 1. migrate a comp layout file to a comp layout
8214         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8215         fid_after=$($LFS getstripe --fid $f_comp)
8216         [ "$fid_before" == "$fid_after" ] ||
8217                 error "comp-to-comp migrate: $fid_before != $fid_after"
8218
8219         # 2. migrate a comp layout file to a plain layout
8220         $LFS migrate -c2 $f_comp ||
8221                 error "cannot migrate $f_comp by lfs migrate"
8222         fid_after=$($LFS getstripe --fid $f_comp)
8223         [ "$fid_before" == "$fid_after" ] ||
8224                 error "comp-to-plain migrate: $fid_before != $fid_after"
8225
8226         # 3. migrate a plain layout file to a comp layout
8227         $LFS migrate $layout $f_comp ||
8228                 error "cannot migrate $f_comp by lfs migrate"
8229         fid_after=$($LFS getstripe --fid $f_comp)
8230         [ "$fid_before" == "$fid_after" ] ||
8231                 error "plain-to-comp migrate: $fid_before != $fid_after"
8232 }
8233 run_test 56xf "FID is not lost during migration of a composite layout file"
8234
8235 check_file_ost_range() {
8236         local file="$1"
8237         shift
8238         local range="$*"
8239         local -a file_range
8240         local idx
8241
8242         file_range=($($LFS getstripe -y "$file" |
8243                 awk '/l_ost_idx:/ { print $NF }'))
8244
8245         if [[ "${#file_range[@]}" = 0 ]]; then
8246                 echo "No osts found for $file"
8247                 return 1
8248         fi
8249
8250         for idx in "${file_range[@]}"; do
8251                 [[ " $range " =~ " $idx " ]] ||
8252                         return 1
8253         done
8254
8255         return 0
8256 }
8257
8258 sub_test_56xg() {
8259         local stripe_opt="$1"
8260         local pool="$2"
8261         shift 2
8262         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8263
8264         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8265                 error "Fail to migrate $tfile on $pool"
8266         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8267                 error "$tfile is not in pool $pool"
8268         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8269                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8270 }
8271
8272 test_56xg() {
8273         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8274         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8275         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8276                 skip "Need MDS version newer than 2.14.52"
8277
8278         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8279         local -a pool_ranges=("0 0" "1 1" "0 1")
8280
8281         # init pools
8282         for i in "${!pool_names[@]}"; do
8283                 pool_add ${pool_names[$i]} ||
8284                         error "pool_add failed (pool: ${pool_names[$i]})"
8285                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8286                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8287         done
8288
8289         # init the file to migrate
8290         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8291                 error "Unable to create $tfile on OST1"
8292         stack_trap "rm -f $DIR/$tfile"
8293         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8294                 error "Unable to write on $tfile"
8295
8296         echo "1. migrate $tfile on pool ${pool_names[0]}"
8297         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8298
8299         echo "2. migrate $tfile on pool ${pool_names[2]}"
8300         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8301
8302         echo "3. migrate $tfile on pool ${pool_names[1]}"
8303         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8304
8305         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8306         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8307         echo
8308
8309         # Clean pools
8310         destroy_test_pools ||
8311                 error "pool_destroy failed"
8312 }
8313 run_test 56xg "lfs migrate pool support"
8314
8315 test_56xh() {
8316         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8317
8318         local size_mb=25
8319         local file1=$DIR/$tfile
8320         local tmp1=$TMP/$tfile.tmp
8321
8322         $LFS setstripe -c 2 $file1
8323
8324         stack_trap "rm -f $file1 $tmp1"
8325         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8326                         error "error creating $tmp1"
8327         ls -lsh $tmp1
8328         cp $tmp1 $file1
8329
8330         local start=$SECONDS
8331
8332         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8333                 error "migrate failed rc = $?"
8334
8335         local elapsed=$((SECONDS - start))
8336
8337         # with 1MB/s, elapsed should equal size_mb
8338         (( elapsed >= size_mb * 95 / 100 )) ||
8339                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8340
8341         (( elapsed <= size_mb * 120 / 100 )) ||
8342                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8343
8344         (( elapsed <= size_mb * 350 / 100 )) ||
8345                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8346
8347         stripe=$($LFS getstripe -c $file1)
8348         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8349         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8350
8351         # Clean up file (since it is multiple MB)
8352         rm -f $file1 $tmp1
8353 }
8354 run_test 56xh "lfs migrate bandwidth limitation support"
8355
8356 test_56xi() {
8357         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8358         verify_yaml_available || skip_env "YAML verification not installed"
8359
8360         local size_mb=5
8361         local file1=$DIR/$tfile.1
8362         local file2=$DIR/$tfile.2
8363         local file3=$DIR/$tfile.3
8364         local output_file=$DIR/$tfile.out
8365         local tmp1=$TMP/$tfile.tmp
8366
8367         $LFS setstripe -c 2 $file1
8368         $LFS setstripe -c 2 $file2
8369         $LFS setstripe -c 2 $file3
8370
8371         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8372         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8373                         error "error creating $tmp1"
8374         ls -lsh $tmp1
8375         cp $tmp1 $file1
8376         cp $tmp1 $file2
8377         cp $tmp1 $file3
8378
8379         $LFS migrate --stats --stats-interval=1 \
8380                 -c 1 $file1 $file2 $file3 1> $output_file ||
8381                 error "migrate failed rc = $?"
8382
8383         cat $output_file
8384         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8385
8386         # Clean up file (since it is multiple MB)
8387         rm -f $file1 $file2 $file3 $tmp1 $output_file
8388 }
8389 run_test 56xi "lfs migrate stats support"
8390
8391 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8392         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8393
8394         local file=$DIR/$tfile
8395         local linkdir=$DIR/$tdir
8396
8397         test_mkdir $linkdir || error "fail to create $linkdir"
8398         $LFS setstripe -i 0 -c 1 -S1M $file
8399         stack_trap "rm -rf $file $linkdir"
8400         dd if=/dev/urandom of=$file bs=1M count=10 ||
8401                 error "fail to create $file"
8402
8403         # Create file links
8404         local cpts
8405         local threads_max
8406         local nlinks
8407
8408         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8409         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8410         (( nlinks = thread_max * 3 / 2 / cpts))
8411
8412         echo "create $nlinks hard links of $file"
8413         createmany -l $file $linkdir/link $nlinks
8414
8415         # Parallel migrates (should not block)
8416         local i
8417         for ((i = 0; i < nlinks; i++)); do
8418                 echo $linkdir/link$i
8419         done | xargs -n1 -P $nlinks $LFS migrate -c2
8420
8421         local stripe_count
8422         stripe_count=$($LFS getstripe -c $file) ||
8423                 error "fail to get stripe count on $file"
8424
8425         ((stripe_count == 2)) ||
8426                 error "fail to migrate $file (stripe_count = $stripe_count)"
8427 }
8428 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8429
8430 test_56xk() {
8431         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8432
8433         local size_mb=5
8434         local file1=$DIR/$tfile
8435
8436         stack_trap "rm -f $file1"
8437         $LFS setstripe -c 1 $file1
8438         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8439                 error "error creating $file1"
8440         $LFS mirror extend -N $file1 || error "can't mirror"
8441         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8442                 error "can't dd"
8443         $LFS getstripe $file1 | grep stale ||
8444                 error "one component must be stale"
8445
8446         local start=$SECONDS
8447         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8448                 error "migrate failed rc = $?"
8449         local elapsed=$((SECONDS - start))
8450         $LFS getstripe $file1 | grep stale &&
8451                 error "all components must be sync"
8452
8453         # with 1MB/s, elapsed should equal size_mb
8454         (( elapsed >= size_mb * 95 / 100 )) ||
8455                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8456
8457         (( elapsed <= size_mb * 120 / 100 )) ||
8458                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8459
8460         (( elapsed <= size_mb * 350 / 100 )) ||
8461                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8462 }
8463 run_test 56xk "lfs mirror resync bandwidth limitation support"
8464
8465 test_56xl() {
8466         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8467         verify_yaml_available || skip_env "YAML verification not installed"
8468
8469         local size_mb=5
8470         local file1=$DIR/$tfile.1
8471         local output_file=$DIR/$tfile.out
8472
8473         stack_trap "rm -f $file1"
8474         $LFS setstripe -c 1 $file1
8475         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8476                 error "error creating $file1"
8477         $LFS mirror extend -N $file1 || error "can't mirror"
8478         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8479                 error "can't dd"
8480         $LFS getstripe $file1 | grep stale ||
8481                 error "one component must be stale"
8482         $LFS getstripe $file1
8483
8484         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8485                 error "resync failed rc = $?"
8486         $LFS getstripe $file1 | grep stale &&
8487                 error "all components must be sync"
8488
8489         cat $output_file
8490         cat $output_file | verify_yaml || error "stats is not valid YAML"
8491 }
8492 run_test 56xl "lfs mirror resync stats support"
8493
8494 test_56y() {
8495         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8496                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8497
8498         local res=""
8499         local dir=$DIR/$tdir
8500         local f1=$dir/file1
8501         local f2=$dir/file2
8502
8503         test_mkdir -p $dir || error "creating dir $dir"
8504         touch $f1 || error "creating std file $f1"
8505         $MULTIOP $f2 H2c || error "creating released file $f2"
8506
8507         # a directory can be raid0, so ask only for files
8508         res=$($LFS find $dir -L raid0 -type f | wc -l)
8509         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8510
8511         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8512         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8513
8514         # only files can be released, so no need to force file search
8515         res=$($LFS find $dir -L released)
8516         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8517
8518         res=$($LFS find $dir -type f \! -L released)
8519         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8520 }
8521 run_test 56y "lfs find -L raid0|released"
8522
8523 test_56z() { # LU-4824
8524         # This checks to make sure 'lfs find' continues after errors
8525         # There are two classes of errors that should be caught:
8526         # - If multiple paths are provided, all should be searched even if one
8527         #   errors out
8528         # - If errors are encountered during the search, it should not terminate
8529         #   early
8530         local dir=$DIR/$tdir
8531         local i
8532
8533         test_mkdir $dir
8534         for i in d{0..9}; do
8535                 test_mkdir $dir/$i
8536                 touch $dir/$i/$tfile
8537         done
8538         $LFS find $DIR/non_existent_dir $dir &&
8539                 error "$LFS find did not return an error"
8540         # Make a directory unsearchable. This should NOT be the last entry in
8541         # directory order.  Arbitrarily pick the 6th entry
8542         chmod 700 $($LFS find $dir -type d | sed '6!d')
8543
8544         $RUNAS $LFS find $DIR/non_existent $dir
8545         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8546
8547         # The user should be able to see 10 directories and 9 files
8548         (( count == 19 )) ||
8549                 error "$LFS find found $count != 19 entries after error"
8550 }
8551 run_test 56z "lfs find should continue after an error"
8552
8553 test_56aa() { # LU-5937
8554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8555
8556         local dir=$DIR/$tdir
8557
8558         mkdir $dir
8559         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8560
8561         createmany -o $dir/striped_dir/${tfile}- 1024
8562         local dirs=$($LFS find --size +8k $dir/)
8563
8564         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8565 }
8566 run_test 56aa "lfs find --size under striped dir"
8567
8568 test_56ab() { # LU-10705
8569         test_mkdir $DIR/$tdir
8570         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8571         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8572         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8573         # Flush writes to ensure valid blocks.  Need to be more thorough for
8574         # ZFS, since blocks are not allocated/returned to client immediately.
8575         sync_all_data
8576         wait_zfs_commit ost1 2
8577         cancel_lru_locks osc
8578         ls -ls $DIR/$tdir
8579
8580         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8581
8582         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8583
8584         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8585         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8586
8587         rm -f $DIR/$tdir/$tfile.[123]
8588 }
8589 run_test 56ab "lfs find --blocks"
8590
8591 # LU-11188
8592 test_56aca() {
8593         local dir="$DIR/$tdir"
8594         local perms=(001 002 003 004 005 006 007
8595                      010 020 030 040 050 060 070
8596                      100 200 300 400 500 600 700
8597                      111 222 333 444 555 666 777)
8598         local perm_minus=(8 8 4 8 4 4 2
8599                           8 8 4 8 4 4 2
8600                           8 8 4 8 4 4 2
8601                           4 4 2 4 2 2 1)
8602         local perm_slash=(8  8 12  8 12 12 14
8603                           8  8 12  8 12 12 14
8604                           8  8 12  8 12 12 14
8605                          16 16 24 16 24 24 28)
8606
8607         test_mkdir "$dir"
8608         for perm in ${perms[*]}; do
8609                 touch "$dir/$tfile.$perm"
8610                 chmod $perm "$dir/$tfile.$perm"
8611         done
8612
8613         for ((i = 0; i < ${#perms[*]}; i++)); do
8614                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8615                 (( $num == 1 )) ||
8616                         error "lfs find -perm ${perms[i]}:"\
8617                               "$num != 1"
8618
8619                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8620                 (( $num == ${perm_minus[i]} )) ||
8621                         error "lfs find -perm -${perms[i]}:"\
8622                               "$num != ${perm_minus[i]}"
8623
8624                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8625                 (( $num == ${perm_slash[i]} )) ||
8626                         error "lfs find -perm /${perms[i]}:"\
8627                               "$num != ${perm_slash[i]}"
8628         done
8629 }
8630 run_test 56aca "check lfs find -perm with octal representation"
8631
8632 test_56acb() {
8633         local dir=$DIR/$tdir
8634         # p is the permission of write and execute for user, group and other
8635         # without the umask. It is used to test +wx.
8636         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8637         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8638         local symbolic=(+t  a+t u+t g+t o+t
8639                         g+s u+s o+s +s o+sr
8640                         o=r,ug+o,u+w
8641                         u+ g+ o+ a+ ugo+
8642                         u- g- o- a- ugo-
8643                         u= g= o= a= ugo=
8644                         o=r,ug+o,u+w u=r,a+u,u+w
8645                         g=r,ugo=g,u+w u+x,+X +X
8646                         u+x,u+X u+X u+x,g+X o+r,+X
8647                         u+x,go+X +wx +rwx)
8648
8649         test_mkdir $dir
8650         for perm in ${perms[*]}; do
8651                 touch "$dir/$tfile.$perm"
8652                 chmod $perm "$dir/$tfile.$perm"
8653         done
8654
8655         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8656                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8657
8658                 (( $num == 1 )) ||
8659                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8660         done
8661 }
8662 run_test 56acb "check lfs find -perm with symbolic representation"
8663
8664 test_56acc() {
8665         local dir=$DIR/$tdir
8666         local tests="17777 787 789 abcd
8667                 ug=uu ug=a ug=gu uo=ou urw
8668                 u+xg+x a=r,u+x,"
8669
8670         test_mkdir $dir
8671         for err in $tests; do
8672                 if $LFS find $dir -perm $err 2>/dev/null; then
8673                         error "lfs find -perm $err: parsing should have failed"
8674                 fi
8675         done
8676 }
8677 run_test 56acc "check parsing error for lfs find -perm"
8678
8679 test_56ba() {
8680         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8681                 skip "Need MDS version at least 2.10.50"
8682
8683         # Create composite files with one component
8684         local dir=$DIR/$tdir
8685
8686         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8687         # Create composite files with three components
8688         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8689         # LU-16904 Create plain layout files
8690         lfs setstripe -c 1 $dir/$tfile-{1..10}
8691
8692         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8693
8694         [[ $nfiles == 10 ]] ||
8695                 error "lfs find -E 1M found $nfiles != 10 files"
8696
8697         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8698         [[ $nfiles == 25 ]] ||
8699                 error "lfs find ! -E 1M found $nfiles != 25 files"
8700
8701         # All files have a component that starts at 0
8702         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8703         [[ $nfiles == 35 ]] ||
8704                 error "lfs find --component-start 0 - $nfiles != 35 files"
8705
8706         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8707         [[ $nfiles == 15 ]] ||
8708                 error "lfs find --component-start 2M - $nfiles != 15 files"
8709
8710         # All files created here have a componenet that does not starts at 2M
8711         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8712         [[ $nfiles == 35 ]] ||
8713                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8714
8715         # Find files with a specified number of components
8716         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8717         [[ $nfiles == 15 ]] ||
8718                 error "lfs find --component-count 3 - $nfiles != 15 files"
8719
8720         # Remember non-composite files have a component count of zero
8721         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8722         [[ $nfiles == 10 ]] ||
8723                 error "lfs find --component-count 0 - $nfiles != 10 files"
8724
8725         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8726         [[ $nfiles == 20 ]] ||
8727                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8728
8729         # All files have a flag called "init"
8730         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8731         [[ $nfiles == 35 ]] ||
8732                 error "lfs find --component-flags init - $nfiles != 35 files"
8733
8734         # Multi-component files will have a component not initialized
8735         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8736         [[ $nfiles == 15 ]] ||
8737                 error "lfs find !--component-flags init - $nfiles != 15 files"
8738
8739         rm -rf $dir
8740
8741 }
8742 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8743
8744 test_56ca() {
8745         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8746                 skip "Need MDS version at least 2.10.57"
8747
8748         local td=$DIR/$tdir
8749         local tf=$td/$tfile
8750         local dir
8751         local nfiles
8752         local cmd
8753         local i
8754         local j
8755
8756         # create mirrored directories and mirrored files
8757         mkdir $td || error "mkdir $td failed"
8758         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8759         createmany -o $tf- 10 || error "create $tf- failed"
8760
8761         for i in $(seq 2); do
8762                 dir=$td/dir$i
8763                 mkdir $dir || error "mkdir $dir failed"
8764                 $LFS mirror create -N$((3 + i)) $dir ||
8765                         error "create mirrored dir $dir failed"
8766                 createmany -o $dir/$tfile- 10 ||
8767                         error "create $dir/$tfile- failed"
8768         done
8769
8770         # change the states of some mirrored files
8771         echo foo > $tf-6
8772         for i in $(seq 2); do
8773                 dir=$td/dir$i
8774                 for j in $(seq 4 9); do
8775                         echo foo > $dir/$tfile-$j
8776                 done
8777         done
8778
8779         # find mirrored files with specific mirror count
8780         cmd="$LFS find --mirror-count 3 --type f $td"
8781         nfiles=$($cmd | wc -l)
8782         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8783
8784         cmd="$LFS find ! --mirror-count 3 --type f $td"
8785         nfiles=$($cmd | wc -l)
8786         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8787
8788         cmd="$LFS find --mirror-count +2 --type f $td"
8789         nfiles=$($cmd | wc -l)
8790         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8791
8792         cmd="$LFS find --mirror-count -6 --type f $td"
8793         nfiles=$($cmd | wc -l)
8794         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8795
8796         # find mirrored files with specific file state
8797         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8798         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8799
8800         cmd="$LFS find --mirror-state=ro --type f $td"
8801         nfiles=$($cmd | wc -l)
8802         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8803
8804         cmd="$LFS find ! --mirror-state=ro --type f $td"
8805         nfiles=$($cmd | wc -l)
8806         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8807
8808         cmd="$LFS find --mirror-state=wp --type f $td"
8809         nfiles=$($cmd | wc -l)
8810         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8811
8812         cmd="$LFS find ! --mirror-state=sp --type f $td"
8813         nfiles=$($cmd | wc -l)
8814         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8815 }
8816 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8817
8818 test_56da() { # LU-14179
8819         local path=$DIR/$tdir
8820
8821         test_mkdir $path
8822         cd $path
8823
8824         local longdir=$(str_repeat 'a' 255)
8825
8826         for i in {1..15}; do
8827                 path=$path/$longdir
8828                 test_mkdir $longdir
8829                 cd $longdir
8830         done
8831
8832         local len=${#path}
8833         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8834
8835         test_mkdir $lastdir
8836         cd $lastdir
8837         # PATH_MAX-1
8838         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8839
8840         # NAME_MAX
8841         touch $(str_repeat 'f' 255)
8842
8843         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8844                 error "lfs find reported an error"
8845
8846         rm -rf $DIR/$tdir
8847 }
8848 run_test 56da "test lfs find with long paths"
8849
8850 test_56ea() { #LU-10378
8851         local path=$DIR/$tdir
8852         local pool=$TESTNAME
8853
8854         # Create ost pool
8855         pool_add $pool || error "pool_add $pool failed"
8856         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8857                 error "adding targets to $pool failed"
8858
8859         # Set default pool on directory before creating file
8860         mkdir $path || error "mkdir $path failed"
8861         $LFS setstripe -p $pool $path ||
8862                 error "set OST pool on $pool failed"
8863         touch $path/$tfile || error "touch $path/$tfile failed"
8864
8865         # Compare basic file attributes from -printf and stat
8866         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8867         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8868
8869         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8870                 error "Attrs from lfs find and stat don't match"
8871
8872         # Compare Lustre attributes from lfs find and lfs getstripe
8873         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8874         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8875         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8876         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8877         local fpool=$($LFS getstripe --pool $path/$tfile)
8878         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8879
8880         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8881                 error "Attrs from lfs find and lfs getstripe don't match"
8882
8883         # Verify behavior for unknown escape/format sequences
8884         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8885
8886         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8887                 error "Escape/format codes don't match"
8888 }
8889 run_test 56ea "test lfs find -printf option"
8890
8891 test_56eb() {
8892         local dir=$DIR/$tdir
8893         local subdir_1=$dir/subdir_1
8894
8895         test_mkdir -p $subdir_1
8896         ln -s subdir_1 $dir/link_1
8897
8898         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8899                 error "symlink is not followed"
8900
8901         $LFS getstripe --no-follow $dir |
8902                 grep "^$dir/link_1 has no stripe info$" ||
8903                 error "symlink should not have stripe info"
8904
8905         touch $dir/testfile
8906         ln -s testfile $dir/file_link_2
8907
8908         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8909                 error "symlink is not followed"
8910
8911         $LFS getstripe --no-follow $dir |
8912                 grep "^$dir/file_link_2 has no stripe info$" ||
8913                 error "symlink should not have stripe info"
8914 }
8915 run_test 56eb "check lfs getstripe on symlink"
8916
8917 test_56ec() {
8918         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8919         local dir=$DIR/$tdir
8920         local srcfile=$dir/srcfile
8921         local srcyaml=$dir/srcyaml
8922         local destfile=$dir/destfile
8923
8924         test_mkdir -p $dir
8925
8926         $LFS setstripe -i 1 $srcfile
8927         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8928         # if the setstripe yaml parsing fails for any reason, the command can
8929         # randomly assign the correct OST index, leading to an erroneous
8930         # success. but the chance of false success is low enough that a
8931         # regression should still be quickly caught.
8932         $LFS setstripe --yaml=$srcyaml $destfile
8933
8934         local srcindex=$($LFS getstripe -i $srcfile)
8935         local destindex=$($LFS getstripe -i $destfile)
8936
8937         if [[ ! $srcindex -eq $destindex ]]; then
8938                 error "setstripe did not set OST index correctly"
8939         fi
8940 }
8941 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8942
8943 test_56eda() {
8944         local dir=$DIR/$tdir
8945         local subdir=$dir/subdir
8946         local file1=$dir/$tfile
8947         local file2=$dir/$tfile\2
8948         local link=$dir/$tfile-link
8949         local nfiles
8950
8951         test_mkdir -p $dir
8952         $LFS setdirstripe -c1 $subdir
8953         touch $file1
8954         touch $file2
8955         ln $file2 $link
8956
8957         nfiles=$($LFS find --links 1 $dir | wc -l)
8958         (( $nfiles == 1 )) ||
8959                 error "lfs find --links expected 1 file, got $nfiles"
8960
8961         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8962         (( $nfiles == 2 )) ||
8963                 error "lfs find --links expected 2 files, got $nfiles"
8964
8965         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8966         (( $nfiles == 1 )) ||
8967                 error "lfs find --links expected 1 directory, got $nfiles"
8968 }
8969 run_test 56eda "check lfs find --links"
8970
8971 test_56edb() {
8972         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8973
8974         local dir=$DIR/$tdir
8975         local stripedir=$dir/stripedir
8976         local nfiles
8977
8978         test_mkdir -p $dir
8979
8980         $LFS setdirstripe -c2 $stripedir
8981
8982         $LFS getdirstripe $stripedir
8983
8984         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8985         (( $nfiles == 1 )) ||
8986                 error "lfs find --links expected 1 directory, got $nfiles"
8987 }
8988 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8989
8990 test_56ef() {
8991         local dir=$DIR/$tdir
8992         local dir1=$dir/d1
8993         local dir2=$dir/d2
8994         local nfiles
8995         local err_msg
8996
8997         test_mkdir -p $dir
8998
8999         mkdir $dir1
9000         mkdir $dir2
9001
9002         touch $dir1/f
9003         touch $dir2/f
9004
9005         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9006         (( $nfiles == 2 )) ||
9007                 error "(1) lfs find expected 2 files, got $nfiles"
9008
9009         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9010         (( $nfiles == 2 )) ||
9011                 error "(2) lfs find expected 2 files, got $nfiles"
9012
9013         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9014         (( $nfiles == 2 )) ||
9015                 error "(3) lfs find expected 2 files, got $nfiles"
9016
9017         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9018         [[ $err_msg =~ "No such file or directory" ]] ||
9019                 error "expected standard error message, got: '$err_msg'"
9020 }
9021 run_test 56ef "lfs find with multiple paths"
9022
9023 test_57a() {
9024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9025         # note test will not do anything if MDS is not local
9026         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9027                 skip_env "ldiskfs only test"
9028         fi
9029         remote_mds_nodsh && skip "remote MDS with nodsh"
9030
9031         local MNTDEV="osd*.*MDT*.mntdev"
9032         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9033         [ -z "$DEV" ] && error "can't access $MNTDEV"
9034         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9035                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9036                         error "can't access $DEV"
9037                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9038                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9039                 rm $TMP/t57a.dump
9040         done
9041 }
9042 run_test 57a "verify MDS filesystem created with large inodes =="
9043
9044 test_57b() {
9045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9046         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9047                 skip_env "ldiskfs only test"
9048         fi
9049         remote_mds_nodsh && skip "remote MDS with nodsh"
9050
9051         local dir=$DIR/$tdir
9052         local filecount=100
9053         local file1=$dir/f1
9054         local fileN=$dir/f$filecount
9055
9056         rm -rf $dir || error "removing $dir"
9057         test_mkdir -c1 $dir
9058         local mdtidx=$($LFS getstripe -m $dir)
9059         local mdtname=MDT$(printf %04x $mdtidx)
9060         local facet=mds$((mdtidx + 1))
9061
9062         echo "mcreating $filecount files"
9063         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9064
9065         # verify that files do not have EAs yet
9066         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9067                 error "$file1 has an EA"
9068         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9069                 error "$fileN has an EA"
9070
9071         sync
9072         sleep 1
9073         df $dir  #make sure we get new statfs data
9074         local mdsfree=$(do_facet $facet \
9075                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9076         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9077         local file
9078
9079         echo "opening files to create objects/EAs"
9080         for file in $(seq -f $dir/f%g 1 $filecount); do
9081                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9082                         error "opening $file"
9083         done
9084
9085         # verify that files have EAs now
9086         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9087                 error "$file1 missing EA"
9088         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9089                 error "$fileN missing EA"
9090
9091         sleep 1  #make sure we get new statfs data
9092         df $dir
9093         local mdsfree2=$(do_facet $facet \
9094                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9095         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9096
9097         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9098                 if [ "$mdsfree" != "$mdsfree2" ]; then
9099                         error "MDC before $mdcfree != after $mdcfree2"
9100                 else
9101                         echo "MDC before $mdcfree != after $mdcfree2"
9102                         echo "unable to confirm if MDS has large inodes"
9103                 fi
9104         fi
9105         rm -rf $dir
9106 }
9107 run_test 57b "default LOV EAs are stored inside large inodes ==="
9108
9109 test_58() {
9110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9111         [ -z "$(which wiretest 2>/dev/null)" ] &&
9112                         skip_env "could not find wiretest"
9113
9114         wiretest
9115 }
9116 run_test 58 "verify cross-platform wire constants =============="
9117
9118 test_59() {
9119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9120
9121         echo "touch 130 files"
9122         createmany -o $DIR/f59- 130
9123         echo "rm 130 files"
9124         unlinkmany $DIR/f59- 130
9125         sync
9126         # wait for commitment of removal
9127         wait_delete_completed
9128 }
9129 run_test 59 "verify cancellation of llog records async ========="
9130
9131 TEST60_HEAD="test_60 run $RANDOM"
9132 test_60a() {
9133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9134         remote_mgs_nodsh && skip "remote MGS with nodsh"
9135         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9136                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9137                         skip_env "missing subtest run-llog.sh"
9138
9139         log "$TEST60_HEAD - from kernel mode"
9140         do_facet mgs "$LCTL dk > /dev/null"
9141         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9142         do_facet mgs $LCTL dk > $TMP/$tfile
9143
9144         # LU-6388: test llog_reader
9145         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9146         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9147         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9148                         skip_env "missing llog_reader"
9149         local fstype=$(facet_fstype mgs)
9150         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9151                 skip_env "Only for ldiskfs or zfs type mgs"
9152
9153         local mntpt=$(facet_mntpt mgs)
9154         local mgsdev=$(mgsdevname 1)
9155         local fid_list
9156         local fid
9157         local rec_list
9158         local rec
9159         local rec_type
9160         local obj_file
9161         local path
9162         local seq
9163         local oid
9164         local pass=true
9165
9166         #get fid and record list
9167         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9168                 tail -n 4))
9169         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9170                 tail -n 4))
9171         #remount mgs as ldiskfs or zfs type
9172         stop mgs || error "stop mgs failed"
9173         mount_fstype mgs || error "remount mgs failed"
9174         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9175                 fid=${fid_list[i]}
9176                 rec=${rec_list[i]}
9177                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9178                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9179                 oid=$((16#$oid))
9180
9181                 case $fstype in
9182                         ldiskfs )
9183                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9184                         zfs )
9185                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9186                 esac
9187                 echo "obj_file is $obj_file"
9188                 do_facet mgs $llog_reader $obj_file
9189
9190                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9191                         awk '{ print $3 }' | sed -e "s/^type=//g")
9192                 if [ $rec_type != $rec ]; then
9193                         echo "FAILED test_60a wrong record type $rec_type," \
9194                               "should be $rec"
9195                         pass=false
9196                         break
9197                 fi
9198
9199                 #check obj path if record type is LLOG_LOGID_MAGIC
9200                 if [ "$rec" == "1064553b" ]; then
9201                         path=$(do_facet mgs $llog_reader $obj_file |
9202                                 grep "path=" | awk '{ print $NF }' |
9203                                 sed -e "s/^path=//g")
9204                         if [ $obj_file != $mntpt/$path ]; then
9205                                 echo "FAILED test_60a wrong obj path" \
9206                                       "$montpt/$path, should be $obj_file"
9207                                 pass=false
9208                                 break
9209                         fi
9210                 fi
9211         done
9212         rm -f $TMP/$tfile
9213         #restart mgs before "error", otherwise it will block the next test
9214         stop mgs || error "stop mgs failed"
9215         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9216         $pass || error "test failed, see FAILED test_60a messages for specifics"
9217 }
9218 run_test 60a "llog_test run from kernel module and test llog_reader"
9219
9220 test_60b() { # bug 6411
9221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9222
9223         dmesg > $DIR/$tfile
9224         LLOG_COUNT=$(do_facet mgs dmesg |
9225                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9226                           /llog_[a-z]*.c:[0-9]/ {
9227                                 if (marker)
9228                                         from_marker++
9229                                 from_begin++
9230                           }
9231                           END {
9232                                 if (marker)
9233                                         print from_marker
9234                                 else
9235                                         print from_begin
9236                           }")
9237
9238         [[ $LLOG_COUNT -gt 120 ]] &&
9239                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9240 }
9241 run_test 60b "limit repeated messages from CERROR/CWARN"
9242
9243 test_60c() {
9244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9245
9246         echo "create 5000 files"
9247         createmany -o $DIR/f60c- 5000
9248 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9249         lctl set_param fail_loc=0x80000137
9250         unlinkmany $DIR/f60c- 5000
9251         lctl set_param fail_loc=0
9252 }
9253 run_test 60c "unlink file when mds full"
9254
9255 test_60d() {
9256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9257
9258         SAVEPRINTK=$(lctl get_param -n printk)
9259         # verify "lctl mark" is even working"
9260         MESSAGE="test message ID $RANDOM $$"
9261         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9262         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9263
9264         lctl set_param printk=0 || error "set lnet.printk failed"
9265         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9266         MESSAGE="new test message ID $RANDOM $$"
9267         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9268         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9269         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9270
9271         lctl set_param -n printk="$SAVEPRINTK"
9272 }
9273 run_test 60d "test printk console message masking"
9274
9275 test_60e() {
9276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9277         remote_mds_nodsh && skip "remote MDS with nodsh"
9278
9279         touch $DIR/$tfile
9280 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9281         do_facet mds1 lctl set_param fail_loc=0x15b
9282         rm $DIR/$tfile
9283 }
9284 run_test 60e "no space while new llog is being created"
9285
9286 test_60f() {
9287         local old_path=$($LCTL get_param -n debug_path)
9288
9289         stack_trap "$LCTL set_param debug_path=$old_path"
9290         stack_trap "rm -f $TMP/$tfile*"
9291         rm -f $TMP/$tfile* 2> /dev/null
9292         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9293         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9294         test_mkdir $DIR/$tdir
9295         # retry in case the open is cached and not released
9296         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9297                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9298                 sleep 0.1
9299         done
9300         ls $TMP/$tfile*
9301         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9302 }
9303 run_test 60f "change debug_path works"
9304
9305 test_60g() {
9306         local pid
9307         local i
9308
9309         test_mkdir -c $MDSCOUNT $DIR/$tdir
9310
9311         (
9312                 local index=0
9313                 while true; do
9314                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9315                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9316                                 2>/dev/null
9317                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9318                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9319                         index=$((index + 1))
9320                 done
9321         ) &
9322
9323         pid=$!
9324
9325         for i in {0..100}; do
9326                 # define OBD_FAIL_OSD_TXN_START    0x19a
9327                 local index=$((i % MDSCOUNT + 1))
9328
9329                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9330                         > /dev/null
9331                 sleep 0.01
9332         done
9333
9334         kill -9 $pid
9335
9336         for i in $(seq $MDSCOUNT); do
9337                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9338         done
9339
9340         mkdir $DIR/$tdir/new || error "mkdir failed"
9341         rmdir $DIR/$tdir/new || error "rmdir failed"
9342
9343         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9344                 -t namespace
9345         for i in $(seq $MDSCOUNT); do
9346                 wait_update_facet mds$i "$LCTL get_param -n \
9347                         mdd.$(facet_svc mds$i).lfsck_namespace |
9348                         awk '/^status/ { print \\\$2 }'" "completed"
9349         done
9350
9351         ls -R $DIR/$tdir
9352         rm -rf $DIR/$tdir || error "rmdir failed"
9353 }
9354 run_test 60g "transaction abort won't cause MDT hung"
9355
9356 test_60h() {
9357         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9358                 skip "Need MDS version at least 2.12.52"
9359         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9360
9361         local f
9362
9363         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9364         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9365         for fail_loc in 0x80000188 0x80000189; do
9366                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9367                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9368                         error "mkdir $dir-$fail_loc failed"
9369                 for i in {0..10}; do
9370                         # create may fail on missing stripe
9371                         echo $i > $DIR/$tdir-$fail_loc/$i
9372                 done
9373                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9374                         error "getdirstripe $tdir-$fail_loc failed"
9375                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9376                         error "migrate $tdir-$fail_loc failed"
9377                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9378                         error "getdirstripe $tdir-$fail_loc failed"
9379                 pushd $DIR/$tdir-$fail_loc
9380                 for f in *; do
9381                         echo $f | cmp $f - || error "$f data mismatch"
9382                 done
9383                 popd
9384                 rm -rf $DIR/$tdir-$fail_loc
9385         done
9386 }
9387 run_test 60h "striped directory with missing stripes can be accessed"
9388
9389 function t60i_load() {
9390         mkdir $DIR/$tdir
9391         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9392         $LCTL set_param fail_loc=0x131c fail_val=1
9393         for ((i=0; i<5000; i++)); do
9394                 touch $DIR/$tdir/f$i
9395         done
9396 }
9397
9398 test_60i() {
9399         changelog_register || error "changelog_register failed"
9400         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9401         changelog_users $SINGLEMDS | grep -q $cl_user ||
9402                 error "User $cl_user not found in changelog_users"
9403         changelog_chmask "ALL"
9404         t60i_load &
9405         local PID=$!
9406         for((i=0; i<100; i++)); do
9407                 changelog_dump >/dev/null ||
9408                         error "can't read changelog"
9409         done
9410         kill $PID
9411         wait $PID
9412         changelog_deregister || error "changelog_deregister failed"
9413         $LCTL set_param fail_loc=0
9414 }
9415 run_test 60i "llog: new record vs reader race"
9416
9417 test_60j() {
9418         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9419                 skip "need MDS version at least 2.15.50"
9420         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9421         remote_mds_nodsh && skip "remote MDS with nodsh"
9422         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9423
9424         changelog_users $SINGLEMDS | grep "^cl" &&
9425                 skip "active changelog user"
9426
9427         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9428
9429         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9430                 skip_env "missing llog_reader"
9431
9432         mkdir_on_mdt0 $DIR/$tdir
9433
9434         local f=$DIR/$tdir/$tfile
9435         local mdt_dev
9436         local tmpfile
9437         local plain
9438
9439         changelog_register || error "cannot register changelog user"
9440
9441         # set changelog_mask to ALL
9442         changelog_chmask "ALL"
9443         changelog_clear
9444
9445         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9446         unlinkmany ${f}- 100 || error "unlinkmany failed"
9447
9448         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9449         mdt_dev=$(facet_device $SINGLEMDS)
9450
9451         do_facet $SINGLEMDS sync
9452         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9453                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9454                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9455
9456         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9457
9458         # if $tmpfile is not on EXT3 filesystem for some reason
9459         [[ ${plain:0:1} == 'O' ]] ||
9460                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9461
9462         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9463                 $mdt_dev; stat -c %s $tmpfile")
9464         echo "Truncate llog from $size to $((size - size % 8192))"
9465         size=$((size - size % 8192))
9466         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9467         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9468                 grep -c 'in bitmap only')
9469         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9470
9471         size=$((size - 9000))
9472         echo "Corrupt llog in the middle at $size"
9473         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9474                 count=333 conv=notrunc
9475         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9476                 grep -c 'next chunk')
9477         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9478 }
9479 run_test 60j "llog_reader reports corruptions"
9480
9481 test_61a() {
9482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9483
9484         f="$DIR/f61"
9485         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9486         cancel_lru_locks osc
9487         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9488         sync
9489 }
9490 run_test 61a "mmap() writes don't make sync hang ================"
9491
9492 test_61b() {
9493         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9494 }
9495 run_test 61b "mmap() of unstriped file is successful"
9496
9497 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9498 # Though this test is irrelevant anymore, it helped to reveal some
9499 # other grant bugs (LU-4482), let's keep it.
9500 test_63a() {   # was test_63
9501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9502
9503         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9504
9505         for i in `seq 10` ; do
9506                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9507                 sleep 5
9508                 kill $!
9509                 sleep 1
9510         done
9511
9512         rm -f $DIR/f63 || true
9513 }
9514 run_test 63a "Verify oig_wait interruption does not crash ======="
9515
9516 # bug 2248 - async write errors didn't return to application on sync
9517 # bug 3677 - async write errors left page locked
9518 test_63b() {
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520
9521         debugsave
9522         lctl set_param debug=-1
9523
9524         # ensure we have a grant to do async writes
9525         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9526         rm $DIR/$tfile
9527
9528         sync    # sync lest earlier test intercept the fail_loc
9529
9530         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9531         lctl set_param fail_loc=0x80000406
9532         $MULTIOP $DIR/$tfile Owy && \
9533                 error "sync didn't return ENOMEM"
9534         sync; sleep 2; sync     # do a real sync this time to flush page
9535         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9536                 error "locked page left in cache after async error" || true
9537         debugrestore
9538 }
9539 run_test 63b "async write errors should be returned to fsync ==="
9540
9541 test_64a () {
9542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9543
9544         lfs df $DIR
9545         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9546 }
9547 run_test 64a "verify filter grant calculations (in kernel) ====="
9548
9549 test_64b () {
9550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9551
9552         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9553 }
9554 run_test 64b "check out-of-space detection on client"
9555
9556 test_64c() {
9557         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9558 }
9559 run_test 64c "verify grant shrink"
9560
9561 import_param() {
9562         local tgt=$1
9563         local param=$2
9564
9565         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9566 }
9567
9568 # this does exactly what osc_request.c:osc_announce_cached() does in
9569 # order to calculate max amount of grants to ask from server
9570 want_grant() {
9571         local tgt=$1
9572
9573         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9574         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9575
9576         ((rpc_in_flight++));
9577         nrpages=$((nrpages * rpc_in_flight))
9578
9579         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9580
9581         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9582
9583         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9584         local undirty=$((nrpages * PAGE_SIZE))
9585
9586         local max_extent_pages
9587         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9588         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9589         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9590         local grant_extent_tax
9591         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9592
9593         undirty=$((undirty + nrextents * grant_extent_tax))
9594
9595         echo $undirty
9596 }
9597
9598 # this is size of unit for grant allocation. It should be equal to
9599 # what tgt_grant.c:tgt_grant_chunk() calculates
9600 grant_chunk() {
9601         local tgt=$1
9602         local max_brw_size
9603         local grant_extent_tax
9604
9605         max_brw_size=$(import_param $tgt max_brw_size)
9606
9607         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9608
9609         echo $(((max_brw_size + grant_extent_tax) * 2))
9610 }
9611
9612 test_64d() {
9613         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9614                 skip "OST < 2.10.55 doesn't limit grants enough"
9615
9616         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9617
9618         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9619                 skip "no grant_param connect flag"
9620
9621         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9622
9623         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9624         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9625
9626
9627         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9628         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9629
9630         $LFS setstripe $DIR/$tfile -i 0 -c 1
9631         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9632         ddpid=$!
9633
9634         while kill -0 $ddpid; do
9635                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9636
9637                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9638                         kill $ddpid
9639                         error "cur_grant $cur_grant > $max_cur_granted"
9640                 fi
9641
9642                 sleep 1
9643         done
9644 }
9645 run_test 64d "check grant limit exceed"
9646
9647 check_grants() {
9648         local tgt=$1
9649         local expected=$2
9650         local msg=$3
9651         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9652
9653         ((cur_grants == expected)) ||
9654                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9655 }
9656
9657 round_up_p2() {
9658         echo $((($1 + $2 - 1) & ~($2 - 1)))
9659 }
9660
9661 test_64e() {
9662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9663         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9664                 skip "Need OSS version at least 2.11.56"
9665
9666         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9667         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9668         $LCTL set_param debug=+cache
9669
9670         # Remount client to reset grant
9671         remount_client $MOUNT || error "failed to remount client"
9672         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9673
9674         local init_grants=$(import_param $osc_tgt initial_grant)
9675
9676         check_grants $osc_tgt $init_grants "init grants"
9677
9678         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9679         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9680         local gbs=$(import_param $osc_tgt grant_block_size)
9681
9682         # write random number of bytes from max_brw_size / 4 to max_brw_size
9683         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9684         # align for direct io
9685         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9686         # round to grant consumption unit
9687         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9688
9689         local grants=$((wb_round_up + extent_tax))
9690
9691         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9692         stack_trap "rm -f $DIR/$tfile"
9693
9694         # define OBD_FAIL_TGT_NO_GRANT 0x725
9695         # make the server not grant more back
9696         do_facet ost1 $LCTL set_param fail_loc=0x725
9697         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9698
9699         do_facet ost1 $LCTL set_param fail_loc=0
9700
9701         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9702
9703         rm -f $DIR/$tfile || error "rm failed"
9704
9705         # Remount client to reset grant
9706         remount_client $MOUNT || error "failed to remount client"
9707         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9708
9709         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9710
9711         # define OBD_FAIL_TGT_NO_GRANT 0x725
9712         # make the server not grant more back
9713         do_facet ost1 $LCTL set_param fail_loc=0x725
9714         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9715         do_facet ost1 $LCTL set_param fail_loc=0
9716
9717         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9718 }
9719 run_test 64e "check grant consumption (no grant allocation)"
9720
9721 test_64f() {
9722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9723
9724         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9725         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9726         $LCTL set_param debug=+cache
9727
9728         # Remount client to reset grant
9729         remount_client $MOUNT || error "failed to remount client"
9730         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9731
9732         local init_grants=$(import_param $osc_tgt initial_grant)
9733         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9734         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9735         local gbs=$(import_param $osc_tgt grant_block_size)
9736         local chunk=$(grant_chunk $osc_tgt)
9737
9738         # write random number of bytes from max_brw_size / 4 to max_brw_size
9739         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9740         # align for direct io
9741         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9742         # round to grant consumption unit
9743         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9744
9745         local grants=$((wb_round_up + extent_tax))
9746
9747         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9748         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9749                 error "error writing to $DIR/$tfile"
9750
9751         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9752                 "direct io with grant allocation"
9753
9754         rm -f $DIR/$tfile || error "rm failed"
9755
9756         # Remount client to reset grant
9757         remount_client $MOUNT || error "failed to remount client"
9758         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9759
9760         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9761
9762         # Testing that buffered IO consumes grant on the client
9763
9764         # Delay the RPC on the server so it's guaranteed to not complete even
9765         # if the RPC is sent from the client
9766         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9767         $LCTL set_param fail_loc=0x50a fail_val=3
9768         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9769                 error "error writing to $DIR/$tfile with buffered IO"
9770
9771         check_grants $osc_tgt $((init_grants - grants)) \
9772                 "buffered io, not write rpc"
9773
9774         # Clear the fail loc and do a sync on the client
9775         $LCTL set_param fail_loc=0 fail_val=0
9776         sync
9777
9778         # RPC is now known to have sent
9779         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9780                 "buffered io, one RPC"
9781 }
9782 run_test 64f "check grant consumption (with grant allocation)"
9783
9784 test_64g() {
9785         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9786                 skip "Need MDS version at least 2.14.56"
9787
9788         local mdts=$(comma_list $(mdts_nodes))
9789
9790         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9791                         tr '\n' ' ')
9792         stack_trap "$LCTL set_param $old"
9793
9794         # generate dirty pages and increase dirty granted on MDT
9795         stack_trap "rm -f $DIR/$tfile-*"
9796         for (( i = 0; i < 10; i++)); do
9797                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9798                         error "can't set stripe"
9799                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9800                         error "can't dd"
9801                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9802                         $LFS getstripe $DIR/$tfile-$i
9803                         error "not DoM file"
9804                 }
9805         done
9806
9807         # flush dirty pages
9808         sync
9809
9810         # wait until grant shrink reset grant dirty on MDTs
9811         for ((i = 0; i < 120; i++)); do
9812                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9813                         awk '{sum=sum+$1} END {print sum}')
9814                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9815                 echo "$grant_dirty grants, $vm_dirty pages"
9816                 (( grant_dirty + vm_dirty == 0 )) && break
9817                 (( i == 3 )) && sync &&
9818                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9819                 sleep 1
9820         done
9821
9822         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9823                 awk '{sum=sum+$1} END {print sum}')
9824         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9825 }
9826 run_test 64g "grant shrink on MDT"
9827
9828 test_64h() {
9829         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9830                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9831
9832         local instance=$($LFS getname -i $DIR)
9833         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9834         local num_exps=$(do_facet ost1 \
9835             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9836         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9837         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9838         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9839
9840         # 10MiB is for file to be written, max_brw_size * 16 *
9841         # num_exps is space reserve so that tgt_grant_shrink() decided
9842         # to not shrink
9843         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9844         (( avail * 1024 < expect )) &&
9845                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9846
9847         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9848         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9849         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9850         $LCTL set_param osc.*OST0000*.grant_shrink=1
9851         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9852
9853         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9854         stack_trap "rm -f $DIR/$tfile"
9855         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9856
9857         # drop cache so that coming read would do rpc
9858         cancel_lru_locks osc
9859
9860         # shrink interval is set to 10, pause for 7 seconds so that
9861         # grant thread did not wake up yet but coming read entered
9862         # shrink mode for rpc (osc_should_shrink_grant())
9863         sleep 7
9864
9865         declare -a cur_grant_bytes
9866         declare -a tot_granted
9867         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9868         tot_granted[0]=$(do_facet ost1 \
9869             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9870
9871         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9872
9873         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9874         tot_granted[1]=$(do_facet ost1 \
9875             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9876
9877         # grant change should be equal on both sides
9878         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9879                 tot_granted[0] - tot_granted[1])) ||
9880                 error "grant change mismatch, "                                \
9881                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9882                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9883 }
9884 run_test 64h "grant shrink on read"
9885
9886 test_64i() {
9887         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9888                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9889
9890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9891         remote_ost_nodsh && skip "remote OSTs with nodsh"
9892
9893         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9894         stack_trap "rm -f $DIR/$tfile"
9895
9896         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9897
9898         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9899         local instance=$($LFS getname -i $DIR)
9900
9901         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9902         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9903
9904         # shrink grants and simulate rpc loss
9905         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9906         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9907         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9908
9909         fail ost1
9910
9911         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9912
9913         local testid=$(echo $TESTNAME | tr '_' ' ')
9914
9915         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9916                 grep "GRANT, real grant" &&
9917                 error "client has more grants then it owns" || true
9918 }
9919 run_test 64i "shrink on reconnect"
9920
9921 # bug 1414 - set/get directories' stripe info
9922 test_65a() {
9923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9924
9925         test_mkdir $DIR/$tdir
9926         touch $DIR/$tdir/f1
9927         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9928 }
9929 run_test 65a "directory with no stripe info"
9930
9931 test_65b() {
9932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9933
9934         test_mkdir $DIR/$tdir
9935         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9936
9937         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9938                                                 error "setstripe"
9939         touch $DIR/$tdir/f2
9940         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9941 }
9942 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9943
9944 test_65c() {
9945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9946         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9947
9948         test_mkdir $DIR/$tdir
9949         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9950
9951         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9952                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9953         touch $DIR/$tdir/f3
9954         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9955 }
9956 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9957
9958 test_65d() {
9959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9960
9961         test_mkdir $DIR/$tdir
9962         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9963         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9964
9965         if [[ $STRIPECOUNT -le 0 ]]; then
9966                 sc=1
9967         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9968                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9969                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9970         else
9971                 sc=$(($STRIPECOUNT - 1))
9972         fi
9973         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9974         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9975         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9976                 error "lverify failed"
9977 }
9978 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9979
9980 test_65e() {
9981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9982
9983         # LU-16904 delete layout when root is set as PFL layout
9984         save_layout_restore_at_exit $MOUNT
9985         $LFS setstripe -d $MOUNT || error "setstripe failed"
9986
9987         test_mkdir $DIR/$tdir
9988
9989         $LFS setstripe $DIR/$tdir || error "setstripe"
9990         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9991                                         error "no stripe info failed"
9992         touch $DIR/$tdir/f6
9993         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9994 }
9995 run_test 65e "directory setstripe defaults"
9996
9997 test_65f() {
9998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9999
10000         test_mkdir $DIR/${tdir}f
10001         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10002                 error "setstripe succeeded" || true
10003 }
10004 run_test 65f "dir setstripe permission (should return error) ==="
10005
10006 test_65g() {
10007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10008
10009         # LU-16904 delete layout when root is set as PFL layout
10010         save_layout_restore_at_exit $MOUNT
10011         $LFS setstripe -d $MOUNT || error "setstripe failed"
10012
10013         test_mkdir $DIR/$tdir
10014         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10015
10016         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10017                 error "setstripe -S failed"
10018         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10019         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10020                 error "delete default stripe failed"
10021 }
10022 run_test 65g "directory setstripe -d"
10023
10024 test_65h() {
10025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10026
10027         test_mkdir $DIR/$tdir
10028         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10029
10030         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10031                 error "setstripe -S failed"
10032         test_mkdir $DIR/$tdir/dd1
10033         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10034                 error "stripe info inherit failed"
10035 }
10036 run_test 65h "directory stripe info inherit ===================="
10037
10038 test_65i() {
10039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10040
10041         save_layout_restore_at_exit $MOUNT
10042
10043         # bug6367: set non-default striping on root directory
10044         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10045
10046         # bug12836: getstripe on -1 default directory striping
10047         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10048
10049         # bug12836: getstripe -v on -1 default directory striping
10050         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10051
10052         # bug12836: new find on -1 default directory striping
10053         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10054 }
10055 run_test 65i "various tests to set root directory striping"
10056
10057 test_65j() { # bug6367
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059
10060         sync; sleep 1
10061
10062         # if we aren't already remounting for each test, do so for this test
10063         if [ "$I_MOUNTED" = "yes" ]; then
10064                 cleanup || error "failed to unmount"
10065                 setup
10066         fi
10067
10068         save_layout_restore_at_exit $MOUNT
10069
10070         $LFS setstripe -d $MOUNT || error "setstripe failed"
10071 }
10072 run_test 65j "set default striping on root directory (bug 6367)="
10073
10074 cleanup_65k() {
10075         rm -rf $DIR/$tdir
10076         wait_delete_completed
10077         do_facet $SINGLEMDS "lctl set_param -n \
10078                 osp.$ost*MDT0000.max_create_count=$max_count"
10079         do_facet $SINGLEMDS "lctl set_param -n \
10080                 osp.$ost*MDT0000.create_count=$count"
10081         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10082         echo $INACTIVE_OSC "is Activate"
10083
10084         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10085 }
10086
10087 test_65k() { # bug11679
10088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10089         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10090         remote_mds_nodsh && skip "remote MDS with nodsh"
10091
10092         local disable_precreate=true
10093         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10094                 disable_precreate=false
10095
10096         echo "Check OST status: "
10097         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10098                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10099
10100         for OSC in $MDS_OSCS; do
10101                 echo $OSC "is active"
10102                 do_facet $SINGLEMDS lctl --device %$OSC activate
10103         done
10104
10105         for INACTIVE_OSC in $MDS_OSCS; do
10106                 local ost=$(osc_to_ost $INACTIVE_OSC)
10107                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10108                                lov.*md*.target_obd |
10109                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10110
10111                 mkdir -p $DIR/$tdir
10112                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10113                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10114
10115                 echo "Deactivate: " $INACTIVE_OSC
10116                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10117
10118                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10119                               osp.$ost*MDT0000.create_count")
10120                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10121                                   osp.$ost*MDT0000.max_create_count")
10122                 $disable_precreate &&
10123                         do_facet $SINGLEMDS "lctl set_param -n \
10124                                 osp.$ost*MDT0000.max_create_count=0"
10125
10126                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10127                         [ -f $DIR/$tdir/$idx ] && continue
10128                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10129                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10130                                 { cleanup_65k;
10131                                   error "setstripe $idx should succeed"; }
10132                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10133                 done
10134                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10135                 rmdir $DIR/$tdir
10136
10137                 do_facet $SINGLEMDS "lctl set_param -n \
10138                         osp.$ost*MDT0000.max_create_count=$max_count"
10139                 do_facet $SINGLEMDS "lctl set_param -n \
10140                         osp.$ost*MDT0000.create_count=$count"
10141                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10142                 echo $INACTIVE_OSC "is Activate"
10143
10144                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10145         done
10146 }
10147 run_test 65k "validate manual striping works properly with deactivated OSCs"
10148
10149 test_65l() { # bug 12836
10150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10151
10152         test_mkdir -p $DIR/$tdir/test_dir
10153         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10154         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10155 }
10156 run_test 65l "lfs find on -1 stripe dir ========================"
10157
10158 test_65m() {
10159         local layout=$(save_layout $MOUNT)
10160         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10161                 restore_layout $MOUNT $layout
10162                 error "setstripe should fail by non-root users"
10163         }
10164         true
10165 }
10166 run_test 65m "normal user can't set filesystem default stripe"
10167
10168 test_65n() {
10169         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10170         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10171                 skip "Need MDS version at least 2.12.50"
10172         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10173
10174         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10175         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10176         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10177
10178         save_layout_restore_at_exit $MOUNT
10179
10180         # new subdirectory under root directory should not inherit
10181         # the default layout from root
10182         # LU-16904 check if the root is set as PFL layout
10183         local numcomp=$($LFS getstripe --component-count $MOUNT)
10184
10185         if [[ $numcomp -eq 0 ]]; then
10186                 local dir1=$MOUNT/$tdir-1
10187                 mkdir $dir1 || error "mkdir $dir1 failed"
10188                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10189                         error "$dir1 shouldn't have LOV EA"
10190         fi
10191
10192         # delete the default layout on root directory
10193         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10194
10195         local dir2=$MOUNT/$tdir-2
10196         mkdir $dir2 || error "mkdir $dir2 failed"
10197         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10198                 error "$dir2 shouldn't have LOV EA"
10199
10200         # set a new striping pattern on root directory
10201         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10202         local new_def_stripe_size=$((def_stripe_size * 2))
10203         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10204                 error "set stripe size on $MOUNT failed"
10205
10206         # new file created in $dir2 should inherit the new stripe size from
10207         # the filesystem default
10208         local file2=$dir2/$tfile-2
10209         touch $file2 || error "touch $file2 failed"
10210
10211         local file2_stripe_size=$($LFS getstripe -S $file2)
10212         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10213         {
10214                 echo "file2_stripe_size: '$file2_stripe_size'"
10215                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10216                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10217         }
10218
10219         local dir3=$MOUNT/$tdir-3
10220         mkdir $dir3 || error "mkdir $dir3 failed"
10221         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10222         # the root layout, which is the actual default layout that will be used
10223         # when new files are created in $dir3.
10224         local dir3_layout=$(get_layout_param $dir3)
10225         local root_dir_layout=$(get_layout_param $MOUNT)
10226         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10227         {
10228                 echo "dir3_layout: '$dir3_layout'"
10229                 echo "root_dir_layout: '$root_dir_layout'"
10230                 error "$dir3 should show the default layout from $MOUNT"
10231         }
10232
10233         # set OST pool on root directory
10234         local pool=$TESTNAME
10235         pool_add $pool || error "add $pool failed"
10236         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10237                 error "add targets to $pool failed"
10238
10239         $LFS setstripe -p $pool $MOUNT ||
10240                 error "set OST pool on $MOUNT failed"
10241
10242         # new file created in $dir3 should inherit the pool from
10243         # the filesystem default
10244         local file3=$dir3/$tfile-3
10245         touch $file3 || error "touch $file3 failed"
10246
10247         local file3_pool=$($LFS getstripe -p $file3)
10248         [[ "$file3_pool" = "$pool" ]] ||
10249                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10250
10251         local dir4=$MOUNT/$tdir-4
10252         mkdir $dir4 || error "mkdir $dir4 failed"
10253         local dir4_layout=$(get_layout_param $dir4)
10254         root_dir_layout=$(get_layout_param $MOUNT)
10255         echo "$LFS getstripe -d $dir4"
10256         $LFS getstripe -d $dir4
10257         echo "$LFS getstripe -d $MOUNT"
10258         $LFS getstripe -d $MOUNT
10259         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10260         {
10261                 echo "dir4_layout: '$dir4_layout'"
10262                 echo "root_dir_layout: '$root_dir_layout'"
10263                 error "$dir4 should show the default layout from $MOUNT"
10264         }
10265
10266         # new file created in $dir4 should inherit the pool from
10267         # the filesystem default
10268         local file4=$dir4/$tfile-4
10269         touch $file4 || error "touch $file4 failed"
10270
10271         local file4_pool=$($LFS getstripe -p $file4)
10272         [[ "$file4_pool" = "$pool" ]] ||
10273                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10274
10275         # new subdirectory under non-root directory should inherit
10276         # the default layout from its parent directory
10277         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10278                 error "set directory layout on $dir4 failed"
10279
10280         local dir5=$dir4/$tdir-5
10281         mkdir $dir5 || error "mkdir $dir5 failed"
10282
10283         dir4_layout=$(get_layout_param $dir4)
10284         local dir5_layout=$(get_layout_param $dir5)
10285         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10286         {
10287                 echo "dir4_layout: '$dir4_layout'"
10288                 echo "dir5_layout: '$dir5_layout'"
10289                 error "$dir5 should inherit the default layout from $dir4"
10290         }
10291
10292         # though subdir under ROOT doesn't inherit default layout, but
10293         # its sub dir/file should be created with default layout.
10294         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10295         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10296                 skip "Need MDS version at least 2.12.59"
10297
10298         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10299         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10300         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10301
10302         if [ $default_lmv_hash == "none" ]; then
10303                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10304         else
10305                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10306                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10307         fi
10308
10309         $LFS setdirstripe -D -c 2 $MOUNT ||
10310                 error "setdirstripe -D -c 2 failed"
10311         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10312         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10313         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10314
10315         # $dir4 layout includes pool
10316         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10317         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10318                 error "pool lost on setstripe"
10319         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10320         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10321                 error "pool lost on compound layout setstripe"
10322 }
10323 run_test 65n "don't inherit default layout from root for new subdirectories"
10324
10325 test_65o() {
10326         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10327                 skip "need MDS version at least 2.14.57"
10328
10329         # set OST pool on root directory
10330         local pool=$TESTNAME
10331
10332         pool_add $pool || error "add $pool failed"
10333         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10334                 error "add targets to $pool failed"
10335
10336         local dir1=$MOUNT/$tdir
10337
10338         mkdir $dir1 || error "mkdir $dir1 failed"
10339
10340         # set a new striping pattern on root directory
10341         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10342
10343         $LFS setstripe -p $pool $dir1 ||
10344                 error "set directory layout on $dir1 failed"
10345
10346         # $dir1 layout includes pool
10347         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10348         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10349                 error "pool lost on setstripe"
10350         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10351         $LFS getstripe $dir1
10352         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10353                 error "pool lost on compound layout setstripe"
10354
10355         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10356                 error "setdirstripe failed on sub-dir with inherited pool"
10357         $LFS getstripe $dir1/dir2
10358         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10359                 error "pool lost on compound layout setdirstripe"
10360
10361         $LFS setstripe -E -1 -c 1 $dir1
10362         $LFS getstripe -d $dir1
10363         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10364                 error "pool lost on setstripe"
10365 }
10366 run_test 65o "pool inheritance for mdt component"
10367
10368 test_65p () { # LU-16152
10369         local src_dir=$DIR/$tdir/src_dir
10370         local dst_dir=$DIR/$tdir/dst_dir
10371         local yaml_file=$DIR/$tdir/layout.yaml
10372         local border
10373
10374         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10375                 skip "Need at least version 2.15.51"
10376
10377         test_mkdir -p $src_dir
10378         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10379                 error "failed to setstripe"
10380         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10381                 error "failed to getstripe"
10382
10383         test_mkdir -p $dst_dir
10384         $LFS setstripe --yaml $yaml_file $dst_dir ||
10385                 error "failed to setstripe with yaml file"
10386         border=$($LFS getstripe -d $dst_dir |
10387                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10388                 error "failed to getstripe"
10389
10390         # 2048M is 0x80000000, or 2147483648
10391         (( $border == 2147483648 )) ||
10392                 error "failed to handle huge number in yaml layout"
10393 }
10394 run_test 65p "setstripe with yaml file and huge number"
10395
10396 test_65p () { # LU-16194
10397         local src_dir=$DIR/$tdir/src_dir
10398
10399         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10400                 skip "Need at least version 2.15.51"
10401
10402         test_mkdir -p $src_dir
10403         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10404         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10405                 error "should fail if extent start/end >=8E"
10406
10407         # EOF should work as before
10408         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10409                 error "failed to setstripe normally"
10410 }
10411 run_test 65p "setstripe with >=8E offset should fail"
10412
10413 # bug 2543 - update blocks count on client
10414 test_66() {
10415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10416
10417         local COUNT=${COUNT:-8}
10418         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10419         sync; sync_all_data; sync; sync_all_data
10420         cancel_lru_locks osc
10421         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10422         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10423 }
10424 run_test 66 "update inode blocks count on client ==============="
10425
10426 meminfo() {
10427         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10428 }
10429
10430 swap_used() {
10431         swapon -s | awk '($1 == "'$1'") { print $4 }'
10432 }
10433
10434 # bug5265, obdfilter oa2dentry return -ENOENT
10435 # #define OBD_FAIL_SRV_ENOENT 0x217
10436 test_69() {
10437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10438         remote_ost_nodsh && skip "remote OST with nodsh"
10439
10440         f="$DIR/$tfile"
10441         $LFS setstripe -c 1 -i 0 $f
10442         stack_trap "rm -f $f ${f}.2"
10443
10444         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10445
10446         do_facet ost1 lctl set_param fail_loc=0x217
10447         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10448         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10449
10450         do_facet ost1 lctl set_param fail_loc=0
10451         $DIRECTIO write $f 0 2 || error "write error"
10452
10453         cancel_lru_locks osc
10454         $DIRECTIO read $f 0 1 || error "read error"
10455
10456         do_facet ost1 lctl set_param fail_loc=0x217
10457         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10458
10459         do_facet ost1 lctl set_param fail_loc=0
10460 }
10461 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10462
10463 test_70a() {
10464         # Perform a really simple test of health write
10465         # and health check
10466
10467         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10468
10469         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10470
10471         # Test with health write off
10472         do_facet ost1 $LCTL set_param enable_health_write off ||
10473                 error "can't set enable_health_write off"
10474         do_facet ost1 $LCTL get_param enable_health_write ||
10475                 error "can't get enable_health_write"
10476
10477         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10478                 error "not healthy (1)"
10479
10480         # Test with health write on
10481         do_facet ost1 $LCTL set_param enable_health_write on ||
10482                 error "can't set enable_health_write on"
10483         do_facet ost1 $LCTL get_param enable_health_write ||
10484                 error "can't get enable_health_write"
10485
10486         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10487                 error "not healthy (2)"
10488 }
10489 run_test 70a "verify health_check, health_write don't explode (on OST)"
10490
10491 test_71() {
10492         test_mkdir $DIR/$tdir
10493         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10494         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10495 }
10496 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10497
10498 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10500         [ "$RUNAS_ID" = "$UID" ] &&
10501                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10502         # Check that testing environment is properly set up. Skip if not
10503         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10504                 skip_env "User $RUNAS_ID does not exist - skipping"
10505
10506         touch $DIR/$tfile
10507         chmod 777 $DIR/$tfile
10508         chmod ug+s $DIR/$tfile
10509         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10510                 error "$RUNAS dd $DIR/$tfile failed"
10511         # See if we are still setuid/sgid
10512         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10513                 error "S/gid is not dropped on write"
10514         # Now test that MDS is updated too
10515         cancel_lru_locks mdc
10516         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10517                 error "S/gid is not dropped on MDS"
10518         rm -f $DIR/$tfile
10519 }
10520 run_test 72a "Test that remove suid works properly (bug5695) ===="
10521
10522 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10523         local perm
10524
10525         [ "$RUNAS_ID" = "$UID" ] &&
10526                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10527         [ "$RUNAS_ID" -eq 0 ] &&
10528                 skip_env "RUNAS_ID = 0 -- skipping"
10529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10530         # Check that testing environment is properly set up. Skip if not
10531         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10532                 skip_env "User $RUNAS_ID does not exist - skipping"
10533
10534         touch $DIR/${tfile}-f{g,u}
10535         test_mkdir $DIR/${tfile}-dg
10536         test_mkdir $DIR/${tfile}-du
10537         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10538         chmod g+s $DIR/${tfile}-{f,d}g
10539         chmod u+s $DIR/${tfile}-{f,d}u
10540         for perm in 777 2777 4777; do
10541                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10542                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10543                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10544                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10545         done
10546         true
10547 }
10548 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10549
10550 # bug 3462 - multiple simultaneous MDC requests
10551 test_73() {
10552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10553
10554         test_mkdir $DIR/d73-1
10555         test_mkdir $DIR/d73-2
10556         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10557         pid1=$!
10558
10559         lctl set_param fail_loc=0x80000129
10560         $MULTIOP $DIR/d73-1/f73-2 Oc &
10561         sleep 1
10562         lctl set_param fail_loc=0
10563
10564         $MULTIOP $DIR/d73-2/f73-3 Oc &
10565         pid3=$!
10566
10567         kill -USR1 $pid1
10568         wait $pid1 || return 1
10569
10570         sleep 25
10571
10572         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10573         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10574         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10575
10576         rm -rf $DIR/d73-*
10577 }
10578 run_test 73 "multiple MDC requests (should not deadlock)"
10579
10580 test_74a() { # bug 6149, 6184
10581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10582
10583         touch $DIR/f74a
10584         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10585         #
10586         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10587         # will spin in a tight reconnection loop
10588         $LCTL set_param fail_loc=0x8000030e
10589         # get any lock that won't be difficult - lookup works.
10590         ls $DIR/f74a
10591         $LCTL set_param fail_loc=0
10592         rm -f $DIR/f74a
10593         true
10594 }
10595 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10596
10597 test_74b() { # bug 13310
10598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10599
10600         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10601         #
10602         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10603         # will spin in a tight reconnection loop
10604         $LCTL set_param fail_loc=0x8000030e
10605         # get a "difficult" lock
10606         touch $DIR/f74b
10607         $LCTL set_param fail_loc=0
10608         rm -f $DIR/f74b
10609         true
10610 }
10611 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10612
10613 test_74c() {
10614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10615
10616         #define OBD_FAIL_LDLM_NEW_LOCK
10617         $LCTL set_param fail_loc=0x319
10618         touch $DIR/$tfile && error "touch successful"
10619         $LCTL set_param fail_loc=0
10620         true
10621 }
10622 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10623
10624 slab_lic=/sys/kernel/slab/lustre_inode_cache
10625 num_objects() {
10626         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10627         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10628                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10629 }
10630
10631 test_76a() { # Now for b=20433, added originally in b=1443
10632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10633
10634         cancel_lru_locks osc
10635         # there may be some slab objects cached per core
10636         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10637         local before=$(num_objects)
10638         local count=$((512 * cpus))
10639         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10640         local margin=$((count / 10))
10641         if [[ -f $slab_lic/aliases ]]; then
10642                 local aliases=$(cat $slab_lic/aliases)
10643                 (( aliases > 0 )) && margin=$((margin * aliases))
10644         fi
10645
10646         echo "before slab objects: $before"
10647         for i in $(seq $count); do
10648                 touch $DIR/$tfile
10649                 rm -f $DIR/$tfile
10650         done
10651         cancel_lru_locks osc
10652         local after=$(num_objects)
10653         echo "created: $count, after slab objects: $after"
10654         # shared slab counts are not very accurate, allow significant margin
10655         # the main goal is that the cache growth is not permanently > $count
10656         while (( after > before + margin )); do
10657                 sleep 1
10658                 after=$(num_objects)
10659                 wait=$((wait + 1))
10660                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10661                 if (( wait > 60 )); then
10662                         error "inode slab grew from $before+$margin to $after"
10663                 fi
10664         done
10665 }
10666 run_test 76a "confirm clients recycle inodes properly ===="
10667
10668 test_76b() {
10669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10670         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10671
10672         local count=512
10673         local before=$(num_objects)
10674
10675         for i in $(seq $count); do
10676                 mkdir $DIR/$tdir
10677                 rmdir $DIR/$tdir
10678         done
10679
10680         local after=$(num_objects)
10681         local wait=0
10682
10683         while (( after > before )); do
10684                 sleep 1
10685                 after=$(num_objects)
10686                 wait=$((wait + 1))
10687                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10688                 if (( wait > 60 )); then
10689                         error "inode slab grew from $before to $after"
10690                 fi
10691         done
10692
10693         echo "slab objects before: $before, after: $after"
10694 }
10695 run_test 76b "confirm clients recycle directory inodes properly ===="
10696
10697 export ORIG_CSUM=""
10698 set_checksums()
10699 {
10700         # Note: in sptlrpc modes which enable its own bulk checksum, the
10701         # original crc32_le bulk checksum will be automatically disabled,
10702         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10703         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10704         # In this case set_checksums() will not be no-op, because sptlrpc
10705         # bulk checksum will be enabled all through the test.
10706
10707         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10708         lctl set_param -n osc.*.checksums $1
10709         return 0
10710 }
10711
10712 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10713                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10714 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10715                              tr -d [] | head -n1)}
10716 set_checksum_type()
10717 {
10718         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10719         rc=$?
10720         log "set checksum type to $1, rc = $rc"
10721         return $rc
10722 }
10723
10724 get_osc_checksum_type()
10725 {
10726         # arugment 1: OST name, like OST0000
10727         ost=$1
10728         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10729                         sed 's/.*\[\(.*\)\].*/\1/g')
10730         rc=$?
10731         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10732         echo $checksum_type
10733 }
10734
10735 F77_TMP=$TMP/f77-temp
10736 F77SZ=8
10737 setup_f77() {
10738         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10739                 error "error writing to $F77_TMP"
10740 }
10741
10742 test_77a() { # bug 10889
10743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10744         $GSS && skip_env "could not run with gss"
10745
10746         [ ! -f $F77_TMP ] && setup_f77
10747         set_checksums 1
10748         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10749         set_checksums 0
10750         rm -f $DIR/$tfile
10751 }
10752 run_test 77a "normal checksum read/write operation"
10753
10754 test_77b() { # bug 10889
10755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10756         $GSS && skip_env "could not run with gss"
10757
10758         [ ! -f $F77_TMP ] && setup_f77
10759         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10760         $LCTL set_param fail_loc=0x80000409
10761         set_checksums 1
10762
10763         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10764                 error "dd error: $?"
10765         $LCTL set_param fail_loc=0
10766
10767         for algo in $CKSUM_TYPES; do
10768                 cancel_lru_locks osc
10769                 set_checksum_type $algo
10770                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10771                 $LCTL set_param fail_loc=0x80000408
10772                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10773                 $LCTL set_param fail_loc=0
10774         done
10775         set_checksums 0
10776         set_checksum_type $ORIG_CSUM_TYPE
10777         rm -f $DIR/$tfile
10778 }
10779 run_test 77b "checksum error on client write, read"
10780
10781 cleanup_77c() {
10782         trap 0
10783         set_checksums 0
10784         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10785         $check_ost &&
10786                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10787         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10788         $check_ost && [ -n "$ost_file_prefix" ] &&
10789                 do_facet ost1 rm -f ${ost_file_prefix}\*
10790 }
10791
10792 test_77c() {
10793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10794         $GSS && skip_env "could not run with gss"
10795         remote_ost_nodsh && skip "remote OST with nodsh"
10796
10797         local bad1
10798         local osc_file_prefix
10799         local osc_file
10800         local check_ost=false
10801         local ost_file_prefix
10802         local ost_file
10803         local orig_cksum
10804         local dump_cksum
10805         local fid
10806
10807         # ensure corruption will occur on first OSS/OST
10808         $LFS setstripe -i 0 $DIR/$tfile
10809
10810         [ ! -f $F77_TMP ] && setup_f77
10811         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10812                 error "dd write error: $?"
10813         fid=$($LFS path2fid $DIR/$tfile)
10814
10815         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10816         then
10817                 check_ost=true
10818                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10819                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10820         else
10821                 echo "OSS do not support bulk pages dump upon error"
10822         fi
10823
10824         osc_file_prefix=$($LCTL get_param -n debug_path)
10825         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10826
10827         trap cleanup_77c EXIT
10828
10829         set_checksums 1
10830         # enable bulk pages dump upon error on Client
10831         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10832         # enable bulk pages dump upon error on OSS
10833         $check_ost &&
10834                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10835
10836         # flush Client cache to allow next read to reach OSS
10837         cancel_lru_locks osc
10838
10839         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10840         $LCTL set_param fail_loc=0x80000408
10841         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10842         $LCTL set_param fail_loc=0
10843
10844         rm -f $DIR/$tfile
10845
10846         # check cksum dump on Client
10847         osc_file=$(ls ${osc_file_prefix}*)
10848         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10849         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10850         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10851         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10852         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10853                      cksum)
10854         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10855         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10856                 error "dump content does not match on Client"
10857
10858         $check_ost || skip "No need to check cksum dump on OSS"
10859
10860         # check cksum dump on OSS
10861         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10862         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10863         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10864         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10865         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10866                 error "dump content does not match on OSS"
10867
10868         cleanup_77c
10869 }
10870 run_test 77c "checksum error on client read with debug"
10871
10872 test_77d() { # bug 10889
10873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10874         $GSS && skip_env "could not run with gss"
10875
10876         stack_trap "rm -f $DIR/$tfile"
10877         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10878         $LCTL set_param fail_loc=0x80000409
10879         set_checksums 1
10880         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10881                 error "direct write: rc=$?"
10882         $LCTL set_param fail_loc=0
10883         set_checksums 0
10884
10885         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10886         $LCTL set_param fail_loc=0x80000408
10887         set_checksums 1
10888         cancel_lru_locks osc
10889         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10890                 error "direct read: rc=$?"
10891         $LCTL set_param fail_loc=0
10892         set_checksums 0
10893 }
10894 run_test 77d "checksum error on OST direct write, read"
10895
10896 test_77f() { # bug 10889
10897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10898         $GSS && skip_env "could not run with gss"
10899
10900         set_checksums 1
10901         stack_trap "rm -f $DIR/$tfile"
10902         for algo in $CKSUM_TYPES; do
10903                 cancel_lru_locks osc
10904                 set_checksum_type $algo
10905                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10906                 $LCTL set_param fail_loc=0x409
10907                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10908                         error "direct write succeeded"
10909                 $LCTL set_param fail_loc=0
10910         done
10911         set_checksum_type $ORIG_CSUM_TYPE
10912         set_checksums 0
10913 }
10914 run_test 77f "repeat checksum error on write (expect error)"
10915
10916 test_77g() { # bug 10889
10917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10918         $GSS && skip_env "could not run with gss"
10919         remote_ost_nodsh && skip "remote OST with nodsh"
10920
10921         [ ! -f $F77_TMP ] && setup_f77
10922
10923         local file=$DIR/$tfile
10924         stack_trap "rm -f $file" EXIT
10925
10926         $LFS setstripe -c 1 -i 0 $file
10927         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10928         do_facet ost1 lctl set_param fail_loc=0x8000021a
10929         set_checksums 1
10930         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10931                 error "write error: rc=$?"
10932         do_facet ost1 lctl set_param fail_loc=0
10933         set_checksums 0
10934
10935         cancel_lru_locks osc
10936         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10937         do_facet ost1 lctl set_param fail_loc=0x8000021b
10938         set_checksums 1
10939         cmp $F77_TMP $file || error "file compare failed"
10940         do_facet ost1 lctl set_param fail_loc=0
10941         set_checksums 0
10942 }
10943 run_test 77g "checksum error on OST write, read"
10944
10945 test_77k() { # LU-10906
10946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10947         $GSS && skip_env "could not run with gss"
10948
10949         local cksum_param="osc.$FSNAME*.checksums"
10950         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10951         local checksum
10952         local i
10953
10954         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10955         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10956         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10957
10958         for i in 0 1; do
10959                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10960                         error "failed to set checksum=$i on MGS"
10961                 wait_update $HOSTNAME "$get_checksum" $i
10962                 #remount
10963                 echo "remount client, checksum should be $i"
10964                 remount_client $MOUNT || error "failed to remount client"
10965                 checksum=$(eval $get_checksum)
10966                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10967         done
10968         # remove persistent param to avoid races with checksum mountopt below
10969         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10970                 error "failed to delete checksum on MGS"
10971
10972         for opt in "checksum" "nochecksum"; do
10973                 #remount with mount option
10974                 echo "remount client with option $opt, checksum should be $i"
10975                 umount_client $MOUNT || error "failed to umount client"
10976                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10977                         error "failed to mount client with option '$opt'"
10978                 checksum=$(eval $get_checksum)
10979                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10980                 i=$((i - 1))
10981         done
10982
10983         remount_client $MOUNT || error "failed to remount client"
10984 }
10985 run_test 77k "enable/disable checksum correctly"
10986
10987 test_77l() {
10988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10989         $GSS && skip_env "could not run with gss"
10990
10991         set_checksums 1
10992         stack_trap "set_checksums $ORIG_CSUM" EXIT
10993         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10994
10995         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10996
10997         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10998         for algo in $CKSUM_TYPES; do
10999                 set_checksum_type $algo || error "fail to set checksum type $algo"
11000                 osc_algo=$(get_osc_checksum_type OST0000)
11001                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11002
11003                 # no locks, no reqs to let the connection idle
11004                 cancel_lru_locks osc
11005                 lru_resize_disable osc
11006                 wait_osc_import_state client ost1 IDLE
11007
11008                 # ensure ost1 is connected
11009                 stat $DIR/$tfile >/dev/null || error "can't stat"
11010                 wait_osc_import_state client ost1 FULL
11011
11012                 osc_algo=$(get_osc_checksum_type OST0000)
11013                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11014         done
11015         return 0
11016 }
11017 run_test 77l "preferred checksum type is remembered after reconnected"
11018
11019 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11020 rm -f $F77_TMP
11021 unset F77_TMP
11022
11023 test_77m() {
11024         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11025                 skip "Need at least version 2.14.52"
11026         local param=checksum_speed
11027
11028         $LCTL get_param $param || error "reading $param failed"
11029
11030         csum_speeds=$($LCTL get_param -n $param)
11031
11032         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11033                 error "known checksum types are missing"
11034 }
11035 run_test 77m "Verify checksum_speed is correctly read"
11036
11037 check_filefrag_77n() {
11038         local nr_ext=0
11039         local starts=()
11040         local ends=()
11041
11042         while read extidx a b start end rest; do
11043                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11044                         nr_ext=$(( $nr_ext + 1 ))
11045                         starts+=( ${start%..} )
11046                         ends+=( ${end%:} )
11047                 fi
11048         done < <( filefrag -sv $1 )
11049
11050         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11051         return 1
11052 }
11053
11054 test_77n() {
11055         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11056
11057         touch $DIR/$tfile
11058         $TRUNCATE $DIR/$tfile 0
11059         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11060         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11061         check_filefrag_77n $DIR/$tfile ||
11062                 skip "$tfile blocks not contiguous around hole"
11063
11064         set_checksums 1
11065         stack_trap "set_checksums $ORIG_CSUM" EXIT
11066         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11067         stack_trap "rm -f $DIR/$tfile"
11068
11069         for algo in $CKSUM_TYPES; do
11070                 if [[ "$algo" =~ ^t10 ]]; then
11071                         set_checksum_type $algo ||
11072                                 error "fail to set checksum type $algo"
11073                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11074                                 error "fail to read $tfile with $algo"
11075                 fi
11076         done
11077         rm -f $DIR/$tfile
11078         return 0
11079 }
11080 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11081
11082 test_77o() {
11083         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11084                 skip "Need MDS version at least 2.14.55"
11085         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11086                 skip "Need OST version at least 2.14.55"
11087         local ofd=obdfilter
11088         local mdt=mdt
11089
11090         # print OST checksum_type
11091         echo "$ofd.$FSNAME-*.checksum_type:"
11092         do_nodes $(comma_list $(osts_nodes)) \
11093                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11094
11095         # print MDT checksum_type
11096         echo "$mdt.$FSNAME-*.checksum_type:"
11097         do_nodes $(comma_list $(mdts_nodes)) \
11098                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11099
11100         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11101                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11102
11103         (( $o_count == $OSTCOUNT )) ||
11104                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11105
11106         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11107                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11108
11109         (( $m_count == $MDSCOUNT )) ||
11110                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11111 }
11112 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11113
11114 cleanup_test_78() {
11115         trap 0
11116         rm -f $DIR/$tfile
11117 }
11118
11119 test_78() { # bug 10901
11120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11121         remote_ost || skip_env "local OST"
11122
11123         NSEQ=5
11124         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11125         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11126         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11127         echo "MemTotal: $MEMTOTAL"
11128
11129         # reserve 256MB of memory for the kernel and other running processes,
11130         # and then take 1/2 of the remaining memory for the read/write buffers.
11131         if [ $MEMTOTAL -gt 512 ] ;then
11132                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11133         else
11134                 # for those poor memory-starved high-end clusters...
11135                 MEMTOTAL=$((MEMTOTAL / 2))
11136         fi
11137         echo "Mem to use for directio: $MEMTOTAL"
11138
11139         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11140         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11141         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11142         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11143                 head -n1)
11144         echo "Smallest OST: $SMALLESTOST"
11145         [[ $SMALLESTOST -lt 10240 ]] &&
11146                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11147
11148         trap cleanup_test_78 EXIT
11149
11150         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11151                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11152
11153         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11154         echo "File size: $F78SIZE"
11155         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11156         for i in $(seq 1 $NSEQ); do
11157                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11158                 echo directIO rdwr round $i of $NSEQ
11159                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11160         done
11161
11162         cleanup_test_78
11163 }
11164 run_test 78 "handle large O_DIRECT writes correctly ============"
11165
11166 test_79() { # bug 12743
11167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11168
11169         wait_delete_completed
11170
11171         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11172         BKFREE=$(calc_osc_kbytes kbytesfree)
11173         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11174
11175         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11176         DFTOTAL=`echo $STRING | cut -d, -f1`
11177         DFUSED=`echo $STRING  | cut -d, -f2`
11178         DFAVAIL=`echo $STRING | cut -d, -f3`
11179         DFFREE=$(($DFTOTAL - $DFUSED))
11180
11181         ALLOWANCE=$((64 * $OSTCOUNT))
11182
11183         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11184            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11185                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11186         fi
11187         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11188            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11189                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11190         fi
11191         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11192            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11193                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11194         fi
11195 }
11196 run_test 79 "df report consistency check ======================="
11197
11198 test_80() { # bug 10718
11199         remote_ost_nodsh && skip "remote OST with nodsh"
11200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11201
11202         # relax strong synchronous semantics for slow backends like ZFS
11203         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11204                 local soc="obdfilter.*.sync_lock_cancel"
11205                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11206
11207                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11208                 if [ -z "$save" ]; then
11209                         soc="obdfilter.*.sync_on_lock_cancel"
11210                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11211                 fi
11212
11213                 if [ "$save" != "never" ]; then
11214                         local hosts=$(comma_list $(osts_nodes))
11215
11216                         do_nodes $hosts $LCTL set_param $soc=never
11217                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11218                 fi
11219         fi
11220
11221         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11222         sync; sleep 1; sync
11223         local before=$(date +%s)
11224         cancel_lru_locks osc
11225         local after=$(date +%s)
11226         local diff=$((after - before))
11227         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11228
11229         rm -f $DIR/$tfile
11230 }
11231 run_test 80 "Page eviction is equally fast at high offsets too"
11232
11233 test_81a() { # LU-456
11234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11235         remote_ost_nodsh && skip "remote OST with nodsh"
11236
11237         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11238         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11239         do_facet ost1 lctl set_param fail_loc=0x80000228
11240
11241         # write should trigger a retry and success
11242         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11243         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11244         RC=$?
11245         if [ $RC -ne 0 ] ; then
11246                 error "write should success, but failed for $RC"
11247         fi
11248 }
11249 run_test 81a "OST should retry write when get -ENOSPC ==============="
11250
11251 test_81b() { # LU-456
11252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11253         remote_ost_nodsh && skip "remote OST with nodsh"
11254
11255         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11256         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11257         do_facet ost1 lctl set_param fail_loc=0x228
11258
11259         # write should retry several times and return -ENOSPC finally
11260         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11261         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11262         RC=$?
11263         ENOSPC=28
11264         if [ $RC -ne $ENOSPC ] ; then
11265                 error "dd should fail for -ENOSPC, but succeed."
11266         fi
11267 }
11268 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11269
11270 test_99() {
11271         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11272
11273         test_mkdir $DIR/$tdir.cvsroot
11274         chown $RUNAS_ID $DIR/$tdir.cvsroot
11275
11276         cd $TMP
11277         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11278
11279         cd /etc/init.d
11280         # some versions of cvs import exit(1) when asked to import links or
11281         # files they can't read.  ignore those files.
11282         local toignore=$(find . -type l -printf '-I %f\n' -o \
11283                          ! -perm /4 -printf '-I %f\n')
11284         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11285                 $tdir.reposname vtag rtag
11286
11287         cd $DIR
11288         test_mkdir $DIR/$tdir.reposname
11289         chown $RUNAS_ID $DIR/$tdir.reposname
11290         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11291
11292         cd $DIR/$tdir.reposname
11293         $RUNAS touch foo99
11294         $RUNAS cvs add -m 'addmsg' foo99
11295         $RUNAS cvs update
11296         $RUNAS cvs commit -m 'nomsg' foo99
11297         rm -fr $DIR/$tdir.cvsroot
11298 }
11299 run_test 99 "cvs strange file/directory operations"
11300
11301 test_100() {
11302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11303         [[ "$NETTYPE" =~ tcp ]] ||
11304                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11305         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11306         remote_ost_nodsh && skip "remote OST with nodsh"
11307         remote_mds_nodsh && skip "remote MDS with nodsh"
11308         remote_servers || skip "useless for local single node setup"
11309
11310         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11311                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11312
11313                 rc=0
11314                 if (( ${LOCAL/*:/} >= 1024 )); then
11315                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11316                         ss -tna
11317                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11318                 fi
11319         done
11320         (( $rc == 0 )) || error "privileged port not found" )
11321 }
11322 run_test 100 "check local port using privileged port"
11323
11324 function get_named_value()
11325 {
11326     local tag=$1
11327
11328     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11329 }
11330
11331 test_101a() {
11332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11333
11334         local s
11335         local discard
11336         local nreads=10000
11337         local cache_limit=32
11338
11339         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11340         $LCTL set_param -n llite.*.read_ahead_stats=0
11341         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11342                               awk '/^max_cached_mb/ { print $2 }')
11343         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11344         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11345
11346         #
11347         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11348         #
11349         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11350         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11351
11352         discard=0
11353         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11354                    get_named_value 'read.but.discarded'); do
11355                         discard=$(($discard + $s))
11356         done
11357
11358         $LCTL get_param osc.*-osc*.rpc_stats
11359         $LCTL get_param llite.*.read_ahead_stats
11360
11361         # Discard is generally zero, but sometimes a few random reads line up
11362         # and trigger larger readahead, which is wasted & leads to discards.
11363         if [[ $(($discard)) -gt $nreads ]]; then
11364                 error "too many ($discard) discarded pages"
11365         fi
11366         rm -f $DIR/$tfile || true
11367 }
11368 run_test 101a "check read-ahead for random reads"
11369
11370 setup_test101bc() {
11371         test_mkdir $DIR/$tdir
11372         local ssize=$1
11373         local FILE_LENGTH=$2
11374         STRIPE_OFFSET=0
11375
11376         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11377
11378         local list=$(comma_list $(osts_nodes))
11379         set_osd_param $list '' read_cache_enable 0
11380         set_osd_param $list '' writethrough_cache_enable 0
11381
11382         trap cleanup_test101bc EXIT
11383         # prepare the read-ahead file
11384         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11385
11386         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11387                                 count=$FILE_SIZE_MB 2> /dev/null
11388
11389 }
11390
11391 cleanup_test101bc() {
11392         trap 0
11393         rm -rf $DIR/$tdir
11394         rm -f $DIR/$tfile
11395
11396         local list=$(comma_list $(osts_nodes))
11397         set_osd_param $list '' read_cache_enable 1
11398         set_osd_param $list '' writethrough_cache_enable 1
11399 }
11400
11401 ra_check_101() {
11402         local read_size=$1
11403         local stripe_size=$2
11404         local stride_length=$((stripe_size / read_size))
11405         local stride_width=$((stride_length * OSTCOUNT))
11406         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11407                                 (stride_width - stride_length) ))
11408         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11409                   get_named_value 'read.but.discarded' | calc_sum)
11410
11411         if [[ $discard -gt $discard_limit ]]; then
11412                 $LCTL get_param llite.*.read_ahead_stats
11413                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11414         else
11415                 echo "Read-ahead success for size ${read_size}"
11416         fi
11417 }
11418
11419 test_101b() {
11420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11421         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11422
11423         local STRIPE_SIZE=1048576
11424         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11425
11426         if [ $SLOW == "yes" ]; then
11427                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11428         else
11429                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11430         fi
11431
11432         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11433
11434         # prepare the read-ahead file
11435         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11436         cancel_lru_locks osc
11437         for BIDX in 2 4 8 16 32 64 128 256
11438         do
11439                 local BSIZE=$((BIDX*4096))
11440                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11441                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11442                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11443                 $LCTL set_param -n llite.*.read_ahead_stats=0
11444                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11445                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11446                 cancel_lru_locks osc
11447                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11448         done
11449         cleanup_test101bc
11450         true
11451 }
11452 run_test 101b "check stride-io mode read-ahead ================="
11453
11454 test_101c() {
11455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11456
11457         local STRIPE_SIZE=1048576
11458         local FILE_LENGTH=$((STRIPE_SIZE*100))
11459         local nreads=10000
11460         local rsize=65536
11461         local osc_rpc_stats
11462
11463         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11464
11465         cancel_lru_locks osc
11466         $LCTL set_param osc.*.rpc_stats=0
11467         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11468         $LCTL get_param osc.*.rpc_stats
11469         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11470                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11471                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11472                 local size
11473
11474                 if [ $lines -le 20 ]; then
11475                         echo "continue debug"
11476                         continue
11477                 fi
11478                 for size in 1 2 4 8; do
11479                         local rpc=$(echo "$stats" |
11480                                     awk '($1 == "'$size':") {print $2; exit; }')
11481                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11482                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11483                 done
11484                 echo "$osc_rpc_stats check passed!"
11485         done
11486         cleanup_test101bc
11487         true
11488 }
11489 run_test 101c "check stripe_size aligned read-ahead"
11490
11491 test_101d() {
11492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11493
11494         local file=$DIR/$tfile
11495         local sz_MB=${FILESIZE_101d:-80}
11496         local ra_MB=${READAHEAD_MB:-40}
11497
11498         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11499         [ $free_MB -lt $sz_MB ] &&
11500                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11501
11502         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11503         $LFS setstripe -c -1 $file || error "setstripe failed"
11504
11505         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11506         echo Cancel LRU locks on lustre client to flush the client cache
11507         cancel_lru_locks osc
11508
11509         echo Disable read-ahead
11510         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11511         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11512         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11513         $LCTL get_param -n llite.*.max_read_ahead_mb
11514
11515         echo "Reading the test file $file with read-ahead disabled"
11516         local sz_KB=$((sz_MB * 1024 / 4))
11517         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11518         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11519         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11520         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11521                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11522
11523         echo "Cancel LRU locks on lustre client to flush the client cache"
11524         cancel_lru_locks osc
11525         echo Enable read-ahead with ${ra_MB}MB
11526         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11527
11528         echo "Reading the test file $file with read-ahead enabled"
11529         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11530                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11531
11532         echo "read-ahead disabled time read '$raOFF'"
11533         echo "read-ahead enabled time read '$raON'"
11534
11535         rm -f $file
11536         wait_delete_completed
11537
11538         # use awk for this check instead of bash because it handles decimals
11539         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11540                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11541 }
11542 run_test 101d "file read with and without read-ahead enabled"
11543
11544 test_101e() {
11545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11546
11547         local file=$DIR/$tfile
11548         local size_KB=500  #KB
11549         local count=100
11550         local bsize=1024
11551
11552         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11553         local need_KB=$((count * size_KB))
11554         [[ $free_KB -le $need_KB ]] &&
11555                 skip_env "Need free space $need_KB, have $free_KB"
11556
11557         echo "Creating $count ${size_KB}K test files"
11558         for ((i = 0; i < $count; i++)); do
11559                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11560         done
11561
11562         echo "Cancel LRU locks on lustre client to flush the client cache"
11563         cancel_lru_locks $OSC
11564
11565         echo "Reset readahead stats"
11566         $LCTL set_param -n llite.*.read_ahead_stats=0
11567
11568         for ((i = 0; i < $count; i++)); do
11569                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11570         done
11571
11572         $LCTL get_param llite.*.max_cached_mb
11573         $LCTL get_param llite.*.read_ahead_stats
11574         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11575                      get_named_value 'misses' | calc_sum)
11576
11577         for ((i = 0; i < $count; i++)); do
11578                 rm -rf $file.$i 2>/dev/null
11579         done
11580
11581         #10000 means 20% reads are missing in readahead
11582         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11583 }
11584 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11585
11586 test_101f() {
11587         which iozone || skip_env "no iozone installed"
11588
11589         local old_debug=$($LCTL get_param debug)
11590         old_debug=${old_debug#*=}
11591         $LCTL set_param debug="reada mmap"
11592
11593         # create a test file
11594         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11595
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 mmap read the file with small block size
11603         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11604                 > /dev/null 2>&1
11605
11606         echo checking missing pages
11607         $LCTL get_param llite.*.read_ahead_stats
11608         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11609                         get_named_value 'misses' | calc_sum)
11610
11611         $LCTL set_param debug="$old_debug"
11612         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11613         rm -f $DIR/$tfile
11614 }
11615 run_test 101f "check mmap read performance"
11616
11617 test_101g_brw_size_test() {
11618         local mb=$1
11619         local pages=$((mb * 1048576 / PAGE_SIZE))
11620         local file=$DIR/$tfile
11621
11622         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11623                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11624         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11625                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11626                         return 2
11627         done
11628
11629         stack_trap "rm -f $file" EXIT
11630         $LCTL set_param -n osc.*.rpc_stats=0
11631
11632         # 10 RPCs should be enough for the test
11633         local count=10
11634         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11635                 { error "dd write ${mb} MB blocks failed"; return 3; }
11636         cancel_lru_locks osc
11637         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11638                 { error "dd write ${mb} MB blocks failed"; return 4; }
11639
11640         # calculate number of full-sized read and write RPCs
11641         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11642                 sed -n '/pages per rpc/,/^$/p' |
11643                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11644                 END { print reads,writes }'))
11645         # allow one extra full-sized read RPC for async readahead
11646         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11647                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11648         [[ ${rpcs[1]} == $count ]] ||
11649                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11650 }
11651
11652 test_101g() {
11653         remote_ost_nodsh && skip "remote OST with nodsh"
11654
11655         local rpcs
11656         local osts=$(get_facets OST)
11657         local list=$(comma_list $(osts_nodes))
11658         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11659         local brw_size="obdfilter.*.brw_size"
11660
11661         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11662
11663         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11664
11665         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11666                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11667                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11668            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11669                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11670                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11671
11672                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11673                         suffix="M"
11674
11675                 if [[ $orig_mb -lt 16 ]]; then
11676                         save_lustre_params $osts "$brw_size" > $p
11677                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11678                                 error "set 16MB RPC size failed"
11679
11680                         echo "remount client to enable new RPC size"
11681                         remount_client $MOUNT || error "remount_client failed"
11682                 fi
11683
11684                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11685                 # should be able to set brw_size=12, but no rpc_stats for that
11686                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11687         fi
11688
11689         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11690
11691         if [[ $orig_mb -lt 16 ]]; then
11692                 restore_lustre_params < $p
11693                 remount_client $MOUNT || error "remount_client restore failed"
11694         fi
11695
11696         rm -f $p $DIR/$tfile
11697 }
11698 run_test 101g "Big bulk(4/16 MiB) readahead"
11699
11700 test_101h() {
11701         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11702
11703         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11704                 error "dd 70M file failed"
11705         echo Cancel LRU locks on lustre client to flush the client cache
11706         cancel_lru_locks osc
11707
11708         echo "Reset readahead stats"
11709         $LCTL set_param -n llite.*.read_ahead_stats 0
11710
11711         echo "Read 10M of data but cross 64M bundary"
11712         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11713         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11714                      get_named_value 'misses' | calc_sum)
11715         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11716         rm -f $p $DIR/$tfile
11717 }
11718 run_test 101h "Readahead should cover current read window"
11719
11720 test_101i() {
11721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11722                 error "dd 10M file failed"
11723
11724         local max_per_file_mb=$($LCTL get_param -n \
11725                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11726         cancel_lru_locks osc
11727         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11728         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11729                 error "set max_read_ahead_per_file_mb to 1 failed"
11730
11731         echo "Reset readahead stats"
11732         $LCTL set_param llite.*.read_ahead_stats=0
11733
11734         dd if=$DIR/$tfile of=/dev/null bs=2M
11735
11736         $LCTL get_param llite.*.read_ahead_stats
11737         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11738                      awk '/misses/ { print $2 }')
11739         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11740         rm -f $DIR/$tfile
11741 }
11742 run_test 101i "allow current readahead to exceed reservation"
11743
11744 test_101j() {
11745         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11746                 error "setstripe $DIR/$tfile failed"
11747         local file_size=$((1048576 * 16))
11748         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11749         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11750
11751         echo Disable read-ahead
11752         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11753
11754         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11755         for blk in $PAGE_SIZE 1048576 $file_size; do
11756                 cancel_lru_locks osc
11757                 echo "Reset readahead stats"
11758                 $LCTL set_param -n llite.*.read_ahead_stats=0
11759                 local count=$(($file_size / $blk))
11760                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11761                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11762                              get_named_value 'failed.to.fast.read' | calc_sum)
11763                 $LCTL get_param -n llite.*.read_ahead_stats
11764                 [ $miss -eq $count ] || error "expected $count got $miss"
11765         done
11766
11767         rm -f $p $DIR/$tfile
11768 }
11769 run_test 101j "A complete read block should be submitted when no RA"
11770
11771 test_readahead_base() {
11772         local file=$DIR/$tfile
11773         local size=$1
11774         local iosz
11775         local ramax
11776         local ranum
11777
11778         $LCTL set_param -n llite.*.read_ahead_stats=0
11779         # The first page is not accounted into readahead
11780         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11781         iosz=$(((size + 1048575) / 1048576 * 1048576))
11782         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11783
11784         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11785         fallocate -l $size $file || error "failed to fallocate $file"
11786         cancel_lru_locks osc
11787         $MULTIOP $file or${iosz}c || error "failed to read $file"
11788         $LCTL get_param -n llite.*.read_ahead_stats
11789         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11790                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11791         (( $ranum <= $ramax )) ||
11792                 error "read-ahead pages is $ranum more than $ramax"
11793         rm -rf $file || error "failed to remove $file"
11794 }
11795
11796 test_101m()
11797 {
11798         local file=$DIR/$tfile
11799         local ramax
11800         local ranum
11801         local size
11802         local iosz
11803
11804         check_set_fallocate_or_skip
11805         stack_trap "rm -f $file" EXIT
11806
11807         test_readahead_base 4096
11808
11809         # file size: 16K = 16384
11810         test_readahead_base 16384
11811         test_readahead_base 16385
11812         test_readahead_base 16383
11813
11814         # file size: 1M + 1 = 1048576 + 1
11815         test_readahead_base 1048577
11816         # file size: 1M + 16K
11817         test_readahead_base $((1048576 + 16384))
11818
11819         # file size: stripe_size * (stripe_count - 1) + 16K
11820         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11821         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11822         # file size: stripe_size * stripe_count + 16K
11823         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11824         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11825         # file size: 2 * stripe_size * stripe_count + 16K
11826         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11827         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11828 }
11829 run_test 101m "read ahead for small file and last stripe of the file"
11830
11831 setup_test102() {
11832         test_mkdir $DIR/$tdir
11833         chown $RUNAS_ID $DIR/$tdir
11834         STRIPE_SIZE=65536
11835         STRIPE_OFFSET=1
11836         STRIPE_COUNT=$OSTCOUNT
11837         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11838
11839         trap cleanup_test102 EXIT
11840         cd $DIR
11841         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11842         cd $DIR/$tdir
11843         for num in 1 2 3 4; do
11844                 for count in $(seq 1 $STRIPE_COUNT); do
11845                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11846                                 local size=`expr $STRIPE_SIZE \* $num`
11847                                 local file=file"$num-$idx-$count"
11848                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11849                         done
11850                 done
11851         done
11852
11853         cd $DIR
11854         $1 tar cf $TMP/f102.tar $tdir --xattrs
11855 }
11856
11857 cleanup_test102() {
11858         trap 0
11859         rm -f $TMP/f102.tar
11860         rm -rf $DIR/d0.sanity/d102
11861 }
11862
11863 test_102a() {
11864         [ "$UID" != 0 ] && skip "must run as root"
11865         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11866                 skip_env "must have user_xattr"
11867
11868         [ -z "$(which setfattr 2>/dev/null)" ] &&
11869                 skip_env "could not find setfattr"
11870
11871         local testfile=$DIR/$tfile
11872
11873         touch $testfile
11874         echo "set/get xattr..."
11875         setfattr -n trusted.name1 -v value1 $testfile ||
11876                 error "setfattr -n trusted.name1=value1 $testfile failed"
11877         getfattr -n trusted.name1 $testfile 2> /dev/null |
11878           grep "trusted.name1=.value1" ||
11879                 error "$testfile missing trusted.name1=value1"
11880
11881         setfattr -n user.author1 -v author1 $testfile ||
11882                 error "setfattr -n user.author1=author1 $testfile failed"
11883         getfattr -n user.author1 $testfile 2> /dev/null |
11884           grep "user.author1=.author1" ||
11885                 error "$testfile missing trusted.author1=author1"
11886
11887         echo "listxattr..."
11888         setfattr -n trusted.name2 -v value2 $testfile ||
11889                 error "$testfile unable to set trusted.name2"
11890         setfattr -n trusted.name3 -v value3 $testfile ||
11891                 error "$testfile unable to set trusted.name3"
11892         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11893             grep "trusted.name" | wc -l) -eq 3 ] ||
11894                 error "$testfile missing 3 trusted.name xattrs"
11895
11896         setfattr -n user.author2 -v author2 $testfile ||
11897                 error "$testfile unable to set user.author2"
11898         setfattr -n user.author3 -v author3 $testfile ||
11899                 error "$testfile unable to set user.author3"
11900         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11901             grep "user.author" | wc -l) -eq 3 ] ||
11902                 error "$testfile missing 3 user.author xattrs"
11903
11904         echo "remove xattr..."
11905         setfattr -x trusted.name1 $testfile ||
11906                 error "$testfile error deleting trusted.name1"
11907         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11908                 error "$testfile did not delete trusted.name1 xattr"
11909
11910         setfattr -x user.author1 $testfile ||
11911                 error "$testfile error deleting user.author1"
11912         echo "set lustre special xattr ..."
11913         $LFS setstripe -c1 $testfile
11914         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11915                 awk -F "=" '/trusted.lov/ { print $2 }' )
11916         setfattr -n "trusted.lov" -v $lovea $testfile ||
11917                 error "$testfile doesn't ignore setting trusted.lov again"
11918         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11919                 error "$testfile allow setting invalid trusted.lov"
11920         rm -f $testfile
11921 }
11922 run_test 102a "user xattr test =================================="
11923
11924 check_102b_layout() {
11925         local layout="$*"
11926         local testfile=$DIR/$tfile
11927
11928         echo "test layout '$layout'"
11929         $LFS setstripe $layout $testfile || error "setstripe failed"
11930         $LFS getstripe -y $testfile
11931
11932         echo "get/set/list trusted.lov xattr ..." # b=10930
11933         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11934         [[ "$value" =~ "trusted.lov" ]] ||
11935                 error "can't get trusted.lov from $testfile"
11936         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11937                 error "getstripe failed"
11938
11939         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11940
11941         value=$(cut -d= -f2 <<<$value)
11942         # LU-13168: truncated xattr should fail if short lov_user_md header
11943         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11944                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11945         for len in $lens; do
11946                 echo "setfattr $len $testfile.2"
11947                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11948                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11949         done
11950         local stripe_size=$($LFS getstripe -S $testfile.2)
11951         local stripe_count=$($LFS getstripe -c $testfile.2)
11952         [[ $stripe_size -eq 65536 ]] ||
11953                 error "stripe size $stripe_size != 65536"
11954         [[ $stripe_count -eq $stripe_count_orig ]] ||
11955                 error "stripe count $stripe_count != $stripe_count_orig"
11956         rm $testfile $testfile.2
11957 }
11958
11959 test_102b() {
11960         [ -z "$(which setfattr 2>/dev/null)" ] &&
11961                 skip_env "could not find setfattr"
11962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11963
11964         # check plain layout
11965         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11966
11967         # and also check composite layout
11968         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11969
11970 }
11971 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11972
11973 test_102c() {
11974         [ -z "$(which setfattr 2>/dev/null)" ] &&
11975                 skip_env "could not find setfattr"
11976         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11977
11978         # b10930: get/set/list lustre.lov xattr
11979         echo "get/set/list lustre.lov xattr ..."
11980         test_mkdir $DIR/$tdir
11981         chown $RUNAS_ID $DIR/$tdir
11982         local testfile=$DIR/$tdir/$tfile
11983         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11984                 error "setstripe failed"
11985         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11986                 error "getstripe failed"
11987         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11988         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11989
11990         local testfile2=${testfile}2
11991         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11992                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11993
11994         $RUNAS $MCREATE $testfile2
11995         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11996         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11997         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11998         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11999         [ $stripe_count -eq $STRIPECOUNT ] ||
12000                 error "stripe count $stripe_count != $STRIPECOUNT"
12001 }
12002 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12003
12004 compare_stripe_info1() {
12005         local stripe_index_all_zero=true
12006
12007         for num in 1 2 3 4; do
12008                 for count in $(seq 1 $STRIPE_COUNT); do
12009                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12010                                 local size=$((STRIPE_SIZE * num))
12011                                 local file=file"$num-$offset-$count"
12012                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12013                                 [[ $stripe_size -ne $size ]] &&
12014                                     error "$file: size $stripe_size != $size"
12015                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12016                                 # allow fewer stripes to be created, ORI-601
12017                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12018                                     error "$file: count $stripe_count != $count"
12019                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12020                                 [[ $stripe_index -ne 0 ]] &&
12021                                         stripe_index_all_zero=false
12022                         done
12023                 done
12024         done
12025         $stripe_index_all_zero &&
12026                 error "all files are being extracted starting from OST index 0"
12027         return 0
12028 }
12029
12030 have_xattrs_include() {
12031         tar --help | grep -q xattrs-include &&
12032                 echo --xattrs-include="lustre.*"
12033 }
12034
12035 test_102d() {
12036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12037         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12038
12039         XINC=$(have_xattrs_include)
12040         setup_test102
12041         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12042         cd $DIR/$tdir/$tdir
12043         compare_stripe_info1
12044 }
12045 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12046
12047 test_102f() {
12048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12050
12051         XINC=$(have_xattrs_include)
12052         setup_test102
12053         test_mkdir $DIR/$tdir.restore
12054         cd $DIR
12055         tar cf - --xattrs $tdir | tar xf - \
12056                 -C $DIR/$tdir.restore --xattrs $XINC
12057         cd $DIR/$tdir.restore/$tdir
12058         compare_stripe_info1
12059 }
12060 run_test 102f "tar copy files, not keep osts"
12061
12062 grow_xattr() {
12063         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12064                 skip "must have user_xattr"
12065         [ -z "$(which setfattr 2>/dev/null)" ] &&
12066                 skip_env "could not find setfattr"
12067         [ -z "$(which getfattr 2>/dev/null)" ] &&
12068                 skip_env "could not find getfattr"
12069
12070         local xsize=${1:-1024}  # in bytes
12071         local file=$DIR/$tfile
12072         local value="$(generate_string $xsize)"
12073         local xbig=trusted.big
12074         local toobig=$2
12075
12076         touch $file
12077         log "save $xbig on $file"
12078         if [ -z "$toobig" ]
12079         then
12080                 setfattr -n $xbig -v $value $file ||
12081                         error "saving $xbig on $file failed"
12082         else
12083                 setfattr -n $xbig -v $value $file &&
12084                         error "saving $xbig on $file succeeded"
12085                 return 0
12086         fi
12087
12088         local orig=$(get_xattr_value $xbig $file)
12089         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12090
12091         local xsml=trusted.sml
12092         log "save $xsml on $file"
12093         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12094
12095         local new=$(get_xattr_value $xbig $file)
12096         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12097
12098         log "grow $xsml on $file"
12099         setfattr -n $xsml -v "$value" $file ||
12100                 error "growing $xsml on $file failed"
12101
12102         new=$(get_xattr_value $xbig $file)
12103         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12104         log "$xbig still valid after growing $xsml"
12105
12106         rm -f $file
12107 }
12108
12109 test_102h() { # bug 15777
12110         grow_xattr 1024
12111 }
12112 run_test 102h "grow xattr from inside inode to external block"
12113
12114 test_102ha() {
12115         large_xattr_enabled || skip_env "ea_inode feature disabled"
12116
12117         echo "setting xattr of max xattr size: $(max_xattr_size)"
12118         grow_xattr $(max_xattr_size)
12119
12120         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12121         echo "This should fail:"
12122         grow_xattr $(($(max_xattr_size) + 10)) 1
12123 }
12124 run_test 102ha "grow xattr from inside inode to external inode"
12125
12126 test_102i() { # bug 17038
12127         [ -z "$(which getfattr 2>/dev/null)" ] &&
12128                 skip "could not find getfattr"
12129
12130         touch $DIR/$tfile
12131         ln -s $DIR/$tfile $DIR/${tfile}link
12132         getfattr -n trusted.lov $DIR/$tfile ||
12133                 error "lgetxattr on $DIR/$tfile failed"
12134         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12135                 grep -i "no such attr" ||
12136                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12137         rm -f $DIR/$tfile $DIR/${tfile}link
12138 }
12139 run_test 102i "lgetxattr test on symbolic link ============"
12140
12141 test_102j() {
12142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12143         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12144
12145         XINC=$(have_xattrs_include)
12146         setup_test102 "$RUNAS"
12147         chown $RUNAS_ID $DIR/$tdir
12148         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12149         cd $DIR/$tdir/$tdir
12150         compare_stripe_info1 "$RUNAS"
12151 }
12152 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12153
12154 test_102k() {
12155         [ -z "$(which setfattr 2>/dev/null)" ] &&
12156                 skip "could not find setfattr"
12157
12158         touch $DIR/$tfile
12159         # b22187 just check that does not crash for regular file.
12160         setfattr -n trusted.lov $DIR/$tfile
12161         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12162         local test_kdir=$DIR/$tdir
12163         test_mkdir $test_kdir
12164         local default_size=$($LFS getstripe -S $test_kdir)
12165         local default_count=$($LFS getstripe -c $test_kdir)
12166         local default_offset=$($LFS getstripe -i $test_kdir)
12167         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12168                 error 'dir setstripe failed'
12169         setfattr -n trusted.lov $test_kdir
12170         local stripe_size=$($LFS getstripe -S $test_kdir)
12171         local stripe_count=$($LFS getstripe -c $test_kdir)
12172         local stripe_offset=$($LFS getstripe -i $test_kdir)
12173         [ $stripe_size -eq $default_size ] ||
12174                 error "stripe size $stripe_size != $default_size"
12175         [ $stripe_count -eq $default_count ] ||
12176                 error "stripe count $stripe_count != $default_count"
12177         [ $stripe_offset -eq $default_offset ] ||
12178                 error "stripe offset $stripe_offset != $default_offset"
12179         rm -rf $DIR/$tfile $test_kdir
12180 }
12181 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12182
12183 test_102l() {
12184         [ -z "$(which getfattr 2>/dev/null)" ] &&
12185                 skip "could not find getfattr"
12186
12187         # LU-532 trusted. xattr is invisible to non-root
12188         local testfile=$DIR/$tfile
12189
12190         touch $testfile
12191
12192         echo "listxattr as user..."
12193         chown $RUNAS_ID $testfile
12194         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12195             grep -q "trusted" &&
12196                 error "$testfile trusted xattrs are user visible"
12197
12198         return 0;
12199 }
12200 run_test 102l "listxattr size test =================================="
12201
12202 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12203         local path=$DIR/$tfile
12204         touch $path
12205
12206         listxattr_size_check $path || error "listattr_size_check $path failed"
12207 }
12208 run_test 102m "Ensure listxattr fails on small bufffer ========"
12209
12210 cleanup_test102
12211
12212 getxattr() { # getxattr path name
12213         # Return the base64 encoding of the value of xattr name on path.
12214         local path=$1
12215         local name=$2
12216
12217         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12218         # file: $path
12219         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12220         #
12221         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12222
12223         getfattr --absolute-names --encoding=base64 --name=$name $path |
12224                 awk -F= -v name=$name '$1 == name {
12225                         print substr($0, index($0, "=") + 1);
12226         }'
12227 }
12228
12229 test_102n() { # LU-4101 mdt: protect internal xattrs
12230         [ -z "$(which setfattr 2>/dev/null)" ] &&
12231                 skip "could not find setfattr"
12232         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12233         then
12234                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12235         fi
12236
12237         local file0=$DIR/$tfile.0
12238         local file1=$DIR/$tfile.1
12239         local xattr0=$TMP/$tfile.0
12240         local xattr1=$TMP/$tfile.1
12241         local namelist="lov lma lmv link fid version som hsm"
12242         local name
12243         local value
12244
12245         rm -rf $file0 $file1 $xattr0 $xattr1
12246         touch $file0 $file1
12247
12248         # Get 'before' xattrs of $file1.
12249         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12250
12251         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12252                 namelist+=" lfsck_namespace"
12253         for name in $namelist; do
12254                 # Try to copy xattr from $file0 to $file1.
12255                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12256
12257                 setfattr --name=trusted.$name --value="$value" $file1 ||
12258                         error "setxattr 'trusted.$name' failed"
12259
12260                 # Try to set a garbage xattr.
12261                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12262
12263                 if [[ x$name == "xlov" ]]; then
12264                         setfattr --name=trusted.lov --value="$value" $file1 &&
12265                         error "setxattr invalid 'trusted.lov' success"
12266                 else
12267                         setfattr --name=trusted.$name --value="$value" $file1 ||
12268                                 error "setxattr invalid 'trusted.$name' failed"
12269                 fi
12270
12271                 # Try to remove the xattr from $file1. We don't care if this
12272                 # appears to succeed or fail, we just don't want there to be
12273                 # any changes or crashes.
12274                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12275         done
12276
12277         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12278         then
12279                 name="lfsck_ns"
12280                 # Try to copy xattr from $file0 to $file1.
12281                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12282
12283                 setfattr --name=trusted.$name --value="$value" $file1 ||
12284                         error "setxattr 'trusted.$name' failed"
12285
12286                 # Try to set a garbage xattr.
12287                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12288
12289                 setfattr --name=trusted.$name --value="$value" $file1 ||
12290                         error "setxattr 'trusted.$name' failed"
12291
12292                 # Try to remove the xattr from $file1. We don't care if this
12293                 # appears to succeed or fail, we just don't want there to be
12294                 # any changes or crashes.
12295                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12296         fi
12297
12298         # Get 'after' xattrs of file1.
12299         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12300
12301         if ! diff $xattr0 $xattr1; then
12302                 error "before and after xattrs of '$file1' differ"
12303         fi
12304
12305         rm -rf $file0 $file1 $xattr0 $xattr1
12306
12307         return 0
12308 }
12309 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12310
12311 test_102p() { # LU-4703 setxattr did not check ownership
12312         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12313                 skip "MDS needs to be at least 2.5.56"
12314
12315         local testfile=$DIR/$tfile
12316
12317         touch $testfile
12318
12319         echo "setfacl as user..."
12320         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12321         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12322
12323         echo "setfattr as user..."
12324         setfacl -m "u:$RUNAS_ID:---" $testfile
12325         $RUNAS setfattr -x system.posix_acl_access $testfile
12326         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12327 }
12328 run_test 102p "check setxattr(2) correctly fails without permission"
12329
12330 test_102q() {
12331         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12332                 skip "MDS needs to be at least 2.6.92"
12333
12334         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12335 }
12336 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12337
12338 test_102r() {
12339         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12340                 skip "MDS needs to be at least 2.6.93"
12341
12342         touch $DIR/$tfile || error "touch"
12343         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12344         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12345         rm $DIR/$tfile || error "rm"
12346
12347         #normal directory
12348         mkdir -p $DIR/$tdir || error "mkdir"
12349         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12350         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12351         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12352                 error "$testfile error deleting user.author1"
12353         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12354                 grep "user.$(basename $tdir)" &&
12355                 error "$tdir did not delete user.$(basename $tdir)"
12356         rmdir $DIR/$tdir || error "rmdir"
12357
12358         #striped directory
12359         test_mkdir $DIR/$tdir
12360         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12361         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12362         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12363                 error "$testfile error deleting user.author1"
12364         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12365                 grep "user.$(basename $tdir)" &&
12366                 error "$tdir did not delete user.$(basename $tdir)"
12367         rmdir $DIR/$tdir || error "rm striped dir"
12368 }
12369 run_test 102r "set EAs with empty values"
12370
12371 test_102s() {
12372         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12373                 skip "MDS needs to be at least 2.11.52"
12374
12375         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12376
12377         save_lustre_params client "llite.*.xattr_cache" > $save
12378
12379         for cache in 0 1; do
12380                 lctl set_param llite.*.xattr_cache=$cache
12381
12382                 rm -f $DIR/$tfile
12383                 touch $DIR/$tfile || error "touch"
12384                 for prefix in lustre security system trusted user; do
12385                         # Note getxattr() may fail with 'Operation not
12386                         # supported' or 'No such attribute' depending
12387                         # on prefix and cache.
12388                         getfattr -n $prefix.n102s $DIR/$tfile &&
12389                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12390                 done
12391         done
12392
12393         restore_lustre_params < $save
12394 }
12395 run_test 102s "getting nonexistent xattrs should fail"
12396
12397 test_102t() {
12398         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12399                 skip "MDS needs to be at least 2.11.52"
12400
12401         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12402
12403         save_lustre_params client "llite.*.xattr_cache" > $save
12404
12405         for cache in 0 1; do
12406                 lctl set_param llite.*.xattr_cache=$cache
12407
12408                 for buf_size in 0 256; do
12409                         rm -f $DIR/$tfile
12410                         touch $DIR/$tfile || error "touch"
12411                         setfattr -n user.multiop $DIR/$tfile
12412                         $MULTIOP $DIR/$tfile oa$buf_size ||
12413                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12414                 done
12415         done
12416
12417         restore_lustre_params < $save
12418 }
12419 run_test 102t "zero length xattr values handled correctly"
12420
12421 run_acl_subtest()
12422 {
12423         local test=$LUSTRE/tests/acl/$1.test
12424         local tmp=$(mktemp -t $1-XXXXXX).test
12425         local bin=$2
12426         local dmn=$3
12427         local grp=$4
12428         local nbd=$5
12429         export LANG=C
12430
12431
12432         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12433         local sedgroups="-e s/:users/:$grp/g"
12434         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12435
12436         sed $sedusers $sedgroups < $test > $tmp
12437         stack_trap "rm -f $tmp"
12438         [[ -s $tmp ]] || error "sed failed to create test script"
12439
12440         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12441         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12442 }
12443
12444 test_103a() {
12445         [ "$UID" != 0 ] && skip "must run as root"
12446         $GSS && skip_env "could not run under gss"
12447         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12448                 skip_env "must have acl enabled"
12449         which setfacl || skip_env "could not find setfacl"
12450         remote_mds_nodsh && skip "remote MDS with nodsh"
12451
12452         local mdts=$(comma_list $(mdts_nodes))
12453         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12454
12455         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12456         stack_trap "[[ -z \"$saved\" ]] || \
12457                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12458
12459         ACLBIN=${ACLBIN:-"bin"}
12460         ACLDMN=${ACLDMN:-"daemon"}
12461         ACLGRP=${ACLGRP:-"users"}
12462         ACLNBD=${ACLNBD:-"nobody"}
12463
12464         if ! id $ACLBIN ||
12465            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12466                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12467                 ACLBIN=$USER0
12468                 if ! id $ACLBIN ; then
12469                         cat /etc/passwd
12470                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12471                 fi
12472         fi
12473         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12474            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12475                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12476                 ACLDMN=$USER1
12477                 if ! id $ACLDMN ; then
12478                         cat /etc/passwd
12479                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12480                 fi
12481         fi
12482         if ! getent group $ACLGRP; then
12483                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12484                 ACLGRP="$TSTUSR"
12485                 if ! getent group $ACLGRP; then
12486                         echo "cannot find group '$ACLGRP', adding it"
12487                         cat /etc/group
12488                         add_group 60000 $ACLGRP
12489                 fi
12490         fi
12491
12492         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12493         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12494         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12495
12496         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12497                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12498                 ACLGRP="$TSTUSR"
12499                 if ! getent group $ACLGRP; then
12500                         echo "cannot find group '$ACLGRP', adding it"
12501                         cat /etc/group
12502                         add_group 60000 $ACLGRP
12503                 fi
12504                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12505                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12506                         cat /etc/group
12507                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12508                 fi
12509         fi
12510
12511         gpasswd -a $ACLDMN $ACLBIN ||
12512                 error "setting client group failed"             # LU-5641
12513         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12514                 error "setting MDS group failed"                # LU-5641
12515
12516         declare -a identity_old
12517
12518         for ((num = 1; num <= $MDSCOUNT; num++)); do
12519                 switch_identity $num true || identity_old[$num]=$?
12520         done
12521
12522         SAVE_UMASK=$(umask)
12523         umask 0022
12524         mkdir -p $DIR/$tdir
12525         cd $DIR/$tdir
12526
12527         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12528         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12529         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12530         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12531         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12532         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12533         if ! id -u $ACLNBD ||
12534            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12535                 ACLNBD="nfsnobody"
12536                 if ! id -u $ACLNBD; then
12537                         ACLNBD=""
12538                 fi
12539         fi
12540         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12541                 add_group $(id -u $ACLNBD) $ACLNBD
12542                 if ! getent group $ACLNBD; then
12543                         ACLNBD=""
12544                 fi
12545         fi
12546         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12547            [[ -n "$ACLNBD" ]] && which setfattr; then
12548                 run_acl_subtest permissions_xattr \
12549                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12550         elif [[ -z "$ACLNBD" ]]; then
12551                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12552         else
12553                 echo "skip 'permission_xattr' test - missing setfattr command"
12554         fi
12555         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12556
12557         # inheritance test got from HP
12558         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12559         chmod +x make-tree || error "chmod +x failed"
12560         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12561         rm -f make-tree
12562
12563         echo "LU-974 ignore umask when acl is enabled..."
12564         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12565         if [ $MDSCOUNT -ge 2 ]; then
12566                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12567         fi
12568
12569         echo "LU-2561 newly created file is same size as directory..."
12570         if [ "$mds1_FSTYPE" != "zfs" ]; then
12571                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12572         else
12573                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12574         fi
12575
12576         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12577
12578         cd $SAVE_PWD
12579         umask $SAVE_UMASK
12580
12581         for ((num = 1; num <= $MDSCOUNT; num++)); do
12582                 if [[ "${identity_old[$num]}" == 1 ]]; then
12583                         switch_identity $num false || identity_old[$num]=$?
12584                 fi
12585         done
12586 }
12587 run_test 103a "acl test"
12588
12589 test_103b() {
12590         declare -a pids
12591         local U
12592
12593         stack_trap "rm -f $DIR/$tfile.*"
12594         for U in {0..511}; do
12595                 {
12596                 local O=$(printf "%04o" $U)
12597
12598                 umask $(printf "%04o" $((511 ^ $O)))
12599                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12600                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12601
12602                 (( $S == ($O & 0666) )) ||
12603                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12604
12605                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12606                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12607                 (( $S == ($O & 0666) )) ||
12608                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12609
12610                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12611                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12612                 (( $S == ($O & 0666) )) ||
12613                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12614                 rm -f $DIR/$tfile.[smp]$0
12615                 } &
12616                 local pid=$!
12617
12618                 # limit the concurrently running threads to 64. LU-11878
12619                 local idx=$((U % 64))
12620                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12621                 pids[idx]=$pid
12622         done
12623         wait
12624 }
12625 run_test 103b "umask lfs setstripe"
12626
12627 test_103c() {
12628         mkdir -p $DIR/$tdir
12629         cp -rp $DIR/$tdir $DIR/$tdir.bak
12630
12631         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12632                 error "$DIR/$tdir shouldn't contain default ACL"
12633         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12634                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12635         true
12636 }
12637 run_test 103c "'cp -rp' won't set empty acl"
12638
12639 test_103e() {
12640         local numacl
12641         local fileacl
12642         local saved_debug=$($LCTL get_param -n debug)
12643
12644         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12645                 skip "MDS needs to be at least 2.14.52"
12646
12647         large_xattr_enabled || skip_env "ea_inode feature disabled"
12648
12649         mkdir -p $DIR/$tdir
12650         # add big LOV EA to cause reply buffer overflow earlier
12651         $LFS setstripe -C 1000 $DIR/$tdir
12652         lctl set_param mdc.*-mdc*.stats=clear
12653
12654         $LCTL set_param debug=0
12655         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12656         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12657
12658         # add a large number of default ACLs (expect 8000+ for 2.13+)
12659         for U in {2..7000}; do
12660                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12661                         error "Able to add just $U default ACLs"
12662         done
12663         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12664         echo "$numacl default ACLs created"
12665
12666         stat $DIR/$tdir || error "Cannot stat directory"
12667         # check file creation
12668         touch $DIR/$tdir/$tfile ||
12669                 error "failed to create $tfile with $numacl default ACLs"
12670         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12671         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12672         echo "$fileacl ACLs were inherited"
12673         (( $fileacl == $numacl )) ||
12674                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12675         # check that new ACLs creation adds new ACLs to inherited ACLs
12676         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12677                 error "Cannot set new ACL"
12678         numacl=$((numacl + 1))
12679         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12680         (( $fileacl == $numacl )) ||
12681                 error "failed to add new ACL: $fileacl != $numacl as expected"
12682         # adds more ACLs to a file to reach their maximum at 8000+
12683         numacl=0
12684         for U in {20000..25000}; do
12685                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12686                 numacl=$((numacl + 1))
12687         done
12688         echo "Added $numacl more ACLs to the file"
12689         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12690         echo "Total $fileacl ACLs in file"
12691         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12692         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12693         rmdir $DIR/$tdir || error "Cannot remove directory"
12694 }
12695 run_test 103e "inheritance of big amount of default ACLs"
12696
12697 test_103f() {
12698         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12699                 skip "MDS needs to be at least 2.14.51"
12700
12701         large_xattr_enabled || skip_env "ea_inode feature disabled"
12702
12703         # enable changelog to consume more internal MDD buffers
12704         changelog_register
12705
12706         mkdir -p $DIR/$tdir
12707         # add big LOV EA
12708         $LFS setstripe -C 1000 $DIR/$tdir
12709         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12710         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12711         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12712         rmdir $DIR/$tdir || error "Cannot remove directory"
12713 }
12714 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12715
12716 test_104a() {
12717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12718
12719         touch $DIR/$tfile
12720         lfs df || error "lfs df failed"
12721         lfs df -ih || error "lfs df -ih failed"
12722         lfs df -h $DIR || error "lfs df -h $DIR failed"
12723         lfs df -i $DIR || error "lfs df -i $DIR failed"
12724         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12725         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12726
12727         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12728         lctl --device %$OSC deactivate
12729         lfs df || error "lfs df with deactivated OSC failed"
12730         lctl --device %$OSC activate
12731         # wait the osc back to normal
12732         wait_osc_import_ready client ost
12733
12734         lfs df || error "lfs df with reactivated OSC failed"
12735         rm -f $DIR/$tfile
12736 }
12737 run_test 104a "lfs df [-ih] [path] test ========================="
12738
12739 test_104b() {
12740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12741         [ $RUNAS_ID -eq $UID ] &&
12742                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12743
12744         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12745                         grep "Permission denied" | wc -l)))
12746         if [ $denied_cnt -ne 0 ]; then
12747                 error "lfs check servers test failed"
12748         fi
12749 }
12750 run_test 104b "$RUNAS lfs check servers test ===================="
12751
12752 #
12753 # Verify $1 is within range of $2.
12754 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12755 # $1 is <= 2% of $2. Else Fail.
12756 #
12757 value_in_range() {
12758         # Strip all units (M, G, T)
12759         actual=$(echo $1 | tr -d A-Z)
12760         expect=$(echo $2 | tr -d A-Z)
12761
12762         expect_lo=$(($expect * 98 / 100)) # 2% below
12763         expect_hi=$(($expect * 102 / 100)) # 2% above
12764
12765         # permit 2% drift above and below
12766         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12767 }
12768
12769 test_104c() {
12770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12771         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12772
12773         local ost_param="osd-zfs.$FSNAME-OST0000."
12774         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12775         local ofacets=$(get_facets OST)
12776         local mfacets=$(get_facets MDS)
12777         local saved_ost_blocks=
12778         local saved_mdt_blocks=
12779
12780         echo "Before recordsize change"
12781         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12782         df=($(df -h | grep "$MOUNT"$))
12783
12784         # For checking.
12785         echo "lfs output : ${lfs_df[*]}"
12786         echo "df  output : ${df[*]}"
12787
12788         for facet in ${ofacets//,/ }; do
12789                 if [ -z $saved_ost_blocks ]; then
12790                         saved_ost_blocks=$(do_facet $facet \
12791                                 lctl get_param -n $ost_param.blocksize)
12792                         echo "OST Blocksize: $saved_ost_blocks"
12793                 fi
12794                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12795                 do_facet $facet zfs set recordsize=32768 $ost
12796         done
12797
12798         # BS too small. Sufficient for functional testing.
12799         for facet in ${mfacets//,/ }; do
12800                 if [ -z $saved_mdt_blocks ]; then
12801                         saved_mdt_blocks=$(do_facet $facet \
12802                                 lctl get_param -n $mdt_param.blocksize)
12803                         echo "MDT Blocksize: $saved_mdt_blocks"
12804                 fi
12805                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12806                 do_facet $facet zfs set recordsize=32768 $mdt
12807         done
12808
12809         # Give new values chance to reflect change
12810         sleep 2
12811
12812         echo "After recordsize change"
12813         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12814         df_after=($(df -h | grep "$MOUNT"$))
12815
12816         # For checking.
12817         echo "lfs output : ${lfs_df_after[*]}"
12818         echo "df  output : ${df_after[*]}"
12819
12820         # Verify lfs df
12821         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12822                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12823         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12824                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12825         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12826                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12827
12828         # Verify df
12829         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12830                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12831         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12832                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12833         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12834                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12835
12836         # Restore MDT recordize back to original
12837         for facet in ${mfacets//,/ }; do
12838                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12839                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12840         done
12841
12842         # Restore OST recordize back to original
12843         for facet in ${ofacets//,/ }; do
12844                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12845                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12846         done
12847
12848         return 0
12849 }
12850 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12851
12852 test_104d() {
12853         (( $RUNAS_ID != $UID )) ||
12854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12855
12856         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12857                 skip "lustre version doesn't support lctl dl with non-root"
12858
12859         # debugfs only allows root users to access files, so the
12860         # previous move of the "devices" file to debugfs broke
12861         # "lctl dl" for non-root users. The LU-9680 Netlink
12862         # interface again allows non-root users to list devices.
12863         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12864                 error "lctl dl doesn't work for non root"
12865
12866         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12867         [ "$ost_count" -eq $OSTCOUNT ]  ||
12868                 error "lctl dl reports wrong number of OST devices"
12869
12870         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12871         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12872                 error "lctl dl reports wrong number of MDT devices"
12873 }
12874 run_test 104d "$RUNAS lctl dl test"
12875
12876 test_105a() {
12877         # doesn't work on 2.4 kernels
12878         touch $DIR/$tfile
12879         if $(flock_is_enabled); then
12880                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12881         else
12882                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12883         fi
12884         rm -f $DIR/$tfile
12885 }
12886 run_test 105a "flock when mounted without -o flock test ========"
12887
12888 test_105b() {
12889         touch $DIR/$tfile
12890         if $(flock_is_enabled); then
12891                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12892         else
12893                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12894         fi
12895         rm -f $DIR/$tfile
12896 }
12897 run_test 105b "fcntl when mounted without -o flock test ========"
12898
12899 test_105c() {
12900         touch $DIR/$tfile
12901         if $(flock_is_enabled); then
12902                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12903         else
12904                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12905         fi
12906         rm -f $DIR/$tfile
12907 }
12908 run_test 105c "lockf when mounted without -o flock test"
12909
12910 test_105d() { # bug 15924
12911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12912
12913         test_mkdir $DIR/$tdir
12914         flock_is_enabled || skip_env "mount w/o flock enabled"
12915         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12916         $LCTL set_param fail_loc=0x80000315
12917         flocks_test 2 $DIR/$tdir
12918 }
12919 run_test 105d "flock race (should not freeze) ========"
12920
12921 test_105e() { # bug 22660 && 22040
12922         flock_is_enabled || skip_env "mount w/o flock enabled"
12923
12924         touch $DIR/$tfile
12925         flocks_test 3 $DIR/$tfile
12926 }
12927 run_test 105e "Two conflicting flocks from same process"
12928
12929 test_106() { #bug 10921
12930         test_mkdir $DIR/$tdir
12931         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12932         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12933 }
12934 run_test 106 "attempt exec of dir followed by chown of that dir"
12935
12936 test_107() {
12937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12938
12939         CDIR=`pwd`
12940         local file=core
12941
12942         cd $DIR
12943         rm -f $file
12944
12945         local save_pattern=$(sysctl -n kernel.core_pattern)
12946         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12947         sysctl -w kernel.core_pattern=$file
12948         sysctl -w kernel.core_uses_pid=0
12949
12950         ulimit -c unlimited
12951         sleep 60 &
12952         SLEEPPID=$!
12953
12954         sleep 1
12955
12956         kill -s 11 $SLEEPPID
12957         wait $SLEEPPID
12958         if [ -e $file ]; then
12959                 size=`stat -c%s $file`
12960                 [ $size -eq 0 ] && error "Fail to create core file $file"
12961         else
12962                 error "Fail to create core file $file"
12963         fi
12964         rm -f $file
12965         sysctl -w kernel.core_pattern=$save_pattern
12966         sysctl -w kernel.core_uses_pid=$save_uses_pid
12967         cd $CDIR
12968 }
12969 run_test 107 "Coredump on SIG"
12970
12971 test_110() {
12972         test_mkdir $DIR/$tdir
12973         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12974         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12975                 error "mkdir with 256 char should fail, but did not"
12976         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12977                 error "create with 255 char failed"
12978         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12979                 error "create with 256 char should fail, but did not"
12980
12981         ls -l $DIR/$tdir
12982         rm -rf $DIR/$tdir
12983 }
12984 run_test 110 "filename length checking"
12985
12986 test_116a() { # was previously test_116()
12987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12989         remote_mds_nodsh && skip "remote MDS with nodsh"
12990
12991         echo -n "Free space priority "
12992         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12993                 head -n1
12994         declare -a AVAIL
12995         free_min_max
12996
12997         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12998         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12999         stack_trap simple_cleanup_common
13000
13001         # Check if we need to generate uneven OSTs
13002         test_mkdir -p $DIR/$tdir/OST${MINI}
13003         local FILL=$((MINV / 4))
13004         local DIFF=$((MAXV - MINV))
13005         local DIFF2=$((DIFF * 100 / MINV))
13006
13007         local threshold=$(do_facet $SINGLEMDS \
13008                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13009         threshold=${threshold%%%}
13010         echo -n "Check for uneven OSTs: "
13011         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13012
13013         if [[ $DIFF2 -gt $threshold ]]; then
13014                 echo "ok"
13015                 echo "Don't need to fill OST$MINI"
13016         else
13017                 # generate uneven OSTs. Write 2% over the QOS threshold value
13018                 echo "no"
13019                 DIFF=$((threshold - DIFF2 + 2))
13020                 DIFF2=$((MINV * DIFF / 100))
13021                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13022                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13023                         error "setstripe failed"
13024                 DIFF=$((DIFF2 / 2048))
13025                 i=0
13026                 while [ $i -lt $DIFF ]; do
13027                         i=$((i + 1))
13028                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13029                                 bs=2M count=1 2>/dev/null
13030                         echo -n .
13031                 done
13032                 echo .
13033                 sync
13034                 sleep_maxage
13035                 free_min_max
13036         fi
13037
13038         DIFF=$((MAXV - MINV))
13039         DIFF2=$((DIFF * 100 / MINV))
13040         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13041         if [ $DIFF2 -gt $threshold ]; then
13042                 echo "ok"
13043         else
13044                 skip "QOS imbalance criteria not met"
13045         fi
13046
13047         MINI1=$MINI
13048         MINV1=$MINV
13049         MAXI1=$MAXI
13050         MAXV1=$MAXV
13051
13052         # now fill using QOS
13053         $LFS setstripe -c 1 $DIR/$tdir
13054         FILL=$((FILL / 200))
13055         if [ $FILL -gt 600 ]; then
13056                 FILL=600
13057         fi
13058         echo "writing $FILL files to QOS-assigned OSTs"
13059         i=0
13060         while [ $i -lt $FILL ]; do
13061                 i=$((i + 1))
13062                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13063                         count=1 2>/dev/null
13064                 echo -n .
13065         done
13066         echo "wrote $i 200k files"
13067         sync
13068         sleep_maxage
13069
13070         echo "Note: free space may not be updated, so measurements might be off"
13071         free_min_max
13072         DIFF2=$((MAXV - MINV))
13073         echo "free space delta: orig $DIFF final $DIFF2"
13074         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13075         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13076         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13077         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13078         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13079         if [[ $DIFF -gt 0 ]]; then
13080                 FILL=$((DIFF2 * 100 / DIFF - 100))
13081                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13082         fi
13083
13084         # Figure out which files were written where
13085         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13086                awk '/'$MINI1': / {print $2; exit}')
13087         echo $UUID
13088         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13089         echo "$MINC files created on smaller OST $MINI1"
13090         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13091                awk '/'$MAXI1': / {print $2; exit}')
13092         echo $UUID
13093         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13094         echo "$MAXC files created on larger OST $MAXI1"
13095         if [[ $MINC -gt 0 ]]; then
13096                 FILL=$((MAXC * 100 / MINC - 100))
13097                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13098         fi
13099         [[ $MAXC -gt $MINC ]] ||
13100                 error_ignore LU-9 "stripe QOS didn't balance free space"
13101 }
13102 run_test 116a "stripe QOS: free space balance ==================="
13103
13104 test_116b() { # LU-2093
13105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13106         remote_mds_nodsh && skip "remote MDS with nodsh"
13107
13108 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13109         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13110                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13111         [ -z "$old_rr" ] && skip "no QOS"
13112         do_facet $SINGLEMDS lctl set_param \
13113                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13114         mkdir -p $DIR/$tdir
13115         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13116         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13117         do_facet $SINGLEMDS lctl set_param fail_loc=0
13118         rm -rf $DIR/$tdir
13119         do_facet $SINGLEMDS lctl set_param \
13120                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13121 }
13122 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13123
13124 test_117() # bug 10891
13125 {
13126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13127
13128         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13129         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13130         lctl set_param fail_loc=0x21e
13131         > $DIR/$tfile || error "truncate failed"
13132         lctl set_param fail_loc=0
13133         echo "Truncate succeeded."
13134         rm -f $DIR/$tfile
13135 }
13136 run_test 117 "verify osd extend =========="
13137
13138 NO_SLOW_RESENDCOUNT=4
13139 export OLD_RESENDCOUNT=""
13140 set_resend_count () {
13141         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13142         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13143         lctl set_param -n $PROC_RESENDCOUNT $1
13144         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13145 }
13146
13147 # for reduce test_118* time (b=14842)
13148 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13149
13150 # Reset async IO behavior after error case
13151 reset_async() {
13152         FILE=$DIR/reset_async
13153
13154         # Ensure all OSCs are cleared
13155         $LFS setstripe -c -1 $FILE
13156         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13157         sync
13158         rm $FILE
13159 }
13160
13161 test_118a() #bug 11710
13162 {
13163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13164
13165         reset_async
13166
13167         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13168         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13169         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13170
13171         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13172                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13173                 return 1;
13174         fi
13175         rm -f $DIR/$tfile
13176 }
13177 run_test 118a "verify O_SYNC works =========="
13178
13179 test_118b()
13180 {
13181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13182         remote_ost_nodsh && skip "remote OST with nodsh"
13183
13184         reset_async
13185
13186         #define OBD_FAIL_SRV_ENOENT 0x217
13187         set_nodes_failloc "$(osts_nodes)" 0x217
13188         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13189         RC=$?
13190         set_nodes_failloc "$(osts_nodes)" 0
13191         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13192         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13193                     grep -c writeback)
13194
13195         if [[ $RC -eq 0 ]]; then
13196                 error "Must return error due to dropped pages, rc=$RC"
13197                 return 1;
13198         fi
13199
13200         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13201                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13202                 return 1;
13203         fi
13204
13205         echo "Dirty pages not leaked on ENOENT"
13206
13207         # Due to the above error the OSC will issue all RPCs syncronously
13208         # until a subsequent RPC completes successfully without error.
13209         $MULTIOP $DIR/$tfile Ow4096yc
13210         rm -f $DIR/$tfile
13211
13212         return 0
13213 }
13214 run_test 118b "Reclaim dirty pages on fatal error =========="
13215
13216 test_118c()
13217 {
13218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13219
13220         # for 118c, restore the original resend count, LU-1940
13221         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13222                                 set_resend_count $OLD_RESENDCOUNT
13223         remote_ost_nodsh && skip "remote OST with nodsh"
13224
13225         reset_async
13226
13227         #define OBD_FAIL_OST_EROFS               0x216
13228         set_nodes_failloc "$(osts_nodes)" 0x216
13229
13230         # multiop should block due to fsync until pages are written
13231         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13232         MULTIPID=$!
13233         sleep 1
13234
13235         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13236                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13237         fi
13238
13239         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13240                     grep -c writeback)
13241         if [[ $WRITEBACK -eq 0 ]]; then
13242                 error "No page in writeback, writeback=$WRITEBACK"
13243         fi
13244
13245         set_nodes_failloc "$(osts_nodes)" 0
13246         wait $MULTIPID
13247         RC=$?
13248         if [[ $RC -ne 0 ]]; then
13249                 error "Multiop fsync failed, rc=$RC"
13250         fi
13251
13252         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13253         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13254                     grep -c writeback)
13255         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13256                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13257         fi
13258
13259         rm -f $DIR/$tfile
13260         echo "Dirty pages flushed via fsync on EROFS"
13261         return 0
13262 }
13263 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13264
13265 # continue to use small resend count to reduce test_118* time (b=14842)
13266 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13267
13268 test_118d()
13269 {
13270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13271         remote_ost_nodsh && skip "remote OST with nodsh"
13272
13273         reset_async
13274
13275         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13276         set_nodes_failloc "$(osts_nodes)" 0x214
13277         # multiop should block due to fsync until pages are written
13278         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13279         MULTIPID=$!
13280         sleep 1
13281
13282         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13283                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13284         fi
13285
13286         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13287                     grep -c writeback)
13288         if [[ $WRITEBACK -eq 0 ]]; then
13289                 error "No page in writeback, writeback=$WRITEBACK"
13290         fi
13291
13292         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13293         set_nodes_failloc "$(osts_nodes)" 0
13294
13295         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13296         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13297                     grep -c writeback)
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 "Dirty pages gaurenteed flushed via fsync"
13304         return 0
13305 }
13306 run_test 118d "Fsync validation inject a delay of the bulk =========="
13307
13308 test_118f() {
13309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13310
13311         reset_async
13312
13313         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13314         lctl set_param fail_loc=0x8000040a
13315
13316         # Should simulate EINVAL error which is fatal
13317         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13318         RC=$?
13319         if [[ $RC -eq 0 ]]; then
13320                 error "Must return error due to dropped pages, rc=$RC"
13321         fi
13322
13323         lctl set_param fail_loc=0x0
13324
13325         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13326         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13327         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13328                     grep -c writeback)
13329         if [[ $LOCKED -ne 0 ]]; then
13330                 error "Locked pages remain in cache, locked=$LOCKED"
13331         fi
13332
13333         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13334                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13335         fi
13336
13337         rm -f $DIR/$tfile
13338         echo "No pages locked after fsync"
13339
13340         reset_async
13341         return 0
13342 }
13343 run_test 118f "Simulate unrecoverable OSC side error =========="
13344
13345 test_118g() {
13346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13347
13348         reset_async
13349
13350         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13351         lctl set_param fail_loc=0x406
13352
13353         # simulate local -ENOMEM
13354         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13355         RC=$?
13356
13357         lctl set_param fail_loc=0
13358         if [[ $RC -eq 0 ]]; then
13359                 error "Must return error due to dropped pages, rc=$RC"
13360         fi
13361
13362         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13363         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13364         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13365                         grep -c writeback)
13366         if [[ $LOCKED -ne 0 ]]; then
13367                 error "Locked pages remain in cache, locked=$LOCKED"
13368         fi
13369
13370         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13371                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13372         fi
13373
13374         rm -f $DIR/$tfile
13375         echo "No pages locked after fsync"
13376
13377         reset_async
13378         return 0
13379 }
13380 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13381
13382 test_118h() {
13383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13384         remote_ost_nodsh && skip "remote OST with nodsh"
13385
13386         reset_async
13387
13388         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13389         set_nodes_failloc "$(osts_nodes)" 0x20e
13390         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13391         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13392         RC=$?
13393
13394         set_nodes_failloc "$(osts_nodes)" 0
13395         if [[ $RC -eq 0 ]]; then
13396                 error "Must return error due to dropped pages, rc=$RC"
13397         fi
13398
13399         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13400         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13401         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13402                     grep -c writeback)
13403         if [[ $LOCKED -ne 0 ]]; then
13404                 error "Locked pages remain in cache, locked=$LOCKED"
13405         fi
13406
13407         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13408                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13409         fi
13410
13411         rm -f $DIR/$tfile
13412         echo "No pages locked after fsync"
13413
13414         return 0
13415 }
13416 run_test 118h "Verify timeout in handling recoverables errors  =========="
13417
13418 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13419
13420 test_118i() {
13421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13422         remote_ost_nodsh && skip "remote OST with nodsh"
13423
13424         reset_async
13425
13426         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13427         set_nodes_failloc "$(osts_nodes)" 0x20e
13428
13429         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13430         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13431         PID=$!
13432         sleep 5
13433         set_nodes_failloc "$(osts_nodes)" 0
13434
13435         wait $PID
13436         RC=$?
13437         if [[ $RC -ne 0 ]]; then
13438                 error "got error, but should be not, rc=$RC"
13439         fi
13440
13441         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13442         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13443         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13444         if [[ $LOCKED -ne 0 ]]; then
13445                 error "Locked pages remain in cache, locked=$LOCKED"
13446         fi
13447
13448         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13449                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13450         fi
13451
13452         rm -f $DIR/$tfile
13453         echo "No pages locked after fsync"
13454
13455         return 0
13456 }
13457 run_test 118i "Fix error before timeout in recoverable error  =========="
13458
13459 [ "$SLOW" = "no" ] && set_resend_count 4
13460
13461 test_118j() {
13462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13463         remote_ost_nodsh && skip "remote OST with nodsh"
13464
13465         reset_async
13466
13467         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13468         set_nodes_failloc "$(osts_nodes)" 0x220
13469
13470         # return -EIO from OST
13471         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13472         RC=$?
13473         set_nodes_failloc "$(osts_nodes)" 0x0
13474         if [[ $RC -eq 0 ]]; then
13475                 error "Must return error due to dropped pages, rc=$RC"
13476         fi
13477
13478         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13479         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13480         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13481         if [[ $LOCKED -ne 0 ]]; then
13482                 error "Locked pages remain in cache, locked=$LOCKED"
13483         fi
13484
13485         # in recoverable error on OST we want resend and stay until it finished
13486         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13487                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13488         fi
13489
13490         rm -f $DIR/$tfile
13491         echo "No pages locked after fsync"
13492
13493         return 0
13494 }
13495 run_test 118j "Simulate unrecoverable OST side error =========="
13496
13497 test_118k()
13498 {
13499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13500         remote_ost_nodsh && skip "remote OSTs with nodsh"
13501
13502         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13503         set_nodes_failloc "$(osts_nodes)" 0x20e
13504         test_mkdir $DIR/$tdir
13505
13506         for ((i=0;i<10;i++)); do
13507                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13508                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13509                 SLEEPPID=$!
13510                 sleep 0.500s
13511                 kill $SLEEPPID
13512                 wait $SLEEPPID
13513         done
13514
13515         set_nodes_failloc "$(osts_nodes)" 0
13516         rm -rf $DIR/$tdir
13517 }
13518 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13519
13520 test_118l() # LU-646
13521 {
13522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13523
13524         test_mkdir $DIR/$tdir
13525         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13526         rm -rf $DIR/$tdir
13527 }
13528 run_test 118l "fsync dir"
13529
13530 test_118m() # LU-3066
13531 {
13532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13533
13534         test_mkdir $DIR/$tdir
13535         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13536         rm -rf $DIR/$tdir
13537 }
13538 run_test 118m "fdatasync dir ========="
13539
13540 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13541
13542 test_118n()
13543 {
13544         local begin
13545         local end
13546
13547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13548         remote_ost_nodsh && skip "remote OSTs with nodsh"
13549
13550         # Sleep to avoid a cached response.
13551         #define OBD_STATFS_CACHE_SECONDS 1
13552         sleep 2
13553
13554         # Inject a 10 second delay in the OST_STATFS handler.
13555         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13556         set_nodes_failloc "$(osts_nodes)" 0x242
13557
13558         begin=$SECONDS
13559         stat --file-system $MOUNT > /dev/null
13560         end=$SECONDS
13561
13562         set_nodes_failloc "$(osts_nodes)" 0
13563
13564         if ((end - begin > 20)); then
13565             error "statfs took $((end - begin)) seconds, expected 10"
13566         fi
13567 }
13568 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13569
13570 test_119a() # bug 11737
13571 {
13572         BSIZE=$((512 * 1024))
13573         directio write $DIR/$tfile 0 1 $BSIZE
13574         # We ask to read two blocks, which is more than a file size.
13575         # directio will indicate an error when requested and actual
13576         # sizes aren't equeal (a normal situation in this case) and
13577         # print actual read amount.
13578         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13579         if [ "$NOB" != "$BSIZE" ]; then
13580                 error "read $NOB bytes instead of $BSIZE"
13581         fi
13582         rm -f $DIR/$tfile
13583 }
13584 run_test 119a "Short directIO read must return actual read amount"
13585
13586 test_119b() # bug 11737
13587 {
13588         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13589
13590         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13591         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13592         sync
13593         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13594                 error "direct read failed"
13595         rm -f $DIR/$tfile
13596 }
13597 run_test 119b "Sparse directIO read must return actual read amount"
13598
13599 test_119c() # bug 13099
13600 {
13601         BSIZE=1048576
13602         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13603         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13604         rm -f $DIR/$tfile
13605 }
13606 run_test 119c "Testing for direct read hitting hole"
13607
13608 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13609 # Maloo test history
13610
13611 test_119e()
13612 {
13613         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13614                 skip "Need server version at least 2.15.58"
13615         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13616
13617         local stripe_size=$((1024 * 1024)) #1 MiB
13618         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13619         local file_size=$((25 * stripe_size))
13620         local bsizes
13621
13622         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13623         stack_trap "rm -f $DIR/$tfile*"
13624
13625         # Just a bit bigger than the largest size in the test set below
13626         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13627                 error "buffered i/o to create file failed"
13628
13629         # trivial test of unaligned DIO
13630         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13631                 iflag=direct oflag=direct ||
13632                 error "trivial unaligned dio failed"
13633
13634         # Test of disabling unaligned DIO support
13635         $LCTL set_param llite.*.unaligned_dio=0
13636         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13637         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13638         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13639                 iflag=direct oflag=direct &&
13640                 error "unaligned dio succeeded when disabled"
13641         $LCTL set_param llite.*.unaligned_dio=1
13642
13643         # Clean up before next part of test
13644         rm -f $DIR/$tfile.2
13645
13646         if zfs_or_rotational; then
13647                 # DIO on ZFS can take up to 2 seconds per IO
13648                 # rotational is better, but still slow.
13649                 # Limit testing on those media to larger sizes
13650                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13651                         $((stripe_size + 1024))"
13652         else
13653                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13654                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13655                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13656                         $((stripe_size - 1)) $stripe_size \
13657                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13658                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13659         fi
13660
13661         for bs in $bsizes; do
13662                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13663                 echo "Read/write with DIO at size $bs"
13664                 # Read and write with DIO from source to dest
13665                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13666                         iflag=direct oflag=direct ||
13667                         error "dio failed"
13668
13669                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13670                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13671                         error "size incorrect, file copy read/write bsize: $bs"
13672                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13673                         error "files differ, bsize $bs"
13674                 rm -f $DIR/$tfile.2
13675         done
13676 }
13677 run_test 119e "Basic tests of dio read and write at various sizes"
13678
13679 test_119f()
13680 {
13681         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13682
13683         local stripe_size=$((1024 * 1024)) #1 MiB
13684         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13685         local file_size=$((25 * stripe_size))
13686         local bsizes
13687
13688         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13689         stack_trap "rm -f $DIR/$tfile*"
13690
13691         # Just a bit bigger than the largest size in the test set below
13692         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13693                 error "buffered i/o to create file failed"
13694
13695         if zfs_or_rotational; then
13696                 # DIO on ZFS can take up to 2 seconds per IO
13697                 # rotational is better, but still slow.
13698                 # Limit testing on those media to larger sizes
13699                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13700                         $((stripe_size + 1024))"
13701         else
13702                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13703                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13704                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13705                         $((stripe_size - 1)) $stripe_size \
13706                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13707                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13708         fi
13709
13710         for bs in $bsizes; do
13711                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13712                 # Read and write with DIO from source to dest in two
13713                 # threads - should give correct copy of file
13714
13715                 echo "bs: $bs"
13716                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13717                         oflag=direct conv=notrunc &
13718                 pid_dio1=$!
13719                 # Note block size is different here for a more interesting race
13720                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13721                         iflag=direct oflag=direct conv=notrunc &
13722                 pid_dio2=$!
13723                 wait $pid_dio1
13724                 rc1=$?
13725                 wait $pid_dio2
13726                 rc2=$?
13727                 if (( rc1 != 0 )); then
13728                         error "dio copy 1 w/bsize $bs failed: $rc1"
13729                 fi
13730                 if (( rc2 != 0 )); then
13731                         error "dio copy 2 w/bsize $bs failed: $rc2"
13732                 fi
13733
13734
13735                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13736                         error "size incorrect, file copy read/write bsize: $bs"
13737                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13738                         error "files differ, bsize $bs"
13739                 rm -f $DIR/$tfile.2
13740         done
13741 }
13742 run_test 119f "dio vs dio race"
13743
13744 test_119g()
13745 {
13746         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13747
13748         local stripe_size=$((1024 * 1024)) #1 MiB
13749         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13750         local file_size=$((25 * stripe_size))
13751         local bsizes
13752
13753         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13754         stack_trap "rm -f $DIR/$tfile*"
13755
13756         # Just a bit bigger than the largest size in the test set below
13757         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13758                 error "buffered i/o to create file failed"
13759
13760         if zfs_or_rotational; then
13761                 # DIO on ZFS can take up to 2 seconds per IO
13762                 # rotational is better, but still slow.
13763                 # Limit testing on those media to larger sizes
13764                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13765                         $((stripe_size + 1024))"
13766         else
13767                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13768                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13769                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13770                         $((stripe_size - 1)) $stripe_size \
13771                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13772                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13773         fi
13774
13775         for bs in $bsizes; do
13776                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13777                 echo "bs: $bs"
13778                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13779                         oflag=direct conv=notrunc &
13780                 pid_dio1=$!
13781                 # Buffered I/O with similar but not the same block size
13782                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13783                 pid_bio2=$!
13784                 wait $pid_dio1
13785                 rc1=$?
13786                 wait $pid_bio2
13787                 rc2=$?
13788                 if (( rc1 != 0 )); then
13789                         error "dio copy 1 w/bsize $bs failed: $rc1"
13790                 fi
13791                 if (( rc2 != 0 )); then
13792                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13793                 fi
13794
13795                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13796                         error "size incorrect"
13797                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13798                         error "files differ, bsize $bs"
13799                 rm -f $DIR/$tfile.2
13800         done
13801 }
13802 run_test 119g "dio vs buffered I/O race"
13803
13804 test_119h()
13805 {
13806         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13807
13808         local stripe_size=$((1024 * 1024)) #1 MiB
13809         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13810         local file_size=$((25 * stripe_size))
13811         local bsizes
13812
13813         stack_trap "rm -f $DIR/$tfile.*"
13814
13815         if zfs_or_rotational; then
13816                 # DIO on ZFS can take up to 2 seconds per IO
13817                 # rotational is better, but still slow.
13818                 # Limit testing on those media to larger sizes
13819                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13820                         $((stripe_size + 1024))"
13821         else
13822                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13823                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13824                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13825                         $((stripe_size - 1)) $stripe_size \
13826                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13827                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13828         fi
13829
13830         for bs in $bsizes; do
13831                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13832                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13833                 echo "unaligned writes of blocksize: $bs"
13834                 # Write a file with unaligned DIO and regular DIO, and compare
13835                 # them
13836                 # with 'u', multiop randomly unaligns the io from the buffer
13837                 $MULTIOP $DIR/$tfile.1 \
13838                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13839                         error "multiop memory unaligned write failed, $bs"
13840                 $MULTIOP $DIR/$tfile.2 \
13841                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13842                         error "multiop memory aligned write failed, $bs"
13843
13844                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13845                         error "files differ, bsize $bs"
13846                 rm -f $DIR/$tfile.*
13847         done
13848
13849         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13850         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13851                 error "dd to create source file for read failed"
13852
13853         # Just a few quick tests to make sure unaligned DIO reads don't crash
13854         for bs in $bsizes; do
13855
13856                 echo "unaligned reads of blocksize: $bs"
13857                 # with 'u', multiop randomly unaligns the io from the buffer
13858                 $MULTIOP $DIR/$tfile.1 \
13859                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13860                         error "multiop memory unaligned read failed, $bs"
13861
13862         done
13863         rm -f $DIR/$tfile*
13864 }
13865 run_test 119h "basic tests of memory unaligned dio"
13866
13867 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13868 test_119i()
13869 {
13870         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13871         which aiocp || skip_env "no aiocp installed"
13872
13873         local stripe_size=$((1024 * 1024)) #1 MiB
13874         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13875         local file_size=$((25 * stripe_size))
13876         local bsizes
13877
13878         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13879         stack_trap "rm -f $DIR/$tfile.*"
13880
13881         # Just a bit bigger than the largest size in the test set below
13882         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13883                 error "buffered i/o to create file failed"
13884
13885         if zfs_or_rotational; then
13886                 # DIO on ZFS can take up to 2 seconds per IO
13887                 # rotational is better, but still slow.
13888                 # Limit testing on those media to larger sizes
13889                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13890                         $((stripe_size + 1024))"
13891         else
13892                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13893                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13894                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13895                         $((stripe_size - 1)) $stripe_size \
13896                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13897                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13898         fi
13899
13900         # Do page aligned and NOT page aligned AIO
13901         for align in 8 512 $((PAGE_SIZE)); do
13902         # Deliberately includes a few aligned sizes
13903         for bs in $bsizes; do
13904                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13905
13906                 echo "bs: $bs, align: $align, file_size $file_size"
13907                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13908                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13909                         error "unaligned aio failed, bs: $bs, align: $align"
13910
13911                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13912                         error "size incorrect"
13913                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13914                         error "files differ"
13915                 rm -f $DIR/$tfile.2
13916         done
13917         done
13918 }
13919 run_test 119i "test unaligned aio at varying sizes"
13920
13921 test_120a() {
13922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13923         remote_mds_nodsh && skip "remote MDS with nodsh"
13924         test_mkdir -i0 -c1 $DIR/$tdir
13925         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13926                 skip_env "no early lock cancel on server"
13927
13928         lru_resize_disable mdc
13929         lru_resize_disable osc
13930         cancel_lru_locks mdc
13931         # asynchronous object destroy at MDT could cause bl ast to client
13932         cancel_lru_locks osc
13933
13934         stat $DIR/$tdir > /dev/null
13935         can1=$(do_facet mds1 \
13936                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13937                awk '/ldlm_cancel/ {print $2}')
13938         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13939                awk '/ldlm_bl_callback/ {print $2}')
13940         test_mkdir -i0 -c1 $DIR/$tdir/d1
13941         can2=$(do_facet mds1 \
13942                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13943                awk '/ldlm_cancel/ {print $2}')
13944         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13945                awk '/ldlm_bl_callback/ {print $2}')
13946         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13947         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13948         lru_resize_enable mdc
13949         lru_resize_enable osc
13950 }
13951 run_test 120a "Early Lock Cancel: mkdir test"
13952
13953 test_120b() {
13954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13955         remote_mds_nodsh && skip "remote MDS with nodsh"
13956         test_mkdir $DIR/$tdir
13957         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13958                 skip_env "no early lock cancel on server"
13959
13960         lru_resize_disable mdc
13961         lru_resize_disable osc
13962         cancel_lru_locks mdc
13963         stat $DIR/$tdir > /dev/null
13964         can1=$(do_facet $SINGLEMDS \
13965                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13966                awk '/ldlm_cancel/ {print $2}')
13967         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13968                awk '/ldlm_bl_callback/ {print $2}')
13969         touch $DIR/$tdir/f1
13970         can2=$(do_facet $SINGLEMDS \
13971                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13972                awk '/ldlm_cancel/ {print $2}')
13973         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13974                awk '/ldlm_bl_callback/ {print $2}')
13975         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13976         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13977         lru_resize_enable mdc
13978         lru_resize_enable osc
13979 }
13980 run_test 120b "Early Lock Cancel: create test"
13981
13982 test_120c() {
13983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13984         remote_mds_nodsh && skip "remote MDS with nodsh"
13985         test_mkdir -i0 -c1 $DIR/$tdir
13986         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13987                 skip "no early lock cancel on server"
13988
13989         lru_resize_disable mdc
13990         lru_resize_disable osc
13991         test_mkdir -i0 -c1 $DIR/$tdir/d1
13992         test_mkdir -i0 -c1 $DIR/$tdir/d2
13993         touch $DIR/$tdir/d1/f1
13994         cancel_lru_locks mdc
13995         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13996         can1=$(do_facet mds1 \
13997                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13998                awk '/ldlm_cancel/ {print $2}')
13999         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14000                awk '/ldlm_bl_callback/ {print $2}')
14001         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14002         can2=$(do_facet mds1 \
14003                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14004                awk '/ldlm_cancel/ {print $2}')
14005         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14006                awk '/ldlm_bl_callback/ {print $2}')
14007         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14008         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14009         lru_resize_enable mdc
14010         lru_resize_enable osc
14011 }
14012 run_test 120c "Early Lock Cancel: link test"
14013
14014 test_120d() {
14015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14016         remote_mds_nodsh && skip "remote MDS with nodsh"
14017         test_mkdir -i0 -c1 $DIR/$tdir
14018         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14019                 skip_env "no early lock cancel on server"
14020
14021         lru_resize_disable mdc
14022         lru_resize_disable osc
14023         touch $DIR/$tdir
14024         cancel_lru_locks mdc
14025         stat $DIR/$tdir > /dev/null
14026         can1=$(do_facet mds1 \
14027                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14028                awk '/ldlm_cancel/ {print $2}')
14029         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14030                awk '/ldlm_bl_callback/ {print $2}')
14031         chmod a+x $DIR/$tdir
14032         can2=$(do_facet mds1 \
14033                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14034                awk '/ldlm_cancel/ {print $2}')
14035         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14036                awk '/ldlm_bl_callback/ {print $2}')
14037         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14038         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14039         lru_resize_enable mdc
14040         lru_resize_enable osc
14041 }
14042 run_test 120d "Early Lock Cancel: setattr test"
14043
14044 test_120e() {
14045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14046         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14047                 skip_env "no early lock cancel on server"
14048         remote_mds_nodsh && skip "remote MDS with nodsh"
14049
14050         local dlmtrace_set=false
14051
14052         test_mkdir -i0 -c1 $DIR/$tdir
14053         lru_resize_disable mdc
14054         lru_resize_disable osc
14055         ! $LCTL get_param debug | grep -q dlmtrace &&
14056                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14057         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14058         cancel_lru_locks mdc
14059         cancel_lru_locks osc
14060         dd if=$DIR/$tdir/f1 of=/dev/null
14061         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14062         # XXX client can not do early lock cancel of OST lock
14063         # during unlink (LU-4206), so cancel osc lock now.
14064         sleep 2
14065         cancel_lru_locks osc
14066         can1=$(do_facet mds1 \
14067                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14068                awk '/ldlm_cancel/ {print $2}')
14069         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14070                awk '/ldlm_bl_callback/ {print $2}')
14071         unlink $DIR/$tdir/f1
14072         sleep 5
14073         can2=$(do_facet mds1 \
14074                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14075                awk '/ldlm_cancel/ {print $2}')
14076         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14077                awk '/ldlm_bl_callback/ {print $2}')
14078         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14079                 $LCTL dk $TMP/cancel.debug.txt
14080         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14081                 $LCTL dk $TMP/blocking.debug.txt
14082         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14083         lru_resize_enable mdc
14084         lru_resize_enable osc
14085 }
14086 run_test 120e "Early Lock Cancel: unlink test"
14087
14088 test_120f() {
14089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14090         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14091                 skip_env "no early lock cancel on server"
14092         remote_mds_nodsh && skip "remote MDS with nodsh"
14093
14094         test_mkdir -i0 -c1 $DIR/$tdir
14095         lru_resize_disable mdc
14096         lru_resize_disable osc
14097         test_mkdir -i0 -c1 $DIR/$tdir/d1
14098         test_mkdir -i0 -c1 $DIR/$tdir/d2
14099         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14100         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14101         cancel_lru_locks mdc
14102         cancel_lru_locks osc
14103         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14104         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14105         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14106         # XXX client can not do early lock cancel of OST lock
14107         # during rename (LU-4206), so cancel osc lock now.
14108         sleep 2
14109         cancel_lru_locks osc
14110         can1=$(do_facet mds1 \
14111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14112                awk '/ldlm_cancel/ {print $2}')
14113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14114                awk '/ldlm_bl_callback/ {print $2}')
14115         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14116         sleep 5
14117         can2=$(do_facet mds1 \
14118                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14119                awk '/ldlm_cancel/ {print $2}')
14120         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14121                awk '/ldlm_bl_callback/ {print $2}')
14122         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14123         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14124         lru_resize_enable mdc
14125         lru_resize_enable osc
14126 }
14127 run_test 120f "Early Lock Cancel: rename test"
14128
14129 test_120g() {
14130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14131         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14132                 skip_env "no early lock cancel on server"
14133         remote_mds_nodsh && skip "remote MDS with nodsh"
14134
14135         lru_resize_disable mdc
14136         lru_resize_disable osc
14137         count=10000
14138         echo create $count files
14139         test_mkdir $DIR/$tdir
14140         cancel_lru_locks mdc
14141         cancel_lru_locks osc
14142         t0=$(date +%s)
14143
14144         can0=$(do_facet $SINGLEMDS \
14145                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14146                awk '/ldlm_cancel/ {print $2}')
14147         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14148                awk '/ldlm_bl_callback/ {print $2}')
14149         createmany -o $DIR/$tdir/f $count
14150         sync
14151         can1=$(do_facet $SINGLEMDS \
14152                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14153                awk '/ldlm_cancel/ {print $2}')
14154         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14155                awk '/ldlm_bl_callback/ {print $2}')
14156         t1=$(date +%s)
14157         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14158         echo rm $count files
14159         rm -r $DIR/$tdir
14160         sync
14161         can2=$(do_facet $SINGLEMDS \
14162                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14163                awk '/ldlm_cancel/ {print $2}')
14164         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14165                awk '/ldlm_bl_callback/ {print $2}')
14166         t2=$(date +%s)
14167         echo total: $count removes in $((t2-t1))
14168         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14169         sleep 2
14170         # wait for commitment of removal
14171         lru_resize_enable mdc
14172         lru_resize_enable osc
14173 }
14174 run_test 120g "Early Lock Cancel: performance test"
14175
14176 test_121() { #bug #10589
14177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14178
14179         rm -rf $DIR/$tfile
14180         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14181 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14182         lctl set_param fail_loc=0x310
14183         cancel_lru_locks osc > /dev/null
14184         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14185         lctl set_param fail_loc=0
14186         [[ $reads -eq $writes ]] ||
14187                 error "read $reads blocks, must be $writes blocks"
14188 }
14189 run_test 121 "read cancel race ========="
14190
14191 test_123a_base() { # was test 123, statahead(bug 11401)
14192         local lsx="$1"
14193
14194         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14195
14196         SLOWOK=0
14197         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14198                 log "testing UP system. Performance may be lower than expected."
14199                 SLOWOK=1
14200         fi
14201         running_in_vm && SLOWOK=1
14202
14203         $LCTL set_param mdc.*.batch_stats=0
14204
14205         rm -rf $DIR/$tdir
14206         test_mkdir $DIR/$tdir
14207         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14208         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14209         MULT=10
14210         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14211                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14212
14213                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14214                 lctl set_param -n llite.*.statahead_max 0
14215                 lctl get_param llite.*.statahead_max
14216                 cancel_lru_locks mdc
14217                 cancel_lru_locks osc
14218                 stime=$(date +%s)
14219                 time $lsx $DIR/$tdir | wc -l
14220                 etime=$(date +%s)
14221                 delta=$((etime - stime))
14222                 log "$lsx $i files without statahead: $delta sec"
14223                 lctl set_param llite.*.statahead_max=$max
14224
14225                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14226                          awk '/statahead.wrong:/ { print $NF }')
14227                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14228                 cancel_lru_locks mdc
14229                 cancel_lru_locks osc
14230                 stime=$(date +%s)
14231                 time $lsx $DIR/$tdir | wc -l
14232                 etime=$(date +%s)
14233                 delta_sa=$((etime - stime))
14234                 log "$lsx $i files with statahead: $delta_sa sec"
14235                 lctl get_param -n llite.*.statahead_stats
14236                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14237                          awk '/statahead.wrong:/ { print $NF }')
14238
14239                 [[ $swrong -lt $ewrong ]] &&
14240                         log "statahead was stopped, maybe too many locks held!"
14241                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14242
14243                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14244                         max=$(lctl get_param -n llite.*.statahead_max |
14245                                 head -n 1)
14246                         lctl set_param -n llite.*.statahead_max 0
14247                         lctl get_param llite.*.statahead_max
14248                         cancel_lru_locks mdc
14249                         cancel_lru_locks osc
14250                         stime=$(date +%s)
14251                         time $lsx $DIR/$tdir | wc -l
14252                         etime=$(date +%s)
14253                         delta=$((etime - stime))
14254                         log "$lsx $i files again without statahead: $delta sec"
14255                         lctl set_param llite.*.statahead_max=$max
14256                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14257                                 if [ $SLOWOK -eq 0 ]; then
14258                                         error "$lsx $i files is slower with statahead!"
14259                                 else
14260                                         log "$lsx $i files is slower with statahead!"
14261                                 fi
14262                                 break
14263                         fi
14264                 fi
14265
14266                 [ $delta -gt 20 ] && break
14267                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14268                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14269         done
14270         log "$lsx done"
14271
14272         stime=$(date +%s)
14273         rm -r $DIR/$tdir
14274         sync
14275         etime=$(date +%s)
14276         delta=$((etime - stime))
14277         log "rm -r $DIR/$tdir/: $delta seconds"
14278         log "rm done"
14279         lctl get_param -n llite.*.statahead_stats
14280         $LCTL get_param mdc.*.batch_stats
14281 }
14282
14283 test_123aa() {
14284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14285
14286         test_123a_base "ls -l"
14287 }
14288 run_test 123aa "verify statahead work"
14289
14290 test_123ab() {
14291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14292
14293         statx_supported || skip_env "Test must be statx() syscall supported"
14294
14295         test_123a_base "$STATX -l"
14296 }
14297 run_test 123ab "verify statahead work by using statx"
14298
14299 test_123ac() {
14300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14301
14302         statx_supported || skip_env "Test must be statx() syscall supported"
14303
14304         local rpcs_before
14305         local rpcs_after
14306         local agl_before
14307         local agl_after
14308
14309         cancel_lru_locks $OSC
14310         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14311         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14312                      awk '/agl.total:/ { print $NF }')
14313         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14314         test_123a_base "$STATX --cached=always -D"
14315         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14316                     awk '/agl.total:/ { print $NF }')
14317         [ $agl_before -eq $agl_after ] ||
14318                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14319         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14320         [ $rpcs_after -eq $rpcs_before ] ||
14321                 error "$STATX should not send glimpse RPCs to $OSC"
14322 }
14323 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14324
14325 test_batch_statahead() {
14326         local max=$1
14327         local batch_max=$2
14328         local num=10000
14329         local batch_rpcs
14330         local unbatch_rpcs
14331         local hit_total
14332
14333         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14334         $LCTL set_param mdc.*.batch_stats=0
14335         $LCTL set_param llite.*.statahead_max=$max
14336         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14337         # Verify that batched statahead is faster than one without statahead
14338         test_123a_base "ls -l"
14339
14340         stack_trap "rm -rf $DIR/$tdir" EXIT
14341         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14342         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14343
14344         # unbatched statahead
14345         $LCTL set_param llite.*.statahead_batch_max=0
14346         $LCTL set_param llite.*.statahead_stats=clear
14347         $LCTL set_param mdc.*.stats=clear
14348         cancel_lru_locks mdc
14349         cancel_lru_locks osc
14350         time ls -l $DIR/$tdir | wc -l
14351         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14352         wait_update_facet client "pgrep ll_sa" "" 35 ||
14353                 error "ll_sa thread is still running"
14354         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14355                     awk '/hit.total:/ { print $NF }')
14356         # hit ratio should be larger than 75% (7500).
14357         (( $hit_total > 7500 )) ||
14358                 error "unbatched statahead hit count ($hit_total) is too low"
14359
14360         # batched statahead
14361         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14362         $LCTL set_param llite.*.statahead_stats=clear
14363         $LCTL set_param mdc.*.batch_stats=clear
14364         $LCTL set_param mdc.*.stats=clear
14365         cancel_lru_locks mdc
14366         cancel_lru_locks osc
14367         time ls -l $DIR/$tdir | wc -l
14368         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14369         # wait for statahead thread to quit and update statahead stats
14370         wait_update_facet client "pgrep ll_sa" "" 35 ||
14371                 error "ll_sa thread is still running"
14372         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14373                     awk '/hit.total:/ { print $NF }')
14374         # hit ratio should be larger than 75% (7500).
14375         (( $hit_total > 7500 )) ||
14376                 error "batched statahead hit count ($hit_total) is too low"
14377
14378         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14379         (( $unbatch_rpcs > $batch_rpcs )) ||
14380                 error "batched statahead does not reduce RPC count"
14381         $LCTL get_param mdc.*.batch_stats
14382 }
14383
14384 test_123ad() {
14385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14386
14387         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14388                 skip "Need server version at least 2.15.53"
14389
14390         local max
14391         local batch_max
14392
14393         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14394         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14395
14396         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14397         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14398
14399         test_batch_statahead 32 32
14400         test_batch_statahead 2048 256
14401 }
14402 run_test 123ad "Verify batching statahead works correctly"
14403
14404 test_123b () { # statahead(bug 15027)
14405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14406
14407         test_mkdir $DIR/$tdir
14408         createmany -o $DIR/$tdir/$tfile-%d 1000
14409
14410         cancel_lru_locks mdc
14411         cancel_lru_locks osc
14412
14413 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14414         lctl set_param fail_loc=0x80000803
14415         ls -lR $DIR/$tdir > /dev/null
14416         log "ls done"
14417         lctl set_param fail_loc=0x0
14418         lctl get_param -n llite.*.statahead_stats
14419         rm -r $DIR/$tdir
14420         sync
14421
14422 }
14423 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14424
14425 test_123c() {
14426         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14427
14428         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14429         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14430         touch $DIR/$tdir.1/{1..3}
14431         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14432
14433         remount_client $MOUNT
14434
14435         $MULTIOP $DIR/$tdir.0 Q
14436
14437         # let statahead to complete
14438         ls -l $DIR/$tdir.0 > /dev/null
14439
14440         testid=$(echo $TESTNAME | tr '_' ' ')
14441         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14442                 error "statahead warning" || true
14443 }
14444 run_test 123c "Can not initialize inode warning on DNE statahead"
14445
14446 test_123d() {
14447         local num=100
14448         local swrong
14449         local ewrong
14450
14451         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14452         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14453                 error "setdirstripe $DIR/$tdir failed"
14454         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14455         remount_client $MOUNT
14456         $LCTL get_param llite.*.statahead_max
14457         $LCTL set_param llite.*.statahead_stats=0 ||
14458                 error "clear statahead_stats failed"
14459         swrong=$(lctl get_param -n llite.*.statahead_stats |
14460                  awk '/statahead.wrong:/ { print $NF }')
14461         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14462         # wait for statahead thread finished to update hit/miss stats.
14463         sleep 1
14464         $LCTL get_param -n llite.*.statahead_stats
14465         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14466                  awk '/statahead.wrong:/ { print $NF }')
14467         (( $swrong == $ewrong )) ||
14468                 log "statahead was stopped, maybe too many locks held!"
14469 }
14470 run_test 123d "Statahead on striped directories works correctly"
14471
14472 test_123e() {
14473         local max
14474         local batch_max
14475         local dir=$DIR/$tdir
14476
14477         mkdir $dir || error "mkdir $dir failed"
14478         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14479         stack_trap "rm -rf $dir"
14480
14481         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14482
14483         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14484         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14485         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14486         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14487
14488         $LCTL set_param llite.*.statahead_max=2048
14489         $LCTL set_param llite.*.statahead_batch_max=1024
14490
14491         ls -l $dir
14492         $LCTL get_param mdc.*.batch_stats
14493         $LCTL get_param llite.*.statahead_*
14494 }
14495 run_test 123e "statahead with large wide striping"
14496
14497 test_123f() {
14498         local max
14499         local batch_max
14500         local dir=$DIR/$tdir
14501
14502         mkdir $dir || error "mkdir $dir failed"
14503         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14504         stack_trap "rm -rf $dir"
14505
14506         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14507
14508         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14509         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14510
14511         $LCTL set_param llite.*.statahead_max=64
14512         $LCTL set_param llite.*.statahead_batch_max=64
14513
14514         ls -l $dir
14515         lctl get_param mdc.*.batch_stats
14516         lctl get_param llite.*.statahead_*
14517
14518         $LCTL set_param llite.*.statahead_max=$max
14519         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14520 }
14521 run_test 123f "Retry mechanism with large wide striping files"
14522
14523 test_123g() {
14524         local dir=$DIR/$tdir
14525         local num=1000
14526
14527         mkdir $dir || error "failed to mkdir $dir"
14528         createmany -o $dir/$tfile $num || error "failed creatmany files"
14529         cancel_lru_locks mdc
14530         cancel_lru_locks osc
14531
14532         $LCTL set_param llite.*.statahead_stats=clear
14533         $LCTL set_param mdc.*.batch_stats=clear
14534         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14535                 error "aheadmany $dir with $tfile failed"
14536         wait_update_facet client "pgrep ll_sa" "" 35 ||
14537                 error "ll_sa thread is still running"
14538         $LCTL get_param -n llite.*.statahead_stats
14539         $LCTL get_param -n mdc.*.batch_stats
14540
14541         local count
14542
14543         count=$($LCTL get_param -n llite.*.statahead_stats |
14544                 awk '/hit.total:/ {print $2}')
14545         echo "Hit total: $count"
14546         # Hit ratio should be >= 75%
14547         (( $count > num * 75 / 100 )) ||
14548                 error "hit total $count is be > 75% of $num"
14549 }
14550 run_test 123g "Test for stat-ahead advise"
14551
14552 test_123h_base() {
14553         local dir=$DIR/$tdir
14554         local cmd="touch $dir/$tfile.{$1}"
14555         local fcnt=$2
14556
14557         stack_trap "rm -rf $dir"
14558         mkdir -p $dir || error "failed to mkdir $dir"
14559         eval $cmd
14560
14561         cancel_lru_locks mdc
14562         $LCTL set_param llite.*.statahead_stats=clear
14563         $LCTL set_param mdc.*.batch_stats=0
14564         $LCTL set_param llite.*.statahead_max=1024
14565         $LCTL set_param llite.*.statahead_batch_max=1024
14566         lctl get_param -n llite.*.statahead_stats
14567         du -a $dir > /dev/null
14568         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14569         wait_update_facet client "pgrep ll_sa" "" 35 ||
14570                 error "ll_sa statahead thread does not quit in 35s"
14571         $LCTL get_param -n llite.*.statahead_stats
14572         $LCTL get_param -n mdc.*.batch_stats
14573
14574         local count=$($LCTL get_param -n llite.*.statahead_stats |
14575                         awk '/fname.total:/ {print $2}')
14576
14577         [ $count == 1 ] || error "File name pattern statahead not trigger"
14578         count=$($LCTL get_param -n llite.*.statahead_stats |
14579                 awk '/hit.total:/ {print $2}')
14580         # Hit ratio should be >= 75%
14581         (( $count > fcnt * 75 / 100 )) ||
14582                 error "hit total is too low: $count"
14583         rm -rf $dir || error "rm -rf $dir failed"
14584 }
14585
14586 test_123h() {
14587         local max
14588         local batch_max
14589         local enabled
14590
14591         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14592         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14593         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14594         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14595         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14596         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14597
14598         $LCTL set_param llite.*.enable_statahead_fname=1
14599
14600         echo "Scan a directory with number regularized fname"
14601         test_123h_base "0..10000" 10000
14602
14603         echo "Scan a directory with zeroed padding number regularized fname"
14604         test_123h_base "000000..010000" 10000
14605 }
14606 run_test 123h "Verify statahead work with the fname pattern via du"
14607
14608 test_123i_base() {
14609         local fmt=$1
14610         local iocmd=$2
14611         local dir=$DIR/$tdir
14612         local cmd="createmany -m $fmt"
14613
14614         echo "Command:"
14615         echo "- $cmd"
14616         echo "- $iocmd"
14617         stack_trap "unlinkmany $fmt"
14618         mkdir -p $dir || error "failed to mkdir $dir"
14619         eval $cmd
14620
14621         cancel_lru_locks mdc
14622         $LCTL set_param llite.*.statahead_stats=clear
14623         $LCTL set_param mdc.*.batch_stats=0
14624
14625         echo "statahead_stats (Pre):"
14626         lctl get_param -n llite.*.statahead_stats
14627         eval $iocmd || error "$iocmd failed"
14628         echo "statahead_stats (Post):"
14629         $LCTL get_param -n llite.*.statahead_stats
14630         $LCTL get_param -n mdc.*.batch_stats
14631
14632         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14633         wait_update_facet client "pgrep ll_sa" "" 35 ||
14634                 error "ll_sa statahead thread does not quit in 35s"
14635         $LCTL get_param -n llite.*.statahead_stats
14636         $LCTL get_param -n mdc.*.batch_stats
14637
14638         local count=$($LCTL get_param -n llite.*.statahead_stats |
14639                         awk '/fname.total:/ {print $2}')
14640
14641         [ $count == 1 ] || error "File name pattern statahead not trigger"
14642         count=$($LCTL get_param -n llite.*.statahead_stats |
14643                 awk '/hit.total:/ {print $2}')
14644         # Hit ratio should be >= 75%
14645         (( $count > 750 )) || error "hit total is too low: $count"
14646 }
14647
14648 test_123i() {
14649         local dir=$DIR/$tdir
14650         local cnt=1000
14651         local max
14652         local batch_max
14653         local enabled
14654         local min
14655
14656         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14657         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14658         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14659         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14660         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14661         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14662         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14663         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14664         $LCTL set_param llite.*.statahead_max=1024
14665         $LCTL set_param llite.*.statahead_batch_max=32
14666         $LCTL set_param llite.*.statahead_min=64
14667         $LCTL set_param llite.*.enable_statahead_fname=1
14668
14669         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14670         test_123i_base "$dir/$tfile $cnt" \
14671                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14672 }
14673 run_test 123i "Verify statahead work with the fname indexing pattern"
14674
14675 test_124a() {
14676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14677         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14678                 skip_env "no lru resize on server"
14679
14680         local NR=2000
14681
14682         test_mkdir $DIR/$tdir
14683
14684         log "create $NR files at $DIR/$tdir"
14685         createmany -o $DIR/$tdir/f $NR ||
14686                 error "failed to create $NR files in $DIR/$tdir"
14687
14688         cancel_lru_locks mdc
14689         ls -l $DIR/$tdir > /dev/null
14690
14691         local NSDIR=""
14692         local LRU_SIZE=0
14693         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14694                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14695                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14696                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14697                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14698                         log "NSDIR=$NSDIR"
14699                         log "NS=$(basename $NSDIR)"
14700                         break
14701                 fi
14702         done
14703
14704         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14705                 skip "Not enough cached locks created!"
14706         fi
14707         log "LRU=$LRU_SIZE"
14708
14709         local SLEEP=30
14710
14711         # We know that lru resize allows one client to hold $LIMIT locks
14712         # for 10h. After that locks begin to be killed by client.
14713         local MAX_HRS=10
14714         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14715         log "LIMIT=$LIMIT"
14716         if [ $LIMIT -lt $LRU_SIZE ]; then
14717                 skip "Limit is too small $LIMIT"
14718         fi
14719
14720         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14721         # killing locks. Some time was spent for creating locks. This means
14722         # that up to the moment of sleep finish we must have killed some of
14723         # them (10-100 locks). This depends on how fast ther were created.
14724         # Many of them were touched in almost the same moment and thus will
14725         # be killed in groups.
14726         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14727
14728         # Use $LRU_SIZE_B here to take into account real number of locks
14729         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14730         local LRU_SIZE_B=$LRU_SIZE
14731         log "LVF=$LVF"
14732         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14733         log "OLD_LVF=$OLD_LVF"
14734         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14735
14736         # Let's make sure that we really have some margin. Client checks
14737         # cached locks every 10 sec.
14738         SLEEP=$((SLEEP+20))
14739         log "Sleep ${SLEEP} sec"
14740         local SEC=0
14741         while ((SEC<$SLEEP)); do
14742                 echo -n "..."
14743                 sleep 5
14744                 SEC=$((SEC+5))
14745                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14746                 echo -n "$LRU_SIZE"
14747         done
14748         echo ""
14749         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14750         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14751
14752         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14753                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14754                 unlinkmany $DIR/$tdir/f $NR
14755                 return
14756         }
14757
14758         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14759         log "unlink $NR files at $DIR/$tdir"
14760         unlinkmany $DIR/$tdir/f $NR
14761 }
14762 run_test 124a "lru resize ======================================="
14763
14764 get_max_pool_limit()
14765 {
14766         local limit=$($LCTL get_param \
14767                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14768         local max=0
14769         for l in $limit; do
14770                 if [[ $l -gt $max ]]; then
14771                         max=$l
14772                 fi
14773         done
14774         echo $max
14775 }
14776
14777 test_124b() {
14778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14779         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14780                 skip_env "no lru resize on server"
14781
14782         LIMIT=$(get_max_pool_limit)
14783
14784         NR=$(($(default_lru_size)*20))
14785         if [[ $NR -gt $LIMIT ]]; then
14786                 log "Limit lock number by $LIMIT locks"
14787                 NR=$LIMIT
14788         fi
14789
14790         IFree=$(mdsrate_inodes_available)
14791         if [ $IFree -lt $NR ]; then
14792                 log "Limit lock number by $IFree inodes"
14793                 NR=$IFree
14794         fi
14795
14796         lru_resize_disable mdc
14797         test_mkdir -p $DIR/$tdir/disable_lru_resize
14798
14799         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14800         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14801         cancel_lru_locks mdc
14802         stime=`date +%s`
14803         PID=""
14804         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14805         PID="$PID $!"
14806         sleep 2
14807         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14808         PID="$PID $!"
14809         sleep 2
14810         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14811         PID="$PID $!"
14812         wait $PID
14813         etime=`date +%s`
14814         nolruresize_delta=$((etime-stime))
14815         log "ls -la time: $nolruresize_delta seconds"
14816         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14817         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14818
14819         lru_resize_enable mdc
14820         test_mkdir -p $DIR/$tdir/enable_lru_resize
14821
14822         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14823         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14824         cancel_lru_locks mdc
14825         stime=`date +%s`
14826         PID=""
14827         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14828         PID="$PID $!"
14829         sleep 2
14830         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14831         PID="$PID $!"
14832         sleep 2
14833         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14834         PID="$PID $!"
14835         wait $PID
14836         etime=`date +%s`
14837         lruresize_delta=$((etime-stime))
14838         log "ls -la time: $lruresize_delta seconds"
14839         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14840
14841         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14842                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14843         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14844                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14845         else
14846                 log "lru resize performs the same with no lru resize"
14847         fi
14848         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14849 }
14850 run_test 124b "lru resize (performance test) ======================="
14851
14852 test_124c() {
14853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14854         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14855                 skip_env "no lru resize on server"
14856
14857         # cache ununsed locks on client
14858         local nr=100
14859         cancel_lru_locks mdc
14860         test_mkdir $DIR/$tdir
14861         createmany -o $DIR/$tdir/f $nr ||
14862                 error "failed to create $nr files in $DIR/$tdir"
14863         ls -l $DIR/$tdir > /dev/null
14864
14865         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14866         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14867         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14868         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14869         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14870
14871         # set lru_max_age to 1 sec
14872         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14873         echo "sleep $((recalc_p * 2)) seconds..."
14874         sleep $((recalc_p * 2))
14875
14876         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14877         # restore lru_max_age
14878         $LCTL set_param -n $nsdir.lru_max_age $max_age
14879         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14880         unlinkmany $DIR/$tdir/f $nr
14881 }
14882 run_test 124c "LRUR cancel very aged locks"
14883
14884 test_124d() {
14885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14886         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14887                 skip_env "no lru resize on server"
14888
14889         # cache ununsed locks on client
14890         local nr=100
14891
14892         lru_resize_disable mdc
14893         stack_trap "lru_resize_enable mdc" EXIT
14894
14895         cancel_lru_locks mdc
14896
14897         # asynchronous object destroy at MDT could cause bl ast to client
14898         test_mkdir $DIR/$tdir
14899         createmany -o $DIR/$tdir/f $nr ||
14900                 error "failed to create $nr files in $DIR/$tdir"
14901         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14902
14903         ls -l $DIR/$tdir > /dev/null
14904
14905         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14906         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14907         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14908         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14909
14910         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14911
14912         # set lru_max_age to 1 sec
14913         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14914         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14915
14916         echo "sleep $((recalc_p * 2)) seconds..."
14917         sleep $((recalc_p * 2))
14918
14919         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14920
14921         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14922 }
14923 run_test 124d "cancel very aged locks if lru-resize disabled"
14924
14925 test_125() { # 13358
14926         $LCTL get_param -n llite.*.client_type | grep -q local ||
14927                 skip "must run as local client"
14928         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14929                 skip_env "must have acl enabled"
14930         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14931         id $USER0 || skip_env "missing user $USER0"
14932
14933         test_mkdir $DIR/$tdir
14934         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14935         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14936                 error "setfacl $DIR/$tdir failed"
14937         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14938 }
14939 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14940
14941 test_126() { # bug 12829/13455
14942         $GSS && skip_env "must run as gss disabled"
14943         $LCTL get_param -n llite.*.client_type | grep -q local ||
14944                 skip "must run as local client"
14945         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14946
14947         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14948         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14949         rm -f $DIR/$tfile
14950         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14951 }
14952 run_test 126 "check that the fsgid provided by the client is taken into account"
14953
14954 test_127a() { # bug 15521
14955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14956         local name count samp unit min max sum sumsq
14957         local tmpfile=$TMP/$tfile.tmp
14958
14959         # enable stats header if it is disabled
14960         $LCTL set_param enable_stats_header=1
14961
14962         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14963         echo "stats before reset"
14964         stack_trap "rm -f $tmpfile"
14965         local now=$(date +%s)
14966
14967         $LCTL get_param osc.*.stats | tee $tmpfile
14968
14969         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14970         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14971         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14972         local uptime=$(awk '{ print $1 }' /proc/uptime)
14973
14974         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14975         (( ${snapshot_time%\.*} >= $now - 5 &&
14976            ${snapshot_time%\.*} <= $now + 5 )) ||
14977                 error "snapshot_time=$snapshot_time != now=$now"
14978         # elapsed _should_ be from mount, but at least less than uptime
14979         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14980                 error "elapsed=$elapsed > uptime=$uptime"
14981         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14982            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14983                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14984
14985         $LCTL set_param osc.*.stats=0
14986         local reset=$(date +%s)
14987         local fsize=$((2048 * 1024))
14988
14989         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14990         cancel_lru_locks osc
14991         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14992
14993         now=$(date +%s)
14994         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14995         while read name count samp unit min max sum sumsq; do
14996                 [[ "$samp" == "samples" ]] || continue
14997
14998                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14999                 [ ! $min ] && error "Missing min value for $name proc entry"
15000                 eval $name=$count || error "Wrong proc format"
15001
15002                 case $name in
15003                 read_bytes|write_bytes)
15004                         [[ "$unit" =~ "bytes" ]] ||
15005                                 error "unit is not 'bytes': $unit"
15006                         (( $min >= 4096 )) || error "min is too small: $min"
15007                         (( $min <= $fsize )) || error "min is too big: $min"
15008                         (( $max >= 4096 )) || error "max is too small: $max"
15009                         (( $max <= $fsize )) || error "max is too big: $max"
15010                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15011                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15012                                 error "sumsquare is too small: $sumsq"
15013                         (( $sumsq <= $fsize * $fsize )) ||
15014                                 error "sumsquare is too big: $sumsq"
15015                         ;;
15016                 ost_read|ost_write)
15017                         [[ "$unit" =~ "usec" ]] ||
15018                                 error "unit is not 'usec': $unit"
15019                         ;;
15020                 *)      ;;
15021                 esac
15022         done < $tmpfile
15023
15024         #check that we actually got some stats
15025         [ "$read_bytes" ] || error "Missing read_bytes stats"
15026         [ "$write_bytes" ] || error "Missing write_bytes stats"
15027         [ "$read_bytes" != 0 ] || error "no read done"
15028         [ "$write_bytes" != 0 ] || error "no write done"
15029
15030         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15031         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15032         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15033
15034         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15035         (( ${snapshot_time%\.*} >= $now - 5 &&
15036            ${snapshot_time%\.*} <= $now + 5 )) ||
15037                 error "reset snapshot_time=$snapshot_time != now=$now"
15038         # elapsed should be from time of stats reset
15039         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15040            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15041                 error "reset elapsed=$elapsed > $now - $reset"
15042         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15043            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15044                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15045 }
15046 run_test 127a "verify the client stats are sane"
15047
15048 test_127b() { # bug LU-333
15049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15050         local name count samp unit min max sum sumsq
15051
15052         echo "stats before reset"
15053         $LCTL get_param llite.*.stats
15054         $LCTL set_param llite.*.stats=0
15055
15056         # perform 2 reads and writes so MAX is different from SUM.
15057         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15058         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15059         cancel_lru_locks osc
15060         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15061         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15062
15063         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15064         stack_trap "rm -f $TMP/$tfile.tmp"
15065         while read name count samp unit min max sum sumsq; do
15066                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15067                 eval $name=$count || error "Wrong proc format"
15068
15069                 case $name in
15070                 read_bytes|write_bytes)
15071                         [[ "$unit" =~ "bytes" ]] ||
15072                                 error "unit is not 'bytes': $unit"
15073                         (( $count == 2 )) || error "count is not 2: $count"
15074                         (( $min == $PAGE_SIZE )) ||
15075                                 error "min is not $PAGE_SIZE: $min"
15076                         (( $max == $PAGE_SIZE )) ||
15077                                 error "max is not $PAGE_SIZE: $max"
15078                         (( $sum == $PAGE_SIZE * 2 )) ||
15079                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15080                         ;;
15081                 read|write)
15082                         [[ "$unit" =~ "usec" ]] ||
15083                                 error "unit is not 'usec': $unit"
15084                         ;;
15085                 *)      ;;
15086                 esac
15087         done < $TMP/$tfile.tmp
15088
15089         #check that we actually got some stats
15090         [ "$read_bytes" ] || error "Missing read_bytes stats"
15091         [ "$write_bytes" ] || error "Missing write_bytes stats"
15092         [ "$read_bytes" != 0 ] || error "no read done"
15093         [ "$write_bytes" != 0 ] || error "no write done"
15094 }
15095 run_test 127b "verify the llite client stats are sane"
15096
15097 test_127c() { # LU-12394
15098         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15099         local size
15100         local bsize
15101         local reads
15102         local writes
15103         local count
15104
15105         $LCTL set_param llite.*.extents_stats=1
15106         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15107
15108         # Use two stripes so there is enough space in default config
15109         $LFS setstripe -c 2 $DIR/$tfile
15110
15111         # Extent stats start at 0-4K and go in power of two buckets
15112         # LL_HIST_START = 12 --> 2^12 = 4K
15113         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15114         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15115         # small configs
15116         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15117                 do
15118                 # Write and read, 2x each, second time at a non-zero offset
15119                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15120                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15121                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15122                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15123                 rm -f $DIR/$tfile
15124         done
15125
15126         $LCTL get_param llite.*.extents_stats
15127
15128         count=2
15129         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15130                 do
15131                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15132                                 grep -m 1 $bsize)
15133                 reads=$(echo $bucket | awk '{print $5}')
15134                 writes=$(echo $bucket | awk '{print $9}')
15135                 [ "$reads" -eq $count ] ||
15136                         error "$reads reads in < $bsize bucket, expect $count"
15137                 [ "$writes" -eq $count ] ||
15138                         error "$writes writes in < $bsize bucket, expect $count"
15139         done
15140
15141         # Test mmap write and read
15142         $LCTL set_param llite.*.extents_stats=c
15143         size=512
15144         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15145         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15146         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15147
15148         $LCTL get_param llite.*.extents_stats
15149
15150         count=$(((size*1024) / PAGE_SIZE))
15151
15152         bsize=$((2 * PAGE_SIZE / 1024))K
15153
15154         bucket=$($LCTL get_param -n llite.*.extents_stats |
15155                         grep -m 1 $bsize)
15156         reads=$(echo $bucket | awk '{print $5}')
15157         writes=$(echo $bucket | awk '{print $9}')
15158         # mmap writes fault in the page first, creating an additonal read
15159         [ "$reads" -eq $((2 * count)) ] ||
15160                 error "$reads reads in < $bsize bucket, expect $count"
15161         [ "$writes" -eq $count ] ||
15162                 error "$writes writes in < $bsize bucket, expect $count"
15163 }
15164 run_test 127c "test llite extent stats with regular & mmap i/o"
15165
15166 test_128() { # bug 15212
15167         touch $DIR/$tfile
15168         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15169                 find $DIR/$tfile
15170                 find $DIR/$tfile
15171         EOF
15172
15173         result=$(grep error $TMP/$tfile.log)
15174         rm -f $DIR/$tfile $TMP/$tfile.log
15175         [ -z "$result" ] ||
15176                 error "consecutive find's under interactive lfs failed"
15177 }
15178 run_test 128 "interactive lfs for 2 consecutive find's"
15179
15180 set_dir_limits () {
15181         local mntdev
15182         local canondev
15183         local node
15184
15185         local ldproc=/proc/fs/ldiskfs
15186         local facets=$(get_facets MDS)
15187
15188         for facet in ${facets//,/ }; do
15189                 canondev=$(ldiskfs_canon \
15190                            *.$(convert_facet2label $facet).mntdev $facet)
15191                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15192                         ldproc=/sys/fs/ldiskfs
15193                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15194                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15195         done
15196 }
15197
15198 check_mds_dmesg() {
15199         local facets=$(get_facets MDS)
15200         for facet in ${facets//,/ }; do
15201                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15202         done
15203         return 1
15204 }
15205
15206 test_129() {
15207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15208         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15209                 skip "Need MDS version with at least 2.5.56"
15210         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15211                 skip_env "ldiskfs only test"
15212         fi
15213         remote_mds_nodsh && skip "remote MDS with nodsh"
15214
15215         local ENOSPC=28
15216         local has_warning=false
15217
15218         rm -rf $DIR/$tdir
15219         mkdir -p $DIR/$tdir
15220
15221         # block size of mds1
15222         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15223         set_dir_limits $maxsize $((maxsize * 6 / 8))
15224         stack_trap "set_dir_limits 0 0"
15225         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15226         local dirsize=$(stat -c%s "$DIR/$tdir")
15227         local nfiles=0
15228         while (( $dirsize <= $maxsize )); do
15229                 $MCREATE $DIR/$tdir/file_base_$nfiles
15230                 rc=$?
15231                 # check two errors:
15232                 # ENOSPC for ext4 max_dir_size, which has been used since
15233                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15234                 if (( rc == ENOSPC )); then
15235                         set_dir_limits 0 0
15236                         echo "rc=$rc returned as expected after $nfiles files"
15237
15238                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15239                                 error "create failed w/o dir size limit"
15240
15241                         # messages may be rate limited if test is run repeatedly
15242                         check_mds_dmesg '"is approaching max"' ||
15243                                 echo "warning message should be output"
15244                         check_mds_dmesg '"has reached max"' ||
15245                                 echo "reached message should be output"
15246
15247                         dirsize=$(stat -c%s "$DIR/$tdir")
15248
15249                         [[ $dirsize -ge $maxsize ]] && return 0
15250                         error "dirsize $dirsize < $maxsize after $nfiles files"
15251                 elif (( rc != 0 )); then
15252                         break
15253                 fi
15254                 nfiles=$((nfiles + 1))
15255                 dirsize=$(stat -c%s "$DIR/$tdir")
15256         done
15257
15258         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15259 }
15260 run_test 129 "test directory size limit ========================"
15261
15262 OLDIFS="$IFS"
15263 cleanup_130() {
15264         trap 0
15265         IFS="$OLDIFS"
15266         rm -f $DIR/$tfile
15267 }
15268
15269 test_130a() {
15270         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15271         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15272
15273         trap cleanup_130 EXIT RETURN
15274
15275         local fm_file=$DIR/$tfile
15276         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15277         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15278                 error "dd failed for $fm_file"
15279
15280         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15281         filefrag -ves $fm_file
15282         local rc=$?
15283         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15284                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15285         (( $rc == 0 )) || error "filefrag $fm_file failed"
15286
15287         filefrag_op=$(filefrag -ve -k $fm_file |
15288                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15289         local lun=$($LFS getstripe -i $fm_file)
15290
15291         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15292         IFS=$'\n'
15293         local tot_len=0
15294         for line in $filefrag_op; do
15295                 local frag_lun=$(echo $line | cut -d: -f5)
15296                 local ext_len=$(echo $line | cut -d: -f4)
15297
15298                 if (( $frag_lun != $lun )); then
15299                         error "FIEMAP on 1-stripe file($fm_file) failed"
15300                         return
15301                 fi
15302                 (( tot_len += ext_len ))
15303         done
15304
15305         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15306                 error "FIEMAP on 1-stripe file($fm_file) failed"
15307                 return
15308         fi
15309
15310         echo "FIEMAP on single striped file succeeded"
15311 }
15312 run_test 130a "FIEMAP (1-stripe file)"
15313
15314 test_130b() {
15315         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15316
15317         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15318         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15319         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15320                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15321
15322         trap cleanup_130 EXIT RETURN
15323
15324         local fm_file=$DIR/$tfile
15325         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15326                 error "setstripe on $fm_file"
15327
15328         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15329                 error "dd failed on $fm_file"
15330
15331         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15332         filefrag_op=$(filefrag -ve -k $fm_file |
15333                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15334
15335         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15336                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15337
15338         IFS=$'\n'
15339         local tot_len=0
15340         local num_luns=1
15341
15342         for line in $filefrag_op; do
15343                 local frag_lun=$(echo $line | cut -d: -f5 |
15344                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15345                 local ext_len=$(echo $line | cut -d: -f4)
15346                 if (( $frag_lun != $last_lun )); then
15347                         if (( tot_len != 1024 )); then
15348                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15349                                 return
15350                         else
15351                                 (( num_luns += 1 ))
15352                                 tot_len=0
15353                         fi
15354                 fi
15355                 (( tot_len += ext_len ))
15356                 last_lun=$frag_lun
15357         done
15358         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15359                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15360                 return
15361         fi
15362
15363         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15364 }
15365 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15366
15367 test_130c() {
15368         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15369
15370         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15371         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15372         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15373                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15374
15375         trap cleanup_130 EXIT RETURN
15376
15377         local fm_file=$DIR/$tfile
15378         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15379
15380         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15381                 error "dd failed on $fm_file"
15382
15383         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15384         filefrag_op=$(filefrag -ve -k $fm_file |
15385                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15386
15387         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15388                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15389
15390         IFS=$'\n'
15391         local tot_len=0
15392         local num_luns=1
15393         for line in $filefrag_op; do
15394                 local frag_lun=$(echo $line | cut -d: -f5 |
15395                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15396                 local ext_len=$(echo $line | cut -d: -f4)
15397                 if (( $frag_lun != $last_lun )); then
15398                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15399                         if (( logical != 512 )); then
15400                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15401                                 return
15402                         fi
15403                         if (( tot_len != 512 )); then
15404                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15405                                 return
15406                         else
15407                                 (( num_luns += 1 ))
15408                                 tot_len=0
15409                         fi
15410                 fi
15411                 (( tot_len += ext_len ))
15412                 last_lun=$frag_lun
15413         done
15414         if (( num_luns != 2 || tot_len != 512 )); then
15415                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15416                 return
15417         fi
15418
15419         echo "FIEMAP on 2-stripe file with hole succeeded"
15420 }
15421 run_test 130c "FIEMAP (2-stripe file with hole)"
15422
15423 test_130d() {
15424         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15425
15426         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15427         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15428         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15429                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15430
15431         trap cleanup_130 EXIT RETURN
15432
15433         local fm_file=$DIR/$tfile
15434         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15435                         error "setstripe on $fm_file"
15436
15437         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15438         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15439                 error "dd failed on $fm_file"
15440
15441         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15442         filefrag_op=$(filefrag -ve -k $fm_file |
15443                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15444
15445         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15446                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15447
15448         IFS=$'\n'
15449         local tot_len=0
15450         local num_luns=1
15451         for line in $filefrag_op; do
15452                 local frag_lun=$(echo $line | cut -d: -f5 |
15453                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15454                 local ext_len=$(echo $line | cut -d: -f4)
15455                 if (( $frag_lun != $last_lun )); then
15456                         if (( tot_len != 1024 )); then
15457                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15458                                 return
15459                         else
15460                                 (( num_luns += 1 ))
15461                                 local tot_len=0
15462                         fi
15463                 fi
15464                 (( tot_len += ext_len ))
15465                 last_lun=$frag_lun
15466         done
15467         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15468                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15469                 return
15470         fi
15471
15472         echo "FIEMAP on N-stripe file succeeded"
15473 }
15474 run_test 130d "FIEMAP (N-stripe file)"
15475
15476 test_130e() {
15477         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15478
15479         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15480         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15481         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15482                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15483
15484         trap cleanup_130 EXIT RETURN
15485
15486         local fm_file=$DIR/$tfile
15487         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15488         stack_trap "rm -f $fm_file"
15489
15490         local num_blks=512
15491         local expected_len=$(( (num_blks / 2) * 64 ))
15492         for ((i = 0; i < $num_blks; i++)); do
15493                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15494                         conv=notrunc > /dev/null 2>&1
15495         done
15496
15497         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15498         filefrag_op=$(filefrag -ve -k $fm_file |
15499                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15500
15501         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15502
15503         IFS=$'\n'
15504         local tot_len=0
15505         local num_luns=1
15506         for line in $filefrag_op; do
15507                 local frag_lun=$(echo $line | cut -d: -f5)
15508                 local ext_len=$(echo $line | cut -d: -f4)
15509                 if (( $frag_lun != $last_lun )); then
15510                         if (( tot_len != $expected_len )); then
15511                                 error "OST$last_lun $tot_len != $expected_len"
15512                         else
15513                                 (( num_luns += 1 ))
15514                                 tot_len=0
15515                         fi
15516                 fi
15517                 (( tot_len += ext_len ))
15518                 last_lun=$frag_lun
15519         done
15520         if (( num_luns != 2 || tot_len != $expected_len )); then
15521                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15522         fi
15523
15524         echo "FIEMAP with continuation calls succeeded"
15525 }
15526 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15527
15528 test_130f() {
15529         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15530         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15531         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15532                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15533
15534         local fm_file=$DIR/$tfile
15535         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15536                 error "multiop create with lov_delay_create on $fm_file"
15537
15538         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15539         filefrag_extents=$(filefrag -vek $fm_file |
15540                            awk '/extents? found/ { print $2 }')
15541         if (( $filefrag_extents != 0 )); then
15542                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15543         fi
15544
15545         rm -f $fm_file
15546 }
15547 run_test 130f "FIEMAP (unstriped file)"
15548
15549 test_130g() {
15550         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15551                 skip "Need MDS version with at least 2.12.53 for overstriping"
15552         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15553         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15554         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15555                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15556
15557         local file=$DIR/$tfile
15558         local nr=$((OSTCOUNT * 100))
15559
15560         $LFS setstripe -C $nr -S1M $file ||
15561                 error "failed to setstripe -C $nr $file"
15562
15563         stack_trap "rm -f $file"
15564         dd if=/dev/zero of=$file count=$nr bs=1M
15565         sync
15566         nr=$($LFS getstripe -c $file)
15567
15568         local extents=$(filefrag -v $file |
15569                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15570
15571         echo "filefrag list $extents extents in file with stripecount $nr"
15572         if (( extents < nr )); then
15573                 $LFS getstripe $file
15574                 filefrag -v $file
15575                 error "filefrag printed $extents < $nr extents"
15576         fi
15577 }
15578 run_test 130g "FIEMAP (overstripe file)"
15579
15580 # Test for writev/readv
15581 test_131a() {
15582         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15583                 error "writev test failed"
15584         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15585                 error "readv failed"
15586         rm -f $DIR/$tfile
15587 }
15588 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15589
15590 test_131b() {
15591         local fsize=$((524288 + 1048576 + 1572864))
15592         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15593                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15594                         error "append writev test failed"
15595
15596         ((fsize += 1572864 + 1048576))
15597         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15598                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15599                         error "append writev test failed"
15600         rm -f $DIR/$tfile
15601 }
15602 run_test 131b "test append writev"
15603
15604 test_131c() {
15605         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15606         error "NOT PASS"
15607 }
15608 run_test 131c "test read/write on file w/o objects"
15609
15610 test_131d() {
15611         rwv -f $DIR/$tfile -w -n 1 1572864
15612         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15613         if [ "$NOB" != 1572864 ]; then
15614                 error "Short read filed: read $NOB bytes instead of 1572864"
15615         fi
15616         rm -f $DIR/$tfile
15617 }
15618 run_test 131d "test short read"
15619
15620 test_131e() {
15621         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15622         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15623         error "read hitting hole failed"
15624         rm -f $DIR/$tfile
15625 }
15626 run_test 131e "test read hitting hole"
15627
15628 check_stats() {
15629         local facet=$1
15630         local op=$2
15631         local want=${3:-0}
15632         local res
15633
15634         # open             11 samples [usecs] 468 4793 13658 35791898
15635         case $facet in
15636         mds*) res=($(do_facet $facet \
15637                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15638                  ;;
15639         ost*) res=($(do_facet $facet \
15640                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15641                  ;;
15642         *) error "Wrong facet '$facet'" ;;
15643         esac
15644         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15645         # if $want is zero, it means any stat increment is ok.
15646         if (( $want > 0 )); then
15647                 local count=${res[1]}
15648
15649                 if (( $count != $want )); then
15650                         if [[ $facet =~ "mds" ]]; then
15651                                 do_nodes $(comma_list $(mdts_nodes)) \
15652                                         $LCTL get_param mdt.*.md_stats
15653                         else
15654                                 do_nodes $(comma_list $(osts-nodes)) \
15655                                         $LCTL get_param obdfilter.*.stats
15656                         fi
15657                         error "The $op counter on $facet is $count, not $want"
15658                 fi
15659         fi
15660 }
15661
15662 test_133a() {
15663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15664         remote_ost_nodsh && skip "remote OST with nodsh"
15665         remote_mds_nodsh && skip "remote MDS with nodsh"
15666         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15667                 skip_env "MDS doesn't support rename stats"
15668
15669         local testdir=$DIR/${tdir}/stats_testdir
15670
15671         mkdir -p $DIR/${tdir}
15672
15673         # clear stats.
15674         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15675         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15676
15677         # verify mdt stats first.
15678         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15679         check_stats $SINGLEMDS "mkdir" 1
15680
15681         # clear "open" from "lfs mkdir" above
15682         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15683         touch ${testdir}/${tfile} || error "touch failed"
15684         check_stats $SINGLEMDS "open" 1
15685         check_stats $SINGLEMDS "close" 1
15686         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15687                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15688                 check_stats $SINGLEMDS "mknod" 2
15689         }
15690         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15691         check_stats $SINGLEMDS "unlink" 1
15692         rm -f ${testdir}/${tfile} || error "file remove failed"
15693         check_stats $SINGLEMDS "unlink" 2
15694
15695         # remove working dir and check mdt stats again.
15696         rmdir ${testdir} || error "rmdir failed"
15697         check_stats $SINGLEMDS "rmdir" 1
15698
15699         local testdir1=$DIR/${tdir}/stats_testdir1
15700         mkdir_on_mdt0 -p ${testdir}
15701         mkdir_on_mdt0 -p ${testdir1}
15702         touch ${testdir1}/test1
15703         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15704         check_stats $SINGLEMDS "crossdir_rename" 1
15705
15706         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15707         check_stats $SINGLEMDS "samedir_rename" 1
15708
15709         rm -rf $DIR/${tdir}
15710 }
15711 run_test 133a "Verifying MDT stats ========================================"
15712
15713 test_133b() {
15714         local res
15715
15716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15717         remote_ost_nodsh && skip "remote OST with nodsh"
15718         remote_mds_nodsh && skip "remote MDS with nodsh"
15719
15720         local testdir=$DIR/${tdir}/stats_testdir
15721
15722         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15723         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15724         touch ${testdir}/${tfile} || error "touch failed"
15725         cancel_lru_locks mdc
15726
15727         # clear stats.
15728         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15729         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15730
15731         # extra mdt stats verification.
15732         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15733         check_stats $SINGLEMDS "setattr" 1
15734         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15735         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15736         then            # LU-1740
15737                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15738                 check_stats $SINGLEMDS "getattr" 1
15739         fi
15740         rm -rf $DIR/${tdir}
15741
15742         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15743         # so the check below is not reliable
15744         [ $MDSCOUNT -eq 1 ] || return 0
15745
15746         # Sleep to avoid a cached response.
15747         #define OBD_STATFS_CACHE_SECONDS 1
15748         sleep 2
15749         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15750         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15751         $LFS df || error "lfs failed"
15752         check_stats $SINGLEMDS "statfs" 1
15753
15754         # check aggregated statfs (LU-10018)
15755         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15756                 return 0
15757         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15758                 return 0
15759         sleep 2
15760         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15761         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15762         df $DIR
15763         check_stats $SINGLEMDS "statfs" 1
15764
15765         # We want to check that the client didn't send OST_STATFS to
15766         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15767         # extra care is needed here.
15768         if remote_mds; then
15769                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15770                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15771
15772                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15773                 [ "$res" ] && error "OST got STATFS"
15774         fi
15775
15776         return 0
15777 }
15778 run_test 133b "Verifying extra MDT stats =================================="
15779
15780 test_133c() {
15781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15782         remote_ost_nodsh && skip "remote OST with nodsh"
15783         remote_mds_nodsh && skip "remote MDS with nodsh"
15784
15785         local testdir=$DIR/$tdir/stats_testdir
15786
15787         test_mkdir -p $testdir
15788
15789         # verify obdfilter stats.
15790         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15791         sync
15792         cancel_lru_locks osc
15793         wait_delete_completed
15794
15795         # clear stats.
15796         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15797         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15798
15799         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15800                 error "dd failed"
15801         sync
15802         cancel_lru_locks osc
15803         check_stats ost1 "write" 1
15804
15805         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15806         check_stats ost1 "read" 1
15807
15808         > $testdir/$tfile || error "truncate failed"
15809         check_stats ost1 "punch" 1
15810
15811         rm -f $testdir/$tfile || error "file remove failed"
15812         wait_delete_completed
15813         check_stats ost1 "destroy" 1
15814
15815         rm -rf $DIR/$tdir
15816 }
15817 run_test 133c "Verifying OST stats ========================================"
15818
15819 order_2() {
15820         local value=$1
15821         local orig=$value
15822         local order=1
15823
15824         while [ $value -ge 2 ]; do
15825                 order=$((order*2))
15826                 value=$((value/2))
15827         done
15828
15829         if [ $orig -gt $order ]; then
15830                 order=$((order*2))
15831         fi
15832         echo $order
15833 }
15834
15835 size_in_KMGT() {
15836     local value=$1
15837     local size=('K' 'M' 'G' 'T');
15838     local i=0
15839     local size_string=$value
15840
15841     while [ $value -ge 1024 ]; do
15842         if [ $i -gt 3 ]; then
15843             #T is the biggest unit we get here, if that is bigger,
15844             #just return XXXT
15845             size_string=${value}T
15846             break
15847         fi
15848         value=$((value >> 10))
15849         if [ $value -lt 1024 ]; then
15850             size_string=${value}${size[$i]}
15851             break
15852         fi
15853         i=$((i + 1))
15854     done
15855
15856     echo $size_string
15857 }
15858
15859 get_rename_size() {
15860         local size=$1
15861         local context=${2:-.}
15862         local sample=$(do_facet $SINGLEMDS $LCTL \
15863                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15864                 grep -A1 $context |
15865                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15866         echo $sample
15867 }
15868
15869 test_133d() {
15870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15871         remote_ost_nodsh && skip "remote OST with nodsh"
15872         remote_mds_nodsh && skip "remote MDS with nodsh"
15873         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15874                 skip_env "MDS doesn't support rename stats"
15875
15876         local testdir1=$DIR/${tdir}/stats_testdir1
15877         local testdir2=$DIR/${tdir}/stats_testdir2
15878         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15879
15880         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15881
15882         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15883         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15884
15885         createmany -o $testdir1/test 512 || error "createmany failed"
15886
15887         # check samedir rename size
15888         mv ${testdir1}/test0 ${testdir1}/test_0
15889
15890         local testdir1_size=$(ls -l $DIR/${tdir} |
15891                 awk '/stats_testdir1/ {print $5}')
15892         local testdir2_size=$(ls -l $DIR/${tdir} |
15893                 awk '/stats_testdir2/ {print $5}')
15894
15895         testdir1_size=$(order_2 $testdir1_size)
15896         testdir2_size=$(order_2 $testdir2_size)
15897
15898         testdir1_size=$(size_in_KMGT $testdir1_size)
15899         testdir2_size=$(size_in_KMGT $testdir2_size)
15900
15901         echo "source rename dir size: ${testdir1_size}"
15902         echo "target rename dir size: ${testdir2_size}"
15903
15904         local cmd="do_facet $SINGLEMDS $LCTL "
15905         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15906
15907         eval $cmd || error "$cmd failed"
15908         local samedir=$($cmd | grep 'same_dir')
15909         local same_sample=$(get_rename_size $testdir1_size)
15910         [ -z "$samedir" ] && error "samedir_rename_size count error"
15911         [[ $same_sample -eq 1 ]] ||
15912                 error "samedir_rename_size error $same_sample"
15913         echo "Check same dir rename stats success"
15914
15915         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15916
15917         # check crossdir rename size
15918         mv ${testdir1}/test_0 ${testdir2}/test_0
15919
15920         testdir1_size=$(ls -l $DIR/${tdir} |
15921                 awk '/stats_testdir1/ {print $5}')
15922         testdir2_size=$(ls -l $DIR/${tdir} |
15923                 awk '/stats_testdir2/ {print $5}')
15924
15925         testdir1_size=$(order_2 $testdir1_size)
15926         testdir2_size=$(order_2 $testdir2_size)
15927
15928         testdir1_size=$(size_in_KMGT $testdir1_size)
15929         testdir2_size=$(size_in_KMGT $testdir2_size)
15930
15931         echo "source rename dir size: ${testdir1_size}"
15932         echo "target rename dir size: ${testdir2_size}"
15933
15934         eval $cmd || error "$cmd failed"
15935         local crossdir=$($cmd | grep 'crossdir')
15936         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15937         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15938         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15939         [[ $src_sample -eq 1 ]] ||
15940                 error "crossdir_rename_size error $src_sample"
15941         [[ $tgt_sample -eq 1 ]] ||
15942                 error "crossdir_rename_size error $tgt_sample"
15943         echo "Check cross dir rename stats success"
15944         rm -rf $DIR/${tdir}
15945 }
15946 run_test 133d "Verifying rename_stats ========================================"
15947
15948 test_133e() {
15949         remote_mds_nodsh && skip "remote MDS with nodsh"
15950         remote_ost_nodsh && skip "remote OST with nodsh"
15951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15952
15953         local testdir=$DIR/${tdir}/stats_testdir
15954         local ctr f0 f1 bs=32768 count=42 sum
15955
15956         mkdir -p ${testdir} || error "mkdir failed"
15957
15958         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15959
15960         for ctr in {write,read}_bytes; do
15961                 sync
15962                 cancel_lru_locks osc
15963
15964                 do_facet ost1 $LCTL set_param -n \
15965                         "obdfilter.*.exports.clear=clear"
15966
15967                 if [ $ctr = write_bytes ]; then
15968                         f0=/dev/zero
15969                         f1=${testdir}/${tfile}
15970                 else
15971                         f0=${testdir}/${tfile}
15972                         f1=/dev/null
15973                 fi
15974
15975                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15976                         error "dd failed"
15977                 sync
15978                 cancel_lru_locks osc
15979
15980                 sum=$(do_facet ost1 $LCTL get_param \
15981                         "obdfilter.*.exports.*.stats" |
15982                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15983                                 $1 == ctr { sum += $7 }
15984                                 END { printf("%0.0f", sum) }')
15985
15986                 if ((sum != bs * count)); then
15987                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15988                 fi
15989         done
15990
15991         rm -rf $DIR/${tdir}
15992 }
15993 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15994
15995 test_133f() {
15996         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15997                 skip "too old lustre for get_param -R ($facet_ver)"
15998
15999         # verifying readability.
16000         $LCTL get_param -R '*' &> /dev/null
16001
16002         # Verifing writability with badarea_io.
16003         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16004         local skipped_params='force_lbug|changelog_mask|daemon_file'
16005         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16006                 egrep -v "$skipped_params" |
16007                 xargs -n 1 find $proc_dirs -name |
16008                 xargs -n 1 badarea_io ||
16009                 error "client badarea_io failed"
16010
16011         # remount the FS in case writes/reads /proc break the FS
16012         cleanup || error "failed to unmount"
16013         setup || error "failed to setup"
16014 }
16015 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16016
16017 test_133g() {
16018         remote_mds_nodsh && skip "remote MDS with nodsh"
16019         remote_ost_nodsh && skip "remote OST with nodsh"
16020
16021         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16022         local proc_dirs_str=$(eval echo $proc_dirs)
16023         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16024         local facet
16025         for facet in mds1 ost1; do
16026                 local facet_ver=$(lustre_version_code $facet)
16027                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16028                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16029                 else
16030                         log "$facet: too old lustre for get_param -R"
16031                 fi
16032                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16033                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16034                                 tr -d = | egrep -v $skipped_params |
16035                                 xargs -n 1 find $proc_dirs_str -name |
16036                                 xargs -n 1 badarea_io" ||
16037                                         error "$facet badarea_io failed"
16038                 else
16039                         skip_noexit "$facet: too old lustre for get_param -R"
16040                 fi
16041         done
16042
16043         # remount the FS in case writes/reads /proc break the FS
16044         cleanup || error "failed to unmount"
16045         setup || error "failed to setup"
16046 }
16047 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16048
16049 test_133h() {
16050         remote_mds_nodsh && skip "remote MDS with nodsh"
16051         remote_ost_nodsh && skip "remote OST with nodsh"
16052         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16053                 skip "Need MDS version at least 2.9.54"
16054
16055         local facet
16056         for facet in client mds1 ost1; do
16057                 # Get the list of files that are missing the terminating newline
16058                 local plist=$(do_facet $facet
16059                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16060                 local ent
16061                 for ent in $plist; do
16062                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16063                                 awk -v FS='\v' -v RS='\v\v' \
16064                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16065                                         print FILENAME}'" 2>/dev/null)
16066                         [ -z $missing ] || {
16067                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16068                                 error "file does not end with newline: $facet-$ent"
16069                         }
16070                 done
16071         done
16072 }
16073 run_test 133h "Proc files should end with newlines"
16074
16075 test_134a() {
16076         remote_mds_nodsh && skip "remote MDS with nodsh"
16077         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16078                 skip "Need MDS version at least 2.7.54"
16079
16080         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16081         cancel_lru_locks mdc
16082
16083         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16084         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16085         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16086
16087         local nr=1000
16088         createmany -o $DIR/$tdir/f $nr ||
16089                 error "failed to create $nr files in $DIR/$tdir"
16090         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16091
16092         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16093         do_facet mds1 $LCTL set_param fail_loc=0x327
16094         do_facet mds1 $LCTL set_param fail_val=500
16095         touch $DIR/$tdir/m
16096
16097         echo "sleep 10 seconds ..."
16098         sleep 10
16099         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16100
16101         do_facet mds1 $LCTL set_param fail_loc=0
16102         do_facet mds1 $LCTL set_param fail_val=0
16103         [ $lck_cnt -lt $unused ] ||
16104                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16105
16106         rm $DIR/$tdir/m
16107         unlinkmany $DIR/$tdir/f $nr
16108 }
16109 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16110
16111 test_134b() {
16112         remote_mds_nodsh && skip "remote MDS with nodsh"
16113         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16114                 skip "Need MDS version at least 2.7.54"
16115
16116         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16117         cancel_lru_locks mdc
16118
16119         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16120                         ldlm.lock_reclaim_threshold_mb)
16121         # disable reclaim temporarily
16122         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16123
16124         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16125         do_facet mds1 $LCTL set_param fail_loc=0x328
16126         do_facet mds1 $LCTL set_param fail_val=500
16127
16128         $LCTL set_param debug=+trace
16129
16130         local nr=600
16131         createmany -o $DIR/$tdir/f $nr &
16132         local create_pid=$!
16133
16134         echo "Sleep $TIMEOUT seconds ..."
16135         sleep $TIMEOUT
16136         if ! ps -p $create_pid  > /dev/null 2>&1; then
16137                 do_facet mds1 $LCTL set_param fail_loc=0
16138                 do_facet mds1 $LCTL set_param fail_val=0
16139                 do_facet mds1 $LCTL set_param \
16140                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16141                 error "createmany finished incorrectly!"
16142         fi
16143         do_facet mds1 $LCTL set_param fail_loc=0
16144         do_facet mds1 $LCTL set_param fail_val=0
16145         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16146         wait $create_pid || return 1
16147
16148         unlinkmany $DIR/$tdir/f $nr
16149 }
16150 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16151
16152 test_135() {
16153         remote_mds_nodsh && skip "remote MDS with nodsh"
16154         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16155                 skip "Need MDS version at least 2.13.50"
16156         local fname
16157
16158         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16159
16160 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16161         #set only one record at plain llog
16162         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16163
16164         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16165
16166         #fill already existed plain llog each 64767
16167         #wrapping whole catalog
16168         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16169
16170         createmany -o $DIR/$tdir/$tfile_ 64700
16171         for (( i = 0; i < 64700; i = i + 2 ))
16172         do
16173                 rm $DIR/$tdir/$tfile_$i &
16174                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16175                 local pid=$!
16176                 wait $pid
16177         done
16178
16179         #waiting osp synchronization
16180         wait_delete_completed
16181 }
16182 run_test 135 "Race catalog processing"
16183
16184 test_136() {
16185         remote_mds_nodsh && skip "remote MDS with nodsh"
16186         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16187                 skip "Need MDS version at least 2.13.50"
16188         local fname
16189
16190         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16191         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16192         #set only one record at plain llog
16193 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16194         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16195
16196         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16197
16198         #fill already existed 2 plain llogs each 64767
16199         #wrapping whole catalog
16200         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16201         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16202         wait_delete_completed
16203
16204         createmany -o $DIR/$tdir/$tfile_ 10
16205         sleep 25
16206
16207         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16208         for (( i = 0; i < 10; i = i + 3 ))
16209         do
16210                 rm $DIR/$tdir/$tfile_$i &
16211                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16212                 local pid=$!
16213                 wait $pid
16214                 sleep 7
16215                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16216         done
16217
16218         #waiting osp synchronization
16219         wait_delete_completed
16220 }
16221 run_test 136 "Race catalog processing 2"
16222
16223 test_140() { #bug-17379
16224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16225
16226         test_mkdir $DIR/$tdir
16227         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16228         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16229
16230         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16231         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16232         local i=0
16233         while i=$((i + 1)); do
16234                 test_mkdir $i
16235                 cd $i || error "Changing to $i"
16236                 ln -s ../stat stat || error "Creating stat symlink"
16237                 # Read the symlink until ELOOP present,
16238                 # not LBUGing the system is considered success,
16239                 # we didn't overrun the stack.
16240                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16241                 if [ $ret -ne 0 ]; then
16242                         if [ $ret -eq 40 ]; then
16243                                 break  # -ELOOP
16244                         else
16245                                 error "Open stat symlink"
16246                                         return
16247                         fi
16248                 fi
16249         done
16250         i=$((i - 1))
16251         echo "The symlink depth = $i"
16252         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16253                 error "Invalid symlink depth"
16254
16255         # Test recursive symlink
16256         ln -s symlink_self symlink_self
16257         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16258         echo "open symlink_self returns $ret"
16259         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16260 }
16261 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16262
16263 test_150a() {
16264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16265
16266         local TF="$TMP/$tfile"
16267
16268         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16269         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16270         cp $TF $DIR/$tfile
16271         cancel_lru_locks $OSC
16272         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16273         remount_client $MOUNT
16274         df -P $MOUNT
16275         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16276
16277         $TRUNCATE $TF 6000
16278         $TRUNCATE $DIR/$tfile 6000
16279         cancel_lru_locks $OSC
16280         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16281
16282         echo "12345" >>$TF
16283         echo "12345" >>$DIR/$tfile
16284         cancel_lru_locks $OSC
16285         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16286
16287         echo "12345" >>$TF
16288         echo "12345" >>$DIR/$tfile
16289         cancel_lru_locks $OSC
16290         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16291 }
16292 run_test 150a "truncate/append tests"
16293
16294 test_150b() {
16295         check_set_fallocate_or_skip
16296         local out
16297
16298         touch $DIR/$tfile
16299         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16300         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16301                 skip_eopnotsupp "$out|check_fallocate failed"
16302 }
16303 run_test 150b "Verify fallocate (prealloc) functionality"
16304
16305 test_150bb() {
16306         check_set_fallocate_or_skip
16307
16308         touch $DIR/$tfile
16309         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16310         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16311         > $DIR/$tfile
16312         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16313         # precomputed md5sum for 20MB of zeroes
16314         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16315         local sum=($(md5sum $DIR/$tfile))
16316
16317         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16318
16319         check_set_fallocate 1
16320
16321         > $DIR/$tfile
16322         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16323         sum=($(md5sum $DIR/$tfile))
16324
16325         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16326 }
16327 run_test 150bb "Verify fallocate modes both zero space"
16328
16329 test_150c() {
16330         check_set_fallocate_or_skip
16331         local striping="-c2"
16332
16333         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16334         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16335         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16336         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16337         local want=$((OSTCOUNT * 1048576))
16338
16339         # Must allocate all requested space, not more than 5% extra
16340         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16341                 error "bytes $bytes is not $want"
16342
16343         rm -f $DIR/$tfile
16344
16345         echo "verify fallocate on PFL file"
16346
16347         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16348
16349         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16350                 error "Create $DIR/$tfile failed"
16351         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16352         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16353         want=$((512 * 1048576))
16354
16355         # Must allocate all requested space, not more than 5% extra
16356         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16357                 error "bytes $bytes is not $want"
16358 }
16359 run_test 150c "Verify fallocate Size and Blocks"
16360
16361 test_150d() {
16362         check_set_fallocate_or_skip
16363         local striping="-c2"
16364
16365         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16366
16367         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16368         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16369                 error "setstripe failed"
16370         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16371         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16372         local want=$((OSTCOUNT * 1048576))
16373
16374         # Must allocate all requested space, not more than 5% extra
16375         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16376                 error "bytes $bytes is not $want"
16377 }
16378 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16379
16380 test_150e() {
16381         check_set_fallocate_or_skip
16382
16383         echo "df before:"
16384         $LFS df
16385         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16386         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16387                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16388
16389         # Find OST with Minimum Size
16390         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16391                        sort -un | head -1)
16392
16393         # Get 100MB per OST of the available space to reduce run time
16394         # else 60% of the available space if we are running SLOW tests
16395         if [ $SLOW == "no" ]; then
16396                 local space=$((1024 * 100 * OSTCOUNT))
16397         else
16398                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16399         fi
16400
16401         fallocate -l${space}k $DIR/$tfile ||
16402                 error "fallocate ${space}k $DIR/$tfile failed"
16403         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16404
16405         # get size immediately after fallocate. This should be correctly
16406         # updated
16407         local size=$(stat -c '%s' $DIR/$tfile)
16408         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16409
16410         # Sleep for a while for statfs to get updated. And not pull from cache.
16411         sleep 2
16412
16413         echo "df after fallocate:"
16414         $LFS df
16415
16416         (( size / 1024 == space )) || error "size $size != requested $space"
16417         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16418                 error "used $used < space $space"
16419
16420         rm $DIR/$tfile || error "rm failed"
16421         sync
16422         wait_delete_completed
16423
16424         echo "df after unlink:"
16425         $LFS df
16426 }
16427 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16428
16429 test_150f() {
16430         local size
16431         local blocks
16432         local want_size_before=20480 # in bytes
16433         local want_blocks_before=40 # 512 sized blocks
16434         local want_blocks_after=24  # 512 sized blocks
16435         local length=$(((want_blocks_before - want_blocks_after) * 512))
16436
16437         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16438                 skip "need at least 2.14.0 for fallocate punch"
16439
16440         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16441                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16442         fi
16443
16444         check_set_fallocate_or_skip
16445         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16446
16447         [[ "x$DOM" == "xyes" ]] &&
16448                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16449
16450         echo "Verify fallocate punch: Range within the file range"
16451         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16452                 error "dd failed for bs 4096 and count 5"
16453
16454         # Call fallocate with punch range which is within the file range
16455         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16456                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16457         # client must see changes immediately after fallocate
16458         size=$(stat -c '%s' $DIR/$tfile)
16459         blocks=$(stat -c '%b' $DIR/$tfile)
16460
16461         # Verify punch worked.
16462         (( blocks == want_blocks_after )) ||
16463                 error "punch failed: blocks $blocks != $want_blocks_after"
16464
16465         (( size == want_size_before )) ||
16466                 error "punch failed: size $size != $want_size_before"
16467
16468         # Verify there is hole in file
16469         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16470         # precomputed md5sum
16471         local expect="4a9a834a2db02452929c0a348273b4aa"
16472
16473         cksum=($(md5sum $DIR/$tfile))
16474         [[ "${cksum[0]}" == "$expect" ]] ||
16475                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16476
16477         # Start second sub-case for fallocate punch.
16478         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16479         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16480                 error "dd failed for bs 4096 and count 5"
16481
16482         # Punch range less than block size will have no change in block count
16483         want_blocks_after=40  # 512 sized blocks
16484
16485         # Punch overlaps two blocks and less than blocksize
16486         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16487                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16488         size=$(stat -c '%s' $DIR/$tfile)
16489         blocks=$(stat -c '%b' $DIR/$tfile)
16490
16491         # Verify punch worked.
16492         (( blocks == want_blocks_after )) ||
16493                 error "punch failed: blocks $blocks != $want_blocks_after"
16494
16495         (( size == want_size_before )) ||
16496                 error "punch failed: size $size != $want_size_before"
16497
16498         # Verify if range is really zero'ed out. We expect Zeros.
16499         # precomputed md5sum
16500         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16501         cksum=($(md5sum $DIR/$tfile))
16502         [[ "${cksum[0]}" == "$expect" ]] ||
16503                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16504 }
16505 run_test 150f "Verify fallocate punch functionality"
16506
16507 test_150g() {
16508         local space
16509         local size
16510         local blocks
16511         local blocks_after
16512         local size_after
16513         local BS=4096 # Block size in bytes
16514
16515         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16516                 skip "need at least 2.14.0 for fallocate punch"
16517
16518         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16519                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16520         fi
16521
16522         check_set_fallocate_or_skip
16523         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16524
16525         if [[ "x$DOM" == "xyes" ]]; then
16526                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16527                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16528         else
16529                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16530                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16531         fi
16532
16533         # Get 100MB per OST of the available space to reduce run time
16534         # else 60% of the available space if we are running SLOW tests
16535         if [ $SLOW == "no" ]; then
16536                 space=$((1024 * 100 * OSTCOUNT))
16537         else
16538                 # Find OST with Minimum Size
16539                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16540                         sort -un | head -1)
16541                 echo "min size OST: $space"
16542                 space=$(((space * 60)/100 * OSTCOUNT))
16543         fi
16544         # space in 1k units, round to 4k blocks
16545         local blkcount=$((space * 1024 / $BS))
16546
16547         echo "Verify fallocate punch: Very large Range"
16548         fallocate -l${space}k $DIR/$tfile ||
16549                 error "fallocate ${space}k $DIR/$tfile failed"
16550         # write 1M at the end, start and in the middle
16551         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16552                 error "dd failed: bs $BS count 256"
16553         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16554                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16555         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16556                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16557
16558         # Gather stats.
16559         size=$(stat -c '%s' $DIR/$tfile)
16560
16561         # gather punch length.
16562         local punch_size=$((size - (BS * 2)))
16563
16564         echo "punch_size = $punch_size"
16565         echo "size - punch_size: $((size - punch_size))"
16566         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16567
16568         # Call fallocate to punch all except 2 blocks. We leave the
16569         # first and the last block
16570         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16571         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16572                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16573
16574         size_after=$(stat -c '%s' $DIR/$tfile)
16575         blocks_after=$(stat -c '%b' $DIR/$tfile)
16576
16577         # Verify punch worked.
16578         # Size should be kept
16579         (( size == size_after )) ||
16580                 error "punch failed: size $size != $size_after"
16581
16582         # two 4k data blocks to remain plus possible 1 extra extent block
16583         (( blocks_after <= ((BS / 512) * 3) )) ||
16584                 error "too many blocks remains: $blocks_after"
16585
16586         # Verify that file has hole between the first and the last blocks
16587         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16588         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16589
16590         echo "Hole at [$hole_start, $hole_end)"
16591         (( hole_start == BS )) ||
16592                 error "no hole at offset $BS after punch"
16593
16594         (( hole_end == BS + punch_size )) ||
16595                 error "data at offset $hole_end < $((BS + punch_size))"
16596 }
16597 run_test 150g "Verify fallocate punch on large range"
16598
16599 test_150h() {
16600         local file=$DIR/$tfile
16601         local size
16602
16603         check_set_fallocate_or_skip
16604         statx_supported || skip_env "Test must be statx() syscall supported"
16605
16606         # fallocate() does not update the size information on the MDT
16607         fallocate -l 16K $file || error "failed to fallocate $file"
16608         cancel_lru_locks $OSC
16609         # STATX with cached-always mode will not send glimpse RPCs to OST,
16610         # it uses the caching attrs on the client side as much as possible.
16611         size=$($STATX --cached=always -c %s $file)
16612         [ $size == 16384 ] ||
16613                 error "size after fallocate() is $size, expected 16384"
16614 }
16615 run_test 150h "Verify extend fallocate updates the file size"
16616
16617 #LU-2902 roc_hit was not able to read all values from lproc
16618 function roc_hit_init() {
16619         local list=$(comma_list $(osts_nodes))
16620         local dir=$DIR/$tdir-check
16621         local file=$dir/$tfile
16622         local BEFORE
16623         local AFTER
16624         local idx
16625
16626         test_mkdir $dir
16627         #use setstripe to do a write to every ost
16628         for i in $(seq 0 $((OSTCOUNT-1))); do
16629                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16630                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16631                 idx=$(printf %04x $i)
16632                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16633                         awk '$1 == "cache_access" {sum += $7}
16634                                 END { printf("%0.0f", sum) }')
16635
16636                 cancel_lru_locks osc
16637                 cat $file >/dev/null
16638
16639                 AFTER=$(get_osd_param $list *OST*$idx stats |
16640                         awk '$1 == "cache_access" {sum += $7}
16641                                 END { printf("%0.0f", sum) }')
16642
16643                 echo BEFORE:$BEFORE AFTER:$AFTER
16644                 if ! let "AFTER - BEFORE == 4"; then
16645                         rm -rf $dir
16646                         error "roc_hit is not safe to use"
16647                 fi
16648                 rm $file
16649         done
16650
16651         rm -rf $dir
16652 }
16653
16654 function roc_hit() {
16655         local list=$(comma_list $(osts_nodes))
16656         echo $(get_osd_param $list '' stats |
16657                 awk '$1 == "cache_hit" {sum += $7}
16658                         END { printf("%0.0f", sum) }')
16659 }
16660
16661 function set_cache() {
16662         local on=1
16663
16664         if [ "$2" == "off" ]; then
16665                 on=0;
16666         fi
16667         local list=$(comma_list $(osts_nodes))
16668         set_osd_param $list '' $1_cache_enable $on
16669
16670         cancel_lru_locks osc
16671 }
16672
16673 test_151() {
16674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16675         remote_ost_nodsh && skip "remote OST with nodsh"
16676         (( CLIENT_VERSION == OST1_VERSION )) ||
16677                 skip "LU-13081: no interop testing for OSS cache"
16678
16679         local CPAGES=3
16680         local list=$(comma_list $(osts_nodes))
16681
16682         # check whether obdfilter is cache capable at all
16683         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16684                 skip "not cache-capable obdfilter"
16685         fi
16686
16687         # check cache is enabled on all obdfilters
16688         if get_osd_param $list '' read_cache_enable | grep 0; then
16689                 skip "oss cache is disabled"
16690         fi
16691
16692         set_osd_param $list '' writethrough_cache_enable 1
16693
16694         # check write cache is enabled on all obdfilters
16695         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16696                 skip "oss write cache is NOT enabled"
16697         fi
16698
16699         roc_hit_init
16700
16701         #define OBD_FAIL_OBD_NO_LRU  0x609
16702         do_nodes $list $LCTL set_param fail_loc=0x609
16703
16704         # pages should be in the case right after write
16705         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16706                 error "dd failed"
16707
16708         local BEFORE=$(roc_hit)
16709         cancel_lru_locks osc
16710         cat $DIR/$tfile >/dev/null
16711         local AFTER=$(roc_hit)
16712
16713         do_nodes $list $LCTL set_param fail_loc=0
16714
16715         if ! let "AFTER - BEFORE == CPAGES"; then
16716                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16717         fi
16718
16719         cancel_lru_locks osc
16720         # invalidates OST cache
16721         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16722         set_osd_param $list '' read_cache_enable 0
16723         cat $DIR/$tfile >/dev/null
16724
16725         # now data shouldn't be found in the cache
16726         BEFORE=$(roc_hit)
16727         cancel_lru_locks osc
16728         cat $DIR/$tfile >/dev/null
16729         AFTER=$(roc_hit)
16730         if let "AFTER - BEFORE != 0"; then
16731                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16732         fi
16733
16734         set_osd_param $list '' read_cache_enable 1
16735         rm -f $DIR/$tfile
16736 }
16737 run_test 151 "test cache on oss and controls ==============================="
16738
16739 test_152() {
16740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16741
16742         local TF="$TMP/$tfile"
16743
16744         # simulate ENOMEM during write
16745 #define OBD_FAIL_OST_NOMEM      0x226
16746         lctl set_param fail_loc=0x80000226
16747         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16748         cp $TF $DIR/$tfile
16749         sync || error "sync failed"
16750         lctl set_param fail_loc=0
16751
16752         # discard client's cache
16753         cancel_lru_locks osc
16754
16755         # simulate ENOMEM during read
16756         lctl set_param fail_loc=0x80000226
16757         cmp $TF $DIR/$tfile || error "cmp failed"
16758         lctl set_param fail_loc=0
16759
16760         rm -f $TF
16761 }
16762 run_test 152 "test read/write with enomem ============================"
16763
16764 test_153() {
16765         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16766 }
16767 run_test 153 "test if fdatasync does not crash ======================="
16768
16769 dot_lustre_fid_permission_check() {
16770         local fid=$1
16771         local ffid=$MOUNT/.lustre/fid/$fid
16772         local test_dir=$2
16773
16774         echo "stat fid $fid"
16775         stat $ffid || error "stat $ffid failed."
16776         echo "touch fid $fid"
16777         touch $ffid || error "touch $ffid failed."
16778         echo "write to fid $fid"
16779         cat /etc/hosts > $ffid || error "write $ffid failed."
16780         echo "read fid $fid"
16781         diff /etc/hosts $ffid || error "read $ffid failed."
16782         echo "append write to fid $fid"
16783         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16784         echo "rename fid $fid"
16785         mv $ffid $test_dir/$tfile.1 &&
16786                 error "rename $ffid to $tfile.1 should fail."
16787         touch $test_dir/$tfile.1
16788         mv $test_dir/$tfile.1 $ffid &&
16789                 error "rename $tfile.1 to $ffid should fail."
16790         rm -f $test_dir/$tfile.1
16791         echo "truncate fid $fid"
16792         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16793         echo "link fid $fid"
16794         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16795         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16796                 id $USER0 || skip_env "missing user $USER0"
16797                 echo "setfacl fid $fid"
16798                 setfacl -R -m u:$USER0:rwx $ffid ||
16799                         error "setfacl $ffid failed"
16800                 echo "getfacl fid $fid"
16801                 getfacl $ffid || error "getfacl $ffid failed."
16802         fi
16803         echo "unlink fid $fid"
16804         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16805         echo "mknod fid $fid"
16806         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16807
16808         fid=[0xf00000400:0x1:0x0]
16809         ffid=$MOUNT/.lustre/fid/$fid
16810
16811         echo "stat non-exist fid $fid"
16812         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16813         echo "write to non-exist fid $fid"
16814         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16815         echo "link new fid $fid"
16816         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16817
16818         mkdir -p $test_dir/$tdir
16819         touch $test_dir/$tdir/$tfile
16820         fid=$($LFS path2fid $test_dir/$tdir)
16821         rc=$?
16822         [ $rc -ne 0 ] &&
16823                 error "error: could not get fid for $test_dir/$dir/$tfile."
16824
16825         ffid=$MOUNT/.lustre/fid/$fid
16826
16827         echo "ls $fid"
16828         ls $ffid || error "ls $ffid failed."
16829         echo "touch $fid/$tfile.1"
16830         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16831
16832         echo "touch $MOUNT/.lustre/fid/$tfile"
16833         touch $MOUNT/.lustre/fid/$tfile && \
16834                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16835
16836         echo "setxattr to $MOUNT/.lustre/fid"
16837         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16838
16839         echo "listxattr for $MOUNT/.lustre/fid"
16840         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16841
16842         echo "delxattr from $MOUNT/.lustre/fid"
16843         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16844
16845         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16846         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16847                 error "touch invalid fid should fail."
16848
16849         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16850         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16851                 error "touch non-normal fid should fail."
16852
16853         echo "rename $tdir to $MOUNT/.lustre/fid"
16854         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16855                 error "rename to $MOUNT/.lustre/fid should fail."
16856
16857         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16858         then            # LU-3547
16859                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16860                 local new_obf_mode=777
16861
16862                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16863                 chmod $new_obf_mode $DIR/.lustre/fid ||
16864                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16865
16866                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16867                 [ $obf_mode -eq $new_obf_mode ] ||
16868                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16869
16870                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16871                 chmod $old_obf_mode $DIR/.lustre/fid ||
16872                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16873         fi
16874
16875         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16876         fid=$($LFS path2fid $test_dir/$tfile-2)
16877
16878         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16879         then # LU-5424
16880                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16881                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16882                         error "create lov data thru .lustre failed"
16883         fi
16884         echo "cp /etc/passwd $test_dir/$tfile-2"
16885         cp /etc/passwd $test_dir/$tfile-2 ||
16886                 error "copy to $test_dir/$tfile-2 failed."
16887         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16888         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16889                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16890
16891         rm -rf $test_dir/tfile.lnk
16892         rm -rf $test_dir/$tfile-2
16893 }
16894
16895 test_154A() {
16896         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16897                 skip "Need MDS version at least 2.4.1"
16898
16899         local tf=$DIR/$tfile
16900         touch $tf
16901
16902         local fid=$($LFS path2fid $tf)
16903         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16904
16905         # check that we get the same pathname back
16906         local rootpath
16907         local found
16908         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16909                 echo "$rootpath $fid"
16910                 found=$($LFS fid2path $rootpath "$fid")
16911                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16912                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16913         done
16914
16915         # check wrong root path format
16916         rootpath=$MOUNT"_wrong"
16917         found=$($LFS fid2path $rootpath "$fid")
16918         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16919 }
16920 run_test 154A "lfs path2fid and fid2path basic checks"
16921
16922 test_154B() {
16923         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16924                 skip "Need MDS version at least 2.4.1"
16925
16926         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16927         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16928         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16929         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16930
16931         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16932         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16933
16934         # check that we get the same pathname
16935         echo "PFID: $PFID, name: $name"
16936         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16937         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16938         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16939                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16940
16941         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16942 }
16943 run_test 154B "verify the ll_decode_linkea tool"
16944
16945 test_154a() {
16946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16947         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16948         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16949                 skip "Need MDS version at least 2.2.51"
16950         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16951
16952         cp /etc/hosts $DIR/$tfile
16953
16954         fid=$($LFS path2fid $DIR/$tfile)
16955         rc=$?
16956         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16957
16958         dot_lustre_fid_permission_check "$fid" $DIR ||
16959                 error "dot lustre permission check $fid failed"
16960
16961         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16962
16963         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16964
16965         touch $MOUNT/.lustre/file &&
16966                 error "creation is not allowed under .lustre"
16967
16968         mkdir $MOUNT/.lustre/dir &&
16969                 error "mkdir is not allowed under .lustre"
16970
16971         rm -rf $DIR/$tfile
16972 }
16973 run_test 154a "Open-by-FID"
16974
16975 test_154b() {
16976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16977         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16979         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16980                 skip "Need MDS version at least 2.2.51"
16981
16982         local remote_dir=$DIR/$tdir/remote_dir
16983         local MDTIDX=1
16984         local rc=0
16985
16986         mkdir -p $DIR/$tdir
16987         $LFS mkdir -i $MDTIDX $remote_dir ||
16988                 error "create remote directory failed"
16989
16990         cp /etc/hosts $remote_dir/$tfile
16991
16992         fid=$($LFS path2fid $remote_dir/$tfile)
16993         rc=$?
16994         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16995
16996         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16997                 error "dot lustre permission check $fid failed"
16998         rm -rf $DIR/$tdir
16999 }
17000 run_test 154b "Open-by-FID for remote directory"
17001
17002 test_154c() {
17003         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17004                 skip "Need MDS version at least 2.4.1"
17005
17006         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17007         local FID1=$($LFS path2fid $DIR/$tfile.1)
17008         local FID2=$($LFS path2fid $DIR/$tfile.2)
17009         local FID3=$($LFS path2fid $DIR/$tfile.3)
17010
17011         local N=1
17012         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17013                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17014                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17015                 local want=FID$N
17016                 [ "$FID" = "${!want}" ] ||
17017                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17018                 N=$((N + 1))
17019         done
17020
17021         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17022         do
17023                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17024                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17025                 N=$((N + 1))
17026         done
17027 }
17028 run_test 154c "lfs path2fid and fid2path multiple arguments"
17029
17030 test_154d() {
17031         remote_mds_nodsh && skip "remote MDS with nodsh"
17032         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17033                 skip "Need MDS version at least 2.5.53"
17034
17035         if remote_mds; then
17036                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17037         else
17038                 nid="0@lo"
17039         fi
17040         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17041         local fd
17042         local cmd
17043
17044         rm -f $DIR/$tfile
17045         touch $DIR/$tfile
17046
17047         local fid=$($LFS path2fid $DIR/$tfile)
17048         # Open the file
17049         fd=$(free_fd)
17050         cmd="exec $fd<$DIR/$tfile"
17051         eval $cmd
17052         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17053         echo "$fid_list" | grep "$fid"
17054         rc=$?
17055
17056         cmd="exec $fd>/dev/null"
17057         eval $cmd
17058         if [ $rc -ne 0 ]; then
17059                 error "FID $fid not found in open files list $fid_list"
17060         fi
17061 }
17062 run_test 154d "Verify open file fid"
17063
17064 test_154e()
17065 {
17066         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17067                 skip "Need MDS version at least 2.6.50"
17068
17069         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17070                 error ".lustre returned by readdir"
17071         fi
17072 }
17073 run_test 154e ".lustre is not returned by readdir"
17074
17075 test_154f() {
17076         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17077
17078         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17079         mkdir_on_mdt0 $DIR/$tdir
17080         # test dirs inherit from its stripe
17081         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17082         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17083         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17084         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17085         touch $DIR/f
17086
17087         # get fid of parents
17088         local FID0=$($LFS path2fid $DIR/$tdir)
17089         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17090         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17091         local FID3=$($LFS path2fid $DIR)
17092
17093         # check that path2fid --parents returns expected <parent_fid>/name
17094         # 1) test for a directory (single parent)
17095         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17096         [ "$parent" == "$FID0/foo1" ] ||
17097                 error "expected parent: $FID0/foo1, got: $parent"
17098
17099         # 2) test for a file with nlink > 1 (multiple parents)
17100         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17101         echo "$parent" | grep -F "$FID1/$tfile" ||
17102                 error "$FID1/$tfile not returned in parent list"
17103         echo "$parent" | grep -F "$FID2/link" ||
17104                 error "$FID2/link not returned in parent list"
17105
17106         # 3) get parent by fid
17107         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17108         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17109         echo "$parent" | grep -F "$FID1/$tfile" ||
17110                 error "$FID1/$tfile not returned in parent list (by fid)"
17111         echo "$parent" | grep -F "$FID2/link" ||
17112                 error "$FID2/link not returned in parent list (by fid)"
17113
17114         # 4) test for entry in root directory
17115         parent=$($LFS path2fid --parents $DIR/f)
17116         echo "$parent" | grep -F "$FID3/f" ||
17117                 error "$FID3/f not returned in parent list"
17118
17119         # 5) test it on root directory
17120         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17121                 error "$MOUNT should not have parents"
17122
17123         # enable xattr caching and check that linkea is correctly updated
17124         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17125         save_lustre_params client "llite.*.xattr_cache" > $save
17126         lctl set_param llite.*.xattr_cache 1
17127
17128         # 6.1) linkea update on rename
17129         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17130
17131         # get parents by fid
17132         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17133         # foo1 should no longer be returned in parent list
17134         echo "$parent" | grep -F "$FID1" &&
17135                 error "$FID1 should no longer be in parent list"
17136         # the new path should appear
17137         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17138                 error "$FID2/$tfile.moved is not in parent list"
17139
17140         # 6.2) linkea update on unlink
17141         rm -f $DIR/$tdir/foo2/link
17142         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17143         # foo2/link should no longer be returned in parent list
17144         echo "$parent" | grep -F "$FID2/link" &&
17145                 error "$FID2/link should no longer be in parent list"
17146         true
17147
17148         rm -f $DIR/f
17149         restore_lustre_params < $save
17150         rm -f $save
17151 }
17152 run_test 154f "get parent fids by reading link ea"
17153
17154 test_154g()
17155 {
17156         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17157            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17158                 skip "Need MDS version at least 2.6.92"
17159
17160         mkdir_on_mdt0 $DIR/$tdir
17161         llapi_fid_test -d $DIR/$tdir
17162 }
17163 run_test 154g "various llapi FID tests"
17164
17165 test_154h()
17166 {
17167         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17168                 skip "Need client at least version 2.15.55.1"
17169
17170         # Create an empty file
17171         touch $DIR/$tfile
17172
17173         # Get FID (interactive mode) and save under $TMP/$tfile.log
17174         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17175                 path2fid $DIR/$tfile
17176         EOF
17177
17178         fid=$(cat $TMP/$tfile.log)
17179         # $fid should not be empty
17180         [[ ! -z $fid ]] || error "FID is empty"
17181         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17182 }
17183 run_test 154h "Verify interactive path2fid"
17184
17185 test_155_small_load() {
17186     local temp=$TMP/$tfile
17187     local file=$DIR/$tfile
17188
17189     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17190         error "dd of=$temp bs=6096 count=1 failed"
17191     cp $temp $file
17192     cancel_lru_locks $OSC
17193     cmp $temp $file || error "$temp $file differ"
17194
17195     $TRUNCATE $temp 6000
17196     $TRUNCATE $file 6000
17197     cmp $temp $file || error "$temp $file differ (truncate1)"
17198
17199     echo "12345" >>$temp
17200     echo "12345" >>$file
17201     cmp $temp $file || error "$temp $file differ (append1)"
17202
17203     echo "12345" >>$temp
17204     echo "12345" >>$file
17205     cmp $temp $file || error "$temp $file differ (append2)"
17206
17207     rm -f $temp $file
17208     true
17209 }
17210
17211 test_155_big_load() {
17212         remote_ost_nodsh && skip "remote OST with nodsh"
17213
17214         local temp=$TMP/$tfile
17215         local file=$DIR/$tfile
17216
17217         free_min_max
17218         local cache_size=$(do_facet ost$((MAXI+1)) \
17219                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17220
17221         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17222         # pre-set value
17223         if [ -z "$cache_size" ]; then
17224                 cache_size=256
17225         fi
17226         local large_file_size=$((cache_size * 2))
17227
17228         echo "OSS cache size: $cache_size KB"
17229         echo "Large file size: $large_file_size KB"
17230
17231         [ $MAXV -le $large_file_size ] &&
17232                 skip_env "max available OST size needs > $large_file_size KB"
17233
17234         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17235
17236         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17237                 error "dd of=$temp bs=$large_file_size count=1k failed"
17238         cp $temp $file
17239         ls -lh $temp $file
17240         cancel_lru_locks osc
17241         cmp $temp $file || error "$temp $file differ"
17242
17243         rm -f $temp $file
17244         true
17245 }
17246
17247 save_writethrough() {
17248         local facets=$(get_facets OST)
17249
17250         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17251 }
17252
17253 test_155a() {
17254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17255
17256         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17257
17258         save_writethrough $p
17259
17260         set_cache read on
17261         set_cache writethrough on
17262         test_155_small_load
17263         restore_lustre_params < $p
17264         rm -f $p
17265 }
17266 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17267
17268 test_155b() {
17269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17270
17271         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17272
17273         save_writethrough $p
17274
17275         set_cache read on
17276         set_cache writethrough off
17277         test_155_small_load
17278         restore_lustre_params < $p
17279         rm -f $p
17280 }
17281 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17282
17283 test_155c() {
17284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17285
17286         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17287
17288         save_writethrough $p
17289
17290         set_cache read off
17291         set_cache writethrough on
17292         test_155_small_load
17293         restore_lustre_params < $p
17294         rm -f $p
17295 }
17296 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17297
17298 test_155d() {
17299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17300
17301         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17302
17303         save_writethrough $p
17304
17305         set_cache read off
17306         set_cache writethrough off
17307         test_155_small_load
17308         restore_lustre_params < $p
17309         rm -f $p
17310 }
17311 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17312
17313 test_155e() {
17314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17315
17316         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17317
17318         save_writethrough $p
17319
17320         set_cache read on
17321         set_cache writethrough on
17322         test_155_big_load
17323         restore_lustre_params < $p
17324         rm -f $p
17325 }
17326 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17327
17328 test_155f() {
17329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17330
17331         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17332
17333         save_writethrough $p
17334
17335         set_cache read on
17336         set_cache writethrough off
17337         test_155_big_load
17338         restore_lustre_params < $p
17339         rm -f $p
17340 }
17341 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17342
17343 test_155g() {
17344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17345
17346         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17347
17348         save_writethrough $p
17349
17350         set_cache read off
17351         set_cache writethrough on
17352         test_155_big_load
17353         restore_lustre_params < $p
17354         rm -f $p
17355 }
17356 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17357
17358 test_155h() {
17359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17360
17361         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17362
17363         save_writethrough $p
17364
17365         set_cache read off
17366         set_cache writethrough off
17367         test_155_big_load
17368         restore_lustre_params < $p
17369         rm -f $p
17370 }
17371 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17372
17373 test_156() {
17374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17375         remote_ost_nodsh && skip "remote OST with nodsh"
17376         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17377                 skip "stats not implemented on old servers"
17378         [ "$ost1_FSTYPE" = "zfs" ] &&
17379                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17380         (( CLIENT_VERSION == OST1_VERSION )) ||
17381                 skip "LU-13081: no interop testing for OSS cache"
17382
17383         local CPAGES=3
17384         local BEFORE
17385         local AFTER
17386         local file="$DIR/$tfile"
17387         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17388
17389         save_writethrough $p
17390         roc_hit_init
17391
17392         log "Turn on read and write cache"
17393         set_cache read on
17394         set_cache writethrough on
17395
17396         log "Write data and read it back."
17397         log "Read should be satisfied from the cache."
17398         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17399         BEFORE=$(roc_hit)
17400         cancel_lru_locks osc
17401         cat $file >/dev/null
17402         AFTER=$(roc_hit)
17403         if ! let "AFTER - BEFORE == CPAGES"; then
17404                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17405         else
17406                 log "cache hits: before: $BEFORE, after: $AFTER"
17407         fi
17408
17409         log "Read again; it should be satisfied from the cache."
17410         BEFORE=$AFTER
17411         cancel_lru_locks osc
17412         cat $file >/dev/null
17413         AFTER=$(roc_hit)
17414         if ! let "AFTER - BEFORE == CPAGES"; then
17415                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17416         else
17417                 log "cache hits:: before: $BEFORE, after: $AFTER"
17418         fi
17419
17420         log "Turn off the read cache and turn on the write cache"
17421         set_cache read off
17422         set_cache writethrough on
17423
17424         log "Read again; it should be satisfied from the cache."
17425         BEFORE=$(roc_hit)
17426         cancel_lru_locks osc
17427         cat $file >/dev/null
17428         AFTER=$(roc_hit)
17429         if ! let "AFTER - BEFORE == CPAGES"; then
17430                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17431         else
17432                 log "cache hits:: before: $BEFORE, after: $AFTER"
17433         fi
17434
17435         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17436                 # > 2.12.56 uses pagecache if cached
17437                 log "Read again; it should not be satisfied from the cache."
17438                 BEFORE=$AFTER
17439                 cancel_lru_locks osc
17440                 cat $file >/dev/null
17441                 AFTER=$(roc_hit)
17442                 if ! let "AFTER - BEFORE == 0"; then
17443                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17444                 else
17445                         log "cache hits:: before: $BEFORE, after: $AFTER"
17446                 fi
17447         fi
17448
17449         log "Write data and read it back."
17450         log "Read should be satisfied from the cache."
17451         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17452         BEFORE=$(roc_hit)
17453         cancel_lru_locks osc
17454         cat $file >/dev/null
17455         AFTER=$(roc_hit)
17456         if ! let "AFTER - BEFORE == CPAGES"; then
17457                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17458         else
17459                 log "cache hits:: before: $BEFORE, after: $AFTER"
17460         fi
17461
17462         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17463                 # > 2.12.56 uses pagecache if cached
17464                 log "Read again; it should not be satisfied from the cache."
17465                 BEFORE=$AFTER
17466                 cancel_lru_locks osc
17467                 cat $file >/dev/null
17468                 AFTER=$(roc_hit)
17469                 if ! let "AFTER - BEFORE == 0"; then
17470                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17471                 else
17472                         log "cache hits:: before: $BEFORE, after: $AFTER"
17473                 fi
17474         fi
17475
17476         log "Turn off read and write cache"
17477         set_cache read off
17478         set_cache writethrough off
17479
17480         log "Write data and read it back"
17481         log "It should not be satisfied from the cache."
17482         rm -f $file
17483         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17484         cancel_lru_locks osc
17485         BEFORE=$(roc_hit)
17486         cat $file >/dev/null
17487         AFTER=$(roc_hit)
17488         if ! let "AFTER - BEFORE == 0"; then
17489                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17490         else
17491                 log "cache hits:: before: $BEFORE, after: $AFTER"
17492         fi
17493
17494         log "Turn on the read cache and turn off the write cache"
17495         set_cache read on
17496         set_cache writethrough off
17497
17498         log "Write data and read it back"
17499         log "It should not be satisfied from the cache."
17500         rm -f $file
17501         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17502         BEFORE=$(roc_hit)
17503         cancel_lru_locks osc
17504         cat $file >/dev/null
17505         AFTER=$(roc_hit)
17506         if ! let "AFTER - BEFORE == 0"; then
17507                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17508         else
17509                 log "cache hits:: before: $BEFORE, after: $AFTER"
17510         fi
17511
17512         log "Read again; it should be satisfied from the cache."
17513         BEFORE=$(roc_hit)
17514         cancel_lru_locks osc
17515         cat $file >/dev/null
17516         AFTER=$(roc_hit)
17517         if ! let "AFTER - BEFORE == CPAGES"; then
17518                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17519         else
17520                 log "cache hits:: before: $BEFORE, after: $AFTER"
17521         fi
17522
17523         restore_lustre_params < $p
17524         rm -f $p $file
17525 }
17526 run_test 156 "Verification of tunables"
17527
17528 test_160a() {
17529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17530         remote_mds_nodsh && skip "remote MDS with nodsh"
17531         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17532                 skip "Need MDS version at least 2.2.0"
17533
17534         changelog_register || error "changelog_register failed"
17535         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17536         changelog_users $SINGLEMDS | grep -q $cl_user ||
17537                 error "User $cl_user not found in changelog_users"
17538
17539         mkdir_on_mdt0 $DIR/$tdir
17540
17541         # change something
17542         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17543         changelog_clear 0 || error "changelog_clear failed"
17544         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17545         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17546         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17547         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17548         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17549         rm $DIR/$tdir/pics/desktop.jpg
17550
17551         echo "verifying changelog mask"
17552         changelog_chmask "-MKDIR"
17553         changelog_chmask "-CLOSE"
17554
17555         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17556         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17557
17558         changelog_chmask "+MKDIR"
17559         changelog_chmask "+CLOSE"
17560
17561         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17562         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17563
17564         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17565         CLOSES=$(changelog_dump | grep -c "CLOSE")
17566         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17567         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17568
17569         # verify contents
17570         echo "verifying target fid"
17571         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17572         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17573         [ "$fidc" == "$fidf" ] ||
17574                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17575         echo "verifying parent fid"
17576         # The FID returned from the Changelog may be the directory shard on
17577         # a different MDT, and not the FID returned by path2fid on the parent.
17578         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17579         # since this is what will matter when recreating this file in the tree.
17580         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17581         local pathp=$($LFS fid2path $MOUNT "$fidp")
17582         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17583                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17584
17585         echo "getting records for $cl_user"
17586         changelog_users $SINGLEMDS
17587         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17588         local nclr=3
17589         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17590                 error "changelog_clear failed"
17591         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17592         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17593         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17594                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17595
17596         local min0_rec=$(changelog_users $SINGLEMDS |
17597                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17598         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17599                           awk '{ print $1; exit; }')
17600
17601         changelog_dump | tail -n 5
17602         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17603         [ $first_rec == $((min0_rec + 1)) ] ||
17604                 error "first index should be $min0_rec + 1 not $first_rec"
17605
17606         # LU-3446 changelog index reset on MDT restart
17607         local cur_rec1=$(changelog_users $SINGLEMDS |
17608                          awk '/^current.index:/ { print $NF }')
17609         changelog_clear 0 ||
17610                 error "clear all changelog records for $cl_user failed"
17611         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17612         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17613                 error "Fail to start $SINGLEMDS"
17614         local cur_rec2=$(changelog_users $SINGLEMDS |
17615                          awk '/^current.index:/ { print $NF }')
17616         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17617         [ $cur_rec1 == $cur_rec2 ] ||
17618                 error "current index should be $cur_rec1 not $cur_rec2"
17619
17620         echo "verifying users from this test are deregistered"
17621         changelog_deregister || error "changelog_deregister failed"
17622         changelog_users $SINGLEMDS | grep -q $cl_user &&
17623                 error "User '$cl_user' still in changelog_users"
17624
17625         # lctl get_param -n mdd.*.changelog_users
17626         # current_index: 144
17627         # ID    index (idle seconds)
17628         # cl3   144   (2) mask=<list>
17629         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17630                 # this is the normal case where all users were deregistered
17631                 # make sure no new records are added when no users are present
17632                 local last_rec1=$(changelog_users $SINGLEMDS |
17633                                   awk '/^current.index:/ { print $NF }')
17634                 touch $DIR/$tdir/chloe
17635                 local last_rec2=$(changelog_users $SINGLEMDS |
17636                                   awk '/^current.index:/ { print $NF }')
17637                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17638                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17639         else
17640                 # any changelog users must be leftovers from a previous test
17641                 changelog_users $SINGLEMDS
17642                 echo "other changelog users; can't verify off"
17643         fi
17644 }
17645 run_test 160a "changelog sanity"
17646
17647 test_160b() { # LU-3587
17648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17649         remote_mds_nodsh && skip "remote MDS with nodsh"
17650         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17651                 skip "Need MDS version at least 2.2.0"
17652
17653         changelog_register || error "changelog_register failed"
17654         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17655         changelog_users $SINGLEMDS | grep -q $cl_user ||
17656                 error "User '$cl_user' not found in changelog_users"
17657
17658         local longname1=$(str_repeat a 255)
17659         local longname2=$(str_repeat b 255)
17660
17661         cd $DIR
17662         echo "creating very long named file"
17663         touch $longname1 || error "create of '$longname1' failed"
17664         echo "renaming very long named file"
17665         mv $longname1 $longname2
17666
17667         changelog_dump | grep RENME | tail -n 5
17668         rm -f $longname2
17669 }
17670 run_test 160b "Verify that very long rename doesn't crash in changelog"
17671
17672 test_160c() {
17673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17674         remote_mds_nodsh && skip "remote MDS with nodsh"
17675
17676         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17677                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17678                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17679                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17680
17681         local rc=0
17682
17683         # Registration step
17684         changelog_register || error "changelog_register failed"
17685
17686         rm -rf $DIR/$tdir
17687         mkdir -p $DIR/$tdir
17688         $MCREATE $DIR/$tdir/foo_160c
17689         changelog_chmask "-TRUNC"
17690         $TRUNCATE $DIR/$tdir/foo_160c 200
17691         changelog_chmask "+TRUNC"
17692         $TRUNCATE $DIR/$tdir/foo_160c 199
17693         changelog_dump | tail -n 5
17694         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17695         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17696 }
17697 run_test 160c "verify that changelog log catch the truncate event"
17698
17699 test_160d() {
17700         remote_mds_nodsh && skip "remote MDS with nodsh"
17701         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17703         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17704                 skip "Need MDS version at least 2.7.60"
17705
17706         # Registration step
17707         changelog_register || error "changelog_register failed"
17708
17709         mkdir -p $DIR/$tdir/migrate_dir
17710         changelog_clear 0 || error "changelog_clear failed"
17711
17712         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17713         changelog_dump | tail -n 5
17714         local migrates=$(changelog_dump | grep -c "MIGRT")
17715         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17716 }
17717 run_test 160d "verify that changelog log catch the migrate event"
17718
17719 test_160e() {
17720         remote_mds_nodsh && skip "remote MDS with nodsh"
17721
17722         # Create a user
17723         changelog_register || error "changelog_register failed"
17724
17725         local MDT0=$(facet_svc $SINGLEMDS)
17726         local rc
17727
17728         # No user (expect fail)
17729         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17730         rc=$?
17731         if [ $rc -eq 0 ]; then
17732                 error "Should fail without user"
17733         elif [ $rc -ne 4 ]; then
17734                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17735         fi
17736
17737         # Delete a future user (expect fail)
17738         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17739         rc=$?
17740         if [ $rc -eq 0 ]; then
17741                 error "Deleted non-existant user cl77"
17742         elif [ $rc -ne 2 ]; then
17743                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17744         fi
17745
17746         # Clear to a bad index (1 billion should be safe)
17747         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17748         rc=$?
17749
17750         if [ $rc -eq 0 ]; then
17751                 error "Successfully cleared to invalid CL index"
17752         elif [ $rc -ne 22 ]; then
17753                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17754         fi
17755 }
17756 run_test 160e "changelog negative testing (should return errors)"
17757
17758 test_160f() {
17759         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17760         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17761                 skip "Need MDS version at least 2.10.56"
17762
17763         local mdts=$(comma_list $(mdts_nodes))
17764
17765         # Create a user
17766         changelog_register || error "first changelog_register failed"
17767         changelog_register || error "second changelog_register failed"
17768         local cl_users
17769         declare -A cl_user1
17770         declare -A cl_user2
17771         local user_rec1
17772         local user_rec2
17773         local i
17774
17775         # generate some changelog records to accumulate on each MDT
17776         # use all_char because created files should be evenly distributed
17777         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17778                 error "test_mkdir $tdir failed"
17779         log "$(date +%s): creating first files"
17780         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17781                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17782                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17783         done
17784
17785         # check changelogs have been generated
17786         local start=$SECONDS
17787         local idle_time=$((MDSCOUNT * 5 + 5))
17788         local nbcl=$(changelog_dump | wc -l)
17789         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17790
17791         for param in "changelog_max_idle_time=$idle_time" \
17792                      "changelog_gc=1" \
17793                      "changelog_min_gc_interval=2" \
17794                      "changelog_min_free_cat_entries=3"; do
17795                 local MDT0=$(facet_svc $SINGLEMDS)
17796                 local var="${param%=*}"
17797                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17798
17799                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17800                 do_nodes $mdts $LCTL set_param mdd.*.$param
17801         done
17802
17803         # force cl_user2 to be idle (1st part), but also cancel the
17804         # cl_user1 records so that it is not evicted later in the test.
17805         local sleep1=$((idle_time / 2))
17806         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17807         sleep $sleep1
17808
17809         # simulate changelog catalog almost full
17810         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17811         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17812
17813         for i in $(seq $MDSCOUNT); do
17814                 cl_users=(${CL_USERS[mds$i]})
17815                 cl_user1[mds$i]="${cl_users[0]}"
17816                 cl_user2[mds$i]="${cl_users[1]}"
17817
17818                 [ -n "${cl_user1[mds$i]}" ] ||
17819                         error "mds$i: no user registered"
17820                 [ -n "${cl_user2[mds$i]}" ] ||
17821                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17822
17823                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17824                 [ -n "$user_rec1" ] ||
17825                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17826                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17827                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17828                 [ -n "$user_rec2" ] ||
17829                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17830                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17831                      "$user_rec1 + 2 == $user_rec2"
17832                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17833                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17834                               "$user_rec1 + 2, but is $user_rec2"
17835                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17836                 [ -n "$user_rec2" ] ||
17837                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17838                 [ $user_rec1 == $user_rec2 ] ||
17839                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17840                               "$user_rec1, but is $user_rec2"
17841         done
17842
17843         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17844         local sleep2=$((idle_time - (SECONDS - start) + 1))
17845         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17846         sleep $sleep2
17847
17848         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17849         # cl_user1 should be OK because it recently processed records.
17850         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17851         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17852                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17853                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17854         done
17855
17856         # ensure gc thread is done
17857         for i in $(mdts_nodes); do
17858                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17859                         error "$i: GC-thread not done"
17860         done
17861
17862         local first_rec
17863         for (( i = 1; i <= MDSCOUNT; i++ )); do
17864                 # check cl_user1 still registered
17865                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17866                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17867                 # check cl_user2 unregistered
17868                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17869                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17870
17871                 # check changelogs are present and starting at $user_rec1 + 1
17872                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17873                 [ -n "$user_rec1" ] ||
17874                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17875                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17876                             awk '{ print $1; exit; }')
17877
17878                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17879                 [ $((user_rec1 + 1)) == $first_rec ] ||
17880                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17881         done
17882 }
17883 run_test 160f "changelog garbage collect (timestamped users)"
17884
17885 test_160g() {
17886         remote_mds_nodsh && skip "remote MDS with nodsh"
17887         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17888                 skip "Need MDS version at least 2.14.55"
17889
17890         local mdts=$(comma_list $(mdts_nodes))
17891
17892         # Create a user
17893         changelog_register || error "first changelog_register failed"
17894         changelog_register || error "second changelog_register failed"
17895         local cl_users
17896         declare -A cl_user1
17897         declare -A cl_user2
17898         local user_rec1
17899         local user_rec2
17900         local i
17901
17902         # generate some changelog records to accumulate on each MDT
17903         # use all_char because created files should be evenly distributed
17904         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17905                 error "test_mkdir $tdir failed"
17906         for ((i = 0; i < MDSCOUNT; i++)); do
17907                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17908                         error "create $DIR/$tdir/d$i.1 failed"
17909         done
17910
17911         # check changelogs have been generated
17912         local nbcl=$(changelog_dump | wc -l)
17913         (( $nbcl > 0 )) || error "no changelogs found"
17914
17915         # reduce the max_idle_indexes value to make sure we exceed it
17916         for param in "changelog_max_idle_indexes=2" \
17917                      "changelog_gc=1" \
17918                      "changelog_min_gc_interval=2"; do
17919                 local MDT0=$(facet_svc $SINGLEMDS)
17920                 local var="${param%=*}"
17921                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17922
17923                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17924                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17925                         error "unable to set mdd.*.$param"
17926         done
17927
17928         local start=$SECONDS
17929         for i in $(seq $MDSCOUNT); do
17930                 cl_users=(${CL_USERS[mds$i]})
17931                 cl_user1[mds$i]="${cl_users[0]}"
17932                 cl_user2[mds$i]="${cl_users[1]}"
17933
17934                 [ -n "${cl_user1[mds$i]}" ] ||
17935                         error "mds$i: user1 is not registered"
17936                 [ -n "${cl_user2[mds$i]}" ] ||
17937                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17938
17939                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17940                 [ -n "$user_rec1" ] ||
17941                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17942                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17943                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17944                 [ -n "$user_rec2" ] ||
17945                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17946                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17947                      "$user_rec1 + 2 == $user_rec2"
17948                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17949                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17950                               "expected $user_rec1 + 2, but is $user_rec2"
17951                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17952                 [ -n "$user_rec2" ] ||
17953                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17954                 [ $user_rec1 == $user_rec2 ] ||
17955                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17956                               "expected $user_rec1, but is $user_rec2"
17957         done
17958
17959         # ensure we are past the previous changelog_min_gc_interval set above
17960         local sleep2=$((start + 2 - SECONDS))
17961         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17962         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17963         # cl_user1 should be OK because it recently processed records.
17964         for ((i = 0; i < MDSCOUNT; i++)); do
17965                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17966                         error "create $DIR/$tdir/d$i.3 failed"
17967         done
17968
17969         # ensure gc thread is done
17970         for i in $(mdts_nodes); do
17971                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17972                         error "$i: GC-thread not done"
17973         done
17974
17975         local first_rec
17976         for (( i = 1; i <= MDSCOUNT; i++ )); do
17977                 # check cl_user1 still registered
17978                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17979                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17980                 # check cl_user2 unregistered
17981                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17982                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17983
17984                 # check changelogs are present and starting at $user_rec1 + 1
17985                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17986                 [ -n "$user_rec1" ] ||
17987                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17988                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17989                             awk '{ print $1; exit; }')
17990
17991                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17992                 [ $((user_rec1 + 1)) == $first_rec ] ||
17993                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17994         done
17995 }
17996 run_test 160g "changelog garbage collect on idle records"
17997
17998 test_160h() {
17999         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18000         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18001                 skip "Need MDS version at least 2.10.56"
18002
18003         local mdts=$(comma_list $(mdts_nodes))
18004
18005         # Create a user
18006         changelog_register || error "first changelog_register failed"
18007         changelog_register || error "second changelog_register failed"
18008         local cl_users
18009         declare -A cl_user1
18010         declare -A cl_user2
18011         local user_rec1
18012         local user_rec2
18013         local i
18014
18015         # generate some changelog records to accumulate on each MDT
18016         # use all_char because created files should be evenly distributed
18017         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18018                 error "test_mkdir $tdir failed"
18019         for ((i = 0; i < MDSCOUNT; i++)); do
18020                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18021                         error "create $DIR/$tdir/d$i.1 failed"
18022         done
18023
18024         # check changelogs have been generated
18025         local nbcl=$(changelog_dump | wc -l)
18026         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18027
18028         for param in "changelog_max_idle_time=10" \
18029                      "changelog_gc=1" \
18030                      "changelog_min_gc_interval=2"; do
18031                 local MDT0=$(facet_svc $SINGLEMDS)
18032                 local var="${param%=*}"
18033                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18034
18035                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18036                 do_nodes $mdts $LCTL set_param mdd.*.$param
18037         done
18038
18039         # force cl_user2 to be idle (1st part)
18040         sleep 9
18041
18042         for i in $(seq $MDSCOUNT); do
18043                 cl_users=(${CL_USERS[mds$i]})
18044                 cl_user1[mds$i]="${cl_users[0]}"
18045                 cl_user2[mds$i]="${cl_users[1]}"
18046
18047                 [ -n "${cl_user1[mds$i]}" ] ||
18048                         error "mds$i: no user registered"
18049                 [ -n "${cl_user2[mds$i]}" ] ||
18050                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18051
18052                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18053                 [ -n "$user_rec1" ] ||
18054                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18055                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18056                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18057                 [ -n "$user_rec2" ] ||
18058                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18059                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18060                      "$user_rec1 + 2 == $user_rec2"
18061                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18062                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18063                               "$user_rec1 + 2, but is $user_rec2"
18064                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18065                 [ -n "$user_rec2" ] ||
18066                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18067                 [ $user_rec1 == $user_rec2 ] ||
18068                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18069                               "$user_rec1, but is $user_rec2"
18070         done
18071
18072         # force cl_user2 to be idle (2nd part) and to reach
18073         # changelog_max_idle_time
18074         sleep 2
18075
18076         # force each GC-thread start and block then
18077         # one per MDT/MDD, set fail_val accordingly
18078         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18079         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18080
18081         # generate more changelogs to trigger fail_loc
18082         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18083                 error "create $DIR/$tdir/${tfile}bis failed"
18084
18085         # stop MDT to stop GC-thread, should be done in back-ground as it will
18086         # block waiting for the thread to be released and exit
18087         declare -A stop_pids
18088         for i in $(seq $MDSCOUNT); do
18089                 stop mds$i &
18090                 stop_pids[mds$i]=$!
18091         done
18092
18093         for i in $(mdts_nodes); do
18094                 local facet
18095                 local nb=0
18096                 local facets=$(facets_up_on_host $i)
18097
18098                 for facet in ${facets//,/ }; do
18099                         if [[ $facet == mds* ]]; then
18100                                 nb=$((nb + 1))
18101                         fi
18102                 done
18103                 # ensure each MDS's gc threads are still present and all in "R"
18104                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18105                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18106                         error "$i: expected $nb GC-thread"
18107                 wait_update $i \
18108                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18109                         "R" 20 ||
18110                         error "$i: GC-thread not found in R-state"
18111                 # check umounts of each MDT on MDS have reached kthread_stop()
18112                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18113                         error "$i: expected $nb umount"
18114                 wait_update $i \
18115                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18116                         error "$i: umount not found in D-state"
18117         done
18118
18119         # release all GC-threads
18120         do_nodes $mdts $LCTL set_param fail_loc=0
18121
18122         # wait for MDT stop to complete
18123         for i in $(seq $MDSCOUNT); do
18124                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18125         done
18126
18127         # XXX
18128         # may try to check if any orphan changelog records are present
18129         # via ldiskfs/zfs and llog_reader...
18130
18131         # re-start/mount MDTs
18132         for i in $(seq $MDSCOUNT); do
18133                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18134                         error "Fail to start mds$i"
18135         done
18136
18137         local first_rec
18138         for i in $(seq $MDSCOUNT); do
18139                 # check cl_user1 still registered
18140                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18141                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18142                 # check cl_user2 unregistered
18143                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18144                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18145
18146                 # check changelogs are present and starting at $user_rec1 + 1
18147                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18148                 [ -n "$user_rec1" ] ||
18149                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18150                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18151                             awk '{ print $1; exit; }')
18152
18153                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18154                 [ $((user_rec1 + 1)) == $first_rec ] ||
18155                         error "mds$i: first index should be $user_rec1 + 1, " \
18156                               "but is $first_rec"
18157         done
18158 }
18159 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18160               "during mount"
18161
18162 test_160i() {
18163
18164         local mdts=$(comma_list $(mdts_nodes))
18165
18166         changelog_register || error "first changelog_register failed"
18167
18168         # generate some changelog records to accumulate on each MDT
18169         # use all_char because created files should be evenly distributed
18170         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18171                 error "test_mkdir $tdir failed"
18172         for ((i = 0; i < MDSCOUNT; i++)); do
18173                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18174                         error "create $DIR/$tdir/d$i.1 failed"
18175         done
18176
18177         # check changelogs have been generated
18178         local nbcl=$(changelog_dump | wc -l)
18179         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18180
18181         # simulate race between register and unregister
18182         # XXX as fail_loc is set per-MDS, with DNE configs the race
18183         # simulation will only occur for one MDT per MDS and for the
18184         # others the normal race scenario will take place
18185         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18186         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18187         do_nodes $mdts $LCTL set_param fail_val=1
18188
18189         # unregister 1st user
18190         changelog_deregister &
18191         local pid1=$!
18192         # wait some time for deregister work to reach race rdv
18193         sleep 2
18194         # register 2nd user
18195         changelog_register || error "2nd user register failed"
18196
18197         wait $pid1 || error "1st user deregister failed"
18198
18199         local i
18200         local last_rec
18201         declare -A LAST_REC
18202         for i in $(seq $MDSCOUNT); do
18203                 if changelog_users mds$i | grep "^cl"; then
18204                         # make sure new records are added with one user present
18205                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18206                                           awk '/^current.index:/ { print $NF }')
18207                 else
18208                         error "mds$i has no user registered"
18209                 fi
18210         done
18211
18212         # generate more changelog records to accumulate on each MDT
18213         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18214                 error "create $DIR/$tdir/${tfile}bis failed"
18215
18216         for i in $(seq $MDSCOUNT); do
18217                 last_rec=$(changelog_users $SINGLEMDS |
18218                            awk '/^current.index:/ { print $NF }')
18219                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18220                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18221                         error "changelogs are off on mds$i"
18222         done
18223 }
18224 run_test 160i "changelog user register/unregister race"
18225
18226 test_160j() {
18227         remote_mds_nodsh && skip "remote MDS with nodsh"
18228         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18229                 skip "Need MDS version at least 2.12.56"
18230
18231         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18232         stack_trap "umount $MOUNT2" EXIT
18233
18234         changelog_register || error "first changelog_register failed"
18235         stack_trap "changelog_deregister" EXIT
18236
18237         # generate some changelog
18238         # use all_char because created files should be evenly distributed
18239         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18240                 error "mkdir $tdir failed"
18241         for ((i = 0; i < MDSCOUNT; i++)); do
18242                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18243                         error "create $DIR/$tdir/d$i.1 failed"
18244         done
18245
18246         # open the changelog device
18247         exec 3>/dev/changelog-$FSNAME-MDT0000
18248         stack_trap "exec 3>&-" EXIT
18249         exec 4</dev/changelog-$FSNAME-MDT0000
18250         stack_trap "exec 4<&-" EXIT
18251
18252         # umount the first lustre mount
18253         umount $MOUNT
18254         stack_trap "mount_client $MOUNT" EXIT
18255
18256         # read changelog, which may or may not fail, but should not crash
18257         cat <&4 >/dev/null
18258
18259         # clear changelog
18260         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18261         changelog_users $SINGLEMDS | grep -q $cl_user ||
18262                 error "User $cl_user not found in changelog_users"
18263
18264         printf 'clear:'$cl_user':0' >&3
18265 }
18266 run_test 160j "client can be umounted while its chanangelog is being used"
18267
18268 test_160k() {
18269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18270         remote_mds_nodsh && skip "remote MDS with nodsh"
18271
18272         mkdir -p $DIR/$tdir/1/1
18273
18274         changelog_register || error "changelog_register failed"
18275         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18276
18277         changelog_users $SINGLEMDS | grep -q $cl_user ||
18278                 error "User '$cl_user' not found in changelog_users"
18279 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18280         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18281         rmdir $DIR/$tdir/1/1 & sleep 1
18282         mkdir $DIR/$tdir/2
18283         touch $DIR/$tdir/2/2
18284         rm -rf $DIR/$tdir/2
18285
18286         wait
18287         sleep 4
18288
18289         changelog_dump | grep rmdir || error "rmdir not recorded"
18290 }
18291 run_test 160k "Verify that changelog records are not lost"
18292
18293 # Verifies that a file passed as a parameter has recently had an operation
18294 # performed on it that has generated an MTIME changelog which contains the
18295 # correct parent FID. As files might reside on a different MDT from the
18296 # parent directory in DNE configurations, the FIDs are translated to paths
18297 # before being compared, which should be identical
18298 compare_mtime_changelog() {
18299         local file="${1}"
18300         local mdtidx
18301         local mtime
18302         local cl_fid
18303         local pdir
18304         local dir
18305
18306         mdtidx=$($LFS getstripe --mdt-index $file)
18307         mdtidx=$(printf "%04x" $mdtidx)
18308
18309         # Obtain the parent FID from the MTIME changelog
18310         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18311         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18312
18313         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18314         [ -z "$cl_fid" ] && error "parent FID not present"
18315
18316         # Verify that the path for the parent FID is the same as the path for
18317         # the test directory
18318         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18319
18320         dir=$(dirname $1)
18321
18322         [[ "${pdir%/}" == "$dir" ]] ||
18323                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18324 }
18325
18326 test_160l() {
18327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18328
18329         remote_mds_nodsh && skip "remote MDS with nodsh"
18330         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18331                 skip "Need MDS version at least 2.13.55"
18332
18333         local cl_user
18334
18335         changelog_register || error "changelog_register failed"
18336         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18337
18338         changelog_users $SINGLEMDS | grep -q $cl_user ||
18339                 error "User '$cl_user' not found in changelog_users"
18340
18341         # Clear some types so that MTIME changelogs are generated
18342         changelog_chmask "-CREAT"
18343         changelog_chmask "-CLOSE"
18344
18345         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18346
18347         # Test CL_MTIME during setattr
18348         touch $DIR/$tdir/$tfile
18349         compare_mtime_changelog $DIR/$tdir/$tfile
18350
18351         # Test CL_MTIME during close
18352         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18353         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18354 }
18355 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18356
18357 test_160m() {
18358         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18359         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18360                 skip "Need MDS version at least 2.14.51"
18361         local cl_users
18362         local cl_user1
18363         local cl_user2
18364         local pid1
18365
18366         # Create a user
18367         changelog_register || error "first changelog_register failed"
18368         changelog_register || error "second changelog_register failed"
18369
18370         cl_users=(${CL_USERS[mds1]})
18371         cl_user1="${cl_users[0]}"
18372         cl_user2="${cl_users[1]}"
18373         # generate some changelog records to accumulate on MDT0
18374         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18375         createmany -m $DIR/$tdir/$tfile 50 ||
18376                 error "create $DIR/$tdir/$tfile failed"
18377         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18378         rm -f $DIR/$tdir
18379
18380         # check changelogs have been generated
18381         local nbcl=$(changelog_dump | wc -l)
18382         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18383
18384 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18385         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18386
18387         __changelog_clear mds1 $cl_user1 +10
18388         __changelog_clear mds1 $cl_user2 0 &
18389         pid1=$!
18390         sleep 2
18391         __changelog_clear mds1 $cl_user1 0 ||
18392                 error "fail to cancel record for $cl_user1"
18393         wait $pid1
18394         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18395 }
18396 run_test 160m "Changelog clear race"
18397
18398 test_160n() {
18399         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18400         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18401                 skip "Need MDS version at least 2.14.51"
18402         local cl_users
18403         local cl_user1
18404         local cl_user2
18405         local pid1
18406         local first_rec
18407         local last_rec=0
18408
18409         # Create a user
18410         changelog_register || error "first changelog_register failed"
18411
18412         cl_users=(${CL_USERS[mds1]})
18413         cl_user1="${cl_users[0]}"
18414
18415         # generate some changelog records to accumulate on MDT0
18416         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18417         first_rec=$(changelog_users $SINGLEMDS |
18418                         awk '/^current.index:/ { print $NF }')
18419         while (( last_rec < (( first_rec + 65000)) )); do
18420                 createmany -m $DIR/$tdir/$tfile 10000 ||
18421                         error "create $DIR/$tdir/$tfile failed"
18422
18423                 for i in $(seq 0 10000); do
18424                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18425                                 > /dev/null
18426                 done
18427
18428                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18429                         error "unlinkmany failed unlink"
18430                 last_rec=$(changelog_users $SINGLEMDS |
18431                         awk '/^current.index:/ { print $NF }')
18432                 echo last record $last_rec
18433                 (( last_rec == 0 )) && error "no changelog found"
18434         done
18435
18436 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18437         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18438
18439         __changelog_clear mds1 $cl_user1 0 &
18440         pid1=$!
18441         sleep 2
18442         __changelog_clear mds1 $cl_user1 0 ||
18443                 error "fail to cancel record for $cl_user1"
18444         wait $pid1
18445         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18446 }
18447 run_test 160n "Changelog destroy race"
18448
18449 test_160o() {
18450         local mdt="$(facet_svc $SINGLEMDS)"
18451
18452         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18453         remote_mds_nodsh && skip "remote MDS with nodsh"
18454         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18455                 skip "Need MDS version at least 2.14.52"
18456
18457         changelog_register --user test_160o -m unlnk+close+open ||
18458                 error "changelog_register failed"
18459
18460         do_facet $SINGLEMDS $LCTL --device $mdt \
18461                                 changelog_register -u "Tt3_-#" &&
18462                 error "bad symbols in name should fail"
18463
18464         do_facet $SINGLEMDS $LCTL --device $mdt \
18465                                 changelog_register -u test_160o &&
18466                 error "the same name registration should fail"
18467
18468         do_facet $SINGLEMDS $LCTL --device $mdt \
18469                         changelog_register -u test_160toolongname &&
18470                 error "too long name registration should fail"
18471
18472         changelog_chmask "MARK+HSM"
18473         lctl get_param mdd.*.changelog*mask
18474         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18475         changelog_users $SINGLEMDS | grep -q $cl_user ||
18476                 error "User $cl_user not found in changelog_users"
18477         #verify username
18478         echo $cl_user | grep -q test_160o ||
18479                 error "User $cl_user has no specific name 'test160o'"
18480
18481         # change something
18482         changelog_clear 0 || error "changelog_clear failed"
18483         # generate some changelog records to accumulate on MDT0
18484         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18485         touch $DIR/$tdir/$tfile                 # open 1
18486
18487         OPENS=$(changelog_dump | grep -c "OPEN")
18488         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18489
18490         # must be no MKDIR it wasn't set as user mask
18491         MKDIR=$(changelog_dump | grep -c "MKDIR")
18492         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18493
18494         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18495                                 mdd.$mdt.changelog_current_mask -n)
18496         # register maskless user
18497         changelog_register || error "changelog_register failed"
18498         # effective mask should be not changed because it is not minimal
18499         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18500                                 mdd.$mdt.changelog_current_mask -n)
18501         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18502         # set server mask to minimal value
18503         changelog_chmask "MARK"
18504         # check effective mask again, should be treated as DEFMASK now
18505         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18506                                 mdd.$mdt.changelog_current_mask -n)
18507         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18508
18509         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18510                 # set server mask back to some value
18511                 changelog_chmask "CLOSE,UNLNK"
18512                 # check effective mask again, should not remain as DEFMASK
18513                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18514                                 mdd.$mdt.changelog_current_mask -n)
18515                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18516         fi
18517
18518         do_facet $SINGLEMDS $LCTL --device $mdt \
18519                                 changelog_deregister -u test_160o ||
18520                 error "cannot deregister by name"
18521 }
18522 run_test 160o "changelog user name and mask"
18523
18524 test_160p() {
18525         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18526         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18527                 skip "Need MDS version at least 2.14.51"
18528         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18529         local cl_users
18530         local cl_user1
18531         local entry_count
18532
18533         # Create a user
18534         changelog_register || error "first changelog_register failed"
18535
18536         cl_users=(${CL_USERS[mds1]})
18537         cl_user1="${cl_users[0]}"
18538
18539         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18540         createmany -m $DIR/$tdir/$tfile 50 ||
18541                 error "create $DIR/$tdir/$tfile failed"
18542         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18543         rm -rf $DIR/$tdir
18544
18545         # check changelogs have been generated
18546         entry_count=$(changelog_dump | wc -l)
18547         ((entry_count != 0)) || error "no changelog entries found"
18548
18549         # remove changelog_users and check that orphan entries are removed
18550         stop mds1
18551         local dev=$(mdsdevname 1)
18552         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18553         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18554         entry_count=$(changelog_dump | wc -l)
18555         ((entry_count == 0)) ||
18556                 error "found $entry_count changelog entries, expected none"
18557 }
18558 run_test 160p "Changelog orphan cleanup with no users"
18559
18560 test_160q() {
18561         local mdt="$(facet_svc $SINGLEMDS)"
18562         local clu
18563
18564         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18565         remote_mds_nodsh && skip "remote MDS with nodsh"
18566         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18567                 skip "Need MDS version at least 2.14.54"
18568
18569         # set server mask to minimal value like server init does
18570         changelog_chmask "MARK"
18571         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18572                 error "changelog_register failed"
18573         # check effective mask again, should be treated as DEFMASK now
18574         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18575                                 mdd.$mdt.changelog_current_mask -n)
18576         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18577                 error "changelog_deregister failed"
18578         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18579 }
18580 run_test 160q "changelog effective mask is DEFMASK if not set"
18581
18582 test_160s() {
18583         remote_mds_nodsh && skip "remote MDS with nodsh"
18584         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18585                 skip "Need MDS version at least 2.14.55"
18586
18587         local mdts=$(comma_list $(mdts_nodes))
18588
18589         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18590         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18591                                        fail_val=$((24 * 3600 * 10))
18592
18593         # Create a user which is 10 days old
18594         changelog_register || error "first changelog_register failed"
18595         local cl_users
18596         declare -A cl_user1
18597         local i
18598
18599         # generate some changelog records to accumulate on each MDT
18600         # use all_char because created files should be evenly distributed
18601         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18602                 error "test_mkdir $tdir failed"
18603         for ((i = 0; i < MDSCOUNT; i++)); do
18604                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18605                         error "create $DIR/$tdir/d$i.1 failed"
18606         done
18607
18608         # check changelogs have been generated
18609         local nbcl=$(changelog_dump | wc -l)
18610         (( nbcl > 0 )) || error "no changelogs found"
18611
18612         # reduce the max_idle_indexes value to make sure we exceed it
18613         for param in "changelog_max_idle_indexes=2097446912" \
18614                      "changelog_max_idle_time=2592000" \
18615                      "changelog_gc=1" \
18616                      "changelog_min_gc_interval=2"; do
18617                 local MDT0=$(facet_svc $SINGLEMDS)
18618                 local var="${param%=*}"
18619                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18620
18621                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18622                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18623                         error "unable to set mdd.*.$param"
18624         done
18625
18626         local start=$SECONDS
18627         for i in $(seq $MDSCOUNT); do
18628                 cl_users=(${CL_USERS[mds$i]})
18629                 cl_user1[mds$i]="${cl_users[0]}"
18630
18631                 [[ -n "${cl_user1[mds$i]}" ]] ||
18632                         error "mds$i: no user registered"
18633         done
18634
18635         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18636         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18637
18638         # ensure we are past the previous changelog_min_gc_interval set above
18639         local sleep2=$((start + 2 - SECONDS))
18640         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18641
18642         # Generate one more changelog to trigger GC
18643         for ((i = 0; i < MDSCOUNT; i++)); do
18644                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18645                         error "create $DIR/$tdir/d$i.3 failed"
18646         done
18647
18648         # ensure gc thread is done
18649         for node in $(mdts_nodes); do
18650                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18651                         error "$node: GC-thread not done"
18652         done
18653
18654         do_nodes $mdts $LCTL set_param fail_loc=0
18655
18656         for (( i = 1; i <= MDSCOUNT; i++ )); do
18657                 # check cl_user1 is purged
18658                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18659                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18660         done
18661         return 0
18662 }
18663 run_test 160s "changelog garbage collect on idle records * time"
18664
18665 test_160t() {
18666         remote_mds_nodsh && skip "remote MDS with nodsh"
18667         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18668                 skip "Need MDS version at least 2.15.50"
18669
18670         local MDT0=$(facet_svc $SINGLEMDS)
18671         local cl_users
18672         local cl_user1
18673         local cl_user2
18674         local start
18675
18676         changelog_register --user user1 -m all ||
18677                 error "user1 failed to register"
18678
18679         mkdir_on_mdt0 $DIR/$tdir
18680         # create default overstripe to maximize changelog size
18681         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18682         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18683         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18684
18685         # user2 consumes less records so less space
18686         changelog_register --user user2 || error "user2 failed to register"
18687         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18688         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18689
18690         # check changelogs have been generated
18691         local nbcl=$(changelog_dump | wc -l)
18692         (( nbcl > 0 )) || error "no changelogs found"
18693
18694         # reduce the changelog_min_gc_interval to force check
18695         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18696                 local var="${param%=*}"
18697                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18698
18699                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18700                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18701                         error "unable to set mdd.*.$param"
18702         done
18703
18704         start=$SECONDS
18705         cl_users=(${CL_USERS[mds1]})
18706         cl_user1="${cl_users[0]}"
18707         cl_user2="${cl_users[1]}"
18708
18709         [[ -n $cl_user1 ]] ||
18710                 error "mds1: user #1 isn't registered"
18711         [[ -n $cl_user2 ]] ||
18712                 error "mds1: user #2 isn't registered"
18713
18714         # ensure we are past the previous changelog_min_gc_interval set above
18715         local sleep2=$((start + 2 - SECONDS))
18716         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18717
18718         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18719         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18720                         fail_val=$(((llog_size1 + llog_size2) / 2))
18721
18722         # Generate more changelog to trigger GC
18723         createmany -o $DIR/$tdir/u3_ 4 ||
18724                 error "create failed for more files"
18725
18726         # ensure gc thread is done
18727         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18728                 error "mds1: GC-thread not done"
18729
18730         do_facet mds1 $LCTL set_param fail_loc=0
18731
18732         # check cl_user1 is purged
18733         changelog_users mds1 | grep -q "$cl_user1" &&
18734                 error "User $cl_user1 is registered"
18735         # check cl_user2 is not purged
18736         changelog_users mds1 | grep -q "$cl_user2" ||
18737                 error "User $cl_user2 is not registered"
18738 }
18739 run_test 160t "changelog garbage collect on lack of space"
18740
18741 test_160u() { # LU-17400
18742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18743         remote_mds_nodsh && skip "remote MDS with nodsh"
18744         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18745                 skip "Need MDS version at least 2.2.0"
18746
18747         cd $DIR || error "cd $DIR failed"
18748
18749         # ensure changelog has a clean view if tests are run multiple times
18750         [ -d rename ] && rm -rf rename
18751
18752         changelog_register || error "changelog_register failed"
18753         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18754
18755         changelog_users $SINGLEMDS | grep -q $cl_user ||
18756                 error "User '$cl_user' not found in changelog_users"
18757
18758         local longname1=$(str_repeat a 255)
18759
18760         echo "creating simple directory tree"
18761         mkdir -p rename/a || error "create of simple directory tree failed"
18762         echo "creating rename/hw file"
18763         echo "hello world" > rename/hw || error "create of rename/hw failed"
18764         echo "creating very long named file"
18765         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18766         echo "move rename/hw to rename/a/a.hw"
18767         mv rename/hw rename/a/a.hw || error "mv failed"
18768
18769         RENME=($(changelog_dump | grep "RENME"))
18770         #declare -p RENME # for debugging captured value with indexes
18771
18772         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18773                 error "changelog rename record type name/sname error"
18774 }
18775 run_test 160u "changelog rename record type name and sname strings are correct"
18776
18777 test_161a() {
18778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18779
18780         test_mkdir -c1 $DIR/$tdir
18781         cp /etc/hosts $DIR/$tdir/$tfile
18782         test_mkdir -c1 $DIR/$tdir/foo1
18783         test_mkdir -c1 $DIR/$tdir/foo2
18784         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18785         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18786         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18787         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18788         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18789         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18790                 $LFS fid2path $DIR $FID
18791                 error "bad link ea"
18792         fi
18793         # middle
18794         rm $DIR/$tdir/foo2/zachary
18795         # last
18796         rm $DIR/$tdir/foo2/thor
18797         # first
18798         rm $DIR/$tdir/$tfile
18799         # rename
18800         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18801         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18802                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18803         rm $DIR/$tdir/foo2/maggie
18804
18805         # overflow the EA
18806         local longname=$tfile.avg_len_is_thirty_two_
18807         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18808                 error_noexit 'failed to unlink many hardlinks'" EXIT
18809         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18810                 error "failed to hardlink many files"
18811         links=$($LFS fid2path $DIR $FID | wc -l)
18812         echo -n "${links}/1000 links in link EA"
18813         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18814 }
18815 run_test 161a "link ea sanity"
18816
18817 test_161b() {
18818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18819         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18820
18821         local MDTIDX=1
18822         local remote_dir=$DIR/$tdir/remote_dir
18823
18824         mkdir -p $DIR/$tdir
18825         $LFS mkdir -i $MDTIDX $remote_dir ||
18826                 error "create remote directory failed"
18827
18828         cp /etc/hosts $remote_dir/$tfile
18829         mkdir -p $remote_dir/foo1
18830         mkdir -p $remote_dir/foo2
18831         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18832         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18833         ln $remote_dir/$tfile $remote_dir/foo1/luna
18834         ln $remote_dir/$tfile $remote_dir/foo2/thor
18835
18836         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18837                      tr -d ']')
18838         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18839                 $LFS fid2path $DIR $FID
18840                 error "bad link ea"
18841         fi
18842         # middle
18843         rm $remote_dir/foo2/zachary
18844         # last
18845         rm $remote_dir/foo2/thor
18846         # first
18847         rm $remote_dir/$tfile
18848         # rename
18849         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18850         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18851         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18852                 $LFS fid2path $DIR $FID
18853                 error "bad link rename"
18854         fi
18855         rm $remote_dir/foo2/maggie
18856
18857         # overflow the EA
18858         local longname=filename_avg_len_is_thirty_two_
18859         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18860                 error "failed to hardlink many files"
18861         links=$($LFS fid2path $DIR $FID | wc -l)
18862         echo -n "${links}/1000 links in link EA"
18863         [[ ${links} -gt 60 ]] ||
18864                 error "expected at least 60 links in link EA"
18865         unlinkmany $remote_dir/foo2/$longname 1000 ||
18866         error "failed to unlink many hardlinks"
18867 }
18868 run_test 161b "link ea sanity under remote directory"
18869
18870 test_161c() {
18871         remote_mds_nodsh && skip "remote MDS with nodsh"
18872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18873         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18874                 skip "Need MDS version at least 2.1.5"
18875
18876         # define CLF_RENAME_LAST 0x0001
18877         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18878         changelog_register || error "changelog_register failed"
18879
18880         rm -rf $DIR/$tdir
18881         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18882         touch $DIR/$tdir/foo_161c
18883         touch $DIR/$tdir/bar_161c
18884         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18885         changelog_dump | grep RENME | tail -n 5
18886         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18887         changelog_clear 0 || error "changelog_clear failed"
18888         if [ x$flags != "x0x1" ]; then
18889                 error "flag $flags is not 0x1"
18890         fi
18891
18892         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18893         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18894         touch $DIR/$tdir/foo_161c
18895         touch $DIR/$tdir/bar_161c
18896         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18897         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18898         changelog_dump | grep RENME | tail -n 5
18899         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18900         changelog_clear 0 || error "changelog_clear failed"
18901         if [ x$flags != "x0x0" ]; then
18902                 error "flag $flags is not 0x0"
18903         fi
18904         echo "rename overwrite a target having nlink > 1," \
18905                 "changelog record has flags of $flags"
18906
18907         # rename doesn't overwrite a target (changelog flag 0x0)
18908         touch $DIR/$tdir/foo_161c
18909         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18910         changelog_dump | grep RENME | tail -n 5
18911         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18912         changelog_clear 0 || error "changelog_clear failed"
18913         if [ x$flags != "x0x0" ]; then
18914                 error "flag $flags is not 0x0"
18915         fi
18916         echo "rename doesn't overwrite a target," \
18917                 "changelog record has flags of $flags"
18918
18919         # define CLF_UNLINK_LAST 0x0001
18920         # unlink a file having nlink = 1 (changelog flag 0x1)
18921         rm -f $DIR/$tdir/foo2_161c
18922         changelog_dump | grep UNLNK | tail -n 5
18923         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18924         changelog_clear 0 || error "changelog_clear failed"
18925         if [ x$flags != "x0x1" ]; then
18926                 error "flag $flags is not 0x1"
18927         fi
18928         echo "unlink a file having nlink = 1," \
18929                 "changelog record has flags of $flags"
18930
18931         # unlink a file having nlink > 1 (changelog flag 0x0)
18932         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18933         rm -f $DIR/$tdir/foobar_161c
18934         changelog_dump | grep UNLNK | tail -n 5
18935         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18936         changelog_clear 0 || error "changelog_clear failed"
18937         if [ x$flags != "x0x0" ]; then
18938                 error "flag $flags is not 0x0"
18939         fi
18940         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18941 }
18942 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18943
18944 test_161d() {
18945         remote_mds_nodsh && skip "remote MDS with nodsh"
18946         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18947
18948         local pid
18949         local fid
18950
18951         changelog_register || error "changelog_register failed"
18952
18953         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18954         # interfer with $MOUNT/.lustre/fid/ access
18955         mkdir $DIR/$tdir
18956         [[ $? -eq 0 ]] || error "mkdir failed"
18957
18958         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18959         $LCTL set_param fail_loc=0x8000140c
18960         # 5s pause
18961         $LCTL set_param fail_val=5
18962
18963         # create file
18964         echo foofoo > $DIR/$tdir/$tfile &
18965         pid=$!
18966
18967         # wait for create to be delayed
18968         sleep 2
18969
18970         ps -p $pid
18971         [[ $? -eq 0 ]] || error "create should be blocked"
18972
18973         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18974         stack_trap "rm -f $tempfile"
18975         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18976         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18977         # some delay may occur during ChangeLog publishing and file read just
18978         # above, that could allow file write to happen finally
18979         [[ -s $tempfile ]] && echo "file should be empty"
18980
18981         $LCTL set_param fail_loc=0
18982
18983         wait $pid
18984         [[ $? -eq 0 ]] || error "create failed"
18985 }
18986 run_test 161d "create with concurrent .lustre/fid access"
18987
18988 check_path() {
18989         local expected="$1"
18990         shift
18991         local fid="$2"
18992
18993         local path
18994         path=$($LFS fid2path "$@")
18995         local rc=$?
18996
18997         if [ $rc -ne 0 ]; then
18998                 error "path looked up of '$expected' failed: rc=$rc"
18999         elif [ "$path" != "$expected" ]; then
19000                 error "path looked up '$path' instead of '$expected'"
19001         else
19002                 echo "FID '$fid' resolves to path '$path' as expected"
19003         fi
19004 }
19005
19006 test_162a() { # was test_162
19007         test_mkdir -p -c1 $DIR/$tdir/d2
19008         touch $DIR/$tdir/d2/$tfile
19009         touch $DIR/$tdir/d2/x1
19010         touch $DIR/$tdir/d2/x2
19011         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19012         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19013         # regular file
19014         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19015         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19016
19017         # softlink
19018         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19019         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19020         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19021
19022         # softlink to wrong file
19023         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19024         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19025         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19026
19027         # hardlink
19028         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19029         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19030         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19031         # fid2path dir/fsname should both work
19032         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19033         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19034
19035         # hardlink count: check that there are 2 links
19036         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19037         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19038
19039         # hardlink indexing: remove the first link
19040         rm $DIR/$tdir/d2/p/q/r/hlink
19041         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19042 }
19043 run_test 162a "path lookup sanity"
19044
19045 test_162b() {
19046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19048
19049         mkdir $DIR/$tdir
19050         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19051                                 error "create striped dir failed"
19052
19053         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19054                                         tail -n 1 | awk '{print $2}')
19055         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19056
19057         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19058         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19059
19060         # regular file
19061         for ((i=0;i<5;i++)); do
19062                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19063                         error "get fid for f$i failed"
19064                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19065
19066                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19067                         error "get fid for d$i failed"
19068                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19069         done
19070
19071         return 0
19072 }
19073 run_test 162b "striped directory path lookup sanity"
19074
19075 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19076 test_162c() {
19077         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19078                 skip "Need MDS version at least 2.7.51"
19079
19080         local lpath=$tdir.local
19081         local rpath=$tdir.remote
19082
19083         test_mkdir $DIR/$lpath
19084         test_mkdir $DIR/$rpath
19085
19086         for ((i = 0; i <= 101; i++)); do
19087                 lpath="$lpath/$i"
19088                 mkdir $DIR/$lpath
19089                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19090                         error "get fid for local directory $DIR/$lpath failed"
19091                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19092
19093                 rpath="$rpath/$i"
19094                 test_mkdir $DIR/$rpath
19095                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19096                         error "get fid for remote directory $DIR/$rpath failed"
19097                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19098         done
19099
19100         return 0
19101 }
19102 run_test 162c "fid2path works with paths 100 or more directories deep"
19103
19104 oalr_event_count() {
19105         local event="${1}"
19106         local trace="${2}"
19107
19108         awk -v name="${FSNAME}-OST0000" \
19109             -v event="${event}" \
19110             '$1 == "TRACE" && $2 == event && $3 == name' \
19111             "${trace}" |
19112         wc -l
19113 }
19114
19115 oalr_expect_event_count() {
19116         local event="${1}"
19117         local trace="${2}"
19118         local expect="${3}"
19119         local count
19120
19121         count=$(oalr_event_count "${event}" "${trace}")
19122         if ((count == expect)); then
19123                 return 0
19124         fi
19125
19126         error_noexit "${event} event count was '${count}', expected ${expect}"
19127         cat "${trace}" >&2
19128         exit 1
19129 }
19130
19131 cleanup_165() {
19132         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19133         stop ost1
19134         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19135 }
19136
19137 setup_165() {
19138         sync # Flush previous IOs so we can count log entries.
19139         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19140         stack_trap cleanup_165 EXIT
19141 }
19142
19143 test_165a() {
19144         local trace="/tmp/${tfile}.trace"
19145         local rc
19146         local count
19147
19148         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19149                 skip "OFD access log unsupported"
19150
19151         setup_165
19152         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19153         sleep 5
19154
19155         do_facet ost1 ofd_access_log_reader --list
19156         stop ost1
19157
19158         do_facet ost1 killall -TERM ofd_access_log_reader
19159         wait
19160         rc=$?
19161
19162         if ((rc != 0)); then
19163                 error "ofd_access_log_reader exited with rc = '${rc}'"
19164         fi
19165
19166         # Parse trace file for discovery events:
19167         oalr_expect_event_count alr_log_add "${trace}" 1
19168         oalr_expect_event_count alr_log_eof "${trace}" 1
19169         oalr_expect_event_count alr_log_free "${trace}" 1
19170 }
19171 run_test 165a "ofd access log discovery"
19172
19173 test_165b() {
19174         local trace="/tmp/${tfile}.trace"
19175         local file="${DIR}/${tfile}"
19176         local pfid1
19177         local pfid2
19178         local -a entry
19179         local rc
19180         local count
19181         local size
19182         local flags
19183
19184         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19185                 skip "OFD access log unsupported"
19186
19187         setup_165
19188         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19189         sleep 5
19190
19191         do_facet ost1 ofd_access_log_reader --list
19192
19193         lfs setstripe -c 1 -i 0 "${file}"
19194         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19195                 error "cannot create '${file}'"
19196
19197         sleep 5
19198         do_facet ost1 killall -TERM ofd_access_log_reader
19199         wait
19200         rc=$?
19201
19202         if ((rc != 0)); then
19203                 error "ofd_access_log_reader exited with rc = '${rc}'"
19204         fi
19205
19206         oalr_expect_event_count alr_log_entry "${trace}" 1
19207
19208         pfid1=$($LFS path2fid "${file}")
19209
19210         # 1     2             3   4    5     6   7    8    9     10
19211         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19212         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19213
19214         echo "entry = '${entry[*]}'" >&2
19215
19216         pfid2=${entry[4]}
19217         if [[ "${pfid1}" != "${pfid2}" ]]; then
19218                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19219         fi
19220
19221         size=${entry[8]}
19222         if ((size != 1048576)); then
19223                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19224         fi
19225
19226         flags=${entry[10]}
19227         if [[ "${flags}" != "w" ]]; then
19228                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19229         fi
19230
19231         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19232         sleep 5
19233
19234         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19235                 error "cannot read '${file}'"
19236         sleep 5
19237
19238         do_facet ost1 killall -TERM ofd_access_log_reader
19239         wait
19240         rc=$?
19241
19242         if ((rc != 0)); then
19243                 error "ofd_access_log_reader exited with rc = '${rc}'"
19244         fi
19245
19246         oalr_expect_event_count alr_log_entry "${trace}" 1
19247
19248         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19249         echo "entry = '${entry[*]}'" >&2
19250
19251         pfid2=${entry[4]}
19252         if [[ "${pfid1}" != "${pfid2}" ]]; then
19253                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19254         fi
19255
19256         size=${entry[8]}
19257         if ((size != 524288)); then
19258                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19259         fi
19260
19261         flags=${entry[10]}
19262         if [[ "${flags}" != "r" ]]; then
19263                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19264         fi
19265 }
19266 run_test 165b "ofd access log entries are produced and consumed"
19267
19268 test_165c() {
19269         local trace="/tmp/${tfile}.trace"
19270         local file="${DIR}/${tdir}/${tfile}"
19271
19272         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19273                 skip "OFD access log unsupported"
19274
19275         test_mkdir "${DIR}/${tdir}"
19276
19277         setup_165
19278         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19279         sleep 5
19280
19281         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19282
19283         # 4096 / 64 = 64. Create twice as many entries.
19284         for ((i = 0; i < 128; i++)); do
19285                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19286                         error "cannot create file"
19287         done
19288
19289         sync
19290
19291         do_facet ost1 killall -TERM ofd_access_log_reader
19292         wait
19293         rc=$?
19294         if ((rc != 0)); then
19295                 error "ofd_access_log_reader exited with rc = '${rc}'"
19296         fi
19297
19298         unlinkmany  "${file}-%d" 128
19299 }
19300 run_test 165c "full ofd access logs do not block IOs"
19301
19302 oal_get_read_count() {
19303         local stats="$1"
19304
19305         # STATS lustre-OST0001 alr_read_count 1
19306
19307         do_facet ost1 cat "${stats}" |
19308         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19309              END { print count; }'
19310 }
19311
19312 oal_expect_read_count() {
19313         local stats="$1"
19314         local count
19315         local expect="$2"
19316
19317         # Ask ofd_access_log_reader to write stats.
19318         do_facet ost1 killall -USR1 ofd_access_log_reader
19319
19320         # Allow some time for things to happen.
19321         sleep 1
19322
19323         count=$(oal_get_read_count "${stats}")
19324         if ((count == expect)); then
19325                 return 0
19326         fi
19327
19328         error_noexit "bad read count, got ${count}, expected ${expect}"
19329         do_facet ost1 cat "${stats}" >&2
19330         exit 1
19331 }
19332
19333 test_165d() {
19334         local stats="/tmp/${tfile}.stats"
19335         local file="${DIR}/${tdir}/${tfile}"
19336         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19337
19338         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19339                 skip "OFD access log unsupported"
19340
19341         test_mkdir "${DIR}/${tdir}"
19342
19343         setup_165
19344         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19345         sleep 5
19346
19347         lfs setstripe -c 1 -i 0 "${file}"
19348
19349         do_facet ost1 lctl set_param "${param}=rw"
19350         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19351                 error "cannot create '${file}'"
19352         oal_expect_read_count "${stats}" 1
19353
19354         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19355                 error "cannot read '${file}'"
19356         oal_expect_read_count "${stats}" 2
19357
19358         do_facet ost1 lctl set_param "${param}=r"
19359         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19360                 error "cannot create '${file}'"
19361         oal_expect_read_count "${stats}" 2
19362
19363         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19364                 error "cannot read '${file}'"
19365         oal_expect_read_count "${stats}" 3
19366
19367         do_facet ost1 lctl set_param "${param}=w"
19368         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19369                 error "cannot create '${file}'"
19370         oal_expect_read_count "${stats}" 4
19371
19372         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19373                 error "cannot read '${file}'"
19374         oal_expect_read_count "${stats}" 4
19375
19376         do_facet ost1 lctl set_param "${param}=0"
19377         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19378                 error "cannot create '${file}'"
19379         oal_expect_read_count "${stats}" 4
19380
19381         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19382                 error "cannot read '${file}'"
19383         oal_expect_read_count "${stats}" 4
19384
19385         do_facet ost1 killall -TERM ofd_access_log_reader
19386         wait
19387         rc=$?
19388         if ((rc != 0)); then
19389                 error "ofd_access_log_reader exited with rc = '${rc}'"
19390         fi
19391 }
19392 run_test 165d "ofd_access_log mask works"
19393
19394 test_165e() {
19395         local stats="/tmp/${tfile}.stats"
19396         local file0="${DIR}/${tdir}-0/${tfile}"
19397         local file1="${DIR}/${tdir}-1/${tfile}"
19398
19399         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19400                 skip "OFD access log unsupported"
19401
19402         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19403
19404         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19405         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19406
19407         lfs setstripe -c 1 -i 0 "${file0}"
19408         lfs setstripe -c 1 -i 0 "${file1}"
19409
19410         setup_165
19411         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19412         sleep 5
19413
19414         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19415                 error "cannot create '${file0}'"
19416         sync
19417         oal_expect_read_count "${stats}" 0
19418
19419         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19420                 error "cannot create '${file1}'"
19421         sync
19422         oal_expect_read_count "${stats}" 1
19423
19424         do_facet ost1 killall -TERM ofd_access_log_reader
19425         wait
19426         rc=$?
19427         if ((rc != 0)); then
19428                 error "ofd_access_log_reader exited with rc = '${rc}'"
19429         fi
19430 }
19431 run_test 165e "ofd_access_log MDT index filter works"
19432
19433 test_165f() {
19434         local trace="/tmp/${tfile}.trace"
19435         local rc
19436         local count
19437
19438         setup_165
19439         do_facet ost1 timeout 60 ofd_access_log_reader \
19440                 --exit-on-close --debug=- --trace=- > "${trace}" &
19441         sleep 5
19442         stop ost1
19443
19444         wait
19445         rc=$?
19446
19447         if ((rc != 0)); then
19448                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19449                 cat "${trace}"
19450                 exit 1
19451         fi
19452 }
19453 run_test 165f "ofd_access_log_reader --exit-on-close works"
19454
19455 test_169() {
19456         # do directio so as not to populate the page cache
19457         log "creating a 10 Mb file"
19458         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19459                 error "multiop failed while creating a file"
19460         log "starting reads"
19461         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19462         log "truncating the file"
19463         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19464                 error "multiop failed while truncating the file"
19465         log "killing dd"
19466         kill %+ || true # reads might have finished
19467         echo "wait until dd is finished"
19468         wait
19469         log "removing the temporary file"
19470         rm -rf $DIR/$tfile || error "tmp file removal failed"
19471 }
19472 run_test 169 "parallel read and truncate should not deadlock"
19473
19474 test_170() {
19475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19476
19477         $LCTL clear     # bug 18514
19478         $LCTL debug_daemon start $TMP/${tfile}_log_good
19479         touch $DIR/$tfile
19480         $LCTL debug_daemon stop
19481         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19482                 error "sed failed to read log_good"
19483
19484         $LCTL debug_daemon start $TMP/${tfile}_log_good
19485         rm -rf $DIR/$tfile
19486         $LCTL debug_daemon stop
19487
19488         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19489                error "lctl df log_bad failed"
19490
19491         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19492         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19493
19494         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19495         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19496
19497         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19498                 error "bad_line good_line1 good_line2 are empty"
19499
19500         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19501         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19502         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19503
19504         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19505         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19506         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19507
19508         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19509                 error "bad_line_new good_line_new are empty"
19510
19511         local expected_good=$((good_line1 + good_line2*2))
19512
19513         rm -f $TMP/${tfile}*
19514         # LU-231, short malformed line may not be counted into bad lines
19515         if [ $bad_line -ne $bad_line_new ] &&
19516                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19517                 error "expected $bad_line bad lines, but got $bad_line_new"
19518                 return 1
19519         fi
19520
19521         if [ $expected_good -ne $good_line_new ]; then
19522                 error "expected $expected_good good lines, but got $good_line_new"
19523                 return 2
19524         fi
19525         true
19526 }
19527 run_test 170 "test lctl df to handle corrupted log ====================="
19528
19529 test_171() { # bug20592
19530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19531
19532         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19533         $LCTL set_param fail_loc=0x50e
19534         $LCTL set_param fail_val=3000
19535         multiop_bg_pause $DIR/$tfile O_s || true
19536         local MULTIPID=$!
19537         kill -USR1 $MULTIPID
19538         # cause log dump
19539         sleep 3
19540         wait $MULTIPID
19541         if dmesg | grep "recursive fault"; then
19542                 error "caught a recursive fault"
19543         fi
19544         $LCTL set_param fail_loc=0
19545         true
19546 }
19547 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19548
19549 test_172() {
19550
19551         #define OBD_FAIL_OBD_CLEANUP  0x60e
19552         $LCTL set_param fail_loc=0x60e
19553         umount $MOUNT || error "umount $MOUNT failed"
19554         stack_trap "mount_client $MOUNT"
19555
19556         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19557                 error "no client OBDs are remained"
19558
19559         $LCTL dl | while read devno state type name foo; do
19560                 case $type in
19561                 lov|osc|lmv|mdc)
19562                         $LCTL --device $name cleanup
19563                         $LCTL --device $name detach
19564                         ;;
19565                 *)
19566                         # skip server devices
19567                         ;;
19568                 esac
19569         done
19570
19571         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19572                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19573                 error "some client OBDs are still remained"
19574         fi
19575
19576 }
19577 run_test 172 "manual device removal with lctl cleanup/detach ======"
19578
19579 # it would be good to share it with obdfilter-survey/iokit-libecho code
19580 setup_obdecho_osc () {
19581         local rc=0
19582         local ost_nid=$1
19583         local obdfilter_name=$2
19584         echo "Creating new osc for $obdfilter_name on $ost_nid"
19585         # make sure we can find loopback nid
19586         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19587
19588         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19589                            ${obdfilter_name}_osc_UUID || rc=2; }
19590         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19591                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19592         return $rc
19593 }
19594
19595 cleanup_obdecho_osc () {
19596         local obdfilter_name=$1
19597         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19598         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19599         return 0
19600 }
19601
19602 obdecho_test() {
19603         local OBD=$1
19604         local node=$2
19605         local pages=${3:-64}
19606         local rc=0
19607         local id
19608
19609         local count=10
19610         local obd_size=$(get_obd_size $node $OBD)
19611         local page_size=$(get_page_size $node)
19612         if [[ -n "$obd_size" ]]; then
19613                 local new_count=$((obd_size / (pages * page_size / 1024)))
19614                 [[ $new_count -ge $count ]] || count=$new_count
19615         fi
19616
19617         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19618         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19619                            rc=2; }
19620         if [ $rc -eq 0 ]; then
19621             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19622             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19623         fi
19624         echo "New object id is $id"
19625         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19626                            rc=4; }
19627         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19628                            "test_brw $count w v $pages $id" || rc=4; }
19629         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19630                            rc=4; }
19631         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19632                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19633         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19634                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19635         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19636         return $rc
19637 }
19638
19639 test_180a() {
19640         skip "obdecho on osc is no longer supported"
19641 }
19642 run_test 180a "test obdecho on osc"
19643
19644 test_180b() {
19645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19646         remote_ost_nodsh && skip "remote OST with nodsh"
19647
19648         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19649                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19650                 error "failed to load module obdecho"
19651
19652         local target=$(do_facet ost1 $LCTL dl |
19653                        awk '/obdfilter/ { print $4; exit; }')
19654
19655         if [ -n "$target" ]; then
19656                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19657         else
19658                 do_facet ost1 $LCTL dl
19659                 error "there is no obdfilter target on ost1"
19660         fi
19661 }
19662 run_test 180b "test obdecho directly on obdfilter"
19663
19664 test_180c() { # LU-2598
19665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19666         remote_ost_nodsh && skip "remote OST with nodsh"
19667         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19668                 skip "Need MDS version at least 2.4.0"
19669
19670         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19671                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19672                 error "failed to load module obdecho"
19673
19674         local target=$(do_facet ost1 $LCTL dl |
19675                        awk '/obdfilter/ { print $4; exit; }')
19676
19677         if [ -n "$target" ]; then
19678                 local pages=16384 # 64MB bulk I/O RPC size
19679
19680                 obdecho_test "$target" ost1 "$pages" ||
19681                         error "obdecho_test with pages=$pages failed with $?"
19682         else
19683                 do_facet ost1 $LCTL dl
19684                 error "there is no obdfilter target on ost1"
19685         fi
19686 }
19687 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19688
19689 test_181() { # bug 22177
19690         test_mkdir $DIR/$tdir
19691         # create enough files to index the directory
19692         createmany -o $DIR/$tdir/foobar 4000
19693         # print attributes for debug purpose
19694         lsattr -d .
19695         # open dir
19696         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19697         MULTIPID=$!
19698         # remove the files & current working dir
19699         unlinkmany $DIR/$tdir/foobar 4000
19700         rmdir $DIR/$tdir
19701         kill -USR1 $MULTIPID
19702         wait $MULTIPID
19703         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19704         return 0
19705 }
19706 run_test 181 "Test open-unlinked dir ========================"
19707
19708 test_182a() {
19709         local fcount=1000
19710         local tcount=10
19711
19712         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19713
19714         $LCTL set_param mdc.*.rpc_stats=clear
19715
19716         for (( i = 0; i < $tcount; i++ )) ; do
19717                 mkdir $DIR/$tdir/$i
19718         done
19719
19720         for (( i = 0; i < $tcount; i++ )) ; do
19721                 createmany -o $DIR/$tdir/$i/f- $fcount &
19722         done
19723         wait
19724
19725         for (( i = 0; i < $tcount; i++ )) ; do
19726                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19727         done
19728         wait
19729
19730         $LCTL get_param mdc.*.rpc_stats
19731
19732         rm -rf $DIR/$tdir
19733 }
19734 run_test 182a "Test parallel modify metadata operations from mdc"
19735
19736 test_182b() {
19737         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19738         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19739         local dcount=1000
19740         local tcount=10
19741         local stime
19742         local etime
19743         local delta
19744
19745         do_facet mds1 $LCTL list_param \
19746                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19747                 skip "MDS lacks parallel RPC handling"
19748
19749         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19750
19751         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19752                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19753
19754         stime=$(date +%s)
19755         createmany -i 0 -d $DIR/$tdir/t- $tcount
19756
19757         for (( i = 0; i < $tcount; i++ )) ; do
19758                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19759         done
19760         wait
19761         etime=$(date +%s)
19762         delta=$((etime - stime))
19763         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19764
19765         stime=$(date +%s)
19766         for (( i = 0; i < $tcount; i++ )) ; do
19767                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19768         done
19769         wait
19770         etime=$(date +%s)
19771         delta=$((etime - stime))
19772         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19773
19774         rm -rf $DIR/$tdir
19775
19776         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19777
19778         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19779
19780         stime=$(date +%s)
19781         createmany -i 0 -d $DIR/$tdir/t- $tcount
19782
19783         for (( i = 0; i < $tcount; i++ )) ; do
19784                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19785         done
19786         wait
19787         etime=$(date +%s)
19788         delta=$((etime - stime))
19789         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19790
19791         stime=$(date +%s)
19792         for (( i = 0; i < $tcount; i++ )) ; do
19793                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19794         done
19795         wait
19796         etime=$(date +%s)
19797         delta=$((etime - stime))
19798         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19799
19800         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19801 }
19802 run_test 182b "Test parallel modify metadata operations from osp"
19803
19804 test_183() { # LU-2275
19805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19806         remote_mds_nodsh && skip "remote MDS with nodsh"
19807         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19808                 skip "Need MDS version at least 2.3.56"
19809
19810         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19811         echo aaa > $DIR/$tdir/$tfile
19812
19813 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19814         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19815
19816         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19817         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19818
19819         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19820
19821         # Flush negative dentry cache
19822         touch $DIR/$tdir/$tfile
19823
19824         # We are not checking for any leaked references here, they'll
19825         # become evident next time we do cleanup with module unload.
19826         rm -rf $DIR/$tdir
19827 }
19828 run_test 183 "No crash or request leak in case of strange dispositions ========"
19829
19830 # test suite 184 is for LU-2016, LU-2017
19831 test_184a() {
19832         check_swap_layouts_support
19833
19834         dir0=$DIR/$tdir/$testnum
19835         test_mkdir -p -c1 $dir0
19836         ref1=/etc/passwd
19837         ref2=/etc/group
19838         file1=$dir0/f1
19839         file2=$dir0/f2
19840         $LFS setstripe -c1 $file1
19841         cp $ref1 $file1
19842         $LFS setstripe -c2 $file2
19843         cp $ref2 $file2
19844         gen1=$($LFS getstripe -g $file1)
19845         gen2=$($LFS getstripe -g $file2)
19846
19847         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19848         gen=$($LFS getstripe -g $file1)
19849         [[ $gen1 != $gen ]] ||
19850                 error "Layout generation on $file1 does not change"
19851         gen=$($LFS getstripe -g $file2)
19852         [[ $gen2 != $gen ]] ||
19853                 error "Layout generation on $file2 does not change"
19854
19855         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19856         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19857
19858         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19859 }
19860 run_test 184a "Basic layout swap"
19861
19862 test_184b() {
19863         check_swap_layouts_support
19864
19865         dir0=$DIR/$tdir/$testnum
19866         mkdir -p $dir0 || error "creating dir $dir0"
19867         file1=$dir0/f1
19868         file2=$dir0/f2
19869         file3=$dir0/f3
19870         dir1=$dir0/d1
19871         dir2=$dir0/d2
19872         mkdir $dir1 $dir2
19873         $LFS setstripe -c1 $file1
19874         $LFS setstripe -c2 $file2
19875         $LFS setstripe -c1 $file3
19876         chown $RUNAS_ID $file3
19877         gen1=$($LFS getstripe -g $file1)
19878         gen2=$($LFS getstripe -g $file2)
19879
19880         $LFS swap_layouts $dir1 $dir2 &&
19881                 error "swap of directories layouts should fail"
19882         $LFS swap_layouts $dir1 $file1 &&
19883                 error "swap of directory and file layouts should fail"
19884         $RUNAS $LFS swap_layouts $file1 $file2 &&
19885                 error "swap of file we cannot write should fail"
19886         $LFS swap_layouts $file1 $file3 &&
19887                 error "swap of file with different owner should fail"
19888         /bin/true # to clear error code
19889 }
19890 run_test 184b "Forbidden layout swap (will generate errors)"
19891
19892 test_184c() {
19893         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19894         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19895         check_swap_layouts_support
19896         check_swap_layout_no_dom $DIR
19897
19898         local dir0=$DIR/$tdir/$testnum
19899         mkdir -p $dir0 || error "creating dir $dir0"
19900
19901         local ref1=$dir0/ref1
19902         local ref2=$dir0/ref2
19903         local file1=$dir0/file1
19904         local file2=$dir0/file2
19905         # create a file large enough for the concurrent test
19906         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19907         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19908         echo "ref file size: ref1($(stat -c %s $ref1))," \
19909              "ref2($(stat -c %s $ref2))"
19910
19911         cp $ref2 $file2
19912         dd if=$ref1 of=$file1 bs=16k &
19913         local DD_PID=$!
19914
19915         # Make sure dd starts to copy file, but wait at most 5 seconds
19916         local loops=0
19917         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19918
19919         $LFS swap_layouts $file1 $file2
19920         local rc=$?
19921         wait $DD_PID
19922         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19923         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19924
19925         # how many bytes copied before swapping layout
19926         local copied=$(stat -c %s $file2)
19927         local remaining=$(stat -c %s $ref1)
19928         remaining=$((remaining - copied))
19929         echo "Copied $copied bytes before swapping layout..."
19930
19931         cmp -n $copied $file1 $ref2 | grep differ &&
19932                 error "Content mismatch [0, $copied) of ref2 and file1"
19933         cmp -n $copied $file2 $ref1 ||
19934                 error "Content mismatch [0, $copied) of ref1 and file2"
19935         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19936                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19937
19938         # clean up
19939         rm -f $ref1 $ref2 $file1 $file2
19940 }
19941 run_test 184c "Concurrent write and layout swap"
19942
19943 test_184d() {
19944         check_swap_layouts_support
19945         check_swap_layout_no_dom $DIR
19946         [ -z "$(which getfattr 2>/dev/null)" ] &&
19947                 skip_env "no getfattr command"
19948
19949         local file1=$DIR/$tdir/$tfile-1
19950         local file2=$DIR/$tdir/$tfile-2
19951         local file3=$DIR/$tdir/$tfile-3
19952         local lovea1
19953         local lovea2
19954
19955         mkdir -p $DIR/$tdir
19956         touch $file1 || error "create $file1 failed"
19957         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19958                 error "create $file2 failed"
19959         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19960                 error "create $file3 failed"
19961         lovea1=$(get_layout_param $file1)
19962
19963         $LFS swap_layouts $file2 $file3 ||
19964                 error "swap $file2 $file3 layouts failed"
19965         $LFS swap_layouts $file1 $file2 ||
19966                 error "swap $file1 $file2 layouts failed"
19967
19968         lovea2=$(get_layout_param $file2)
19969         echo "$lovea1"
19970         echo "$lovea2"
19971         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19972
19973         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19974         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19975 }
19976 run_test 184d "allow stripeless layouts swap"
19977
19978 test_184e() {
19979         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19980                 skip "Need MDS version at least 2.6.94"
19981         check_swap_layouts_support
19982         check_swap_layout_no_dom $DIR
19983         [ -z "$(which getfattr 2>/dev/null)" ] &&
19984                 skip_env "no getfattr command"
19985
19986         local file1=$DIR/$tdir/$tfile-1
19987         local file2=$DIR/$tdir/$tfile-2
19988         local file3=$DIR/$tdir/$tfile-3
19989         local lovea
19990
19991         mkdir -p $DIR/$tdir
19992         touch $file1 || error "create $file1 failed"
19993         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19994                 error "create $file2 failed"
19995         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19996                 error "create $file3 failed"
19997
19998         $LFS swap_layouts $file1 $file2 ||
19999                 error "swap $file1 $file2 layouts failed"
20000
20001         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20002         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20003
20004         echo 123 > $file1 || error "Should be able to write into $file1"
20005
20006         $LFS swap_layouts $file1 $file3 ||
20007                 error "swap $file1 $file3 layouts failed"
20008
20009         echo 123 > $file1 || error "Should be able to write into $file1"
20010
20011         rm -rf $file1 $file2 $file3
20012 }
20013 run_test 184e "Recreate layout after stripeless layout swaps"
20014
20015 test_184f() {
20016         # Create a file with name longer than sizeof(struct stat) ==
20017         # 144 to see if we can get chars from the file name to appear
20018         # in the returned striping. Note that 'f' == 0x66.
20019         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20020
20021         mkdir -p $DIR/$tdir
20022         mcreate $DIR/$tdir/$file
20023         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20024                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20025         fi
20026 }
20027 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20028
20029 test_185() { # LU-2441
20030         # LU-3553 - no volatile file support in old servers
20031         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20032                 skip "Need MDS version at least 2.3.60"
20033
20034         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20035         touch $DIR/$tdir/spoo
20036         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20037         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20038                 error "cannot create/write a volatile file"
20039         [ "$FILESET" == "" ] &&
20040         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20041                 error "FID is still valid after close"
20042
20043         multiop_bg_pause $DIR/$tdir Vw4096_c
20044         local multi_pid=$!
20045
20046         local OLD_IFS=$IFS
20047         IFS=":"
20048         local fidv=($fid)
20049         IFS=$OLD_IFS
20050         # assume that the next FID for this client is sequential, since stdout
20051         # is unfortunately eaten by multiop_bg_pause
20052         local n=$((${fidv[1]} + 1))
20053         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20054         if [ "$FILESET" == "" ]; then
20055                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20056                         error "FID is missing before close"
20057         fi
20058         kill -USR1 $multi_pid
20059         # 1 second delay, so if mtime change we will see it
20060         sleep 1
20061         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20062         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20063 }
20064 run_test 185 "Volatile file support"
20065
20066 function create_check_volatile() {
20067         local idx=$1
20068         local tgt
20069
20070         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20071         local PID=$!
20072         sleep 1
20073         local FID=$(cat /tmp/${tfile}.fid)
20074         [ "$FID" == "" ] && error "can't get FID for volatile"
20075         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20076         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20077         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20078         kill -USR1 $PID
20079         wait
20080         sleep 1
20081         cancel_lru_locks mdc # flush opencache
20082         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20083         return 0
20084 }
20085
20086 test_185a(){
20087         # LU-12516 - volatile creation via .lustre
20088         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20089                 skip "Need MDS version at least 2.3.55"
20090
20091         create_check_volatile 0
20092         [ $MDSCOUNT -lt 2 ] && return 0
20093
20094         # DNE case
20095         create_check_volatile 1
20096
20097         return 0
20098 }
20099 run_test 185a "Volatile file creation in .lustre/fid/"
20100
20101 test_187a() {
20102         remote_mds_nodsh && skip "remote MDS with nodsh"
20103         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20104                 skip "Need MDS version at least 2.3.0"
20105
20106         local dir0=$DIR/$tdir/$testnum
20107         mkdir -p $dir0 || error "creating dir $dir0"
20108
20109         local file=$dir0/file1
20110         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20111         stack_trap "rm -f $file"
20112         local dv1=$($LFS data_version $file)
20113         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20114         local dv2=$($LFS data_version $file)
20115         [[ $dv1 != $dv2 ]] ||
20116                 error "data version did not change on write $dv1 == $dv2"
20117 }
20118 run_test 187a "Test data version change"
20119
20120 test_187b() {
20121         remote_mds_nodsh && skip "remote MDS with nodsh"
20122         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20123                 skip "Need MDS version at least 2.3.0"
20124
20125         local dir0=$DIR/$tdir/$testnum
20126         mkdir -p $dir0 || error "creating dir $dir0"
20127
20128         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20129         [[ ${DV[0]} != ${DV[1]} ]] ||
20130                 error "data version did not change on write"\
20131                       " ${DV[0]} == ${DV[1]}"
20132
20133         # clean up
20134         rm -f $file1
20135 }
20136 run_test 187b "Test data version change on volatile file"
20137
20138 test_200() {
20139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20140         remote_mgs_nodsh && skip "remote MGS with nodsh"
20141         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20142
20143         local POOL=${POOL:-cea1}
20144         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20145         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20146         # Pool OST targets
20147         local first_ost=0
20148         local last_ost=$(($OSTCOUNT - 1))
20149         local ost_step=2
20150         local ost_list=$(seq $first_ost $ost_step $last_ost)
20151         local ost_range="$first_ost $last_ost $ost_step"
20152         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20153         local file_dir=$POOL_ROOT/file_tst
20154         local subdir=$test_path/subdir
20155         local rc=0
20156
20157         while : ; do
20158                 # former test_200a test_200b
20159                 pool_add $POOL                          || { rc=$? ; break; }
20160                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20161                 # former test_200c test_200d
20162                 mkdir -p $test_path
20163                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20164                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20165                 mkdir -p $subdir
20166                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20167                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20168                                                         || { rc=$? ; break; }
20169                 # former test_200e test_200f
20170                 local files=$((OSTCOUNT*3))
20171                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20172                                                         || { rc=$? ; break; }
20173                 pool_create_files $POOL $file_dir $files "$ost_list" \
20174                                                         || { rc=$? ; break; }
20175                 # former test_200g test_200h
20176                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20177                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20178
20179                 # former test_201a test_201b test_201c
20180                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20181
20182                 local f=$test_path/$tfile
20183                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20184                 pool_remove $POOL $f                    || { rc=$? ; break; }
20185                 break
20186         done
20187
20188         destroy_test_pools
20189
20190         return $rc
20191 }
20192 run_test 200 "OST pools"
20193
20194 # usage: default_attr <count | size | offset>
20195 default_attr() {
20196         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20197 }
20198
20199 # usage: check_default_stripe_attr
20200 check_default_stripe_attr() {
20201         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20202         case $1 in
20203         --stripe-count|-c)
20204                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20205         --stripe-size|-S)
20206                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20207         --stripe-index|-i)
20208                 EXPECTED=-1;;
20209         *)
20210                 error "unknown getstripe attr '$1'"
20211         esac
20212
20213         [ $ACTUAL == $EXPECTED ] ||
20214                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20215 }
20216
20217 test_204a() {
20218         test_mkdir $DIR/$tdir
20219         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20220
20221         check_default_stripe_attr --stripe-count
20222         check_default_stripe_attr --stripe-size
20223         check_default_stripe_attr --stripe-index
20224 }
20225 run_test 204a "Print default stripe attributes"
20226
20227 test_204b() {
20228         test_mkdir $DIR/$tdir
20229         $LFS setstripe --stripe-count 1 $DIR/$tdir
20230
20231         check_default_stripe_attr --stripe-size
20232         check_default_stripe_attr --stripe-index
20233 }
20234 run_test 204b "Print default stripe size and offset"
20235
20236 test_204c() {
20237         test_mkdir $DIR/$tdir
20238         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20239
20240         check_default_stripe_attr --stripe-count
20241         check_default_stripe_attr --stripe-index
20242 }
20243 run_test 204c "Print default stripe count and offset"
20244
20245 test_204d() {
20246         test_mkdir $DIR/$tdir
20247         $LFS setstripe --stripe-index 0 $DIR/$tdir
20248
20249         check_default_stripe_attr --stripe-count
20250         check_default_stripe_attr --stripe-size
20251 }
20252 run_test 204d "Print default stripe count and size"
20253
20254 test_204e() {
20255         test_mkdir $DIR/$tdir
20256         $LFS setstripe -d $DIR/$tdir
20257
20258         # LU-16904 check if root is set as PFL layout
20259         local numcomp=$($LFS getstripe --component-count $MOUNT)
20260
20261         if [[ $numcomp -gt 0 ]]; then
20262                 check_default_stripe_attr --stripe-count
20263         else
20264                 check_default_stripe_attr --stripe-count --raw
20265         fi
20266         check_default_stripe_attr --stripe-size --raw
20267         check_default_stripe_attr --stripe-index --raw
20268 }
20269 run_test 204e "Print raw stripe attributes"
20270
20271 test_204f() {
20272         test_mkdir $DIR/$tdir
20273         $LFS setstripe --stripe-count 1 $DIR/$tdir
20274
20275         check_default_stripe_attr --stripe-size --raw
20276         check_default_stripe_attr --stripe-index --raw
20277 }
20278 run_test 204f "Print raw stripe size and offset"
20279
20280 test_204g() {
20281         test_mkdir $DIR/$tdir
20282         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20283
20284         check_default_stripe_attr --stripe-count --raw
20285         check_default_stripe_attr --stripe-index --raw
20286 }
20287 run_test 204g "Print raw stripe count and offset"
20288
20289 test_204h() {
20290         test_mkdir $DIR/$tdir
20291         $LFS setstripe --stripe-index 0 $DIR/$tdir
20292
20293         check_default_stripe_attr --stripe-count --raw
20294         check_default_stripe_attr --stripe-size --raw
20295 }
20296 run_test 204h "Print raw stripe count and size"
20297
20298 # Figure out which job scheduler is being used, if any,
20299 # or use a fake one
20300 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20301         JOBENV=SLURM_JOB_ID
20302 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20303         JOBENV=LSB_JOBID
20304 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20305         JOBENV=PBS_JOBID
20306 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20307         JOBENV=LOADL_STEP_ID
20308 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20309         JOBENV=JOB_ID
20310 else
20311         $LCTL list_param jobid_name > /dev/null 2>&1
20312         if [ $? -eq 0 ]; then
20313                 JOBENV=nodelocal
20314         else
20315                 JOBENV=FAKE_JOBID
20316         fi
20317 fi
20318 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20319
20320 verify_jobstats() {
20321         local cmd=($1)
20322         shift
20323         local facets="$@"
20324
20325 # we don't really need to clear the stats for this test to work, since each
20326 # command has a unique jobid, but it makes debugging easier if needed.
20327 #       for facet in $facets; do
20328 #               local dev=$(convert_facet2label $facet)
20329 #               # clear old jobstats
20330 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20331 #       done
20332
20333         # use a new JobID for each test, or we might see an old one
20334         [ "$JOBENV" = "FAKE_JOBID" ] &&
20335                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20336
20337         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20338
20339         [ "$JOBENV" = "nodelocal" ] && {
20340                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20341                 $LCTL set_param jobid_name=$FAKE_JOBID
20342                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20343         }
20344
20345         log "Test: ${cmd[*]}"
20346         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20347
20348         if [ $JOBENV = "FAKE_JOBID" ]; then
20349                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20350         else
20351                 ${cmd[*]}
20352         fi
20353
20354         # all files are created on OST0000
20355         for facet in $facets; do
20356                 local stats="*.$(convert_facet2label $facet).job_stats"
20357
20358                 # strip out libtool wrappers for in-tree executables
20359                 if (( $(do_facet $facet lctl get_param $stats |
20360                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20361                         do_facet $facet lctl get_param $stats
20362                         error "No jobstats for $JOBVAL found on $facet::$stats"
20363                 fi
20364         done
20365 }
20366
20367 jobstats_set() {
20368         local new_jobenv=$1
20369
20370         set_persistent_param_and_check client "jobid_var" \
20371                 "$FSNAME.sys.jobid_var" $new_jobenv
20372 }
20373
20374 test_205a() { # Job stats
20375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20376         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20377                 skip "Need MDS version with at least 2.7.1"
20378         remote_mgs_nodsh && skip "remote MGS with nodsh"
20379         remote_mds_nodsh && skip "remote MDS with nodsh"
20380         remote_ost_nodsh && skip "remote OST with nodsh"
20381         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20382                 skip "Server doesn't support jobstats"
20383         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20384
20385         local old_jobenv=$($LCTL get_param -n jobid_var)
20386         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20387         stack_trap "jobstats_set $old_jobenv" EXIT
20388
20389         changelog_register
20390
20391         local old_jobid_name=$($LCTL get_param jobid_name)
20392         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20393
20394         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20395                                 mdt.*.job_cleanup_interval | head -n 1)
20396         local new_interval=5
20397         do_facet $SINGLEMDS \
20398                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20399         stack_trap "do_facet $SINGLEMDS \
20400                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20401         local start=$SECONDS
20402
20403         local cmd
20404         # mkdir
20405         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20406         verify_jobstats "$cmd" "$SINGLEMDS"
20407         # rmdir
20408         cmd="rmdir $DIR/$tdir"
20409         verify_jobstats "$cmd" "$SINGLEMDS"
20410         # mkdir on secondary MDT
20411         if [ $MDSCOUNT -gt 1 ]; then
20412                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20413                 verify_jobstats "$cmd" "mds2"
20414         fi
20415         # mknod
20416         cmd="mknod $DIR/$tfile c 1 3"
20417         verify_jobstats "$cmd" "$SINGLEMDS"
20418         # unlink
20419         cmd="rm -f $DIR/$tfile"
20420         verify_jobstats "$cmd" "$SINGLEMDS"
20421         # create all files on OST0000 so verify_jobstats can find OST stats
20422         # open & close
20423         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20424         verify_jobstats "$cmd" "$SINGLEMDS"
20425         # setattr
20426         cmd="touch $DIR/$tfile"
20427         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20428         # write
20429         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20430         verify_jobstats "$cmd" "ost1"
20431         # read
20432         cancel_lru_locks osc
20433         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20434         verify_jobstats "$cmd" "ost1"
20435         # truncate
20436         cmd="$TRUNCATE $DIR/$tfile 0"
20437         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20438         # rename
20439         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20440         verify_jobstats "$cmd" "$SINGLEMDS"
20441         # jobstats expiry - sleep until old stats should be expired
20442         local left=$((new_interval + 5 - (SECONDS - start)))
20443         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20444                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20445                         "0" $left
20446         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20447         verify_jobstats "$cmd" "$SINGLEMDS"
20448         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20449             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20450
20451         # Ensure that jobid are present in changelog (if supported by MDS)
20452         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20453                 changelog_dump | tail -10
20454                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20455                 [ $jobids -eq 9 ] ||
20456                         error "Wrong changelog jobid count $jobids != 9"
20457
20458                 # LU-5862
20459                 JOBENV="disable"
20460                 jobstats_set $JOBENV
20461                 touch $DIR/$tfile
20462                 changelog_dump | grep $tfile
20463                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20464                 [ $jobids -eq 0 ] ||
20465                         error "Unexpected jobids when jobid_var=$JOBENV"
20466         fi
20467
20468         # test '%j' access to environment variable - if supported
20469         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20470                 JOBENV="JOBCOMPLEX"
20471                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20472
20473                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20474         fi
20475
20476         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20477                 JOBENV="JOBCOMPLEX"
20478                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20479
20480                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20481         fi
20482
20483         # test '%j' access to per-session jobid - if supported
20484         if lctl list_param jobid_this_session > /dev/null 2>&1
20485         then
20486                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20487                 lctl set_param jobid_this_session=$USER
20488
20489                 JOBENV="JOBCOMPLEX"
20490                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20491
20492                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20493         fi
20494 }
20495 run_test 205a "Verify job stats"
20496
20497 # LU-13117, LU-13597, LU-16599
20498 test_205b() {
20499         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20500                 skip "Need MDS version at least 2.13.54.91"
20501
20502         local job_stats="mdt.*.job_stats"
20503         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20504
20505         do_facet mds1 $LCTL set_param $job_stats=clear
20506
20507         # Setting jobid_var to USER might not be supported
20508         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20509         $LCTL set_param jobid_var=USER || true
20510         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20511         $LCTL set_param jobid_name="%j.%e.%u"
20512
20513         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20514         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20515                 { do_facet mds1 $LCTL get_param $job_stats;
20516                   error "Unexpected jobid found"; }
20517         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20518                 { do_facet mds1 $LCTL get_param $job_stats;
20519                   error "wrong job_stats format found"; }
20520
20521         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20522                 echo "MDS does not yet escape jobid" && return 0
20523
20524         mkdir_on_mdt0 $DIR/$tdir
20525         $LCTL set_param jobid_var=TEST205b
20526         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20527         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20528                       awk '/has\\x20sp/ {print $3}')
20529         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20530                   error "jobid not escaped"; }
20531
20532         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20533                 # need to run such a command on mds1:
20534                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20535                 #
20536                 # there might be multiple MDTs on single mds server, so need to
20537                 # specifiy MDT0000. Or the command will fail due to other MDTs
20538                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20539                         error "cannot clear escaped jobid in job_stats";
20540         else
20541                 echo "MDS does not support clearing escaped jobid"
20542         fi
20543 }
20544 run_test 205b "Verify job stats jobid and output format"
20545
20546 # LU-13733
20547 test_205c() {
20548         $LCTL set_param llite.*.stats=0
20549         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20550         $LCTL get_param llite.*.stats
20551         $LCTL get_param llite.*.stats | grep \
20552                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20553                         error "wrong client stats format found"
20554 }
20555 run_test 205c "Verify client stats format"
20556
20557 test_205d() {
20558         local file=$DIR/$tdir/$tfile
20559
20560         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20561                 skip "need lustre >= 2.15.53 for lljobstat"
20562         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20563                 skip "need lustre >= 2.15.53 for lljobstat"
20564         verify_yaml_available || skip_env "YAML verification not installed"
20565
20566         test_mkdir -i 0 $DIR/$tdir
20567         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20568         stack_trap "rm -rf $DIR/$tdir"
20569
20570         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20571                 error "failed to write data to $file"
20572         mv $file $file.2
20573
20574         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20575         echo -n 'verify rename_stats...'
20576         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20577                 verify_yaml || error "rename_stats is not valid YAML"
20578         echo " OK"
20579
20580         echo -n 'verify mdt job_stats...'
20581         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20582                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20583         echo " OK"
20584
20585         echo -n 'verify ost job_stats...'
20586         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20587                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20588         echo " OK"
20589 }
20590 run_test 205d "verify the format of some stats files"
20591
20592 test_205e() {
20593         local ops_comma
20594         local file=$DIR/$tdir/$tfile
20595         local -a cli_params
20596
20597         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20598                 skip "need lustre >= 2.15.53 for lljobstat"
20599         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20600                 skip "need lustre >= 2.15.53 for lljobstat"
20601         verify_yaml_available || skip_env "YAML verification not installed"
20602
20603         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20604         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20605         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20606
20607         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20608         stack_trap "rm -rf $DIR/$tdir"
20609
20610         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20611                 error "failed to create $file on ost1"
20612         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20613                 error "failed to write data to $file"
20614
20615         do_facet mds1 "$LCTL get_param *.*.job_stats"
20616         do_facet ost1 "$LCTL get_param *.*.job_stats"
20617
20618         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20619         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20620                 error "The output of lljobstat is not an valid YAML"
20621
20622         # verify that job dd.0 does exist and has some ops on ost1
20623         # typically this line is like:
20624         # - 205e.dd.0:            {ops: 20, ...}
20625         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20626                     awk '$2=="205e.dd.0:" {print $4}')
20627
20628         (( ${ops_comma%,} >= 10 )) ||
20629                 error "cannot find job 205e.dd.0 with ops >= 10"
20630 }
20631 run_test 205e "verify the output of lljobstat"
20632
20633 test_205f() {
20634         verify_yaml_available || skip_env "YAML verification not installed"
20635
20636         # check both qos_ost_weights and qos_mdt_weights
20637         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20638         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20639                 error "qos_ost_weights is not valid YAML"
20640 }
20641 run_test 205f "verify qos_ost_weights YAML format "
20642
20643 __test_205_jobstats_dump() {
20644         local -a pids
20645         local nbr_instance=$1
20646
20647         while true; do
20648                 if (( ${#pids[@]} >= nbr_instance )); then
20649                         wait ${pids[@]}
20650                         pids=()
20651                 fi
20652
20653                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20654                 pids+=( $! )
20655         done
20656 }
20657
20658 __test_205_cleanup() {
20659         kill $@
20660         # Clear all job entries
20661         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20662 }
20663
20664 test_205g() {
20665         local -a mds1_params
20666         local -a cli_params
20667         local pids
20668         local interval=5
20669
20670         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20671         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20672         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20673
20674         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20675         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20676         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20677
20678         # start jobs loop
20679         export TEST205G_ID=205g
20680         stack_trap "unset TEST205G_ID" EXIT
20681         while true; do
20682                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20683         done & pids="$! "
20684
20685         __test_205_jobstats_dump 4 & pids+="$! "
20686         stack_trap "__test_205_cleanup $pids" EXIT INT
20687
20688         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20689 }
20690 run_test 205g "stress test for job_stats procfile"
20691
20692 test_205h() {
20693         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20694                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20695         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20696
20697         local dir=$DIR/$tdir
20698         local f=$dir/$tfile
20699         local f2=$dir/$tfile-2
20700         local f3=$dir/$tfile-3
20701         local subdir=$DIR/dir
20702         local val
20703
20704         local mdts=$(comma_list $(mdts_nodes))
20705         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20706         local client_saved=$($LCTL get_param -n jobid_var)
20707
20708         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20709         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20710
20711         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20712                 error "failed to set job_xattr parameter to user.job"
20713         $LCTL set_param jobid_var=procname.uid ||
20714                 error "failed to set jobid_var parameter"
20715
20716         test_mkdir $dir
20717
20718         touch $f
20719         val=$(getfattr -n user.job $f | grep user.job)
20720         [[ $val = user.job=\"touch.0\" ]] ||
20721                 error "expected user.job=\"touch.0\", got '$val'"
20722
20723         mkdir $subdir
20724         val=$(getfattr -n user.job $subdir | grep user.job)
20725         [[ $val = user.job=\"mkdir.0\" ]] ||
20726                 error "expected user.job=\"mkdir.0\", got '$val'"
20727
20728         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20729                 error "failed to set job_xattr parameter to NONE"
20730
20731         touch $f2
20732         val=$(getfattr -d $f2)
20733         [[ -z $val ]] ||
20734                 error "expected no user xattr, got '$val'"
20735
20736         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20737                 error "failed to set job_xattr parameter to trusted.job"
20738
20739         touch $f3
20740         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20741         [[ $val = trusted.job=\"touch.0\" ]] ||
20742                 error "expected trusted.job=\"touch.0\", got '$val'"
20743 }
20744 run_test 205h "check jobid xattr is stored correctly"
20745
20746 test_205i() {
20747         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20748                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20749
20750         local mdts=$(comma_list $(mdts_nodes))
20751         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20752
20753         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20754
20755         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20756                 error "failed to set mdt.*.job_xattr to user.1234567"
20757
20758         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20759                 error "failed to reject too long job_xattr name"
20760
20761         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20762                 error "failed to reject job_xattr name in bad format"
20763
20764         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20765                 error "failed to reject job_xattr name with invalid character"
20766
20767         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20768                         xargs $LCTL set_param" &&
20769                 error "failed to reject job_xattr name with non-ascii character"
20770
20771         return 0
20772 }
20773 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20774
20775 # LU-1480, LU-1773 and LU-1657
20776 test_206() {
20777         mkdir -p $DIR/$tdir
20778         $LFS setstripe -c -1 $DIR/$tdir
20779 #define OBD_FAIL_LOV_INIT 0x1403
20780         $LCTL set_param fail_loc=0xa0001403
20781         $LCTL set_param fail_val=1
20782         touch $DIR/$tdir/$tfile || true
20783 }
20784 run_test 206 "fail lov_init_raid0() doesn't lbug"
20785
20786 test_207a() {
20787         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20788         local fsz=`stat -c %s $DIR/$tfile`
20789         cancel_lru_locks mdc
20790
20791         # do not return layout in getattr intent
20792 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20793         $LCTL set_param fail_loc=0x170
20794         local sz=`stat -c %s $DIR/$tfile`
20795
20796         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20797
20798         rm -rf $DIR/$tfile
20799 }
20800 run_test 207a "can refresh layout at glimpse"
20801
20802 test_207b() {
20803         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20804         local cksum=`md5sum $DIR/$tfile`
20805         local fsz=`stat -c %s $DIR/$tfile`
20806         cancel_lru_locks mdc
20807         cancel_lru_locks osc
20808
20809         # do not return layout in getattr intent
20810 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20811         $LCTL set_param fail_loc=0x171
20812
20813         # it will refresh layout after the file is opened but before read issues
20814         echo checksum is "$cksum"
20815         echo "$cksum" |md5sum -c --quiet || error "file differs"
20816
20817         rm -rf $DIR/$tfile
20818 }
20819 run_test 207b "can refresh layout at open"
20820
20821 test_208() {
20822         # FIXME: in this test suite, only RD lease is used. This is okay
20823         # for now as only exclusive open is supported. After generic lease
20824         # is done, this test suite should be revised. - Jinshan
20825
20826         remote_mds_nodsh && skip "remote MDS with nodsh"
20827         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20828                 skip "Need MDS version at least 2.4.52"
20829
20830         echo "==== test 1: verify get lease work"
20831         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20832
20833         echo "==== test 2: verify lease can be broken by upcoming open"
20834         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20835         local PID=$!
20836         sleep 2
20837
20838         $MULTIOP $DIR/$tfile oO_RDWR:c
20839         kill -USR1 $PID && wait $PID || error "break lease error"
20840
20841         echo "==== test 3: verify lease can't be granted if an open already exists"
20842         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20843         local PID=$!
20844         sleep 2
20845
20846         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20847         kill -USR1 $PID && wait $PID || error "open file error"
20848
20849         echo "==== test 4: lease can sustain over recovery"
20850         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20851         PID=$!
20852         sleep 2
20853
20854         fail mds1
20855
20856         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20857
20858         echo "==== test 5: lease broken can't be regained by replay"
20859         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20860         PID=$!
20861         sleep 2
20862
20863         # open file to break lease and then recovery
20864         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20865         fail mds1
20866
20867         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20868
20869         rm -f $DIR/$tfile
20870 }
20871 run_test 208 "Exclusive open"
20872
20873 test_209() {
20874         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20875                 skip_env "must have disp_stripe"
20876
20877         touch $DIR/$tfile
20878         sync; sleep 5; sync;
20879
20880         echo 3 > /proc/sys/vm/drop_caches
20881         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20882                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20883         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20884
20885         # open/close 500 times
20886         for i in $(seq 500); do
20887                 cat $DIR/$tfile
20888         done
20889
20890         echo 3 > /proc/sys/vm/drop_caches
20891         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20892                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20893         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20894
20895         echo "before: $req_before, after: $req_after"
20896         [ $((req_after - req_before)) -ge 300 ] &&
20897                 error "open/close requests are not freed"
20898         return 0
20899 }
20900 run_test 209 "read-only open/close requests should be freed promptly"
20901
20902 test_210() {
20903         local pid
20904
20905         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20906         pid=$!
20907         sleep 1
20908
20909         $LFS getstripe $DIR/$tfile
20910         kill -USR1 $pid
20911         wait $pid || error "multiop failed"
20912
20913         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20914         pid=$!
20915         sleep 1
20916
20917         $LFS getstripe $DIR/$tfile
20918         kill -USR1 $pid
20919         wait $pid || error "multiop failed"
20920 }
20921 run_test 210 "lfs getstripe does not break leases"
20922
20923 function test_211() {
20924         local PID
20925         local id
20926         local rc
20927
20928         stack_trap "rm -f $DIR/$tfile" EXIT
20929         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20930                 error "can't create file"
20931         $LFS mirror extend -N $DIR/$tfile ||
20932                 error "can't create a replica"
20933         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20934         $LFS getstripe $DIR/$tfile
20935         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20936         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20937
20938         $MULTIOP $DIR/$tfile OeW_E+eUc &
20939         PID=$!
20940         sleep 0.3
20941
20942         id=$($LFS getstripe $DIR/$tfile |
20943                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20944         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20945                 error "removed last in-sync replica?"
20946
20947         kill -USR1 $PID
20948         wait $PID
20949         (( $? == 0 )) || error "failed split broke the lease"
20950 }
20951 run_test 211 "failed mirror split doesn't break write lease"
20952
20953 test_212() {
20954         size=`date +%s`
20955         size=$((size % 8192 + 1))
20956         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20957         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20958         rm -f $DIR/f212 $DIR/f212.xyz
20959 }
20960 run_test 212 "Sendfile test ============================================"
20961
20962 test_213() {
20963         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20964         cancel_lru_locks osc
20965         lctl set_param fail_loc=0x8000040f
20966         # generate a read lock
20967         cat $DIR/$tfile > /dev/null
20968         # write to the file, it will try to cancel the above read lock.
20969         cat /etc/hosts >> $DIR/$tfile
20970 }
20971 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20972
20973 test_214() { # for bug 20133
20974         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20975         for (( i=0; i < 340; i++ )) ; do
20976                 touch $DIR/$tdir/d214c/a$i
20977         done
20978
20979         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20980         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20981         ls $DIR/d214c || error "ls $DIR/d214c failed"
20982         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20983         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20984 }
20985 run_test 214 "hash-indexed directory test - bug 20133"
20986
20987 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20988 create_lnet_proc_files() {
20989         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20990 }
20991
20992 # counterpart of create_lnet_proc_files
20993 remove_lnet_proc_files() {
20994         rm -f $TMP/lnet_$1.sys
20995 }
20996
20997 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20998 # 3rd arg as regexp for body
20999 check_lnet_proc_stats() {
21000         local l=$(cat "$TMP/lnet_$1" |wc -l)
21001         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21002
21003         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21004 }
21005
21006 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21007 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21008 # optional and can be regexp for 2nd line (lnet.routes case)
21009 check_lnet_proc_entry() {
21010         local blp=2          # blp stands for 'position of 1st line of body'
21011         [ -z "$5" ] || blp=3 # lnet.routes case
21012
21013         local l=$(cat "$TMP/lnet_$1" |wc -l)
21014         # subtracting one from $blp because the body can be empty
21015         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21016
21017         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21018                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21019
21020         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21021                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21022
21023         # bail out if any unexpected line happened
21024         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21025         [ "$?" != 0 ] || error "$2 misformatted"
21026 }
21027
21028 test_215() { # for bugs 18102, 21079, 21517
21029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21030
21031         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21032         local P='[1-9][0-9]*'           # positive numeric
21033         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21034         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
21035         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
21036         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
21037
21038         local L1 # regexp for 1st line
21039         local L2 # regexp for 2nd line (optional)
21040         local BR # regexp for the rest (body)
21041
21042         # lnet.stats should look as 11 space-separated non-negative numerics
21043         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21044         create_lnet_proc_files "stats"
21045         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21046         remove_lnet_proc_files "stats"
21047
21048         # lnet.routes should look like this:
21049         # Routing disabled/enabled
21050         # net hops priority state router
21051         # where net is a string like tcp0, hops > 0, priority >= 0,
21052         # state is up/down,
21053         # router is a string like 192.168.1.1@tcp2
21054         L1="^Routing (disabled|enabled)$"
21055         L2="^net +hops +priority +state +router$"
21056         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
21057         create_lnet_proc_files "routes"
21058         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21059         remove_lnet_proc_files "routes"
21060
21061         # lnet.routers should look like this:
21062         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21063         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21064         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21065         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21066         L1="^ref +rtr_ref +alive +router$"
21067         BR="^$P +$P +(up|down) +$NID$"
21068         create_lnet_proc_files "routers"
21069         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21070         remove_lnet_proc_files "routers"
21071
21072         # lnet.peers should look like this:
21073         # nid refs state last max rtr min tx min queue
21074         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21075         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21076         # numeric (0 or >0 or <0), queue >= 0.
21077         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21078         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21079         create_lnet_proc_files "peers"
21080         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21081         remove_lnet_proc_files "peers"
21082
21083         # lnet.buffers  should look like this:
21084         # pages count credits min
21085         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21086         L1="^pages +count +credits +min$"
21087         BR="^ +$N +$N +$I +$I$"
21088         create_lnet_proc_files "buffers"
21089         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21090         remove_lnet_proc_files "buffers"
21091
21092         # lnet.nis should look like this:
21093         # nid status alive refs peer rtr max tx min
21094         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21095         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21096         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21097         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21098         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21099         create_lnet_proc_files "nis"
21100         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21101         remove_lnet_proc_files "nis"
21102
21103         # can we successfully write to lnet.stats?
21104         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21105 }
21106 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21107
21108 test_216() { # bug 20317
21109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21110         remote_ost_nodsh && skip "remote OST with nodsh"
21111
21112         local node
21113         local facets=$(get_facets OST)
21114         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21115
21116         save_lustre_params client "osc.*.contention_seconds" > $p
21117         save_lustre_params $facets \
21118                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21119         save_lustre_params $facets \
21120                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21121         save_lustre_params $facets \
21122                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21123         clear_stats osc.*.osc_stats
21124
21125         # agressive lockless i/o settings
21126         do_nodes $(comma_list $(osts_nodes)) \
21127                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21128                         ldlm.namespaces.filter-*.contended_locks=0 \
21129                         ldlm.namespaces.filter-*.contention_seconds=60"
21130         lctl set_param -n osc.*.contention_seconds=60
21131
21132         $DIRECTIO write $DIR/$tfile 0 10 4096
21133         $CHECKSTAT -s 40960 $DIR/$tfile
21134
21135         # disable lockless i/o
21136         do_nodes $(comma_list $(osts_nodes)) \
21137                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21138                         ldlm.namespaces.filter-*.contended_locks=32 \
21139                         ldlm.namespaces.filter-*.contention_seconds=0"
21140         lctl set_param -n osc.*.contention_seconds=0
21141         clear_stats osc.*.osc_stats
21142
21143         dd if=/dev/zero of=$DIR/$tfile count=0
21144         $CHECKSTAT -s 0 $DIR/$tfile
21145
21146         restore_lustre_params <$p
21147         rm -f $p
21148         rm $DIR/$tfile
21149 }
21150 run_test 216 "check lockless direct write updates file size and kms correctly"
21151
21152 test_217() { # bug 22430
21153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21154
21155         local node
21156
21157         for node in $(nodes_list); do
21158                 local nid=$(host_nids_address $node $NETTYPE)
21159                 local node_ip=$(do_node $node getent ahostsv4 $node |
21160                                 awk '{ print $1; exit; }')
21161
21162                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21163                 # if hostname matches any NID, use hostname for better testing
21164                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21165                         echo "lctl ping node $node@$NETTYPE"
21166                         lctl ping $node@$NETTYPE ||
21167                                 error "ping $node@$NETTYPE failed rc=$?"
21168                 else # otherwise, at least test 'lctl ping' is working
21169                         echo "lctl ping nid $(h2nettype $nid)"
21170                         lctl ping $(h2nettype $nid) ||
21171                                 error "ping $(h2nettype $nid) failed rc=$?"
21172                         echo "skipping $node (no hyphen detected)"
21173                 fi
21174         done
21175
21176         return 0
21177 }
21178 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21179
21180 test_218() {
21181         # do directio so as not to populate the page cache
21182         log "creating a 10 Mb file"
21183         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21184                 error "multiop failed while creating a file"
21185         log "starting reads"
21186         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21187         log "truncating the file"
21188         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21189                 error "multiop failed while truncating the file"
21190         log "killing dd"
21191         kill %+ || true # reads might have finished
21192         echo "wait until dd is finished"
21193         wait
21194         log "removing the temporary file"
21195         rm -rf $DIR/$tfile || error "tmp file removal failed"
21196 }
21197 run_test 218 "parallel read and truncate should not deadlock"
21198
21199 test_219() {
21200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21201
21202         # write one partial page
21203         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21204         # set no grant so vvp_io_commit_write will do sync write
21205         $LCTL set_param fail_loc=0x411
21206         # write a full page at the end of file
21207         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21208
21209         $LCTL set_param fail_loc=0
21210         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21211         $LCTL set_param fail_loc=0x411
21212         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21213
21214         # LU-4201
21215         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21216         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21217 }
21218 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21219
21220 test_220() { #LU-325
21221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21222         remote_ost_nodsh && skip "remote OST with nodsh"
21223         remote_mds_nodsh && skip "remote MDS with nodsh"
21224         remote_mgs_nodsh && skip "remote MGS with nodsh"
21225
21226         local OSTIDX=0
21227
21228         # create on MDT0000 so the last_id and next_id are correct
21229         mkdir_on_mdt0 $DIR/$tdir
21230         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21231         OST=${OST%_UUID}
21232
21233         # on the mdt's osc
21234         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21235         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21236                         osp.$mdtosc_proc1.prealloc_last_id)
21237         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21238                         osp.$mdtosc_proc1.prealloc_next_id)
21239
21240         $LFS df -i
21241
21242         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21243         #define OBD_FAIL_OST_ENOINO              0x229
21244         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21245         create_pool $FSNAME.$TESTNAME || return 1
21246         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21247
21248         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21249
21250         MDSOBJS=$((last_id - next_id))
21251         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21252
21253         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21254         echo "OST still has $count kbytes free"
21255
21256         echo "create $MDSOBJS files @next_id..."
21257         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21258
21259         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21260                         osp.$mdtosc_proc1.prealloc_last_id)
21261         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21262                         osp.$mdtosc_proc1.prealloc_next_id)
21263
21264         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21265         $LFS df -i
21266
21267         echo "cleanup..."
21268
21269         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21270         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21271
21272         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21273                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21274         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21275                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21276         echo "unlink $MDSOBJS files @$next_id..."
21277         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21278 }
21279 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21280
21281 test_221() {
21282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21283
21284         dd if=`which date` of=$MOUNT/date oflag=sync
21285         chmod +x $MOUNT/date
21286
21287         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21288         $LCTL set_param fail_loc=0x80001401
21289
21290         $MOUNT/date > /dev/null
21291         rm -f $MOUNT/date
21292 }
21293 run_test 221 "make sure fault and truncate race to not cause OOM"
21294
21295 test_222a () {
21296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21297
21298         rm -rf $DIR/$tdir
21299         test_mkdir $DIR/$tdir
21300         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21301         createmany -o $DIR/$tdir/$tfile 10
21302         cancel_lru_locks mdc
21303         cancel_lru_locks osc
21304         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21305         $LCTL set_param fail_loc=0x31a
21306         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21307         $LCTL set_param fail_loc=0
21308         rm -r $DIR/$tdir
21309 }
21310 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21311
21312 test_222b () {
21313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21314
21315         rm -rf $DIR/$tdir
21316         test_mkdir $DIR/$tdir
21317         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21318         createmany -o $DIR/$tdir/$tfile 10
21319         cancel_lru_locks mdc
21320         cancel_lru_locks osc
21321         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21322         $LCTL set_param fail_loc=0x31a
21323         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21324         $LCTL set_param fail_loc=0
21325 }
21326 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21327
21328 test_223 () {
21329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21330
21331         rm -rf $DIR/$tdir
21332         test_mkdir $DIR/$tdir
21333         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21334         createmany -o $DIR/$tdir/$tfile 10
21335         cancel_lru_locks mdc
21336         cancel_lru_locks osc
21337         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21338         $LCTL set_param fail_loc=0x31b
21339         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21340         $LCTL set_param fail_loc=0
21341         rm -r $DIR/$tdir
21342 }
21343 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21344
21345 test_224a() { # LU-1039, MRP-303
21346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21347         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21348         $LCTL set_param fail_loc=0x508
21349         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21350         $LCTL set_param fail_loc=0
21351         df $DIR
21352 }
21353 run_test 224a "Don't panic on bulk IO failure"
21354
21355 test_224bd_sub() { # LU-1039, MRP-303
21356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21357         local timeout=$1
21358
21359         shift
21360         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21361
21362         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21363
21364         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21365         cancel_lru_locks osc
21366         set_checksums 0
21367         stack_trap "set_checksums $ORIG_CSUM" EXIT
21368         local at_max_saved=0
21369
21370         # adaptive timeouts may prevent seeing the issue
21371         if at_is_enabled; then
21372                 at_max_saved=$(at_max_get mds)
21373                 at_max_set 0 mds client
21374                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21375         fi
21376
21377         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21378         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21379         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21380
21381         do_facet ost1 $LCTL set_param fail_loc=0
21382         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21383         df $DIR
21384 }
21385
21386 test_224b() {
21387         test_224bd_sub 3 error "dd failed"
21388 }
21389 run_test 224b "Don't panic on bulk IO failure"
21390
21391 test_224c() { # LU-6441
21392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21393         remote_mds_nodsh && skip "remote MDS with nodsh"
21394
21395         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21396         save_writethrough $p
21397         set_cache writethrough on
21398
21399         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21400         local at_max=$($LCTL get_param -n at_max)
21401         local timeout=$($LCTL get_param -n timeout)
21402         local test_at="at_max"
21403         local param_at="$FSNAME.sys.at_max"
21404         local test_timeout="timeout"
21405         local param_timeout="$FSNAME.sys.timeout"
21406
21407         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21408
21409         set_persistent_param_and_check client "$test_at" "$param_at" 0
21410         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21411
21412         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21413         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21414         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21415         stack_trap "rm -f $DIR/$tfile"
21416         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21417         sync
21418         do_facet ost1 "$LCTL set_param fail_loc=0"
21419
21420         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21421         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21422                 $timeout
21423
21424         $LCTL set_param -n $pages_per_rpc
21425         restore_lustre_params < $p
21426         rm -f $p
21427 }
21428 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21429
21430 test_224d() { # LU-11169
21431         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21432 }
21433 run_test 224d "Don't corrupt data on bulk IO timeout"
21434
21435 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21436 test_225a () {
21437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21438         if [ -z ${MDSSURVEY} ]; then
21439                 skip_env "mds-survey not found"
21440         fi
21441         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21442                 skip "Need MDS version at least 2.2.51"
21443
21444         local mds=$(facet_host $SINGLEMDS)
21445         local target=$(do_nodes $mds 'lctl dl' |
21446                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21447
21448         local cmd1="file_count=1000 thrhi=4"
21449         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21450         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21451         local cmd="$cmd1 $cmd2 $cmd3"
21452
21453         rm -f ${TMP}/mds_survey*
21454         echo + $cmd
21455         eval $cmd || error "mds-survey with zero-stripe failed"
21456         cat ${TMP}/mds_survey*
21457         rm -f ${TMP}/mds_survey*
21458 }
21459 run_test 225a "Metadata survey sanity with zero-stripe"
21460
21461 test_225b () {
21462         if [ -z ${MDSSURVEY} ]; then
21463                 skip_env "mds-survey not found"
21464         fi
21465         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21466                 skip "Need MDS version at least 2.2.51"
21467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21468         remote_mds_nodsh && skip "remote MDS with nodsh"
21469         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21470                 skip_env "Need to mount OST to test"
21471         fi
21472
21473         local mds=$(facet_host $SINGLEMDS)
21474         local target=$(do_nodes $mds 'lctl dl' |
21475                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21476
21477         local cmd1="file_count=1000 thrhi=4"
21478         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21479         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21480         local cmd="$cmd1 $cmd2 $cmd3"
21481
21482         rm -f ${TMP}/mds_survey*
21483         echo + $cmd
21484         eval $cmd || error "mds-survey with stripe_count failed"
21485         cat ${TMP}/mds_survey*
21486         rm -f ${TMP}/mds_survey*
21487 }
21488 run_test 225b "Metadata survey sanity with stripe_count = 1"
21489
21490 mcreate_path2fid () {
21491         local mode=$1
21492         local major=$2
21493         local minor=$3
21494         local name=$4
21495         local desc=$5
21496         local path=$DIR/$tdir/$name
21497         local fid
21498         local rc
21499         local fid_path
21500
21501         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21502                 error "cannot create $desc"
21503
21504         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21505         rc=$?
21506         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21507
21508         fid_path=$($LFS fid2path $MOUNT $fid)
21509         rc=$?
21510         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21511
21512         [ "$path" == "$fid_path" ] ||
21513                 error "fid2path returned $fid_path, expected $path"
21514
21515         echo "pass with $path and $fid"
21516 }
21517
21518 test_226a () {
21519         rm -rf $DIR/$tdir
21520         mkdir -p $DIR/$tdir
21521
21522         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21523         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21524         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21525         mcreate_path2fid 0040666 0 0 dir "directory"
21526         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21527         mcreate_path2fid 0100666 0 0 file "regular file"
21528         mcreate_path2fid 0120666 0 0 link "symbolic link"
21529         mcreate_path2fid 0140666 0 0 sock "socket"
21530 }
21531 run_test 226a "call path2fid and fid2path on files of all type"
21532
21533 test_226b () {
21534         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21535
21536         local MDTIDX=1
21537
21538         rm -rf $DIR/$tdir
21539         mkdir -p $DIR/$tdir
21540         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21541                 error "create remote directory failed"
21542         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21543         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21544                                 "character special file (null)"
21545         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21546                                 "character special file (no device)"
21547         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21548         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21549                                 "block special file (loop)"
21550         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21551         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21552         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21553 }
21554 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21555
21556 test_226c () {
21557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21558         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21559                 skip "Need MDS version at least 2.13.55"
21560
21561         local submnt=/mnt/submnt
21562         local srcfile=/etc/passwd
21563         local dstfile=$submnt/passwd
21564         local path
21565         local fid
21566
21567         rm -rf $DIR/$tdir
21568         rm -rf $submnt
21569         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21570                 error "create remote directory failed"
21571         mkdir -p $submnt || error "create $submnt failed"
21572         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21573                 error "mount $submnt failed"
21574         stack_trap "umount $submnt" EXIT
21575
21576         cp $srcfile $dstfile
21577         fid=$($LFS path2fid $dstfile)
21578         path=$($LFS fid2path $submnt "$fid")
21579         [ "$path" = "$dstfile" ] ||
21580                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21581 }
21582 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21583
21584 test_226d () {
21585         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21586                 skip "Need client at least version 2.15.57"
21587
21588         # Define First test dataset
21589         local testdirs_01=$DIR/$tdir
21590         local testdata_01=$testdirs_01/${tdir}_01
21591         local testresult_01=${tdir}_01
21592         # Define Second test dataset
21593         local testdirs_02=$DIR/$tdir/$tdir
21594         local testdata_02=$testdirs_02/${tdir}_02
21595         local testresult_02=${tdir}_02
21596         # Define third test dataset (top level)
21597         local testdata_03=$DIR/${tdir}_03
21598         local testresult_03=${tdir}_03
21599
21600         # Create first test dataset
21601         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21602         touch $testdata_01 || error "cannot create file $testdata_01"
21603
21604         # Create second test dataset
21605         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21606         touch $testdata_02 || error "cannot create file $testdata_02"
21607
21608         # Create third test dataset
21609         touch $testdata_03 || error "cannot create file $testdata_03"
21610
21611         local fid01=$($LFS getstripe -F "$testdata_01") ||
21612                 error "getstripe failed on $testdata_01"
21613         local fid02=$($LFS getstripe -F "$testdata_02") ||
21614                 error "getstripe failed on $testdata_01"
21615         local fid03=$($LFS getstripe -F "$testdata_03") ||
21616                 error "getstripe failed on $testdata_03"
21617
21618         # Verify only -n option
21619         local out1=$($LFS fid2path -n $DIR $fid01) ||
21620                 error "fid2path failed on $fid01"
21621         local out2=$($LFS fid2path -n $DIR $fid02) ||
21622                 error "fid2path failed on $fid02"
21623         local out3=$($LFS fid2path -n $DIR $fid03) ||
21624                 error "fid2path failed on $fid03"
21625
21626         [[ "$out1" == "$testresult_01" ]] ||
21627                 error "fid2path failed: Expected $testresult_01 got $out1"
21628         [[ "$out2" == "$testresult_02" ]] ||
21629                 error "fid2path failed: Expected $testresult_02 got $out2"
21630         [[ "$out3" == "$testresult_03" ]] ||
21631                 error "fid2path failed: Expected $testresult_03 got $out3"
21632
21633         # Verify with option -fn together
21634         out1=$($LFS fid2path -fn $DIR $fid01) ||
21635                 error "fid2path -fn failed on $fid01"
21636         out2=$($LFS fid2path -fn $DIR $fid02) ||
21637                 error "fid2path -fn failed on $fid02"
21638         out3=$($LFS fid2path -fn $DIR $fid03) ||
21639                 error "fid2path -fn failed on $fid03"
21640
21641         local tmpout=$(echo $out1 | cut -d" " -f2)
21642         [[ "$tmpout" == "$testresult_01" ]] ||
21643                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21644
21645         tmpout=$(echo $out2 | cut -d" " -f2)
21646         [[ "$tmpout" == "$testresult_02" ]] ||
21647                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21648
21649         tmpout=$(echo $out3 | cut -d" " -f2)
21650         [[ "$tmpout" == "$testresult_03" ]] ||
21651                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21652 }
21653 run_test 226d "verify fid2path with -n and -fn option"
21654
21655 test_226e () {
21656         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21657                 skip "Need client at least version 2.15.56"
21658
21659         # Define filename with 'newline' and a space
21660         local testfile="Test"$'\n'"file 01"
21661         # Define link name with multiple 'newline' and a space
21662         local linkfile="Link"$'\n'"file "$'\n'"01"
21663         # Remove prior hard link
21664         rm -f $DIR/"$linkfile"
21665
21666         # Create file
21667         touch $DIR/"$testfile"
21668         # Create link
21669         ln $DIR/"$testfile" $DIR/"$linkfile"
21670
21671         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21672                 error "getstripe failed on $DIR/$testfile"
21673
21674         # Call with -0 option
21675         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21676                 echo "FILE:" | grep -c "FILE:")
21677
21678         # With -0 option the output should be exactly 2 lines.
21679         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21680 }
21681 run_test 226e "Verify path2fid -0 option with newline and space"
21682
21683 # LU-1299 Executing or running ldd on a truncated executable does not
21684 # cause an out-of-memory condition.
21685 test_227() {
21686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21687         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21688
21689         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21690         chmod +x $MOUNT/date
21691
21692         $MOUNT/date > /dev/null
21693         ldd $MOUNT/date > /dev/null
21694         rm -f $MOUNT/date
21695 }
21696 run_test 227 "running truncated executable does not cause OOM"
21697
21698 # LU-1512 try to reuse idle OI blocks
21699 test_228a() {
21700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21701         remote_mds_nodsh && skip "remote MDS with nodsh"
21702         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21703
21704         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21705         local myDIR=$DIR/$tdir
21706
21707         mkdir -p $myDIR
21708         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21709         $LCTL set_param fail_loc=0x80001002
21710         createmany -o $myDIR/t- 10000
21711         $LCTL set_param fail_loc=0
21712         # The guard is current the largest FID holder
21713         touch $myDIR/guard
21714         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21715                     tr -d '[')
21716         local IDX=$(($SEQ % 64))
21717
21718         do_facet $SINGLEMDS sync
21719         # Make sure journal flushed.
21720         sleep 6
21721         local blk1=$(do_facet $SINGLEMDS \
21722                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21723                      grep Blockcount | awk '{print $4}')
21724
21725         # Remove old files, some OI blocks will become idle.
21726         unlinkmany $myDIR/t- 10000
21727         # Create new files, idle OI blocks should be reused.
21728         createmany -o $myDIR/t- 2000
21729         do_facet $SINGLEMDS sync
21730         # Make sure journal flushed.
21731         sleep 6
21732         local blk2=$(do_facet $SINGLEMDS \
21733                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21734                      grep Blockcount | awk '{print $4}')
21735
21736         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21737 }
21738 run_test 228a "try to reuse idle OI blocks"
21739
21740 test_228b() {
21741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21742         remote_mds_nodsh && skip "remote MDS with nodsh"
21743         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21744
21745         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21746         local myDIR=$DIR/$tdir
21747
21748         mkdir -p $myDIR
21749         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21750         $LCTL set_param fail_loc=0x80001002
21751         createmany -o $myDIR/t- 10000
21752         $LCTL set_param fail_loc=0
21753         # The guard is current the largest FID holder
21754         touch $myDIR/guard
21755         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21756                     tr -d '[')
21757         local IDX=$(($SEQ % 64))
21758
21759         do_facet $SINGLEMDS sync
21760         # Make sure journal flushed.
21761         sleep 6
21762         local blk1=$(do_facet $SINGLEMDS \
21763                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21764                      grep Blockcount | awk '{print $4}')
21765
21766         # Remove old files, some OI blocks will become idle.
21767         unlinkmany $myDIR/t- 10000
21768
21769         # stop the MDT
21770         stop $SINGLEMDS || error "Fail to stop MDT."
21771         # remount the MDT
21772         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21773                 error "Fail to start MDT."
21774
21775         client_up || error "Fail to df."
21776         # Create new files, idle OI blocks should be reused.
21777         createmany -o $myDIR/t- 2000
21778         do_facet $SINGLEMDS sync
21779         # Make sure journal flushed.
21780         sleep 6
21781         local blk2=$(do_facet $SINGLEMDS \
21782                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21783                      grep Blockcount | awk '{print $4}')
21784
21785         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21786 }
21787 run_test 228b "idle OI blocks can be reused after MDT restart"
21788
21789 #LU-1881
21790 test_228c() {
21791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21792         remote_mds_nodsh && skip "remote MDS with nodsh"
21793         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21794
21795         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21796         local myDIR=$DIR/$tdir
21797
21798         mkdir -p $myDIR
21799         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21800         $LCTL set_param fail_loc=0x80001002
21801         # 20000 files can guarantee there are index nodes in the OI file
21802         createmany -o $myDIR/t- 20000
21803         $LCTL set_param fail_loc=0
21804         # The guard is current the largest FID holder
21805         touch $myDIR/guard
21806         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21807                     tr -d '[')
21808         local IDX=$(($SEQ % 64))
21809
21810         do_facet $SINGLEMDS sync
21811         # Make sure journal flushed.
21812         sleep 6
21813         local blk1=$(do_facet $SINGLEMDS \
21814                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21815                      grep Blockcount | awk '{print $4}')
21816
21817         # Remove old files, some OI blocks will become idle.
21818         unlinkmany $myDIR/t- 20000
21819         rm -f $myDIR/guard
21820         # The OI file should become empty now
21821
21822         # Create new files, idle OI blocks should be reused.
21823         createmany -o $myDIR/t- 2000
21824         do_facet $SINGLEMDS sync
21825         # Make sure journal flushed.
21826         sleep 6
21827         local blk2=$(do_facet $SINGLEMDS \
21828                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21829                      grep Blockcount | awk '{print $4}')
21830
21831         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21832 }
21833 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21834
21835 test_229() { # LU-2482, LU-3448
21836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21837         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21838         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21839                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21840
21841         rm -f $DIR/$tfile
21842
21843         # Create a file with a released layout and stripe count 2.
21844         $MULTIOP $DIR/$tfile H2c ||
21845                 error "failed to create file with released layout"
21846
21847         $LFS getstripe -v $DIR/$tfile
21848
21849         local pattern=$($LFS getstripe -L $DIR/$tfile)
21850         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21851
21852         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21853                 error "getstripe"
21854         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21855         stat $DIR/$tfile || error "failed to stat released file"
21856
21857         chown $RUNAS_ID $DIR/$tfile ||
21858                 error "chown $RUNAS_ID $DIR/$tfile failed"
21859
21860         chgrp $RUNAS_ID $DIR/$tfile ||
21861                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21862
21863         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21864         rm $DIR/$tfile || error "failed to remove released file"
21865 }
21866 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21867
21868 test_230a() {
21869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21871         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21872                 skip "Need MDS version at least 2.11.52"
21873
21874         local MDTIDX=1
21875
21876         test_mkdir $DIR/$tdir
21877         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21878         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21879         [ $mdt_idx -ne 0 ] &&
21880                 error "create local directory on wrong MDT $mdt_idx"
21881
21882         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21883                         error "create remote directory failed"
21884         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21885         [ $mdt_idx -ne $MDTIDX ] &&
21886                 error "create remote directory on wrong MDT $mdt_idx"
21887
21888         createmany -o $DIR/$tdir/test_230/t- 10 ||
21889                 error "create files on remote directory failed"
21890         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21891         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21892         rm -r $DIR/$tdir || error "unlink remote directory failed"
21893 }
21894 run_test 230a "Create remote directory and files under the remote directory"
21895
21896 test_230b() {
21897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21899         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21900                 skip "Need MDS version at least 2.11.52"
21901
21902         local MDTIDX=1
21903         local mdt_index
21904         local i
21905         local file
21906         local pid
21907         local stripe_count
21908         local migrate_dir=$DIR/$tdir/migrate_dir
21909         local other_dir=$DIR/$tdir/other_dir
21910
21911         test_mkdir $DIR/$tdir
21912         test_mkdir -i0 -c1 $migrate_dir
21913         test_mkdir -i0 -c1 $other_dir
21914         for ((i=0; i<10; i++)); do
21915                 mkdir -p $migrate_dir/dir_${i}
21916                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21917                         error "create files under remote dir failed $i"
21918         done
21919
21920         cp /etc/passwd $migrate_dir/$tfile
21921         cp /etc/passwd $other_dir/$tfile
21922         chattr +SAD $migrate_dir
21923         chattr +SAD $migrate_dir/$tfile
21924
21925         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21926         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21927         local old_dir_mode=$(stat -c%f $migrate_dir)
21928         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21929
21930         mkdir -p $migrate_dir/dir_default_stripe2
21931         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21932         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21933
21934         mkdir -p $other_dir
21935         ln $migrate_dir/$tfile $other_dir/luna
21936         ln $migrate_dir/$tfile $migrate_dir/sofia
21937         ln $other_dir/$tfile $migrate_dir/david
21938         ln -s $migrate_dir/$tfile $other_dir/zachary
21939         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21940         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21941
21942         local len
21943         local lnktgt
21944
21945         # inline symlink
21946         for len in 58 59 60; do
21947                 lnktgt=$(str_repeat 'l' $len)
21948                 touch $migrate_dir/$lnktgt
21949                 ln -s $lnktgt $migrate_dir/${len}char_ln
21950         done
21951
21952         # PATH_MAX
21953         for len in 4094 4095; do
21954                 lnktgt=$(str_repeat 'l' $len)
21955                 ln -s $lnktgt $migrate_dir/${len}char_ln
21956         done
21957
21958         # NAME_MAX
21959         for len in 254 255; do
21960                 touch $migrate_dir/$(str_repeat 'l' $len)
21961         done
21962
21963         $LFS migrate -m $MDTIDX $migrate_dir ||
21964                 error "fails on migrating remote dir to MDT1"
21965
21966         echo "migratate to MDT1, then checking.."
21967         for ((i = 0; i < 10; i++)); do
21968                 for file in $(find $migrate_dir/dir_${i}); do
21969                         mdt_index=$($LFS getstripe -m $file)
21970                         # broken symlink getstripe will fail
21971                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21972                                 error "$file is not on MDT${MDTIDX}"
21973                 done
21974         done
21975
21976         # the multiple link file should still in MDT0
21977         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21978         [ $mdt_index == 0 ] ||
21979                 error "$file is not on MDT${MDTIDX}"
21980
21981         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21982         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21983                 error " expect $old_dir_flag get $new_dir_flag"
21984
21985         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21986         [ "$old_file_flag" = "$new_file_flag" ] ||
21987                 error " expect $old_file_flag get $new_file_flag"
21988
21989         local new_dir_mode=$(stat -c%f $migrate_dir)
21990         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21991                 error "expect mode $old_dir_mode get $new_dir_mode"
21992
21993         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21994         [ "$old_file_mode" = "$new_file_mode" ] ||
21995                 error "expect mode $old_file_mode get $new_file_mode"
21996
21997         diff /etc/passwd $migrate_dir/$tfile ||
21998                 error "$tfile different after migration"
21999
22000         diff /etc/passwd $other_dir/luna ||
22001                 error "luna different after migration"
22002
22003         diff /etc/passwd $migrate_dir/sofia ||
22004                 error "sofia different after migration"
22005
22006         diff /etc/passwd $migrate_dir/david ||
22007                 error "david different after migration"
22008
22009         diff /etc/passwd $other_dir/zachary ||
22010                 error "zachary different after migration"
22011
22012         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22013                 error "${tfile}_ln different after migration"
22014
22015         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22016                 error "${tfile}_ln_other different after migration"
22017
22018         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22019         [ $stripe_count = 2 ] ||
22020                 error "dir strpe_count $d != 2 after migration."
22021
22022         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22023         [ $stripe_count = 2 ] ||
22024                 error "file strpe_count $d != 2 after migration."
22025
22026         #migrate back to MDT0
22027         MDTIDX=0
22028
22029         $LFS migrate -m $MDTIDX $migrate_dir ||
22030                 error "fails on migrating remote dir to MDT0"
22031
22032         echo "migrate back to MDT0, checking.."
22033         for file in $(find $migrate_dir); do
22034                 mdt_index=$($LFS getstripe -m $file)
22035                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22036                         error "$file is not on MDT${MDTIDX}"
22037         done
22038
22039         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22040         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22041                 error " expect $old_dir_flag get $new_dir_flag"
22042
22043         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22044         [ "$old_file_flag" = "$new_file_flag" ] ||
22045                 error " expect $old_file_flag get $new_file_flag"
22046
22047         local new_dir_mode=$(stat -c%f $migrate_dir)
22048         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22049                 error "expect mode $old_dir_mode get $new_dir_mode"
22050
22051         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22052         [ "$old_file_mode" = "$new_file_mode" ] ||
22053                 error "expect mode $old_file_mode get $new_file_mode"
22054
22055         diff /etc/passwd ${migrate_dir}/$tfile ||
22056                 error "$tfile different after migration"
22057
22058         diff /etc/passwd ${other_dir}/luna ||
22059                 error "luna different after migration"
22060
22061         diff /etc/passwd ${migrate_dir}/sofia ||
22062                 error "sofia different after migration"
22063
22064         diff /etc/passwd ${other_dir}/zachary ||
22065                 error "zachary different after migration"
22066
22067         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22068                 error "${tfile}_ln different after migration"
22069
22070         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22071                 error "${tfile}_ln_other different after migration"
22072
22073         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22074         [ $stripe_count = 2 ] ||
22075                 error "dir strpe_count $d != 2 after migration."
22076
22077         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22078         [ $stripe_count = 2 ] ||
22079                 error "file strpe_count $d != 2 after migration."
22080
22081         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22082 }
22083 run_test 230b "migrate directory"
22084
22085 test_230c() {
22086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22088         remote_mds_nodsh && skip "remote MDS with nodsh"
22089         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22090                 skip "Need MDS version at least 2.11.52"
22091
22092         local MDTIDX=1
22093         local total=3
22094         local mdt_index
22095         local file
22096         local migrate_dir=$DIR/$tdir/migrate_dir
22097
22098         #If migrating directory fails in the middle, all entries of
22099         #the directory is still accessiable.
22100         test_mkdir $DIR/$tdir
22101         test_mkdir -i0 -c1 $migrate_dir
22102         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22103         stat $migrate_dir
22104         createmany -o $migrate_dir/f $total ||
22105                 error "create files under ${migrate_dir} failed"
22106
22107         # fail after migrating top dir, and this will fail only once, so the
22108         # first sub file migration will fail (currently f3), others succeed.
22109         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22110         do_facet mds1 lctl set_param fail_loc=0x1801
22111         local t=$(ls $migrate_dir | wc -l)
22112         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22113                 error "migrate should fail"
22114         local u=$(ls $migrate_dir | wc -l)
22115         [ "$u" == "$t" ] || error "$u != $t during migration"
22116
22117         # add new dir/file should succeed
22118         mkdir $migrate_dir/dir ||
22119                 error "mkdir failed under migrating directory"
22120         touch $migrate_dir/file ||
22121                 error "create file failed under migrating directory"
22122
22123         # add file with existing name should fail
22124         for file in $migrate_dir/f*; do
22125                 stat $file > /dev/null || error "stat $file failed"
22126                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22127                         error "open(O_CREAT|O_EXCL) $file should fail"
22128                 $MULTIOP $file m && error "create $file should fail"
22129                 touch $DIR/$tdir/remote_dir/$tfile ||
22130                         error "touch $tfile failed"
22131                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22132                         error "link $file should fail"
22133                 mdt_index=$($LFS getstripe -m $file)
22134                 if [ $mdt_index == 0 ]; then
22135                         # file failed to migrate is not allowed to rename to
22136                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22137                                 error "rename to $file should fail"
22138                 else
22139                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22140                                 error "rename to $file failed"
22141                 fi
22142                 echo hello >> $file || error "write $file failed"
22143         done
22144
22145         # resume migration with different options should fail
22146         $LFS migrate -m 0 $migrate_dir &&
22147                 error "migrate -m 0 $migrate_dir should fail"
22148
22149         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22150                 error "migrate -c 2 $migrate_dir should fail"
22151
22152         # resume migration should succeed
22153         $LFS migrate -m $MDTIDX $migrate_dir ||
22154                 error "migrate $migrate_dir failed"
22155
22156         echo "Finish migration, then checking.."
22157         for file in $(find $migrate_dir); do
22158                 mdt_index=$($LFS getstripe -m $file)
22159                 [ $mdt_index == $MDTIDX ] ||
22160                         error "$file is not on MDT${MDTIDX}"
22161         done
22162
22163         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22164 }
22165 run_test 230c "check directory accessiblity if migration failed"
22166
22167 test_230d() {
22168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22169         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22170         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22171                 skip "Need MDS version at least 2.11.52"
22172         # LU-11235
22173         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22174
22175         local migrate_dir=$DIR/$tdir/migrate_dir
22176         local old_index
22177         local new_index
22178         local old_count
22179         local new_count
22180         local new_hash
22181         local mdt_index
22182         local i
22183         local j
22184
22185         old_index=$((RANDOM % MDSCOUNT))
22186         old_count=$((MDSCOUNT - old_index))
22187         new_index=$((RANDOM % MDSCOUNT))
22188         new_count=$((MDSCOUNT - new_index))
22189         new_hash=1 # for all_char
22190
22191         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22192         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22193
22194         test_mkdir $DIR/$tdir
22195         test_mkdir -i $old_index -c $old_count $migrate_dir
22196
22197         for ((i=0; i<100; i++)); do
22198                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22199                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22200                         error "create files under remote dir failed $i"
22201         done
22202
22203         echo -n "Migrate from MDT$old_index "
22204         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22205         echo -n "to MDT$new_index"
22206         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22207         echo
22208
22209         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22210         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22211                 error "migrate remote dir error"
22212
22213         echo "Finish migration, then checking.."
22214         for file in $(find $migrate_dir -maxdepth 1); do
22215                 mdt_index=$($LFS getstripe -m $file)
22216                 if [ $mdt_index -lt $new_index ] ||
22217                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22218                         error "$file is on MDT$mdt_index"
22219                 fi
22220         done
22221
22222         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22223 }
22224 run_test 230d "check migrate big directory"
22225
22226 test_230e() {
22227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22228         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22229         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22230                 skip "Need MDS version at least 2.11.52"
22231
22232         local i
22233         local j
22234         local a_fid
22235         local b_fid
22236
22237         mkdir_on_mdt0 $DIR/$tdir
22238         mkdir $DIR/$tdir/migrate_dir
22239         mkdir $DIR/$tdir/other_dir
22240         touch $DIR/$tdir/migrate_dir/a
22241         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22242         ls $DIR/$tdir/other_dir
22243
22244         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22245                 error "migrate dir fails"
22246
22247         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22248         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22249
22250         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22251         [ $mdt_index == 0 ] || error "a is not on MDT0"
22252
22253         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22254                 error "migrate dir fails"
22255
22256         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22257         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22258
22259         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22260         [ $mdt_index == 1 ] || error "a is not on MDT1"
22261
22262         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22263         [ $mdt_index == 1 ] || error "b is not on MDT1"
22264
22265         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22266         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22267
22268         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22269
22270         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22271 }
22272 run_test 230e "migrate mulitple local link files"
22273
22274 test_230f() {
22275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22276         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22277         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22278                 skip "Need MDS version at least 2.11.52"
22279
22280         local a_fid
22281         local ln_fid
22282
22283         mkdir -p $DIR/$tdir
22284         mkdir $DIR/$tdir/migrate_dir
22285         $LFS mkdir -i1 $DIR/$tdir/other_dir
22286         touch $DIR/$tdir/migrate_dir/a
22287         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22288         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22289         ls $DIR/$tdir/other_dir
22290
22291         # a should be migrated to MDT1, since no other links on MDT0
22292         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22293                 error "#1 migrate dir fails"
22294         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22295         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22296         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22297         [ $mdt_index == 1 ] || error "a is not on MDT1"
22298
22299         # a should stay on MDT1, because it is a mulitple link file
22300         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22301                 error "#2 migrate dir fails"
22302         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22303         [ $mdt_index == 1 ] || error "a is not on MDT1"
22304
22305         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22306                 error "#3 migrate dir fails"
22307
22308         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22309         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22310         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22311
22312         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22313         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22314
22315         # a should be migrated to MDT0, since no other links on MDT1
22316         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22317                 error "#4 migrate dir fails"
22318         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22319         [ $mdt_index == 0 ] || error "a is not on MDT0"
22320
22321         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22322 }
22323 run_test 230f "migrate mulitple remote link files"
22324
22325 test_230g() {
22326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22327         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22328         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22329                 skip "Need MDS version at least 2.11.52"
22330
22331         mkdir -p $DIR/$tdir/migrate_dir
22332
22333         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22334                 error "migrating dir to non-exist MDT succeeds"
22335         true
22336 }
22337 run_test 230g "migrate dir to non-exist MDT"
22338
22339 test_230h() {
22340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22341         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22342         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22343                 skip "Need MDS version at least 2.11.52"
22344
22345         local mdt_index
22346
22347         mkdir -p $DIR/$tdir/migrate_dir
22348
22349         $LFS migrate -m1 $DIR &&
22350                 error "migrating mountpoint1 should fail"
22351
22352         $LFS migrate -m1 $DIR/$tdir/.. &&
22353                 error "migrating mountpoint2 should fail"
22354
22355         # same as mv
22356         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22357                 error "migrating $tdir/migrate_dir/.. should fail"
22358
22359         true
22360 }
22361 run_test 230h "migrate .. and root"
22362
22363 test_230i() {
22364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22366         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22367                 skip "Need MDS version at least 2.11.52"
22368
22369         mkdir -p $DIR/$tdir/migrate_dir
22370
22371         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22372                 error "migration fails with a tailing slash"
22373
22374         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22375                 error "migration fails with two tailing slashes"
22376 }
22377 run_test 230i "lfs migrate -m tolerates trailing slashes"
22378
22379 test_230j() {
22380         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22381         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22382                 skip "Need MDS version at least 2.11.52"
22383
22384         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22385         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22386                 error "create $tfile failed"
22387         cat /etc/passwd > $DIR/$tdir/$tfile
22388
22389         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22390
22391         cmp /etc/passwd $DIR/$tdir/$tfile ||
22392                 error "DoM file mismatch after migration"
22393 }
22394 run_test 230j "DoM file data not changed after dir migration"
22395
22396 test_230k() {
22397         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22398         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22399                 skip "Need MDS version at least 2.11.56"
22400
22401         local total=20
22402         local files_on_starting_mdt=0
22403
22404         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22405         $LFS getdirstripe $DIR/$tdir
22406         for i in $(seq $total); do
22407                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22408                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22409                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22410         done
22411
22412         echo "$files_on_starting_mdt files on MDT0"
22413
22414         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22415         $LFS getdirstripe $DIR/$tdir
22416
22417         files_on_starting_mdt=0
22418         for i in $(seq $total); do
22419                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22420                         error "file $tfile.$i mismatch after migration"
22421                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22422                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22423         done
22424
22425         echo "$files_on_starting_mdt files on MDT1 after migration"
22426         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22427
22428         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22429         $LFS getdirstripe $DIR/$tdir
22430
22431         files_on_starting_mdt=0
22432         for i in $(seq $total); do
22433                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22434                         error "file $tfile.$i mismatch after 2nd migration"
22435                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22436                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22437         done
22438
22439         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22440         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22441
22442         true
22443 }
22444 run_test 230k "file data not changed after dir migration"
22445
22446 test_230l() {
22447         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22448         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22449                 skip "Need MDS version at least 2.11.56"
22450
22451         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22452         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22453                 error "create files under remote dir failed $i"
22454         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22455 }
22456 run_test 230l "readdir between MDTs won't crash"
22457
22458 test_230m() {
22459         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22460         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22461                 skip "Need MDS version at least 2.11.56"
22462
22463         local MDTIDX=1
22464         local mig_dir=$DIR/$tdir/migrate_dir
22465         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22466         local shortstr="b"
22467         local val
22468
22469         echo "Creating files and dirs with xattrs"
22470         test_mkdir $DIR/$tdir
22471         test_mkdir -i0 -c1 $mig_dir
22472         mkdir $mig_dir/dir
22473         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22474                 error "cannot set xattr attr1 on dir"
22475         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22476                 error "cannot set xattr attr2 on dir"
22477         touch $mig_dir/dir/f0
22478         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22479                 error "cannot set xattr attr1 on file"
22480         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22481                 error "cannot set xattr attr2 on file"
22482         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22483         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22484         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22485         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22486         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22487         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22488         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22489         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22490         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22491
22492         echo "Migrating to MDT1"
22493         $LFS migrate -m $MDTIDX $mig_dir ||
22494                 error "fails on migrating dir to MDT1"
22495
22496         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22497         echo "Checking xattrs"
22498         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22499         [ "$val" = $longstr ] ||
22500                 error "expecting xattr1 $longstr on dir, found $val"
22501         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22502         [ "$val" = $shortstr ] ||
22503                 error "expecting xattr2 $shortstr on dir, found $val"
22504         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22505         [ "$val" = $longstr ] ||
22506                 error "expecting xattr1 $longstr on file, found $val"
22507         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22508         [ "$val" = $shortstr ] ||
22509                 error "expecting xattr2 $shortstr on file, found $val"
22510 }
22511 run_test 230m "xattrs not changed after dir migration"
22512
22513 test_230n() {
22514         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22515         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22516                 skip "Need MDS version at least 2.13.53"
22517
22518         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22519         cat /etc/hosts > $DIR/$tdir/$tfile
22520         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22521         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22522
22523         cmp /etc/hosts $DIR/$tdir/$tfile ||
22524                 error "File data mismatch after migration"
22525 }
22526 run_test 230n "Dir migration with mirrored file"
22527
22528 test_230o() {
22529         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22530         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22531                 skip "Need MDS version at least 2.13.52"
22532
22533         local mdts=$(comma_list $(mdts_nodes))
22534         local timeout=100
22535         local restripe_status
22536         local delta
22537         local i
22538
22539         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22540
22541         # in case "crush" hash type is not set
22542         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22543
22544         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22545                            mdt.*MDT0000.enable_dir_restripe)
22546         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22547         stack_trap "do_nodes $mdts $LCTL set_param \
22548                     mdt.*.enable_dir_restripe=$restripe_status"
22549
22550         mkdir $DIR/$tdir
22551         createmany -m $DIR/$tdir/f 100 ||
22552                 error "create files under remote dir failed $i"
22553         createmany -d $DIR/$tdir/d 100 ||
22554                 error "create dirs under remote dir failed $i"
22555
22556         for i in $(seq 2 $MDSCOUNT); do
22557                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22558                 $LFS setdirstripe -c $i $DIR/$tdir ||
22559                         error "split -c $i $tdir failed"
22560                 wait_update $HOSTNAME \
22561                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22562                         error "dir split not finished"
22563                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22564                         awk '/migrate/ {sum += $2} END { print sum }')
22565                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22566                 # delta is around total_files/stripe_count
22567                 (( $delta < 200 / (i - 1) + 4 )) ||
22568                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22569         done
22570 }
22571 run_test 230o "dir split"
22572
22573 test_230p() {
22574         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22575         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22576                 skip "Need MDS version at least 2.13.52"
22577
22578         local mdts=$(comma_list $(mdts_nodes))
22579         local timeout=100
22580         local restripe_status
22581         local delta
22582         local c
22583
22584         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22585
22586         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22587
22588         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22589                            mdt.*MDT0000.enable_dir_restripe)
22590         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22591         stack_trap "do_nodes $mdts $LCTL set_param \
22592                     mdt.*.enable_dir_restripe=$restripe_status"
22593
22594         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22595         createmany -m $DIR/$tdir/f 100 ||
22596                 error "create files under remote dir failed"
22597         createmany -d $DIR/$tdir/d 100 ||
22598                 error "create dirs under remote dir failed"
22599
22600         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22601                 local mdt_hash="crush"
22602
22603                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22604                 $LFS setdirstripe -c $c $DIR/$tdir ||
22605                         error "split -c $c $tdir failed"
22606                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22607                         mdt_hash="$mdt_hash,fixed"
22608                 elif [ $c -eq 1 ]; then
22609                         mdt_hash="none"
22610                 fi
22611                 wait_update $HOSTNAME \
22612                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22613                         error "dir merge not finished"
22614                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22615                         awk '/migrate/ {sum += $2} END { print sum }')
22616                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22617                 # delta is around total_files/stripe_count
22618                 (( delta < 200 / c + 4 )) ||
22619                         error "$delta files migrated >= $((200 / c + 4))"
22620         done
22621 }
22622 run_test 230p "dir merge"
22623
22624 test_230q() {
22625         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22626         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22627                 skip "Need MDS version at least 2.13.52"
22628
22629         local mdts=$(comma_list $(mdts_nodes))
22630         local saved_threshold=$(do_facet mds1 \
22631                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22632         local saved_delta=$(do_facet mds1 \
22633                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22634         local threshold=100
22635         local delta=2
22636         local total=0
22637         local stripe_count=0
22638         local stripe_index
22639         local nr_files
22640         local create
22641
22642         # test with fewer files on ZFS
22643         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22644
22645         stack_trap "do_nodes $mdts $LCTL set_param \
22646                     mdt.*.dir_split_count=$saved_threshold"
22647         stack_trap "do_nodes $mdts $LCTL set_param \
22648                     mdt.*.dir_split_delta=$saved_delta"
22649         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22650         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22651         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22652         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22653         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22654         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22655
22656         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22657         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22658
22659         create=$((threshold * 3 / 2))
22660         while [ $stripe_count -lt $MDSCOUNT ]; do
22661                 createmany -m $DIR/$tdir/f $total $create ||
22662                         error "create sub files failed"
22663                 stat $DIR/$tdir > /dev/null
22664                 total=$((total + create))
22665                 stripe_count=$((stripe_count + delta))
22666                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22667
22668                 wait_update $HOSTNAME \
22669                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22670                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22671
22672                 wait_update $HOSTNAME \
22673                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22674                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22675
22676                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22677                 echo "$nr_files/$total files on MDT$stripe_index after split"
22678                 # allow 10% margin of imbalance with crush hash
22679                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22680                         error "$nr_files files on MDT$stripe_index after split"
22681
22682                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22683                 [ $nr_files -eq $total ] ||
22684                         error "total sub files $nr_files != $total"
22685         done
22686
22687         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22688
22689         echo "fixed layout directory won't auto split"
22690         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22691         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22692                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22693         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22694                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22695 }
22696 run_test 230q "dir auto split"
22697
22698 test_230r() {
22699         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22700         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22701         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22702                 skip "Need MDS version at least 2.13.54"
22703
22704         # maximum amount of local locks:
22705         # parent striped dir - 2 locks
22706         # new stripe in parent to migrate to - 1 lock
22707         # source and target - 2 locks
22708         # Total 5 locks for regular file
22709         mkdir -p $DIR/$tdir
22710         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22711         touch $DIR/$tdir/dir1/eee
22712
22713         # create 4 hardlink for 4 more locks
22714         # Total: 9 locks > RS_MAX_LOCKS (8)
22715         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22716         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22717         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22718         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22719         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22720         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22721         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22722         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22723
22724         cancel_lru_locks mdc
22725
22726         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22727                 error "migrate dir fails"
22728
22729         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22730 }
22731 run_test 230r "migrate with too many local locks"
22732
22733 test_230s() {
22734         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22735                 skip "Need MDS version at least 2.14.52"
22736
22737         local mdts=$(comma_list $(mdts_nodes))
22738         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22739                                 mdt.*MDT0000.enable_dir_restripe)
22740
22741         stack_trap "do_nodes $mdts $LCTL set_param \
22742                     mdt.*.enable_dir_restripe=$restripe_status"
22743
22744         local st
22745         for st in 0 1; do
22746                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22747                 test_mkdir $DIR/$tdir
22748                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22749                         error "$LFS mkdir should return EEXIST if target exists"
22750                 rmdir $DIR/$tdir
22751         done
22752 }
22753 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22754
22755 test_230t()
22756 {
22757         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22758         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22759                 skip "Need MDS version at least 2.14.50"
22760
22761         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22762         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22763         $LFS project -p 1 -s $DIR/$tdir ||
22764                 error "set $tdir project id failed"
22765         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22766                 error "set subdir project id failed"
22767         local pbefore="$($LFS project -d $DIR/$tdir)"
22768         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22769         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22770
22771         local pafter="$($LFS project -d $DIR/$tdir)"
22772         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22773         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22774         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22775
22776         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22777                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22778
22779         # check rename works, even if source parent projid differs (LU-17016)
22780         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22781         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22782
22783         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22784         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22785                 error "subdir failed rename for different source parent projid"
22786         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22787
22788         [[ "$fid_before" == "$fid_after" ]] ||
22789                 error "fid before '$fid_before' != after '$fid_after'"
22790 }
22791 run_test 230t "migrate directory with project ID set"
22792
22793 test_230u()
22794 {
22795         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22796         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22797                 skip "Need MDS version at least 2.14.53"
22798
22799         local count
22800
22801         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22802         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22803         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22804         for i in $(seq 0 $((MDSCOUNT - 1))); do
22805                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22806                 echo "$count dirs migrated to MDT$i"
22807         done
22808         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22809         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22810 }
22811 run_test 230u "migrate directory by QOS"
22812
22813 test_230v()
22814 {
22815         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22816         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22817                 skip "Need MDS version at least 2.14.53"
22818
22819         local count
22820
22821         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22822         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22823         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22824         for i in $(seq 0 $((MDSCOUNT - 1))); do
22825                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22826                 echo "$count subdirs migrated to MDT$i"
22827                 (( i == 3 )) && (( count > 0 )) &&
22828                         error "subdir shouldn't be migrated to MDT3"
22829         done
22830         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22831         (( count == 3 )) || error "dirs migrated to $count MDTs"
22832 }
22833 run_test 230v "subdir migrated to the MDT where its parent is located"
22834
22835 test_230w() {
22836         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22837         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22838                 skip "Need MDS version at least 2.15.0"
22839
22840         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22841         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22842         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22843
22844         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22845                 error "migrate failed"
22846
22847         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22848                 error "$tdir stripe count mismatch"
22849
22850         for i in $(seq 0 9); do
22851                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22852                         error "d$i is striped"
22853         done
22854 }
22855 run_test 230w "non-recursive mode dir migration"
22856
22857 test_230x() {
22858         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22859         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22860                 skip "Need MDS version at least 2.15.0"
22861
22862         mkdir -p $DIR/$tdir || error "mkdir failed"
22863         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22864
22865         local mdt_name=$(mdtname_from_index 0)
22866         local low=$(do_facet mds2 $LCTL get_param -n \
22867                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22868         local high=$(do_facet mds2 $LCTL get_param -n \
22869                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22870         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22871         local maxage=$(do_facet mds2 $LCTL get_param -n \
22872                 osp.*$mdt_name-osp-MDT0001.maxage)
22873
22874         stack_trap "do_facet mds2 $LCTL set_param -n \
22875                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22876                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22877         stack_trap "do_facet mds2 $LCTL set_param -n \
22878                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22879
22880         do_facet mds2 $LCTL set_param -n \
22881                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22882         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22883         sleep 4
22884         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22885                 error "migrate $tdir should fail"
22886
22887         do_facet mds2 $LCTL set_param -n \
22888                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22889         do_facet mds2 $LCTL set_param -n \
22890                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22891         sleep 4
22892         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22893                 error "migrate failed"
22894         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22895                 error "$tdir stripe count mismatch"
22896 }
22897 run_test 230x "dir migration check space"
22898
22899 test_230y() {
22900         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22901         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22902                 skip "Need MDS version at least 2.15.55.45"
22903
22904         local pid
22905
22906         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22907         $LFS getdirstripe $DIR/$tdir
22908         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22909         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22910         pid=$!
22911         sleep 1
22912
22913         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22914         do_facet mds2 lctl set_param fail_loc=0x1802
22915
22916         wait $pid
22917         do_facet mds2 lctl set_param fail_loc=0
22918         $LFS getdirstripe $DIR/$tdir
22919         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22920         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22921 }
22922 run_test 230y "unlink dir with bad hash type"
22923
22924 test_230z() {
22925         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22926         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22927                 skip "Need MDS version at least 2.15.55.45"
22928
22929         local pid
22930
22931         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22932         $LFS getdirstripe $DIR/$tdir
22933         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22934         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22935         pid=$!
22936         sleep 1
22937
22938         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22939         do_facet mds2 lctl set_param fail_loc=0x1802
22940
22941         wait $pid
22942         do_facet mds2 lctl set_param fail_loc=0
22943         $LFS getdirstripe $DIR/$tdir
22944
22945         # resume migration
22946         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22947                 error "resume migration failed"
22948         $LFS getdirstripe $DIR/$tdir
22949         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22950                 error "migration is not finished"
22951 }
22952 run_test 230z "resume dir migration with bad hash type"
22953
22954 test_231a()
22955 {
22956         # For simplicity this test assumes that max_pages_per_rpc
22957         # is the same across all OSCs
22958         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22959         local bulk_size=$((max_pages * PAGE_SIZE))
22960         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22961                                        head -n 1)
22962
22963         mkdir -p $DIR/$tdir
22964         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22965                 error "failed to set stripe with -S ${brw_size}M option"
22966         stack_trap "rm -rf $DIR/$tdir"
22967
22968         # clear the OSC stats
22969         $LCTL set_param osc.*.stats=0 &>/dev/null
22970         stop_writeback
22971
22972         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22973         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22974                 oflag=direct &>/dev/null || error "dd failed"
22975
22976         sync; sleep 1; sync # just to be safe
22977         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22978         if [ x$nrpcs != "x1" ]; then
22979                 $LCTL get_param osc.*.stats
22980                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22981         fi
22982
22983         start_writeback
22984         # Drop the OSC cache, otherwise we will read from it
22985         cancel_lru_locks osc
22986
22987         # clear the OSC stats
22988         $LCTL set_param osc.*.stats=0 &>/dev/null
22989
22990         # Client reads $bulk_size.
22991         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22992                 iflag=direct &>/dev/null || error "dd failed"
22993
22994         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22995         if [ x$nrpcs != "x1" ]; then
22996                 $LCTL get_param osc.*.stats
22997                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22998         fi
22999 }
23000 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23001
23002 test_231b() {
23003         mkdir -p $DIR/$tdir
23004         stack_trap "rm -rf $DIR/$tdir"
23005         local i
23006         for i in {0..1023}; do
23007                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23008                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23009                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23010         done
23011         sync
23012 }
23013 run_test 231b "must not assert on fully utilized OST request buffer"
23014
23015 test_232a() {
23016         mkdir -p $DIR/$tdir
23017         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23018
23019         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23020         do_facet ost1 $LCTL set_param fail_loc=0x31c
23021
23022         # ignore dd failure
23023         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23024         stack_trap "rm -f $DIR/$tdir/$tfile"
23025
23026         do_facet ost1 $LCTL set_param fail_loc=0
23027         umount_client $MOUNT || error "umount failed"
23028         mount_client $MOUNT || error "mount failed"
23029         stop ost1 || error "cannot stop ost1"
23030         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23031 }
23032 run_test 232a "failed lock should not block umount"
23033
23034 test_232b() {
23035         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23036                 skip "Need MDS version at least 2.10.58"
23037
23038         mkdir -p $DIR/$tdir
23039         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23040         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23041         stack_trap "rm -f $DIR/$tdir/$tfile"
23042         sync
23043         cancel_lru_locks osc
23044
23045         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23046         do_facet ost1 $LCTL set_param fail_loc=0x31c
23047
23048         # ignore failure
23049         $LFS data_version $DIR/$tdir/$tfile || true
23050
23051         do_facet ost1 $LCTL set_param fail_loc=0
23052         umount_client $MOUNT || error "umount failed"
23053         mount_client $MOUNT || error "mount failed"
23054         stop ost1 || error "cannot stop ost1"
23055         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23056 }
23057 run_test 232b "failed data version lock should not block umount"
23058
23059 test_233a() {
23060         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23061                 skip "Need MDS version at least 2.3.64"
23062         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23063
23064         local fid=$($LFS path2fid $MOUNT)
23065
23066         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23067                 error "cannot access $MOUNT using its FID '$fid'"
23068 }
23069 run_test 233a "checking that OBF of the FS root succeeds"
23070
23071 test_233b() {
23072         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23073                 skip "Need MDS version at least 2.5.90"
23074         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23075
23076         local fid=$($LFS path2fid $MOUNT/.lustre)
23077
23078         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23079                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23080
23081         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23082         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23083                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23084 }
23085 run_test 233b "checking that OBF of the FS .lustre succeeds"
23086
23087 test_234() {
23088         local p="$TMP/sanityN-$TESTNAME.parameters"
23089         save_lustre_params client "llite.*.xattr_cache" > $p
23090         lctl set_param llite.*.xattr_cache 1 ||
23091                 skip_env "xattr cache is not supported"
23092
23093         mkdir -p $DIR/$tdir || error "mkdir failed"
23094         touch $DIR/$tdir/$tfile || error "touch failed"
23095         # OBD_FAIL_LLITE_XATTR_ENOMEM
23096         $LCTL set_param fail_loc=0x1405
23097         getfattr -n user.attr $DIR/$tdir/$tfile &&
23098                 error "getfattr should have failed with ENOMEM"
23099         $LCTL set_param fail_loc=0x0
23100         rm -rf $DIR/$tdir
23101
23102         restore_lustre_params < $p
23103         rm -f $p
23104 }
23105 run_test 234 "xattr cache should not crash on ENOMEM"
23106
23107 test_235() {
23108         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23109                 skip "Need MDS version at least 2.4.52"
23110
23111         flock_deadlock $DIR/$tfile
23112         local RC=$?
23113         case $RC in
23114                 0)
23115                 ;;
23116                 124) error "process hangs on a deadlock"
23117                 ;;
23118                 *) error "error executing flock_deadlock $DIR/$tfile"
23119                 ;;
23120         esac
23121 }
23122 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23123
23124 #LU-2935
23125 test_236() {
23126         check_swap_layouts_support
23127
23128         local ref1=/etc/passwd
23129         local ref2=/etc/group
23130         local file1=$DIR/$tdir/f1
23131         local file2=$DIR/$tdir/f2
23132
23133         test_mkdir -c1 $DIR/$tdir
23134         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23135         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23136         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23137         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23138         local fd=$(free_fd)
23139         local cmd="exec $fd<>$file2"
23140         eval $cmd
23141         rm $file2
23142         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23143                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23144         cmd="exec $fd>&-"
23145         eval $cmd
23146         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23147
23148         #cleanup
23149         rm -rf $DIR/$tdir
23150 }
23151 run_test 236 "Layout swap on open unlinked file"
23152
23153 # LU-4659 linkea consistency
23154 test_238() {
23155         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23156                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23157                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23158                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23159
23160         touch $DIR/$tfile
23161         ln $DIR/$tfile $DIR/$tfile.lnk
23162         touch $DIR/$tfile.new
23163         mv $DIR/$tfile.new $DIR/$tfile
23164         local fid1=$($LFS path2fid $DIR/$tfile)
23165         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23166         local path1=$($LFS fid2path $FSNAME "$fid1")
23167         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23168         local path2=$($LFS fid2path $FSNAME "$fid2")
23169         [ $tfile.lnk == $path2 ] ||
23170                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23171         rm -f $DIR/$tfile*
23172 }
23173 run_test 238 "Verify linkea consistency"
23174
23175 test_239A() { # was test_239
23176         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23177                 skip "Need MDS version at least 2.5.60"
23178
23179         local list=$(comma_list $(mdts_nodes))
23180
23181         mkdir -p $DIR/$tdir
23182         createmany -o $DIR/$tdir/f- 5000
23183         unlinkmany $DIR/$tdir/f- 5000
23184         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23185                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23186         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23187                         osp.*MDT*.sync_in_flight" | calc_sum)
23188         [ "$changes" -eq 0 ] || error "$changes not synced"
23189 }
23190 run_test 239A "osp_sync test"
23191
23192 test_239a() { #LU-5297
23193         remote_mds_nodsh && skip "remote MDS with nodsh"
23194
23195         touch $DIR/$tfile
23196         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23197         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23198         chgrp $RUNAS_GID $DIR/$tfile
23199         wait_delete_completed
23200 }
23201 run_test 239a "process invalid osp sync record correctly"
23202
23203 test_239b() { #LU-5297
23204         remote_mds_nodsh && skip "remote MDS with nodsh"
23205
23206         touch $DIR/$tfile1
23207         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23208         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23209         chgrp $RUNAS_GID $DIR/$tfile1
23210         wait_delete_completed
23211         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23212         touch $DIR/$tfile2
23213         chgrp $RUNAS_GID $DIR/$tfile2
23214         wait_delete_completed
23215 }
23216 run_test 239b "process osp sync record with ENOMEM error correctly"
23217
23218 test_240() {
23219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23220         remote_mds_nodsh && skip "remote MDS with nodsh"
23221
23222         mkdir -p $DIR/$tdir
23223
23224         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23225                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23226         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23227                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23228
23229         umount_client $MOUNT || error "umount failed"
23230         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23231         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23232         mount_client $MOUNT || error "failed to mount client"
23233
23234         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23235         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23236 }
23237 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23238
23239 test_241_bio() {
23240         local count=$1
23241         local bsize=$2
23242
23243         for LOOP in $(seq $count); do
23244                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23245                 cancel_lru_locks $OSC || true
23246         done
23247 }
23248
23249 test_241_dio() {
23250         local count=$1
23251         local bsize=$2
23252
23253         for LOOP in $(seq $1); do
23254                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23255                         2>/dev/null
23256         done
23257 }
23258
23259 test_241a() { # was test_241
23260         local bsize=$PAGE_SIZE
23261
23262         (( bsize < 40960 )) && bsize=40960
23263         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23264         ls -la $DIR/$tfile
23265         cancel_lru_locks $OSC
23266         test_241_bio 1000 $bsize &
23267         PID=$!
23268         test_241_dio 1000 $bsize
23269         wait $PID
23270 }
23271 run_test 241a "bio vs dio"
23272
23273 test_241b() {
23274         local bsize=$PAGE_SIZE
23275
23276         (( bsize < 40960 )) && bsize=40960
23277         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23278         ls -la $DIR/$tfile
23279         test_241_dio 1000 $bsize &
23280         PID=$!
23281         test_241_dio 1000 $bsize
23282         wait $PID
23283 }
23284 run_test 241b "dio vs dio"
23285
23286 test_242() {
23287         remote_mds_nodsh && skip "remote MDS with nodsh"
23288
23289         mkdir_on_mdt0 $DIR/$tdir
23290         touch $DIR/$tdir/$tfile
23291
23292         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23293         do_facet mds1 lctl set_param fail_loc=0x105
23294         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23295
23296         do_facet mds1 lctl set_param fail_loc=0
23297         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23298 }
23299 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23300
23301 test_243()
23302 {
23303         test_mkdir $DIR/$tdir
23304         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23305 }
23306 run_test 243 "various group lock tests"
23307
23308 test_244a()
23309 {
23310         test_mkdir $DIR/$tdir
23311         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23312         sendfile_grouplock $DIR/$tdir/$tfile || \
23313                 error "sendfile+grouplock failed"
23314         rm -rf $DIR/$tdir
23315 }
23316 run_test 244a "sendfile with group lock tests"
23317
23318 test_244b()
23319 {
23320         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23321
23322         local threads=50
23323         local size=$((1024*1024))
23324
23325         test_mkdir $DIR/$tdir
23326         for i in $(seq 1 $threads); do
23327                 local file=$DIR/$tdir/file_$((i / 10))
23328                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23329                 local pids[$i]=$!
23330         done
23331         for i in $(seq 1 $threads); do
23332                 wait ${pids[$i]}
23333         done
23334 }
23335 run_test 244b "multi-threaded write with group lock"
23336
23337 test_245a() {
23338         local flagname="multi_mod_rpcs"
23339         local connect_data_name="max_mod_rpcs"
23340         local out
23341
23342         # check if multiple modify RPCs flag is set
23343         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23344                 grep "connect_flags:")
23345         echo "$out"
23346
23347         echo "$out" | grep -qw $flagname
23348         if [ $? -ne 0 ]; then
23349                 echo "connect flag $flagname is not set"
23350                 return
23351         fi
23352
23353         # check if multiple modify RPCs data is set
23354         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23355         echo "$out"
23356
23357         echo "$out" | grep -qw $connect_data_name ||
23358                 error "import should have connect data $connect_data_name"
23359 }
23360 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23361
23362 test_245b() {
23363         local flagname="multi_mod_rpcs"
23364         local connect_data_name="max_mod_rpcs"
23365         local out
23366
23367         remote_mds_nodsh && skip "remote MDS with nodsh"
23368         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23369
23370         # check if multiple modify RPCs flag is set
23371         out=$(do_facet mds1 \
23372               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23373               grep "connect_flags:")
23374         echo "$out"
23375
23376         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23377
23378         # check if multiple modify RPCs data is set
23379         out=$(do_facet mds1 \
23380               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23381
23382         [[ "$out" =~ $connect_data_name ]] ||
23383                 {
23384                         echo "$out"
23385                         error "missing connect data $connect_data_name"
23386                 }
23387 }
23388 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23389
23390 cleanup_247() {
23391         local submount=$1
23392
23393         trap 0
23394         umount_client $submount
23395         rmdir $submount
23396 }
23397
23398 test_247a() {
23399         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23400                 grep -q subtree ||
23401                 skip_env "Fileset feature is not supported"
23402
23403         local submount=${MOUNT}_$tdir
23404
23405         mkdir $MOUNT/$tdir
23406         mkdir -p $submount || error "mkdir $submount failed"
23407         FILESET="$FILESET/$tdir" mount_client $submount ||
23408                 error "mount $submount failed"
23409         trap "cleanup_247 $submount" EXIT
23410         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23411         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23412                 error "read $MOUNT/$tdir/$tfile failed"
23413         cleanup_247 $submount
23414 }
23415 run_test 247a "mount subdir as fileset"
23416
23417 test_247b() {
23418         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23419                 skip_env "Fileset feature is not supported"
23420
23421         local submount=${MOUNT}_$tdir
23422
23423         rm -rf $MOUNT/$tdir
23424         mkdir -p $submount || error "mkdir $submount failed"
23425         SKIP_FILESET=1
23426         FILESET="$FILESET/$tdir" mount_client $submount &&
23427                 error "mount $submount should fail"
23428         rmdir $submount
23429 }
23430 run_test 247b "mount subdir that dose not exist"
23431
23432 test_247c() {
23433         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23434                 skip_env "Fileset feature is not supported"
23435
23436         local submount=${MOUNT}_$tdir
23437
23438         mkdir -p $MOUNT/$tdir/dir1
23439         mkdir -p $submount || error "mkdir $submount failed"
23440         trap "cleanup_247 $submount" EXIT
23441         FILESET="$FILESET/$tdir" mount_client $submount ||
23442                 error "mount $submount failed"
23443         local fid=$($LFS path2fid $MOUNT/)
23444         $LFS fid2path $submount $fid && error "fid2path should fail"
23445         cleanup_247 $submount
23446 }
23447 run_test 247c "running fid2path outside subdirectory root"
23448
23449 test_247d() {
23450         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23451                 skip "Fileset feature is not supported"
23452
23453         local submount=${MOUNT}_$tdir
23454
23455         mkdir -p $MOUNT/$tdir/dir1
23456         mkdir -p $submount || error "mkdir $submount failed"
23457         FILESET="$FILESET/$tdir" mount_client $submount ||
23458                 error "mount $submount failed"
23459         trap "cleanup_247 $submount" EXIT
23460
23461         local td=$submount/dir1
23462         local fid=$($LFS path2fid $td)
23463         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23464
23465         # check that we get the same pathname back
23466         local rootpath
23467         local found
23468         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23469                 echo "$rootpath $fid"
23470                 found=$($LFS fid2path $rootpath "$fid")
23471                 [ -n "$found" ] || error "fid2path should succeed"
23472                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23473         done
23474         # check wrong root path format
23475         rootpath=$submount"_wrong"
23476         found=$($LFS fid2path $rootpath "$fid")
23477         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23478
23479         cleanup_247 $submount
23480 }
23481 run_test 247d "running fid2path inside subdirectory root"
23482
23483 # LU-8037
23484 test_247e() {
23485         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23486                 grep -q subtree ||
23487                 skip "Fileset feature is not supported"
23488
23489         local submount=${MOUNT}_$tdir
23490
23491         mkdir $MOUNT/$tdir
23492         mkdir -p $submount || error "mkdir $submount failed"
23493         FILESET="$FILESET/.." mount_client $submount &&
23494                 error "mount $submount should fail"
23495         rmdir $submount
23496 }
23497 run_test 247e "mount .. as fileset"
23498
23499 test_247f() {
23500         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23501         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23502                 skip "Need at least version 2.14.50.162"
23503         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23504                 skip "Fileset feature is not supported"
23505
23506         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23507         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23508                 error "mkdir remote failed"
23509         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23510                 error "mkdir remote/subdir failed"
23511         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23512                 error "mkdir striped failed"
23513         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23514
23515         local submount=${MOUNT}_$tdir
23516
23517         mkdir -p $submount || error "mkdir $submount failed"
23518         stack_trap "rmdir $submount"
23519
23520         local dir
23521         local fileset=$FILESET
23522         local mdts=$(comma_list $(mdts_nodes))
23523
23524         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23525         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23526                 $tdir/striped/subdir $tdir/striped/.; do
23527                 FILESET="$fileset/$dir" mount_client $submount ||
23528                         error "mount $dir failed"
23529                 umount_client $submount
23530         done
23531 }
23532 run_test 247f "mount striped or remote directory as fileset"
23533
23534 test_subdir_mount_lock()
23535 {
23536         local testdir=$1
23537         local submount=${MOUNT}_$(basename $testdir)
23538
23539         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23540
23541         mkdir -p $submount || error "mkdir $submount failed"
23542         stack_trap "rmdir $submount"
23543
23544         FILESET="$fileset/$testdir" mount_client $submount ||
23545                 error "mount $FILESET failed"
23546         stack_trap "umount $submount"
23547
23548         local mdts=$(comma_list $(mdts_nodes))
23549
23550         local nrpcs
23551
23552         stat $submount > /dev/null || error "stat $submount failed"
23553         cancel_lru_locks $MDC
23554         stat $submount > /dev/null || error "stat $submount failed"
23555         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23556         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23557         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23558         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23559                 awk '/getattr/ {sum += $2} END {print sum}')
23560
23561         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23562 }
23563
23564 test_247g() {
23565         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23566
23567         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23568                 error "mkdir $tdir failed"
23569         test_subdir_mount_lock $tdir
23570 }
23571 run_test 247g "striped directory submount revalidate ROOT from cache"
23572
23573 test_247h() {
23574         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23575         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23576                 skip "Need MDS version at least 2.15.51"
23577
23578         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23579         test_subdir_mount_lock $tdir
23580         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23581         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23582                 error "mkdir $tdir.1 failed"
23583         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23584 }
23585 run_test 247h "remote directory submount revalidate ROOT from cache"
23586
23587 test_248a() {
23588         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23589         [ -z "$fast_read_sav" ] && skip "no fast read support"
23590
23591         # create a large file for fast read verification
23592         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23593
23594         # make sure the file is created correctly
23595         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23596                 { rm -f $DIR/$tfile; skip "file creation error"; }
23597
23598         echo "Test 1: verify that fast read is 4 times faster on cache read"
23599
23600         # small read with fast read enabled
23601         $LCTL set_param -n llite.*.fast_read=1
23602         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23603                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23604                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23605         # small read with fast read disabled
23606         $LCTL set_param -n llite.*.fast_read=0
23607         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23608                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23609                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23610
23611         # verify that fast read is 4 times faster for cache read
23612         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23613                 error_not_in_vm "fast read was not 4 times faster: " \
23614                            "$t_fast vs $t_slow"
23615
23616         echo "Test 2: verify the performance between big and small read"
23617         $LCTL set_param -n llite.*.fast_read=1
23618
23619         # 1k non-cache read
23620         cancel_lru_locks osc
23621         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23622                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23623                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23624
23625         # 1M non-cache read
23626         cancel_lru_locks osc
23627         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23628                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23629                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23630
23631         # verify that big IO is not 4 times faster than small IO
23632         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23633                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23634
23635         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23636         rm -f $DIR/$tfile
23637 }
23638 run_test 248a "fast read verification"
23639
23640 test_248b() {
23641         # Default short_io_bytes=16384, try both smaller and larger sizes.
23642         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23643         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23644         echo "bs=53248 count=113 normal buffered write"
23645         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23646                 error "dd of initial data file failed"
23647         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23648
23649         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23650         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23651                 error "dd with sync normal writes failed"
23652         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23653
23654         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23655         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23656                 error "dd with sync small writes failed"
23657         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23658
23659         cancel_lru_locks osc
23660
23661         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23662         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23663         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23664         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23665                 iflag=direct || error "dd with O_DIRECT small read failed"
23666         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23667         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23668                 error "compare $TMP/$tfile.1 failed"
23669
23670         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23671         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23672
23673         # just to see what the maximum tunable value is, and test parsing
23674         echo "test invalid parameter 2MB"
23675         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23676                 error "too-large short_io_bytes allowed"
23677         echo "test maximum parameter 512KB"
23678         # if we can set a larger short_io_bytes, run test regardless of version
23679         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23680                 # older clients may not allow setting it this large, that's OK
23681                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23682                         skip "Need at least client version 2.13.50"
23683                 error "medium short_io_bytes failed"
23684         fi
23685         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23686         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23687
23688         echo "test large parameter 64KB"
23689         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23690         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23691
23692         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23693         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23694                 error "dd with sync large writes failed"
23695         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23696
23697         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23698         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23699         num=$((113 * 4096 / PAGE_SIZE))
23700         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23701         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23702                 error "dd with O_DIRECT large writes failed"
23703         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23704                 error "compare $DIR/$tfile.3 failed"
23705
23706         cancel_lru_locks osc
23707
23708         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23709         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23710                 error "dd with O_DIRECT large read failed"
23711         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23712                 error "compare $TMP/$tfile.2 failed"
23713
23714         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23715         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23716                 error "dd with O_DIRECT large read failed"
23717         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23718                 error "compare $TMP/$tfile.3 failed"
23719 }
23720 run_test 248b "test short_io read and write for both small and large sizes"
23721
23722 test_249() { # LU-7890
23723         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23724                 skip "Need at least version 2.8.54"
23725
23726         rm -f $DIR/$tfile
23727         $LFS setstripe -c 1 $DIR/$tfile
23728         # Offset 2T == 4k * 512M
23729         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23730                 error "dd to 2T offset failed"
23731 }
23732 run_test 249 "Write above 2T file size"
23733
23734 test_250() {
23735         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23736          && skip "no 16TB file size limit on ZFS"
23737
23738         $LFS setstripe -c 1 $DIR/$tfile
23739         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23740         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23741         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23742         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23743                 conv=notrunc,fsync && error "append succeeded"
23744         return 0
23745 }
23746 run_test 250 "Write above 16T limit"
23747
23748 test_251() {
23749         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23750
23751         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23752         #Skip once - writing the first stripe will succeed
23753         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23754         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23755                 error "short write happened"
23756
23757         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23758         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23759                 error "short read happened"
23760
23761         rm -f $DIR/$tfile
23762 }
23763 run_test 251 "Handling short read and write correctly"
23764
23765 test_252() {
23766         remote_mds_nodsh && skip "remote MDS with nodsh"
23767         remote_ost_nodsh && skip "remote OST with nodsh"
23768         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23769                 skip_env "ldiskfs only test"
23770         fi
23771
23772         local tgt
23773         local dev
23774         local out
23775         local uuid
23776         local num
23777         local gen
23778
23779         # check lr_reader on OST0000
23780         tgt=ost1
23781         dev=$(facet_device $tgt)
23782         out=$(do_facet $tgt $LR_READER $dev)
23783         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23784         echo "$out"
23785         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23786         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23787                 error "Invalid uuid returned by $LR_READER on target $tgt"
23788         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23789
23790         # check lr_reader -c on MDT0000
23791         tgt=mds1
23792         dev=$(facet_device $tgt)
23793         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23794                 skip "$LR_READER does not support additional options"
23795         fi
23796         out=$(do_facet $tgt $LR_READER -c $dev)
23797         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23798         echo "$out"
23799         num=$(echo "$out" | grep -c "mdtlov")
23800         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23801                 error "Invalid number of mdtlov clients returned by $LR_READER"
23802         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23803
23804         # check lr_reader -cr on MDT0000
23805         out=$(do_facet $tgt $LR_READER -cr $dev)
23806         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23807         echo "$out"
23808         echo "$out" | grep -q "^reply_data:$" ||
23809                 error "$LR_READER should have returned 'reply_data' section"
23810         num=$(echo "$out" | grep -c "client_generation")
23811         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23812 }
23813 run_test 252 "check lr_reader tool"
23814
23815 test_253() {
23816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23817         remote_mds_nodsh && skip "remote MDS with nodsh"
23818         remote_mgs_nodsh && skip "remote MGS with nodsh"
23819         check_set_fallocate_or_skip
23820
23821         local ostidx=0
23822         local rc=0
23823         local ost_name=$(ostname_from_index $ostidx)
23824
23825         # on the mdt's osc
23826         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23827         do_facet $SINGLEMDS $LCTL get_param -n \
23828                 osp.$mdtosc_proc1.reserved_mb_high ||
23829                 skip  "remote MDS does not support reserved_mb_high"
23830
23831         rm -rf $DIR/$tdir
23832         wait_mds_ost_sync
23833         wait_delete_completed
23834         mkdir $DIR/$tdir
23835         stack_trap "rm -rf $DIR/$tdir"
23836
23837         pool_add $TESTNAME || error "Pool creation failed"
23838         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23839
23840         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23841                 error "Setstripe failed"
23842
23843         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23844
23845         local wms=$(ost_watermarks_get $ostidx)
23846
23847         ost_watermarks_set $ostidx 60 50
23848         stack_trap "ost_watermarks_set $ostidx $wms"
23849
23850         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
23851         local size=$((free_kb * 1024))
23852
23853         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
23854                 error "fallocate failed"
23855         sleep_maxage
23856
23857         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23858                         osp.$mdtosc_proc1.prealloc_status)
23859         echo "prealloc_status $oa_status"
23860
23861         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23862                 error "File creation should fail"
23863
23864         #object allocation was stopped, but we still able to append files
23865         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23866                 oflag=append || error "Append failed"
23867
23868         rm -f $DIR/$tdir/$tfile.0
23869         rm -f $DIR/$tdir/fill_ost$ostidx
23870
23871         wait_delete_completed
23872         sleep_maxage
23873
23874         for i in $(seq 10 12); do
23875                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23876                         2>/dev/null || error "File creation failed after rm"
23877         done
23878
23879         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23880                         osp.$mdtosc_proc1.prealloc_status)
23881         echo "prealloc_status $oa_status"
23882
23883         if (( oa_status != 0 )); then
23884                 error "Object allocation still disable after rm"
23885         fi
23886 }
23887 run_test 253 "Check object allocation limit"
23888
23889 test_254() {
23890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23891         remote_mds_nodsh && skip "remote MDS with nodsh"
23892
23893         local mdt=$(facet_svc $SINGLEMDS)
23894
23895         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23896                 skip "MDS does not support changelog_size"
23897
23898         local cl_user
23899
23900         changelog_register || error "changelog_register failed"
23901
23902         changelog_clear 0 || error "changelog_clear failed"
23903
23904         local size1=$(do_facet $SINGLEMDS \
23905                       $LCTL get_param -n mdd.$mdt.changelog_size)
23906         echo "Changelog size $size1"
23907
23908         rm -rf $DIR/$tdir
23909         $LFS mkdir -i 0 $DIR/$tdir
23910         # change something
23911         mkdir -p $DIR/$tdir/pics/2008/zachy
23912         touch $DIR/$tdir/pics/2008/zachy/timestamp
23913         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23914         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23915         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23916         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23917         rm $DIR/$tdir/pics/desktop.jpg
23918
23919         local size2=$(do_facet $SINGLEMDS \
23920                       $LCTL get_param -n mdd.$mdt.changelog_size)
23921         echo "Changelog size after work $size2"
23922
23923         (( $size2 > $size1 )) ||
23924                 error "new Changelog size=$size2 less than old size=$size1"
23925 }
23926 run_test 254 "Check changelog size"
23927
23928 ladvise_no_type()
23929 {
23930         local type=$1
23931         local file=$2
23932
23933         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23934                 awk -F: '{print $2}' | grep $type > /dev/null
23935         if [ $? -ne 0 ]; then
23936                 return 0
23937         fi
23938         return 1
23939 }
23940
23941 ladvise_no_ioctl()
23942 {
23943         local file=$1
23944
23945         lfs ladvise -a willread $file > /dev/null 2>&1
23946         if [ $? -eq 0 ]; then
23947                 return 1
23948         fi
23949
23950         lfs ladvise -a willread $file 2>&1 |
23951                 grep "Inappropriate ioctl for device" > /dev/null
23952         if [ $? -eq 0 ]; then
23953                 return 0
23954         fi
23955         return 1
23956 }
23957
23958 percent() {
23959         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23960 }
23961
23962 # run a random read IO workload
23963 # usage: random_read_iops <filename> <filesize> <iosize>
23964 random_read_iops() {
23965         local file=$1
23966         local fsize=$2
23967         local iosize=${3:-4096}
23968
23969         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23970                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23971 }
23972
23973 drop_file_oss_cache() {
23974         local file="$1"
23975         local nodes="$2"
23976
23977         $LFS ladvise -a dontneed $file 2>/dev/null ||
23978                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23979 }
23980
23981 ladvise_willread_performance()
23982 {
23983         local repeat=10
23984         local average_origin=0
23985         local average_cache=0
23986         local average_ladvise=0
23987
23988         for ((i = 1; i <= $repeat; i++)); do
23989                 echo "Iter $i/$repeat: reading without willread hint"
23990                 cancel_lru_locks osc
23991                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23992                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23993                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23994                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23995
23996                 cancel_lru_locks osc
23997                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23998                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23999                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24000
24001                 cancel_lru_locks osc
24002                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24003                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24004                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24005                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24006                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24007         done
24008         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24009         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24010         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24011
24012         speedup_cache=$(percent $average_cache $average_origin)
24013         speedup_ladvise=$(percent $average_ladvise $average_origin)
24014
24015         echo "Average uncached read: $average_origin"
24016         echo "Average speedup with OSS cached read: " \
24017                 "$average_cache = +$speedup_cache%"
24018         echo "Average speedup with ladvise willread: " \
24019                 "$average_ladvise = +$speedup_ladvise%"
24020
24021         local lowest_speedup=20
24022         if (( ${average_cache%.*} < $lowest_speedup )); then
24023                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24024                      " got $average_cache%. Skipping ladvise willread check."
24025                 return 0
24026         fi
24027
24028         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24029         # it is still good to run until then to exercise 'ladvise willread'
24030         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24031                 [ "$ost1_FSTYPE" = "zfs" ] &&
24032                 echo "osd-zfs does not support dontneed or drop_caches" &&
24033                 return 0
24034
24035         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
24036         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
24037                 error_not_in_vm "Speedup with willread is less than " \
24038                         "$lowest_speedup%, got $average_ladvise%"
24039 }
24040
24041 test_255a() {
24042         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24043                 skip "lustre < 2.8.54 does not support ladvise "
24044         remote_ost_nodsh && skip "remote OST with nodsh"
24045
24046         stack_trap "rm -f $DIR/$tfile"
24047         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24048
24049         ladvise_no_type willread $DIR/$tfile &&
24050                 skip "willread ladvise is not supported"
24051
24052         ladvise_no_ioctl $DIR/$tfile &&
24053                 skip "ladvise ioctl is not supported"
24054
24055         local size_mb=100
24056         local size=$((size_mb * 1048576))
24057         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24058                 error "dd to $DIR/$tfile failed"
24059
24060         lfs ladvise -a willread $DIR/$tfile ||
24061                 error "Ladvise failed with no range argument"
24062
24063         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24064                 error "Ladvise failed with no -l or -e argument"
24065
24066         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24067                 error "Ladvise failed with only -e argument"
24068
24069         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24070                 error "Ladvise failed with only -l argument"
24071
24072         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24073                 error "End offset should not be smaller than start offset"
24074
24075         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24076                 error "End offset should not be equal to start offset"
24077
24078         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24079                 error "Ladvise failed with overflowing -s argument"
24080
24081         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24082                 error "Ladvise failed with overflowing -e argument"
24083
24084         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24085                 error "Ladvise failed with overflowing -l argument"
24086
24087         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24088                 error "Ladvise succeeded with conflicting -l and -e arguments"
24089
24090         echo "Synchronous ladvise should wait"
24091         local delay=8
24092 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24093         do_nodes $(comma_list $(osts_nodes)) \
24094                 $LCTL set_param fail_val=$delay fail_loc=0x237
24095         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24096                 $LCTL set_param fail_loc=0"
24097
24098         local start_ts=$SECONDS
24099         lfs ladvise -a willread $DIR/$tfile ||
24100                 error "Ladvise failed with no range argument"
24101         local end_ts=$SECONDS
24102         local inteval_ts=$((end_ts - start_ts))
24103
24104         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24105                 error "Synchronous advice didn't wait reply"
24106         fi
24107
24108         echo "Asynchronous ladvise shouldn't wait"
24109         local start_ts=$SECONDS
24110         lfs ladvise -a willread -b $DIR/$tfile ||
24111                 error "Ladvise failed with no range argument"
24112         local end_ts=$SECONDS
24113         local inteval_ts=$((end_ts - start_ts))
24114
24115         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24116                 error "Asynchronous advice blocked"
24117         fi
24118
24119         ladvise_willread_performance
24120 }
24121 run_test 255a "check 'lfs ladvise -a willread'"
24122
24123 facet_meminfo() {
24124         local facet=$1
24125         local info=$2
24126
24127         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24128 }
24129
24130 test_255b() {
24131         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24132                 skip "lustre < 2.8.54 does not support ladvise "
24133         remote_ost_nodsh && skip "remote OST with nodsh"
24134
24135         stack_trap "rm -f $DIR/$tfile"
24136         lfs setstripe -c 1 -i 0 $DIR/$tfile
24137
24138         ladvise_no_type dontneed $DIR/$tfile &&
24139                 skip "dontneed ladvise is not supported"
24140
24141         ladvise_no_ioctl $DIR/$tfile &&
24142                 skip "ladvise ioctl is not supported"
24143
24144         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24145                 [ "$ost1_FSTYPE" = "zfs" ] &&
24146                 skip "zfs-osd does not support 'ladvise dontneed'"
24147
24148         local size_mb=100
24149         local size=$((size_mb * 1048576))
24150         # In order to prevent disturbance of other processes, only check 3/4
24151         # of the memory usage
24152         local kibibytes=$((size_mb * 1024 * 3 / 4))
24153
24154         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24155                 error "dd to $DIR/$tfile failed"
24156
24157         #force write to complete before dropping OST cache & checking memory
24158         sync
24159
24160         local total=$(facet_meminfo ost1 MemTotal)
24161         echo "Total memory: $total KiB"
24162
24163         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24164         local before_read=$(facet_meminfo ost1 Cached)
24165         echo "Cache used before read: $before_read KiB"
24166
24167         lfs ladvise -a willread $DIR/$tfile ||
24168                 error "Ladvise willread failed"
24169         local after_read=$(facet_meminfo ost1 Cached)
24170         echo "Cache used after read: $after_read KiB"
24171
24172         lfs ladvise -a dontneed $DIR/$tfile ||
24173                 error "Ladvise dontneed again failed"
24174         local no_read=$(facet_meminfo ost1 Cached)
24175         echo "Cache used after dontneed ladvise: $no_read KiB"
24176
24177         if [ $total -lt $((before_read + kibibytes)) ]; then
24178                 echo "Memory is too small, abort checking"
24179                 return 0
24180         fi
24181
24182         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24183                 error "Ladvise willread should use more memory" \
24184                         "than $kibibytes KiB"
24185         fi
24186
24187         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24188                 error "Ladvise dontneed should release more memory" \
24189                         "than $kibibytes KiB"
24190         fi
24191 }
24192 run_test 255b "check 'lfs ladvise -a dontneed'"
24193
24194 test_255c() {
24195         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24196                 skip "lustre < 2.10.50 does not support lockahead"
24197
24198         local ost1_imp=$(get_osc_import_name client ost1)
24199         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24200                          cut -d'.' -f2)
24201         local count
24202         local new_count
24203         local difference
24204         local i
24205         local rc
24206
24207         test_mkdir -p $DIR/$tdir
24208         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24209
24210         #test 10 returns only success/failure
24211         i=10
24212         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24213         rc=$?
24214         if [ $rc -eq 255 ]; then
24215                 error "Ladvise test${i} failed, ${rc}"
24216         fi
24217
24218         #test 11 counts lock enqueue requests, all others count new locks
24219         i=11
24220         count=$(do_facet ost1 \
24221                 $LCTL get_param -n ost.OSS.ost.stats)
24222         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24223
24224         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24225         rc=$?
24226         if [ $rc -eq 255 ]; then
24227                 error "Ladvise test${i} failed, ${rc}"
24228         fi
24229
24230         new_count=$(do_facet ost1 \
24231                 $LCTL get_param -n ost.OSS.ost.stats)
24232         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24233                    awk '{ print $2 }')
24234
24235         difference="$((new_count - count))"
24236         if [ $difference -ne $rc ]; then
24237                 error "Ladvise test${i}, bad enqueue count, returned " \
24238                       "${rc}, actual ${difference}"
24239         fi
24240
24241         for i in $(seq 12 21); do
24242                 # If we do not do this, we run the risk of having too many
24243                 # locks and starting lock cancellation while we are checking
24244                 # lock counts.
24245                 cancel_lru_locks osc
24246
24247                 count=$($LCTL get_param -n \
24248                        ldlm.namespaces.$imp_name.lock_unused_count)
24249
24250                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24251                 rc=$?
24252                 if [ $rc -eq 255 ]; then
24253                         error "Ladvise test ${i} failed, ${rc}"
24254                 fi
24255
24256                 new_count=$($LCTL get_param -n \
24257                        ldlm.namespaces.$imp_name.lock_unused_count)
24258                 difference="$((new_count - count))"
24259
24260                 # Test 15 output is divided by 100 to map down to valid return
24261                 if [ $i -eq 15 ]; then
24262                         rc="$((rc * 100))"
24263                 fi
24264
24265                 if [ $difference -ne $rc ]; then
24266                         error "Ladvise test ${i}, bad lock count, returned " \
24267                               "${rc}, actual ${difference}"
24268                 fi
24269         done
24270
24271         #test 22 returns only success/failure
24272         i=22
24273         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24274         rc=$?
24275         if [ $rc -eq 255 ]; then
24276                 error "Ladvise test${i} failed, ${rc}"
24277         fi
24278 }
24279 run_test 255c "suite of ladvise lockahead tests"
24280
24281 test_256() {
24282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24283         remote_mds_nodsh && skip "remote MDS with nodsh"
24284         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24285         changelog_users $SINGLEMDS | grep "^cl" &&
24286                 skip "active changelog user"
24287
24288         local cl_user
24289         local cat_sl
24290         local mdt_dev
24291
24292         mdt_dev=$(facet_device $SINGLEMDS)
24293         echo $mdt_dev
24294
24295         changelog_register || error "changelog_register failed"
24296
24297         rm -rf $DIR/$tdir
24298         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24299
24300         changelog_clear 0 || error "changelog_clear failed"
24301
24302         # change something
24303         touch $DIR/$tdir/{1..10}
24304
24305         # stop the MDT
24306         stop $SINGLEMDS || error "Fail to stop MDT"
24307
24308         # remount the MDT
24309         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24310                 error "Fail to start MDT"
24311
24312         #after mount new plainllog is used
24313         touch $DIR/$tdir/{11..19}
24314         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24315         stack_trap "rm -f $tmpfile"
24316         cat_sl=$(do_facet $SINGLEMDS "sync; \
24317                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24318                  llog_reader $tmpfile | grep -c type=1064553b")
24319         do_facet $SINGLEMDS llog_reader $tmpfile
24320
24321         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24322
24323         changelog_clear 0 || error "changelog_clear failed"
24324
24325         cat_sl=$(do_facet $SINGLEMDS "sync; \
24326                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24327                  llog_reader $tmpfile | grep -c type=1064553b")
24328
24329         if (( cat_sl == 2 )); then
24330                 error "Empty plain llog was not deleted from changelog catalog"
24331         elif (( cat_sl != 1 )); then
24332                 error "Active plain llog shouldn't be deleted from catalog"
24333         fi
24334 }
24335 run_test 256 "Check llog delete for empty and not full state"
24336
24337 test_257() {
24338         remote_mds_nodsh && skip "remote MDS with nodsh"
24339         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24340                 skip "Need MDS version at least 2.8.55"
24341
24342         test_mkdir $DIR/$tdir
24343
24344         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24345                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24346         stat $DIR/$tdir
24347
24348 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24349         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24350         local facet=mds$((mdtidx + 1))
24351         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24352         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24353
24354         stop $facet || error "stop MDS failed"
24355         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24356                 error "start MDS fail"
24357         wait_recovery_complete $facet
24358 }
24359 run_test 257 "xattr locks are not lost"
24360
24361 # Verify we take the i_mutex when security requires it
24362 test_258a() {
24363 #define OBD_FAIL_IMUTEX_SEC 0x141c
24364         $LCTL set_param fail_loc=0x141c
24365         touch $DIR/$tfile
24366         chmod u+s $DIR/$tfile
24367         chmod a+rwx $DIR/$tfile
24368         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24369         RC=$?
24370         if [ $RC -ne 0 ]; then
24371                 error "error, failed to take i_mutex, rc=$?"
24372         fi
24373         rm -f $DIR/$tfile
24374 }
24375 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24376
24377 # Verify we do NOT take the i_mutex in the normal case
24378 test_258b() {
24379 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24380         $LCTL set_param fail_loc=0x141d
24381         touch $DIR/$tfile
24382         chmod a+rwx $DIR
24383         chmod a+rw $DIR/$tfile
24384         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24385         RC=$?
24386         if [ $RC -ne 0 ]; then
24387                 error "error, took i_mutex unnecessarily, rc=$?"
24388         fi
24389         rm -f $DIR/$tfile
24390
24391 }
24392 run_test 258b "verify i_mutex security behavior"
24393
24394 test_259() {
24395         local file=$DIR/$tfile
24396         local before
24397         local after
24398
24399         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24400
24401         stack_trap "rm -f $file" EXIT
24402
24403         wait_delete_completed
24404         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24405         echo "before: $before"
24406
24407         $LFS setstripe -i 0 -c 1 $file
24408         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24409         sync_all_data
24410         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24411         echo "after write: $after"
24412
24413 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24414         do_facet ost1 $LCTL set_param fail_loc=0x2301
24415         $TRUNCATE $file 0
24416         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24417         echo "after truncate: $after"
24418
24419         stop ost1
24420         do_facet ost1 $LCTL set_param fail_loc=0
24421         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24422         sleep 2
24423         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24424         echo "after restart: $after"
24425         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24426                 error "missing truncate?"
24427
24428         return 0
24429 }
24430 run_test 259 "crash at delayed truncate"
24431
24432 test_260() {
24433 #define OBD_FAIL_MDC_CLOSE               0x806
24434         $LCTL set_param fail_loc=0x80000806
24435         touch $DIR/$tfile
24436
24437 }
24438 run_test 260 "Check mdc_close fail"
24439
24440 ### Data-on-MDT sanity tests ###
24441 test_270a() {
24442         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24443                 skip "Need MDS version at least 2.10.55 for DoM"
24444
24445         # create DoM file
24446         local dom=$DIR/$tdir/dom_file
24447         local tmp=$DIR/$tdir/tmp_file
24448
24449         mkdir_on_mdt0 $DIR/$tdir
24450
24451         # basic checks for DoM component creation
24452         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24453                 error "Can set MDT layout to non-first entry"
24454
24455         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24456                 error "Can define multiple entries as MDT layout"
24457
24458         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24459
24460         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24461         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24462         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24463
24464         local mdtidx=$($LFS getstripe -m $dom)
24465         local mdtname=MDT$(printf %04x $mdtidx)
24466         local facet=mds$((mdtidx + 1))
24467         local space_check=1
24468
24469         # Skip free space checks with ZFS
24470         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24471
24472         # write
24473         sync
24474         local size_tmp=$((65536 * 3))
24475         local mdtfree1=$(do_facet $facet \
24476                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24477
24478         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24479         # check also direct IO along write
24480         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24481         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24482         sync
24483         cmp $tmp $dom || error "file data is different"
24484         [ $(stat -c%s $dom) == $size_tmp ] ||
24485                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24486         if [ $space_check == 1 ]; then
24487                 local mdtfree2=$(do_facet $facet \
24488                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24489
24490                 # increase in usage from by $size_tmp
24491                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24492                         error "MDT free space wrong after write: " \
24493                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24494         fi
24495
24496         # truncate
24497         local size_dom=10000
24498
24499         $TRUNCATE $dom $size_dom
24500         [ $(stat -c%s $dom) == $size_dom ] ||
24501                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24502         if [ $space_check == 1 ]; then
24503                 mdtfree1=$(do_facet $facet \
24504                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24505                 # decrease in usage from $size_tmp to new $size_dom
24506                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24507                   $(((size_tmp - size_dom) / 1024)) ] ||
24508                         error "MDT free space is wrong after truncate: " \
24509                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24510         fi
24511
24512         # append
24513         cat $tmp >> $dom
24514         sync
24515         size_dom=$((size_dom + size_tmp))
24516         [ $(stat -c%s $dom) == $size_dom ] ||
24517                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24518         if [ $space_check == 1 ]; then
24519                 mdtfree2=$(do_facet $facet \
24520                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24521                 # increase in usage by $size_tmp from previous
24522                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24523                         error "MDT free space is wrong after append: " \
24524                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24525         fi
24526
24527         # delete
24528         rm $dom
24529         if [ $space_check == 1 ]; then
24530                 mdtfree1=$(do_facet $facet \
24531                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24532                 # decrease in usage by $size_dom from previous
24533                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24534                         error "MDT free space is wrong after removal: " \
24535                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24536         fi
24537
24538         # combined striping
24539         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24540                 error "Can't create DoM + OST striping"
24541
24542         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24543         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24544         # check also direct IO along write
24545         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24546         sync
24547         cmp $tmp $dom || error "file data is different"
24548         [ $(stat -c%s $dom) == $size_tmp ] ||
24549                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24550         rm $dom $tmp
24551
24552         return 0
24553 }
24554 run_test 270a "DoM: basic functionality tests"
24555
24556 test_270b() {
24557         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24558                 skip "Need MDS version at least 2.10.55"
24559
24560         local dom=$DIR/$tdir/dom_file
24561         local max_size=1048576
24562
24563         mkdir -p $DIR/$tdir
24564         $LFS setstripe -E $max_size -L mdt $dom
24565
24566         # truncate over the limit
24567         $TRUNCATE $dom $(($max_size + 1)) &&
24568                 error "successful truncate over the maximum size"
24569         # write over the limit
24570         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24571                 error "successful write over the maximum size"
24572         # append over the limit
24573         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24574         echo "12345" >> $dom && error "successful append over the maximum size"
24575         rm $dom
24576
24577         return 0
24578 }
24579 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24580
24581 test_270c() {
24582         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24583                 skip "Need MDS version at least 2.10.55"
24584
24585         mkdir -p $DIR/$tdir
24586         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24587
24588         # check files inherit DoM EA
24589         touch $DIR/$tdir/first
24590         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24591                 error "bad pattern"
24592         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24593                 error "bad stripe count"
24594         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24595                 error "bad stripe size"
24596
24597         # check directory inherits DoM EA and uses it as default
24598         mkdir $DIR/$tdir/subdir
24599         touch $DIR/$tdir/subdir/second
24600         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24601                 error "bad pattern in sub-directory"
24602         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24603                 error "bad stripe count in sub-directory"
24604         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24605                 error "bad stripe size in sub-directory"
24606         return 0
24607 }
24608 run_test 270c "DoM: DoM EA inheritance tests"
24609
24610 test_270d() {
24611         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24612                 skip "Need MDS version at least 2.10.55"
24613
24614         mkdir -p $DIR/$tdir
24615         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24616
24617         # inherit default DoM striping
24618         mkdir $DIR/$tdir/subdir
24619         touch $DIR/$tdir/subdir/f1
24620
24621         # change default directory striping
24622         $LFS setstripe -c 1 $DIR/$tdir/subdir
24623         touch $DIR/$tdir/subdir/f2
24624         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24625                 error "wrong default striping in file 2"
24626         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24627                 error "bad pattern in file 2"
24628         return 0
24629 }
24630 run_test 270d "DoM: change striping from DoM to RAID0"
24631
24632 test_270e() {
24633         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24634                 skip "Need MDS version at least 2.10.55"
24635
24636         mkdir -p $DIR/$tdir/dom
24637         mkdir -p $DIR/$tdir/norm
24638         DOMFILES=20
24639         NORMFILES=10
24640         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24641         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24642
24643         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24644         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24645
24646         # find DoM files by layout
24647         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24648         [ $NUM -eq  $DOMFILES ] ||
24649                 error "lfs find -L: found $NUM, expected $DOMFILES"
24650         echo "Test 1: lfs find 20 DOM files by layout: OK"
24651
24652         # there should be 1 dir with default DOM striping
24653         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24654         [ $NUM -eq  1 ] ||
24655                 error "lfs find -L: found $NUM, expected 1 dir"
24656         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24657
24658         # find DoM files by stripe size
24659         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24660         [ $NUM -eq  $DOMFILES ] ||
24661                 error "lfs find -S: found $NUM, expected $DOMFILES"
24662         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24663
24664         # find files by stripe offset except DoM files
24665         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24666         [ $NUM -eq  $NORMFILES ] ||
24667                 error "lfs find -i: found $NUM, expected $NORMFILES"
24668         echo "Test 5: lfs find no DOM files by stripe index: OK"
24669         return 0
24670 }
24671 run_test 270e "DoM: lfs find with DoM files test"
24672
24673 test_270f() {
24674         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24675                 skip "Need MDS version at least 2.10.55"
24676
24677         local mdtname=${FSNAME}-MDT0000-mdtlov
24678         local dom=$DIR/$tdir/dom_file
24679         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24680                                                 lod.$mdtname.dom_stripesize)
24681         local dom_limit=131072
24682
24683         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24684         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24685                                                 lod.$mdtname.dom_stripesize)
24686         [ ${dom_limit} -eq ${dom_current} ] ||
24687                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24688
24689         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24690         $LFS setstripe -d $DIR/$tdir
24691         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24692                 error "Can't set directory default striping"
24693
24694         # exceed maximum stripe size
24695         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24696                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24697         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24698                 error "Able to create DoM component size more than LOD limit"
24699
24700         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24701         dom_current=$(do_facet mds1 $LCTL get_param -n \
24702                                                 lod.$mdtname.dom_stripesize)
24703         [ 0 -eq ${dom_current} ] ||
24704                 error "Can't set zero DoM stripe limit"
24705         rm $dom
24706
24707         # attempt to create DoM file on server with disabled DoM should
24708         # remove DoM entry from layout and be succeed
24709         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24710                 error "Can't create DoM file (DoM is disabled)"
24711         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24712                 error "File has DoM component while DoM is disabled"
24713         rm $dom
24714
24715         # attempt to create DoM file with only DoM stripe should return error
24716         $LFS setstripe -E $dom_limit -L mdt $dom &&
24717                 error "Able to create DoM-only file while DoM is disabled"
24718
24719         # too low values to be aligned with smallest stripe size 64K
24720         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24721         dom_current=$(do_facet mds1 $LCTL get_param -n \
24722                                                 lod.$mdtname.dom_stripesize)
24723         [ 30000 -eq ${dom_current} ] &&
24724                 error "Can set too small DoM stripe limit"
24725
24726         # 64K is a minimal stripe size in Lustre, expect limit of that size
24727         [ 65536 -eq ${dom_current} ] ||
24728                 error "Limit is not set to 64K but ${dom_current}"
24729
24730         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24731         dom_current=$(do_facet mds1 $LCTL get_param -n \
24732                                                 lod.$mdtname.dom_stripesize)
24733         echo $dom_current
24734         [ 2147483648 -eq ${dom_current} ] &&
24735                 error "Can set too large DoM stripe limit"
24736
24737         do_facet mds1 $LCTL set_param -n \
24738                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24739         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24740                 error "Can't create DoM component size after limit change"
24741         do_facet mds1 $LCTL set_param -n \
24742                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24743         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24744                 error "Can't create DoM file after limit decrease"
24745         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24746                 error "Can create big DoM component after limit decrease"
24747         touch ${dom}_def ||
24748                 error "Can't create file with old default layout"
24749
24750         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24751         return 0
24752 }
24753 run_test 270f "DoM: maximum DoM stripe size checks"
24754
24755 test_270g() {
24756         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24757                 skip "Need MDS version at least 2.13.52"
24758         local dom=$DIR/$tdir/$tfile
24759
24760         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24761         local lodname=${FSNAME}-MDT0000-mdtlov
24762
24763         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24764         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24765         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24766         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24767
24768         local dom_limit=1024
24769         local dom_threshold="50%"
24770
24771         $LFS setstripe -d $DIR/$tdir
24772         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24773                 error "Can't set directory default striping"
24774
24775         do_facet mds1 $LCTL set_param -n \
24776                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24777         # set 0 threshold and create DOM file to change tunable stripesize
24778         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24779         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24780                 error "Failed to create $dom file"
24781         # now tunable dom_cur_stripesize should reach maximum
24782         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24783                                         lod.${lodname}.dom_stripesize_cur_kb)
24784         [[ $dom_current == $dom_limit ]] ||
24785                 error "Current DOM stripesize is not maximum"
24786         rm $dom
24787
24788         # set threshold for further tests
24789         do_facet mds1 $LCTL set_param -n \
24790                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24791         echo "DOM threshold is $dom_threshold free space"
24792         local dom_def
24793         local dom_set
24794         # Spoof bfree to exceed threshold
24795         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24796         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24797         for spfree in 40 20 0 15 30 55; do
24798                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24799                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24800                         error "Failed to create $dom file"
24801                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24802                                         lod.${lodname}.dom_stripesize_cur_kb)
24803                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24804                 [[ $dom_def != $dom_current ]] ||
24805                         error "Default stripe size was not changed"
24806                 if (( spfree > 0 )) ; then
24807                         dom_set=$($LFS getstripe -S $dom)
24808                         (( dom_set == dom_def * 1024 )) ||
24809                                 error "DOM component size is still old"
24810                 else
24811                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24812                                 error "DoM component is set with no free space"
24813                 fi
24814                 rm $dom
24815                 dom_current=$dom_def
24816         done
24817 }
24818 run_test 270g "DoM: default DoM stripe size depends on free space"
24819
24820 test_270h() {
24821         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24822                 skip "Need MDS version at least 2.13.53"
24823
24824         local mdtname=${FSNAME}-MDT0000-mdtlov
24825         local dom=$DIR/$tdir/$tfile
24826         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24827
24828         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24829         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24830
24831         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24832         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24833                 error "can't create OST file"
24834         # mirrored file with DOM entry in the second mirror
24835         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24836                 error "can't create mirror with DoM component"
24837
24838         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24839
24840         # DOM component in the middle and has other enries in the same mirror,
24841         # should succeed but lost DoM component
24842         $LFS setstripe --copy=${dom}_1 $dom ||
24843                 error "Can't create file from OST|DOM mirror layout"
24844         # check new file has no DoM layout after all
24845         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24846                 error "File has DoM component while DoM is disabled"
24847 }
24848 run_test 270h "DoM: DoM stripe removal when disabled on server"
24849
24850 test_270i() {
24851         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24852                 skip "Need MDS version at least 2.14.54"
24853
24854         mkdir $DIR/$tdir
24855         # DoM with plain layout
24856         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24857                 error "default plain layout with DoM must fail"
24858         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24859                 error "setstripe plain file layout with DoM must fail"
24860         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24861                 error "default DoM layout with bad striping must fail"
24862         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24863                 error "setstripe to DoM layout with bad striping must fail"
24864         return 0
24865 }
24866 run_test 270i "DoM: setting invalid DoM striping should fail"
24867
24868 test_270j() {
24869         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24870                 skip "Need MDS version at least 2.15.55.203"
24871
24872         local dom=$DIR/$tdir/$tfile
24873         local odv
24874         local ndv
24875
24876         mkdir -p $DIR/$tdir
24877
24878         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24879
24880         odv=$($LFS data_version $dom)
24881         chmod 666 $dom
24882         mv $dom ${dom}_moved
24883         link ${dom}_moved $dom
24884         setfattr -n user.attrx -v "some_attr" $dom
24885         ndv=$($LFS data_version $dom)
24886         (( $ndv == $odv )) ||
24887                 error "data version was changed by metadata operations"
24888
24889         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24890                 error "failed to write data into $dom"
24891         cancel_lru_locks mdc
24892         ndv=$($LFS data_version $dom)
24893         (( $ndv != $odv )) ||
24894                 error "data version wasn't changed on write"
24895
24896         odv=$ndv
24897         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24898         ndv=$($LFS data_version $dom)
24899         (( $ndv != $odv )) ||
24900                 error "data version wasn't changed on truncate down"
24901
24902         odv=$ndv
24903         $TRUNCATE $dom 25000
24904         ndv=$($LFS data_version $dom)
24905         (( $ndv != $odv )) ||
24906                 error "data version wasn't changed on truncate up"
24907
24908         # check also fallocate for ldiskfs
24909         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24910                 odv=$ndv
24911                 fallocate -l 1048576 $dom
24912                 ndv=$($LFS data_version $dom)
24913                 (( $ndv != $odv )) ||
24914                         error "data version wasn't changed on fallocate"
24915
24916                 odv=$ndv
24917                 fallocate -p --offset 4096 -l 4096 $dom
24918                 ndv=$($LFS data_version $dom)
24919                 (( $ndv != $odv )) ||
24920                         error "data version wasn't changed on fallocate punch"
24921         fi
24922 }
24923 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24924
24925 test_271a() {
24926         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24927                 skip "Need MDS version at least 2.10.55"
24928
24929         local dom=$DIR/$tdir/dom
24930
24931         mkdir -p $DIR/$tdir
24932
24933         $LFS setstripe -E 1024K -L mdt $dom
24934
24935         lctl set_param -n mdc.*.stats=clear
24936         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24937         cat $dom > /dev/null
24938         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24939         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24940         ls $dom
24941         rm -f $dom
24942 }
24943 run_test 271a "DoM: data is cached for read after write"
24944
24945 test_271b() {
24946         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24947                 skip "Need MDS version at least 2.10.55"
24948
24949         local dom=$DIR/$tdir/dom
24950
24951         mkdir -p $DIR/$tdir
24952
24953         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24954
24955         lctl set_param -n mdc.*.stats=clear
24956         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24957         cancel_lru_locks mdc
24958         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24959         # second stat to check size is cached on client
24960         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24961         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24962         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24963         rm -f $dom
24964 }
24965 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24966
24967 test_271ba() {
24968         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24969                 skip "Need MDS version at least 2.10.55"
24970
24971         local dom=$DIR/$tdir/dom
24972
24973         mkdir -p $DIR/$tdir
24974
24975         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24976
24977         lctl set_param -n mdc.*.stats=clear
24978         lctl set_param -n osc.*.stats=clear
24979         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24980         cancel_lru_locks mdc
24981         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24982         # second stat to check size is cached on client
24983         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24984         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24985         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24986         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24987         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24988         rm -f $dom
24989 }
24990 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24991
24992
24993 get_mdc_stats() {
24994         local mdtidx=$1
24995         local param=$2
24996         local mdt=MDT$(printf %04x $mdtidx)
24997
24998         if [ -z $param ]; then
24999                 lctl get_param -n mdc.*$mdt*.stats
25000         else
25001                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25002         fi
25003 }
25004
25005 test_271c() {
25006         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25007                 skip "Need MDS version at least 2.10.55"
25008
25009         local dom=$DIR/$tdir/dom
25010
25011         mkdir -p $DIR/$tdir
25012
25013         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25014
25015         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25016         local facet=mds$((mdtidx + 1))
25017
25018         cancel_lru_locks mdc
25019         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25020         createmany -o $dom 1000
25021         lctl set_param -n mdc.*.stats=clear
25022         smalliomany -w $dom 1000 200
25023         get_mdc_stats $mdtidx
25024         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25025         # Each file has 1 open, 1 IO enqueues, total 2000
25026         # but now we have also +1 getxattr for security.capability, total 3000
25027         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25028         unlinkmany $dom 1000
25029
25030         cancel_lru_locks mdc
25031         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25032         createmany -o $dom 1000
25033         lctl set_param -n mdc.*.stats=clear
25034         smalliomany -w $dom 1000 200
25035         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25036         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25037         # for OPEN and IO lock.
25038         [ $((enq - enq_2)) -ge 1000 ] ||
25039                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25040         unlinkmany $dom 1000
25041         return 0
25042 }
25043 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25044
25045 cleanup_271def_tests() {
25046         trap 0
25047         rm -f $1
25048 }
25049
25050 test_271d() {
25051         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25052                 skip "Need MDS version at least 2.10.57"
25053
25054         local dom=$DIR/$tdir/dom
25055         local tmp=$TMP/$tfile
25056         trap "cleanup_271def_tests $tmp" EXIT
25057
25058         mkdir -p $DIR/$tdir
25059
25060         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25061
25062         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25063
25064         cancel_lru_locks mdc
25065         dd if=/dev/urandom of=$tmp bs=1000 count=1
25066         dd if=$tmp of=$dom bs=1000 count=1
25067         cancel_lru_locks mdc
25068
25069         cat /etc/hosts >> $tmp
25070         lctl set_param -n mdc.*.stats=clear
25071
25072         # append data to the same file it should update local page
25073         echo "Append to the same page"
25074         cat /etc/hosts >> $dom
25075         local num=$(get_mdc_stats $mdtidx ost_read)
25076         local ra=$(get_mdc_stats $mdtidx req_active)
25077         local rw=$(get_mdc_stats $mdtidx req_waittime)
25078
25079         [ -z $num ] || error "$num READ RPC occured"
25080         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25081         echo "... DONE"
25082
25083         # compare content
25084         cmp $tmp $dom || error "file miscompare"
25085
25086         cancel_lru_locks mdc
25087         lctl set_param -n mdc.*.stats=clear
25088
25089         echo "Open and read file"
25090         cat $dom > /dev/null
25091         local num=$(get_mdc_stats $mdtidx ost_read)
25092         local ra=$(get_mdc_stats $mdtidx req_active)
25093         local rw=$(get_mdc_stats $mdtidx req_waittime)
25094
25095         [ -z $num ] || error "$num READ RPC occured"
25096         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25097         echo "... DONE"
25098
25099         # compare content
25100         cmp $tmp $dom || error "file miscompare"
25101
25102         return 0
25103 }
25104 run_test 271d "DoM: read on open (1K file in reply buffer)"
25105
25106 test_271f() {
25107         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25108                 skip "Need MDS version at least 2.10.57"
25109
25110         local dom=$DIR/$tdir/dom
25111         local tmp=$TMP/$tfile
25112         trap "cleanup_271def_tests $tmp" EXIT
25113
25114         mkdir -p $DIR/$tdir
25115
25116         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25117
25118         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25119
25120         cancel_lru_locks mdc
25121         dd if=/dev/urandom of=$tmp bs=265000 count=1
25122         dd if=$tmp of=$dom bs=265000 count=1
25123         cancel_lru_locks mdc
25124         cat /etc/hosts >> $tmp
25125         lctl set_param -n mdc.*.stats=clear
25126
25127         echo "Append to the same page"
25128         cat /etc/hosts >> $dom
25129         local num=$(get_mdc_stats $mdtidx ost_read)
25130         local ra=$(get_mdc_stats $mdtidx req_active)
25131         local rw=$(get_mdc_stats $mdtidx req_waittime)
25132
25133         [ -z $num ] || error "$num READ RPC occured"
25134         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25135         echo "... DONE"
25136
25137         # compare content
25138         cmp $tmp $dom || error "file miscompare"
25139
25140         cancel_lru_locks mdc
25141         lctl set_param -n mdc.*.stats=clear
25142
25143         echo "Open and read file"
25144         cat $dom > /dev/null
25145         local num=$(get_mdc_stats $mdtidx ost_read)
25146         local ra=$(get_mdc_stats $mdtidx req_active)
25147         local rw=$(get_mdc_stats $mdtidx req_waittime)
25148
25149         [ -z $num ] && num=0
25150         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25151         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25152         echo "... DONE"
25153
25154         # compare content
25155         cmp $tmp $dom || error "file miscompare"
25156
25157         return 0
25158 }
25159 run_test 271f "DoM: read on open (200K file and read tail)"
25160
25161 test_271g() {
25162         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25163                 skip "Skipping due to old client or server version"
25164
25165         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25166         # to get layout
25167         $CHECKSTAT -t file $DIR1/$tfile
25168
25169         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25170         MULTIOP_PID=$!
25171         sleep 1
25172         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25173         $LCTL set_param fail_loc=0x80000314
25174         rm $DIR1/$tfile || error "Unlink fails"
25175         RC=$?
25176         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25177         [ $RC -eq 0 ] || error "Failed write to stale object"
25178 }
25179 run_test 271g "Discard DoM data vs client flush race"
25180
25181 test_272a() {
25182         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25183                 skip "Need MDS version at least 2.11.50"
25184
25185         local dom=$DIR/$tdir/dom
25186         mkdir -p $DIR/$tdir
25187
25188         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25189         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25190                 error "failed to write data into $dom"
25191         local old_md5=$(md5sum $dom)
25192
25193         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25194                 error "failed to migrate to the same DoM component"
25195
25196         local new_md5=$(md5sum $dom)
25197
25198         [ "$old_md5" == "$new_md5" ] ||
25199                 error "md5sum differ: $old_md5, $new_md5"
25200
25201         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25202                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25203 }
25204 run_test 272a "DoM migration: new layout with the same DOM component"
25205
25206 test_272b() {
25207         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25208                 skip "Need MDS version at least 2.11.50"
25209
25210         local dom=$DIR/$tdir/dom
25211         mkdir -p $DIR/$tdir
25212         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25213         stack_trap "rm -rf $DIR/$tdir"
25214
25215         local mdtidx=$($LFS getstripe -m $dom)
25216         local mdtname=MDT$(printf %04x $mdtidx)
25217         local facet=mds$((mdtidx + 1))
25218
25219         local mdtfree1=$(do_facet $facet \
25220                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25221         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25222                 error "failed to write data into $dom"
25223         local old_md5=$(md5sum $dom)
25224         cancel_lru_locks mdc
25225         local mdtfree1=$(do_facet $facet \
25226                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25227
25228         $LFS migrate -c2 $dom ||
25229                 error "failed to migrate to the new composite layout"
25230         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25231                 error "MDT stripe was not removed"
25232         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25233                 error "$dir1 shouldn't have DATAVER EA"
25234
25235         cancel_lru_locks mdc
25236         local new_md5=$(md5sum $dom)
25237         [ "$old_md5" == "$new_md5" ] ||
25238                 error "$old_md5 != $new_md5"
25239
25240         # Skip free space checks with ZFS
25241         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25242                 local mdtfree2=$(do_facet $facet \
25243                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25244                 [ $mdtfree2 -gt $mdtfree1 ] ||
25245                         error "MDT space is not freed after migration"
25246         fi
25247         return 0
25248 }
25249 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25250
25251 test_272c() {
25252         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25253                 skip "Need MDS version at least 2.11.50"
25254
25255         local dom=$DIR/$tdir/$tfile
25256         mkdir -p $DIR/$tdir
25257         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25258         stack_trap "rm -rf $DIR/$tdir"
25259
25260         local mdtidx=$($LFS getstripe -m $dom)
25261         local mdtname=MDT$(printf %04x $mdtidx)
25262         local facet=mds$((mdtidx + 1))
25263
25264         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25265                 error "failed to write data into $dom"
25266         local old_md5=$(md5sum $dom)
25267         cancel_lru_locks mdc
25268         local mdtfree1=$(do_facet $facet \
25269                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25270
25271         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25272                 error "failed to migrate to the new composite layout"
25273         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25274                 error "MDT stripe was not removed"
25275
25276         cancel_lru_locks mdc
25277         local new_md5=$(md5sum $dom)
25278         [ "$old_md5" == "$new_md5" ] ||
25279                 error "$old_md5 != $new_md5"
25280
25281         # Skip free space checks with ZFS
25282         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25283                 local mdtfree2=$(do_facet $facet \
25284                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25285                 [ $mdtfree2 -gt $mdtfree1 ] ||
25286                         error "MDS space is not freed after migration"
25287         fi
25288         return 0
25289 }
25290 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25291
25292 test_272d() {
25293         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25294                 skip "Need MDS version at least 2.12.55"
25295
25296         local dom=$DIR/$tdir/$tfile
25297         mkdir -p $DIR/$tdir
25298         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25299
25300         local mdtidx=$($LFS getstripe -m $dom)
25301         local mdtname=MDT$(printf %04x $mdtidx)
25302         local facet=mds$((mdtidx + 1))
25303
25304         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25305                 error "failed to write data into $dom"
25306         local old_md5=$(md5sum $dom)
25307         cancel_lru_locks mdc
25308         local mdtfree1=$(do_facet $facet \
25309                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25310
25311         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25312                 error "failed mirroring to the new composite layout"
25313         $LFS mirror resync $dom ||
25314                 error "failed mirror resync"
25315         $LFS mirror split --mirror-id 1 -d $dom ||
25316                 error "failed mirror split"
25317
25318         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25319                 error "MDT stripe was not removed"
25320
25321         cancel_lru_locks mdc
25322         local new_md5=$(md5sum $dom)
25323         [ "$old_md5" == "$new_md5" ] ||
25324                 error "$old_md5 != $new_md5"
25325
25326         # Skip free space checks with ZFS
25327         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25328                 local mdtfree2=$(do_facet $facet \
25329                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25330                 [ $mdtfree2 -gt $mdtfree1 ] ||
25331                         error "MDS space is not freed after DOM mirror deletion"
25332         fi
25333         return 0
25334 }
25335 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25336
25337 test_272e() {
25338         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25339                 skip "Need MDS version at least 2.12.55"
25340
25341         local dom=$DIR/$tdir/$tfile
25342         mkdir -p $DIR/$tdir
25343         $LFS setstripe -c 2 $dom
25344
25345         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25346                 error "failed to write data into $dom"
25347         local old_md5=$(md5sum $dom)
25348         cancel_lru_locks
25349
25350         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25351                 error "failed mirroring to the DOM layout"
25352         $LFS mirror resync $dom ||
25353                 error "failed mirror resync"
25354         $LFS mirror split --mirror-id 1 -d $dom ||
25355                 error "failed mirror split"
25356
25357         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25358                 error "MDT stripe wasn't set"
25359
25360         cancel_lru_locks
25361         local new_md5=$(md5sum $dom)
25362         [ "$old_md5" == "$new_md5" ] ||
25363                 error "$old_md5 != $new_md5"
25364
25365         return 0
25366 }
25367 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25368
25369 test_272f() {
25370         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25371                 skip "Need MDS version at least 2.12.55"
25372
25373         local dom=$DIR/$tdir/$tfile
25374         mkdir -p $DIR/$tdir
25375         $LFS setstripe -c 2 $dom
25376
25377         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25378                 error "failed to write data into $dom"
25379         local old_md5=$(md5sum $dom)
25380         cancel_lru_locks
25381
25382         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25383                 error "failed migrating to the DOM file"
25384
25385         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25386                 error "MDT stripe wasn't set"
25387
25388         cancel_lru_locks
25389         local new_md5=$(md5sum $dom)
25390         [ "$old_md5" != "$new_md5" ] &&
25391                 error "$old_md5 != $new_md5"
25392
25393         return 0
25394 }
25395 run_test 272f "DoM migration: OST-striped file to DOM file"
25396
25397 test_273a() {
25398         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25399                 skip "Need MDS version at least 2.11.50"
25400
25401         # Layout swap cannot be done if either file has DOM component,
25402         # this will never be supported, migration should be used instead
25403
25404         local dom=$DIR/$tdir/$tfile
25405         mkdir -p $DIR/$tdir
25406
25407         $LFS setstripe -c2 ${dom}_plain
25408         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25409         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25410                 error "can swap layout with DoM component"
25411         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25412                 error "can swap layout with DoM component"
25413
25414         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25415         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25416                 error "can swap layout with DoM component"
25417         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25418                 error "can swap layout with DoM component"
25419         return 0
25420 }
25421 run_test 273a "DoM: layout swapping should fail with DOM"
25422
25423 test_273b() {
25424         mkdir -p $DIR/$tdir
25425         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25426
25427 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25428         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25429
25430         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25431 }
25432 run_test 273b "DoM: race writeback and object destroy"
25433
25434 test_273c() {
25435         mkdir -p $DIR/$tdir
25436         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25437
25438         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25439         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25440
25441         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25442 }
25443 run_test 273c "race writeback and object destroy"
25444
25445 test_275() {
25446         remote_ost_nodsh && skip "remote OST with nodsh"
25447         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25448                 skip "Need OST version >= 2.10.57"
25449
25450         local file=$DIR/$tfile
25451         local oss
25452
25453         oss=$(comma_list $(osts_nodes))
25454
25455         dd if=/dev/urandom of=$file bs=1M count=2 ||
25456                 error "failed to create a file"
25457         stack_trap "rm -f $file"
25458         cancel_lru_locks osc
25459
25460         #lock 1
25461         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25462                 error "failed to read a file"
25463
25464 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25465         $LCTL set_param fail_loc=0x8000031f
25466
25467         cancel_lru_locks osc &
25468         sleep 1
25469
25470 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25471         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25472         #IO takes another lock, but matches the PENDING one
25473         #and places it to the IO RPC
25474         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25475                 error "failed to read a file with PENDING lock"
25476 }
25477 run_test 275 "Read on a canceled duplicate lock"
25478
25479 test_276() {
25480         remote_ost_nodsh && skip "remote OST with nodsh"
25481         local pid
25482
25483         do_facet ost1 "(while true; do \
25484                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25485                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25486         pid=$!
25487
25488         for LOOP in $(seq 20); do
25489                 stop ost1
25490                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25491         done
25492         kill -9 $pid
25493         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25494                 rm $TMP/sanity_276_pid"
25495 }
25496 run_test 276 "Race between mount and obd_statfs"
25497
25498 test_277() {
25499         $LCTL set_param ldlm.namespaces.*.lru_size=0
25500         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25501         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25502                           awk '/^used_mb/ { print $2 }')
25503         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25504         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25505                 oflag=direct conv=notrunc
25506         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25507                     awk '/^used_mb/ { print $2 }')
25508         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25509 }
25510 run_test 277 "Direct IO shall drop page cache"
25511
25512 test_278() {
25513         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25514         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25515         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25516                 skip "needs the same host for mdt1 mdt2" && return
25517
25518         local pid1
25519         local pid2
25520
25521 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25522         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25523         stop mds2 &
25524         pid2=$!
25525
25526         stop mds1
25527
25528         echo "Starting MDTs"
25529         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25530         wait $pid2
25531 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25532 #will return NULL
25533         do_facet mds2 $LCTL set_param fail_loc=0
25534
25535         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25536         wait_recovery_complete mds2
25537 }
25538 run_test 278 "Race starting MDS between MDTs stop/start"
25539
25540 test_280() {
25541         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25542                 skip "Need MGS version at least 2.13.52"
25543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25544         combined_mgs_mds || skip "needs combined MGS/MDT"
25545
25546         umount_client $MOUNT
25547 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25548         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25549
25550         mount_client $MOUNT &
25551         sleep 1
25552         stop mgs || error "stop mgs failed"
25553         #for a race mgs would crash
25554         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25555         # make sure we unmount client before remounting
25556         wait
25557         umount_client $MOUNT
25558         mount_client $MOUNT || error "mount client failed"
25559 }
25560 run_test 280 "Race between MGS umount and client llog processing"
25561
25562 cleanup_test_300() {
25563         trap 0
25564         umask $SAVE_UMASK
25565 }
25566 test_striped_dir() {
25567         local mdt_index=$1
25568         local stripe_count
25569         local stripe_index
25570
25571         mkdir -p $DIR/$tdir
25572
25573         SAVE_UMASK=$(umask)
25574         trap cleanup_test_300 RETURN EXIT
25575
25576         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25577                                                 $DIR/$tdir/striped_dir ||
25578                 error "set striped dir error"
25579
25580         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25581         [ "$mode" = "755" ] || error "expect 755 got $mode"
25582
25583         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25584                 error "getdirstripe failed"
25585         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25586         if [ "$stripe_count" != "2" ]; then
25587                 error "1:stripe_count is $stripe_count, expect 2"
25588         fi
25589         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25590         if [ "$stripe_count" != "2" ]; then
25591                 error "2:stripe_count is $stripe_count, expect 2"
25592         fi
25593
25594         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25595         if [ "$stripe_index" != "$mdt_index" ]; then
25596                 error "stripe_index is $stripe_index, expect $mdt_index"
25597         fi
25598
25599         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25600                 error "nlink error after create striped dir"
25601
25602         mkdir $DIR/$tdir/striped_dir/a
25603         mkdir $DIR/$tdir/striped_dir/b
25604
25605         stat $DIR/$tdir/striped_dir/a ||
25606                 error "create dir under striped dir failed"
25607         stat $DIR/$tdir/striped_dir/b ||
25608                 error "create dir under striped dir failed"
25609
25610         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25611                 error "nlink error after mkdir"
25612
25613         rmdir $DIR/$tdir/striped_dir/a
25614         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25615                 error "nlink error after rmdir"
25616
25617         rmdir $DIR/$tdir/striped_dir/b
25618         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25619                 error "nlink error after rmdir"
25620
25621         chattr +i $DIR/$tdir/striped_dir
25622         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25623                 error "immutable flags not working under striped dir!"
25624         chattr -i $DIR/$tdir/striped_dir
25625
25626         rmdir $DIR/$tdir/striped_dir ||
25627                 error "rmdir striped dir error"
25628
25629         cleanup_test_300
25630
25631         true
25632 }
25633
25634 test_300a() {
25635         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25636                 skip "skipped for lustre < 2.7.0"
25637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25639
25640         test_striped_dir 0 || error "failed on striped dir on MDT0"
25641         test_striped_dir 1 || error "failed on striped dir on MDT0"
25642 }
25643 run_test 300a "basic striped dir sanity test"
25644
25645 test_300b() {
25646         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25647                 skip "skipped for lustre < 2.7.0"
25648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25650
25651         local i
25652         local mtime1
25653         local mtime2
25654         local mtime3
25655
25656         test_mkdir $DIR/$tdir || error "mkdir fail"
25657         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25658                 error "set striped dir error"
25659         for i in {0..9}; do
25660                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25661                 sleep 1
25662                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25663                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25664                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25665                 sleep 1
25666                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25667                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25668                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25669         done
25670         true
25671 }
25672 run_test 300b "check ctime/mtime for striped dir"
25673
25674 test_300c() {
25675         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25676                 skip "skipped for lustre < 2.7.0"
25677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25679
25680         local file_count
25681
25682         mkdir_on_mdt0 $DIR/$tdir
25683         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25684                 error "set striped dir error"
25685
25686         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25687                 error "chown striped dir failed"
25688
25689         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25690                 error "create 5k files failed"
25691
25692         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25693
25694         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25695
25696         rm -rf $DIR/$tdir
25697 }
25698 run_test 300c "chown && check ls under striped directory"
25699
25700 test_300d() {
25701         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25702                 skip "skipped for lustre < 2.7.0"
25703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25705
25706         local stripe_count
25707         local file
25708
25709         mkdir -p $DIR/$tdir
25710         $LFS setstripe -c 2 $DIR/$tdir
25711
25712         #local striped directory
25713         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25714                 error "set striped dir error"
25715         #look at the directories for debug purposes
25716         ls -l $DIR/$tdir
25717         $LFS getdirstripe $DIR/$tdir
25718         ls -l $DIR/$tdir/striped_dir
25719         $LFS getdirstripe $DIR/$tdir/striped_dir
25720         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25721                 error "create 10 files failed"
25722
25723         #remote striped directory
25724         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25725                 error "set striped dir error"
25726         #look at the directories for debug purposes
25727         ls -l $DIR/$tdir
25728         $LFS getdirstripe $DIR/$tdir
25729         ls -l $DIR/$tdir/remote_striped_dir
25730         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25731         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25732                 error "create 10 files failed"
25733
25734         for file in $(find $DIR/$tdir); do
25735                 stripe_count=$($LFS getstripe -c $file)
25736                 [ $stripe_count -eq 2 ] ||
25737                         error "wrong stripe $stripe_count for $file"
25738         done
25739
25740         rm -rf $DIR/$tdir
25741 }
25742 run_test 300d "check default stripe under striped directory"
25743
25744 test_300e() {
25745         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25746                 skip "Need MDS version at least 2.7.55"
25747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25749
25750         local stripe_count
25751         local file
25752
25753         mkdir -p $DIR/$tdir
25754
25755         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25756                 error "set striped dir error"
25757
25758         touch $DIR/$tdir/striped_dir/a
25759         touch $DIR/$tdir/striped_dir/b
25760         touch $DIR/$tdir/striped_dir/c
25761
25762         mkdir $DIR/$tdir/striped_dir/dir_a
25763         mkdir $DIR/$tdir/striped_dir/dir_b
25764         mkdir $DIR/$tdir/striped_dir/dir_c
25765
25766         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25767                 error "set striped adir under striped dir error"
25768
25769         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25770                 error "set striped bdir under striped dir error"
25771
25772         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25773                 error "set striped cdir under striped dir error"
25774
25775         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25776                 error "rename dir under striped dir fails"
25777
25778         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25779                 error "rename dir under different stripes fails"
25780
25781         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25782                 error "rename file under striped dir should succeed"
25783
25784         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25785                 error "rename dir under striped dir should succeed"
25786
25787         rm -rf $DIR/$tdir
25788 }
25789 run_test 300e "check rename under striped directory"
25790
25791 test_300f() {
25792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25793         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25794         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25795                 skip "Need MDS version at least 2.7.55"
25796
25797         local stripe_count
25798         local file
25799
25800         rm -rf $DIR/$tdir
25801         mkdir -p $DIR/$tdir
25802
25803         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25804                 error "set striped dir error"
25805
25806         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25807                 error "set striped dir error"
25808
25809         touch $DIR/$tdir/striped_dir/a
25810         mkdir $DIR/$tdir/striped_dir/dir_a
25811         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25812                 error "create striped dir under striped dir fails"
25813
25814         touch $DIR/$tdir/striped_dir1/b
25815         mkdir $DIR/$tdir/striped_dir1/dir_b
25816         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25817                 error "create striped dir under striped dir fails"
25818
25819         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25820                 error "rename dir under different striped dir should fail"
25821
25822         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25823                 error "rename striped dir under diff striped dir should fail"
25824
25825         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25826                 error "rename file under diff striped dirs fails"
25827
25828         rm -rf $DIR/$tdir
25829 }
25830 run_test 300f "check rename cross striped directory"
25831
25832 test_300_check_default_striped_dir()
25833 {
25834         local dirname=$1
25835         local default_count=$2
25836         local default_index=$3
25837         local stripe_count
25838         local stripe_index
25839         local dir_stripe_index
25840         local dir
25841
25842         echo "checking $dirname $default_count $default_index"
25843         $LFS setdirstripe -D -c $default_count -i $default_index \
25844                                 -H all_char $DIR/$tdir/$dirname ||
25845                 error "set default stripe on striped dir error"
25846         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25847         [ $stripe_count -eq $default_count ] ||
25848                 error "expect $default_count get $stripe_count for $dirname"
25849
25850         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25851         [ $stripe_index -eq $default_index ] ||
25852                 error "expect $default_index get $stripe_index for $dirname"
25853
25854         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25855                                                 error "create dirs failed"
25856
25857         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25858         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25859         for dir in $(find $DIR/$tdir/$dirname/*); do
25860                 stripe_count=$($LFS getdirstripe -c $dir)
25861                 (( $stripe_count == $default_count )) ||
25862                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25863                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25864                 error "stripe count $default_count != $stripe_count for $dir"
25865
25866                 stripe_index=$($LFS getdirstripe -i $dir)
25867                 [ $default_index -eq -1 ] ||
25868                         [ $stripe_index -eq $default_index ] ||
25869                         error "$stripe_index != $default_index for $dir"
25870
25871                 #check default stripe
25872                 stripe_count=$($LFS getdirstripe -D -c $dir)
25873                 [ $stripe_count -eq $default_count ] ||
25874                 error "default count $default_count != $stripe_count for $dir"
25875
25876                 stripe_index=$($LFS getdirstripe -D -i $dir)
25877                 [ $stripe_index -eq $default_index ] ||
25878                 error "default index $default_index != $stripe_index for $dir"
25879         done
25880         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25881 }
25882
25883 test_300g() {
25884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25885         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25886                 skip "Need MDS version at least 2.7.55"
25887
25888         local dir
25889         local stripe_count
25890         local stripe_index
25891
25892         mkdir_on_mdt0 $DIR/$tdir
25893         mkdir $DIR/$tdir/normal_dir
25894
25895         #Checking when client cache stripe index
25896         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25897         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25898                 error "create striped_dir failed"
25899
25900         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25901                 error "create dir0 fails"
25902         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25903         [ $stripe_index -eq 0 ] ||
25904                 error "dir0 expect index 0 got $stripe_index"
25905
25906         mkdir $DIR/$tdir/striped_dir/dir1 ||
25907                 error "create dir1 fails"
25908         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25909         [ $stripe_index -eq 1 ] ||
25910                 error "dir1 expect index 1 got $stripe_index"
25911
25912         #check default stripe count/stripe index
25913         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25914         test_300_check_default_striped_dir normal_dir 1 0
25915         test_300_check_default_striped_dir normal_dir -1 1
25916         test_300_check_default_striped_dir normal_dir 2 -1
25917
25918         #delete default stripe information
25919         echo "delete default stripeEA"
25920         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25921                 error "set default stripe on striped dir error"
25922
25923         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25924         for dir in $(find $DIR/$tdir/normal_dir/*); do
25925                 stripe_count=$($LFS getdirstripe -c $dir)
25926                 [ $stripe_count -eq 0 ] ||
25927                         error "expect 1 get $stripe_count for $dir"
25928         done
25929 }
25930 run_test 300g "check default striped directory for normal directory"
25931
25932 test_300h() {
25933         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25934         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25935                 skip "Need MDS version at least 2.7.55"
25936
25937         local dir
25938         local stripe_count
25939
25940         mkdir $DIR/$tdir
25941         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25942                 error "set striped dir error"
25943
25944         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25945         test_300_check_default_striped_dir striped_dir 1 0
25946         test_300_check_default_striped_dir striped_dir -1 1
25947         test_300_check_default_striped_dir striped_dir 2 -1
25948
25949         #delete default stripe information
25950         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25951                 error "set default stripe on striped dir error"
25952
25953         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25954         for dir in $(find $DIR/$tdir/striped_dir/*); do
25955                 stripe_count=$($LFS getdirstripe -c $dir)
25956                 [ $stripe_count -eq 0 ] ||
25957                         error "expect 1 get $stripe_count for $dir"
25958         done
25959 }
25960 run_test 300h "check default striped directory for striped directory"
25961
25962 test_300i() {
25963         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25964         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25965         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25966                 skip "Need MDS version at least 2.7.55"
25967
25968         local stripe_count
25969         local file
25970
25971         mkdir $DIR/$tdir
25972
25973         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25974                 error "set striped dir error"
25975
25976         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25977                 error "create files under striped dir failed"
25978
25979         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25980                 error "set striped hashdir error"
25981
25982         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25983                 error "create dir0 under hash dir failed"
25984         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25985                 error "create dir1 under hash dir failed"
25986         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25987                 error "create dir2 under hash dir failed"
25988
25989         # unfortunately, we need to umount to clear dir layout cache for now
25990         # once we fully implement dir layout, we can drop this
25991         umount_client $MOUNT || error "umount failed"
25992         mount_client $MOUNT || error "mount failed"
25993
25994         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25995         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25996         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25997
25998         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25999                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26000                         error "create crush2 dir $tdir/hashdir/d3 failed"
26001                 $LFS find -H crush2 $DIR/$tdir/hashdir
26002                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26003                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26004
26005                 # mkdir with an invalid hash type (hash=fail_val) from client
26006                 # should be replaced on MDS with a valid (default) hash type
26007                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26008                 $LCTL set_param fail_loc=0x1901 fail_val=99
26009                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26010
26011                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26012                 local expect=$(do_facet mds1 \
26013                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26014                 [[ $hash == $expect ]] ||
26015                         error "d99 hash '$hash' != expected hash '$expect'"
26016         fi
26017
26018         #set the stripe to be unknown hash type on read
26019         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26020         $LCTL set_param fail_loc=0x1901 fail_val=99
26021         for ((i = 0; i < 10; i++)); do
26022                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26023                         error "stat f-$i failed"
26024                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26025         done
26026
26027         touch $DIR/$tdir/striped_dir/f0 &&
26028                 error "create under striped dir with unknown hash should fail"
26029
26030         $LCTL set_param fail_loc=0
26031
26032         umount_client $MOUNT || error "umount failed"
26033         mount_client $MOUNT || error "mount failed"
26034
26035         return 0
26036 }
26037 run_test 300i "client handle unknown hash type striped directory"
26038
26039 test_300j() {
26040         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26042         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26043                 skip "Need MDS version at least 2.7.55"
26044
26045         local stripe_count
26046         local file
26047
26048         mkdir $DIR/$tdir
26049
26050         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26051         $LCTL set_param fail_loc=0x1702
26052         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26053                 error "set striped dir error"
26054
26055         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26056                 error "create files under striped dir failed"
26057
26058         $LCTL set_param fail_loc=0
26059
26060         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26061
26062         return 0
26063 }
26064 run_test 300j "test large update record"
26065
26066 test_300k() {
26067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26069         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26070                 skip "Need MDS version at least 2.7.55"
26071
26072         # this test needs a huge transaction
26073         local kb
26074         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26075              osd*.$FSNAME-MDT0000.kbytestotal")
26076         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26077
26078         local stripe_count
26079         local file
26080
26081         mkdir $DIR/$tdir
26082
26083         #define OBD_FAIL_LARGE_STRIPE   0x1703
26084         $LCTL set_param fail_loc=0x1703
26085         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26086                 error "set striped dir error"
26087         $LCTL set_param fail_loc=0
26088
26089         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26090                 error "getstripeddir fails"
26091         rm -rf $DIR/$tdir/striped_dir ||
26092                 error "unlink striped dir fails"
26093
26094         return 0
26095 }
26096 run_test 300k "test large striped directory"
26097
26098 test_300l() {
26099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26100         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26101         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26102                 skip "Need MDS version at least 2.7.55"
26103
26104         local stripe_index
26105
26106         test_mkdir -p $DIR/$tdir/striped_dir
26107         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26108                         error "chown $RUNAS_ID failed"
26109         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26110                 error "set default striped dir failed"
26111
26112         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26113         $LCTL set_param fail_loc=0x80000158
26114         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26115
26116         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26117         [ $stripe_index -eq 1 ] ||
26118                 error "expect 1 get $stripe_index for $dir"
26119 }
26120 run_test 300l "non-root user to create dir under striped dir with stale layout"
26121
26122 test_300m() {
26123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26124         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26125         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26126                 skip "Need MDS version at least 2.7.55"
26127
26128         mkdir -p $DIR/$tdir/striped_dir
26129         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26130                 error "set default stripes dir error"
26131
26132         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26133
26134         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26135         [ $stripe_count -eq 0 ] ||
26136                         error "expect 0 get $stripe_count for a"
26137
26138         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26139                 error "set default stripes dir error"
26140
26141         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26142
26143         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26144         [ $stripe_count -eq 0 ] ||
26145                         error "expect 0 get $stripe_count for b"
26146
26147         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26148                 error "set default stripes dir error"
26149
26150         mkdir $DIR/$tdir/striped_dir/c &&
26151                 error "default stripe_index is invalid, mkdir c should fails"
26152
26153         rm -rf $DIR/$tdir || error "rmdir fails"
26154 }
26155 run_test 300m "setstriped directory on single MDT FS"
26156
26157 cleanup_300n() {
26158         local list=$(comma_list $(mdts_nodes))
26159
26160         trap 0
26161         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26162 }
26163
26164 test_300n() {
26165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26167         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26168                 skip "Need MDS version at least 2.7.55"
26169         remote_mds_nodsh && skip "remote MDS with nodsh"
26170
26171         local stripe_index
26172         local list=$(comma_list $(mdts_nodes))
26173
26174         trap cleanup_300n RETURN EXIT
26175         mkdir -p $DIR/$tdir
26176         chmod 777 $DIR/$tdir
26177         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26178                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26179                 error "create striped dir succeeds with gid=0"
26180
26181         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26182         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26183                 error "create striped dir fails with gid=-1"
26184
26185         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26186         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26187                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26188                 error "set default striped dir succeeds with gid=0"
26189
26190
26191         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26192         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26193                 error "set default striped dir fails with gid=-1"
26194
26195
26196         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26197         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26198                                         error "create test_dir fails"
26199         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26200                                         error "create test_dir1 fails"
26201         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26202                                         error "create test_dir2 fails"
26203         cleanup_300n
26204 }
26205 run_test 300n "non-root user to create dir under striped dir with default EA"
26206
26207 test_300o() {
26208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26210         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26211                 skip "Need MDS version at least 2.7.55"
26212
26213         local numfree1
26214         local numfree2
26215
26216         mkdir -p $DIR/$tdir
26217
26218         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26219         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26220         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26221                 skip "not enough free inodes $numfree1 $numfree2"
26222         fi
26223
26224         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26225         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26226         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26227                 skip "not enough free space $numfree1 $numfree2"
26228         fi
26229
26230         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26231                 error "setdirstripe fails"
26232
26233         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26234                 error "create dirs fails"
26235
26236         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26237         ls $DIR/$tdir/striped_dir > /dev/null ||
26238                 error "ls striped dir fails"
26239         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26240                 error "unlink big striped dir fails"
26241 }
26242 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26243
26244 test_300p() {
26245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26246         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26247         remote_mds_nodsh && skip "remote MDS with nodsh"
26248
26249         mkdir_on_mdt0 $DIR/$tdir
26250
26251         #define OBD_FAIL_OUT_ENOSPC     0x1704
26252         do_facet mds2 lctl set_param fail_loc=0x80001704
26253         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26254                  && error "create striped directory should fail"
26255
26256         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26257
26258         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26259         true
26260 }
26261 run_test 300p "create striped directory without space"
26262
26263 test_300q() {
26264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26266
26267         local fd=$(free_fd)
26268         local cmd="exec $fd<$tdir"
26269         cd $DIR
26270         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26271         eval $cmd
26272         cmd="exec $fd<&-"
26273         trap "eval $cmd" EXIT
26274         cd $tdir || error "cd $tdir fails"
26275         rmdir  ../$tdir || error "rmdir $tdir fails"
26276         mkdir local_dir && error "create dir succeeds"
26277         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26278         eval $cmd
26279         return 0
26280 }
26281 run_test 300q "create remote directory under orphan directory"
26282
26283 test_300r() {
26284         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26285                 skip "Need MDS version at least 2.7.55" && return
26286         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26287
26288         mkdir $DIR/$tdir
26289
26290         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26291                 error "set striped dir error"
26292
26293         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26294                 error "getstripeddir fails"
26295
26296         local stripe_count
26297         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26298                       awk '/lmv_stripe_count:/ { print $2 }')
26299
26300         [ $MDSCOUNT -ne $stripe_count ] &&
26301                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26302
26303         rm -rf $DIR/$tdir/striped_dir ||
26304                 error "unlink striped dir fails"
26305 }
26306 run_test 300r "test -1 striped directory"
26307
26308 test_300s_helper() {
26309         local count=$1
26310
26311         local stripe_dir=$DIR/$tdir/striped_dir.$count
26312
26313         $LFS mkdir -c $count $stripe_dir ||
26314                 error "lfs mkdir -c error"
26315
26316         $LFS getdirstripe $stripe_dir ||
26317                 error "lfs getdirstripe fails"
26318
26319         local stripe_count
26320         stripe_count=$($LFS getdirstripe $stripe_dir |
26321                       awk '/lmv_stripe_count:/ { print $2 }')
26322
26323         [ $count -ne $stripe_count ] &&
26324                 error_noexit "bad stripe count $stripe_count expected $count"
26325
26326         local dupe_stripes
26327         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26328                 awk '/0x/ {count[$1] += 1}; END {
26329                         for (idx in count) {
26330                                 if (count[idx]>1) {
26331                                         print "index " idx " count " count[idx]
26332                                 }
26333                         }
26334                 }')
26335
26336         if [[ -n "$dupe_stripes" ]] ; then
26337                 lfs getdirstripe $stripe_dir
26338                 error_noexit "Dupe MDT above: $dupe_stripes "
26339         fi
26340
26341         rm -rf $stripe_dir ||
26342                 error_noexit "unlink $stripe_dir fails"
26343 }
26344
26345 test_300s() {
26346         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26347                 skip "Need MDS version at least 2.7.55" && return
26348         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26349
26350         mkdir $DIR/$tdir
26351         for count in $(seq 2 $MDSCOUNT); do
26352                 test_300s_helper $count
26353         done
26354 }
26355 run_test 300s "test lfs mkdir -c without -i"
26356
26357 test_300t() {
26358         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26359                 skip "need MDS 2.14.55 or later"
26360         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26361
26362         local testdir="$DIR/$tdir/striped_dir"
26363         local dir1=$testdir/dir1
26364         local dir2=$testdir/dir2
26365
26366         mkdir -p $testdir
26367
26368         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26369                 error "failed to set default stripe count for $testdir"
26370
26371         mkdir $dir1
26372         local stripe_count=$($LFS getdirstripe -c $dir1)
26373
26374         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26375
26376         local max_count=$((MDSCOUNT - 1))
26377         local mdts=$(comma_list $(mdts_nodes))
26378
26379         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26380         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26381
26382         mkdir $dir2
26383         stripe_count=$($LFS getdirstripe -c $dir2)
26384
26385         (( $stripe_count == $max_count )) || error "wrong stripe count"
26386 }
26387 run_test 300t "test max_mdt_stripecount"
26388
26389 prepare_remote_file() {
26390         mkdir $DIR/$tdir/src_dir ||
26391                 error "create remote source failed"
26392
26393         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26394                  error "cp to remote source failed"
26395         touch $DIR/$tdir/src_dir/a
26396
26397         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26398                 error "create remote target dir failed"
26399
26400         touch $DIR/$tdir/tgt_dir/b
26401
26402         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26403                 error "rename dir cross MDT failed!"
26404
26405         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26406                 error "src_child still exists after rename"
26407
26408         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26409                 error "missing file(a) after rename"
26410
26411         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26412                 error "diff after rename"
26413 }
26414
26415 test_310a() {
26416         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26418
26419         local remote_file=$DIR/$tdir/tgt_dir/b
26420
26421         mkdir -p $DIR/$tdir
26422
26423         prepare_remote_file || error "prepare remote file failed"
26424
26425         #open-unlink file
26426         $OPENUNLINK $remote_file $remote_file ||
26427                 error "openunlink $remote_file failed"
26428         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26429 }
26430 run_test 310a "open unlink remote file"
26431
26432 test_310b() {
26433         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26435
26436         local remote_file=$DIR/$tdir/tgt_dir/b
26437
26438         mkdir -p $DIR/$tdir
26439
26440         prepare_remote_file || error "prepare remote file failed"
26441
26442         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26443         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26444         $CHECKSTAT -t file $remote_file || error "check file failed"
26445 }
26446 run_test 310b "unlink remote file with multiple links while open"
26447
26448 test_310c() {
26449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26450         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26451
26452         local remote_file=$DIR/$tdir/tgt_dir/b
26453
26454         mkdir -p $DIR/$tdir
26455
26456         prepare_remote_file || error "prepare remote file failed"
26457
26458         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26459         multiop_bg_pause $remote_file O_uc ||
26460                         error "mulitop failed for remote file"
26461         MULTIPID=$!
26462         $MULTIOP $DIR/$tfile Ouc
26463         kill -USR1 $MULTIPID
26464         wait $MULTIPID
26465 }
26466 run_test 310c "open-unlink remote file with multiple links"
26467
26468 #LU-4825
26469 test_311() {
26470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26471         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26472         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26473                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26474         remote_mds_nodsh && skip "remote MDS with nodsh"
26475
26476         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26477         local mdts=$(comma_list $(mdts_nodes))
26478
26479         mkdir -p $DIR/$tdir
26480         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26481         createmany -o $DIR/$tdir/$tfile. 1000
26482
26483         # statfs data is not real time, let's just calculate it
26484         old_iused=$((old_iused + 1000))
26485
26486         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26487                         osp.*OST0000*MDT0000.create_count")
26488         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26489                                 osp.*OST0000*MDT0000.max_create_count")
26490         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26491
26492         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26493         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26494         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26495
26496         unlinkmany $DIR/$tdir/$tfile. 1000
26497
26498         do_nodes $mdts "$LCTL set_param -n \
26499                         osp.*OST0000*.max_create_count=$max_count"
26500         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26501                 do_nodes $mdts "$LCTL set_param -n \
26502                                 osp.*OST0000*.create_count=$count"
26503         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26504                         grep "=0" && error "create_count is zero"
26505
26506         local new_iused
26507         for i in $(seq 120); do
26508                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26509                 # system may be too busy to destroy all objs in time, use
26510                 # a somewhat small value to not fail autotest
26511                 [ $((old_iused - new_iused)) -gt 400 ] && break
26512                 sleep 1
26513         done
26514
26515         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26516         [ $((old_iused - new_iused)) -gt 400 ] ||
26517                 error "objs not destroyed after unlink"
26518 }
26519 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26520
26521 zfs_get_objid()
26522 {
26523         local ost=$1
26524         local tf=$2
26525         local fid=($($LFS getstripe $tf | grep 0x))
26526         local seq=${fid[3]#0x}
26527         local objid=${fid[1]}
26528
26529         local vdevdir=$(dirname $(facet_vdevice $ost))
26530         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26531         local zfs_zapid=$(do_facet $ost $cmd |
26532                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26533                           awk '/Object/{getline; print $1}')
26534         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26535                           awk "/$objid = /"'{printf $3}')
26536
26537         echo $zfs_objid
26538 }
26539
26540 zfs_object_blksz() {
26541         local ost=$1
26542         local objid=$2
26543
26544         local vdevdir=$(dirname $(facet_vdevice $ost))
26545         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26546         local blksz=$(do_facet $ost $cmd $objid |
26547                       awk '/dblk/{getline; printf $4}')
26548
26549         case "${blksz: -1}" in
26550                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26551                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26552                 *) ;;
26553         esac
26554
26555         echo $blksz
26556 }
26557
26558 test_312() { # LU-4856
26559         remote_ost_nodsh && skip "remote OST with nodsh"
26560         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26561
26562         local max_blksz=$(do_facet ost1 \
26563                           $ZFS get -p recordsize $(facet_device ost1) |
26564                           awk '!/VALUE/{print $3}')
26565         local tf=$DIR/$tfile
26566
26567         $LFS setstripe -c1 $tf
26568         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26569
26570         # Get ZFS object id
26571         local zfs_objid=$(zfs_get_objid $facet $tf)
26572         # block size change by sequential overwrite
26573         local bs
26574
26575         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26576                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26577
26578                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26579                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26580         done
26581         rm -f $tf
26582
26583         $LFS setstripe -c1 $tf
26584         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26585
26586         # block size change by sequential append write
26587         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26588         zfs_objid=$(zfs_get_objid $facet $tf)
26589         local count
26590
26591         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26592                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26593                         oflag=sync conv=notrunc
26594
26595                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26596                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26597                         error "blksz error, actual $blksz, " \
26598                                 "expected: 2 * $count * $PAGE_SIZE"
26599         done
26600         rm -f $tf
26601
26602         # random write
26603         $LFS setstripe -c1 $tf
26604         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26605         zfs_objid=$(zfs_get_objid $facet $tf)
26606
26607         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26608         blksz=$(zfs_object_blksz $facet $zfs_objid)
26609         (( blksz == PAGE_SIZE )) ||
26610                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26611
26612         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26613         blksz=$(zfs_object_blksz $facet $zfs_objid)
26614         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26615
26616         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26617         blksz=$(zfs_object_blksz $facet $zfs_objid)
26618         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26619 }
26620 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26621
26622 test_313() {
26623         remote_ost_nodsh && skip "remote OST with nodsh"
26624
26625         local file=$DIR/$tfile
26626
26627         rm -f $file
26628         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26629
26630         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26631         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26632         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26633                 error "write should failed"
26634         do_facet ost1 "$LCTL set_param fail_loc=0"
26635         rm -f $file
26636 }
26637 run_test 313 "io should fail after last_rcvd update fail"
26638
26639 test_314() {
26640         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26641
26642         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26643         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26644         rm -f $DIR/$tfile
26645         wait_delete_completed
26646         do_facet ost1 "$LCTL set_param fail_loc=0"
26647 }
26648 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26649
26650 test_315() { # LU-618
26651         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26652
26653         local file=$DIR/$tfile
26654         rm -f $file
26655
26656         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26657                 error "multiop file write failed"
26658         $MULTIOP $file oO_RDONLY:r4063232_c &
26659         PID=$!
26660
26661         sleep 2
26662
26663         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26664         kill -USR1 $PID
26665
26666         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26667         rm -f $file
26668 }
26669 run_test 315 "read should be accounted"
26670
26671 test_316() {
26672         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26673         large_xattr_enabled || skip "ea_inode feature disabled"
26674
26675         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26676         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26677         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26678         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26679
26680         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26681 }
26682 run_test 316 "lfs migrate of file with large_xattr enabled"
26683
26684 test_317() {
26685         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26686                 skip "Need MDS version at least 2.11.53"
26687         if [ "$ost1_FSTYPE" == "zfs" ]; then
26688                 skip "LU-10370: no implementation for ZFS"
26689         fi
26690
26691         local trunc_sz
26692         local grant_blk_size
26693
26694         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26695                         awk '/grant_block_size:/ { print $2; exit; }')
26696         #
26697         # Create File of size 5M. Truncate it to below size's and verify
26698         # blocks count.
26699         #
26700         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26701                 error "Create file $DIR/$tfile failed"
26702         stack_trap "rm -f $DIR/$tfile" EXIT
26703
26704         for trunc_sz in 2097152 4097 4000 509 0; do
26705                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26706                         error "truncate $tfile to $trunc_sz failed"
26707                 local sz=$(stat --format=%s $DIR/$tfile)
26708                 local blk=$(stat --format=%b $DIR/$tfile)
26709                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26710                                      grant_blk_size) * 8))
26711
26712                 if [[ $blk -ne $trunc_blk ]]; then
26713                         $(which stat) $DIR/$tfile
26714                         error "Expected Block $trunc_blk got $blk for $tfile"
26715                 fi
26716
26717                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26718                         error "Expected Size $trunc_sz got $sz for $tfile"
26719         done
26720
26721         #
26722         # sparse file test
26723         # Create file with a hole and write actual 65536 bytes which aligned
26724         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26725         #
26726         local bs=65536
26727         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26728                 error "Create file : $DIR/$tfile"
26729
26730         #
26731         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26732         # blocks. The block count must drop to 8.
26733         #
26734         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26735                 ((bs - grant_blk_size) + 1)))
26736         $TRUNCATE $DIR/$tfile $trunc_sz ||
26737                 error "truncate $tfile to $trunc_sz failed"
26738
26739         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26740         sz=$(stat --format=%s $DIR/$tfile)
26741         blk=$(stat --format=%b $DIR/$tfile)
26742
26743         if [[ $blk -ne $trunc_bsz ]]; then
26744                 $(which stat) $DIR/$tfile
26745                 error "Expected Block $trunc_bsz got $blk for $tfile"
26746         fi
26747
26748         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26749                 error "Expected Size $trunc_sz got $sz for $tfile"
26750 }
26751 run_test 317 "Verify blocks get correctly update after truncate"
26752
26753 test_318() {
26754         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26755         local old_max_active=$($LCTL get_param -n \
26756                             ${llite_name}.max_read_ahead_async_active \
26757                             2>/dev/null)
26758
26759         $LCTL set_param llite.*.max_read_ahead_async_active=256
26760         local max_active=$($LCTL get_param -n \
26761                            ${llite_name}.max_read_ahead_async_active \
26762                            2>/dev/null)
26763         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26764
26765         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26766                 error "set max_read_ahead_async_active should succeed"
26767
26768         $LCTL set_param llite.*.max_read_ahead_async_active=512
26769         max_active=$($LCTL get_param -n \
26770                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26771         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26772
26773         # restore @max_active
26774         [ $old_max_active -ne 0 ] && $LCTL set_param \
26775                 llite.*.max_read_ahead_async_active=$old_max_active
26776
26777         local old_threshold=$($LCTL get_param -n \
26778                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26779         local max_per_file_mb=$($LCTL get_param -n \
26780                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26781
26782         local invalid=$(($max_per_file_mb + 1))
26783         $LCTL set_param \
26784                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26785                         && error "set $invalid should fail"
26786
26787         local valid=$(($invalid - 1))
26788         $LCTL set_param \
26789                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26790                         error "set $valid should succeed"
26791         local threshold=$($LCTL get_param -n \
26792                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26793         [ $threshold -eq $valid ] || error \
26794                 "expect threshold $valid got $threshold"
26795         $LCTL set_param \
26796                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26797 }
26798 run_test 318 "Verify async readahead tunables"
26799
26800 test_319() {
26801         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26802
26803         local before=$(date +%s)
26804         local evict
26805         local mdir=$DIR/$tdir
26806         local file=$mdir/xxx
26807
26808         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26809         touch $file
26810
26811 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26812         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26813         $LFS migrate -m1 $mdir &
26814
26815         sleep 1
26816         dd if=$file of=/dev/null
26817         wait
26818         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26819           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26820
26821         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26822 }
26823 run_test 319 "lost lease lock on migrate error"
26824
26825 test_360() {
26826         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
26827                 skip "Need OST version at least 2.15.58.96"
26828         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
26829
26830         check_set_fallocate_or_skip
26831         local param="osd-ldiskfs.delayed_unlink_mb"
26832         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
26833
26834         do_facet ost1 "$LCTL set_param $param=1MiB"
26835         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
26836
26837         mkdir $DIR/$tdir/
26838         do_facet ost1 $LCTL set_param debug=+inode
26839         do_facet ost1 $LCTL clear
26840         local files=100
26841
26842         for ((i = 0; i < $files; i++)); do
26843                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
26844                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
26845         done
26846         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
26847
26848         for ((i = 0; i < $files; i++)); do
26849                 unlink $DIR/$tdir/$tfile.$i ||
26850                         error "unlink $DIR/$tdir/$tfile.$i failed"
26851         done
26852
26853         local count=0
26854         local loop
26855
26856         for (( loop = 0; loop < 30 && count < min; loop++)); do
26857                 sleep 1
26858                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
26859                 echo "Count[$loop]: $count"
26860         done
26861         (( count >= min )) || error "$count < $min delayed iput after $loop s"
26862 }
26863 run_test 360 "ldiskfs unlink in a separate thread"
26864
26865 test_398a() { # LU-4198
26866         local ost1_imp=$(get_osc_import_name client ost1)
26867         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26868                          cut -d'.' -f2)
26869
26870         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26871         stack_trap "rm -f $DIR/$tfile"
26872         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26873
26874         # request a new lock on client
26875         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26876
26877         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26878         local lock_count=$($LCTL get_param -n \
26879                            ldlm.namespaces.$imp_name.lru_size)
26880         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26881
26882         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26883
26884         # no lock cached, should use lockless DIO and not enqueue new lock
26885         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26886         lock_count=$($LCTL get_param -n \
26887                      ldlm.namespaces.$imp_name.lru_size)
26888         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26889
26890         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26891
26892         # no lock cached, should use locked DIO append
26893         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26894                 conv=notrunc || error "DIO append failed"
26895         lock_count=$($LCTL get_param -n \
26896                      ldlm.namespaces.$imp_name.lru_size)
26897         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26898 }
26899 run_test 398a "direct IO should cancel lock otherwise lockless"
26900
26901 test_398b() { # LU-4198
26902         local before=$(date +%s)
26903         local njobs=4
26904         local size=48
26905
26906         which fio || skip_env "no fio installed"
26907         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26908         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26909
26910         # Single page, multiple pages, stripe size, 4*stripe size
26911         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26912                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26913                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26914                         --numjobs=$njobs --fallocate=none \
26915                         --iodepth=16 --allow_file_create=0 \
26916                         --size=$((size/njobs))M \
26917                         --filename=$DIR/$tfile &
26918                 bg_pid=$!
26919
26920                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26921                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26922                         --numjobs=$njobs --fallocate=none \
26923                         --iodepth=16 --allow_file_create=0 \
26924                         --size=$((size/njobs))M \
26925                         --filename=$DIR/$tfile || true
26926                 wait $bg_pid
26927         done
26928
26929         evict=$(do_facet client $LCTL get_param \
26930                 osc.$FSNAME-OST*-osc-*/state |
26931             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26932
26933         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26934                 (do_facet client $LCTL get_param \
26935                         osc.$FSNAME-OST*-osc-*/state;
26936                     error "eviction happened: $evict before:$before")
26937
26938         rm -f $DIR/$tfile
26939 }
26940 run_test 398b "DIO and buffer IO race"
26941
26942 test_398c() { # LU-4198
26943         local ost1_imp=$(get_osc_import_name client ost1)
26944         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26945                          cut -d'.' -f2)
26946
26947         which fio || skip_env "no fio installed"
26948
26949         saved_debug=$($LCTL get_param -n debug)
26950         $LCTL set_param debug=0
26951
26952         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26953         ((size /= 1024)) # by megabytes
26954         ((size /= 2)) # write half of the OST at most
26955         [ $size -gt 40 ] && size=40 #reduce test time anyway
26956
26957         $LFS setstripe -c 1 $DIR/$tfile
26958
26959         # it seems like ldiskfs reserves more space than necessary if the
26960         # writing blocks are not mapped, so it extends the file firstly
26961         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26962         cancel_lru_locks osc
26963
26964         # clear and verify rpc_stats later
26965         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26966
26967         local njobs=4
26968         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26969         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26970                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26971                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26972                 --filename=$DIR/$tfile
26973         [ $? -eq 0 ] || error "fio write error"
26974
26975         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26976                 error "Locks were requested while doing AIO"
26977
26978         # get the percentage of 1-page I/O
26979         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26980                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26981                 awk '{print $7}')
26982         (( $pct <= 50 )) || {
26983                 $LCTL get_param osc.${imp_name}.rpc_stats
26984                 error "$pct% of I/O are 1-page"
26985         }
26986
26987         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26988         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26989                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26990                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26991                 --filename=$DIR/$tfile
26992         [ $? -eq 0 ] || error "fio mixed read write error"
26993
26994         echo "AIO with large block size ${size}M"
26995         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26996                 --numjobs=1 --fallocate=none --ioengine=libaio \
26997                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26998                 --filename=$DIR/$tfile
26999         [ $? -eq 0 ] || error "fio large block size failed"
27000
27001         rm -f $DIR/$tfile
27002         $LCTL set_param debug="$saved_debug"
27003 }
27004 run_test 398c "run fio to test AIO"
27005
27006 test_398d() { #  LU-13846
27007         which aiocp || skip_env "no aiocp installed"
27008         local aio_file=$DIR/$tfile.aio
27009
27010         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27011
27012         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27013         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27014         stack_trap "rm -f $DIR/$tfile $aio_file"
27015
27016         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27017
27018         # test memory unaligned aio
27019         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27020                 error "unaligned aio failed"
27021         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27022
27023         rm -f $DIR/$tfile $aio_file
27024 }
27025 run_test 398d "run aiocp to verify block size > stripe size"
27026
27027 test_398e() {
27028         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27029         touch $DIR/$tfile.new
27030         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27031 }
27032 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27033
27034 test_398f() { #  LU-14687
27035         which aiocp || skip_env "no aiocp installed"
27036         local aio_file=$DIR/$tfile.aio
27037
27038         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27039
27040         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27041         stack_trap "rm -f $DIR/$tfile $aio_file"
27042
27043         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27044         $LCTL set_param fail_loc=0x1418
27045         # make sure we don't crash and fail properly
27046         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27047                 error "aio with page allocation failure succeeded"
27048         $LCTL set_param fail_loc=0
27049         diff $DIR/$tfile $aio_file
27050         [[ $? != 0 ]] || error "no diff after failed aiocp"
27051 }
27052 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27053
27054 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27055 # stripe and i/o size must be > stripe size
27056 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27057 # single RPC in flight.  This test shows async DIO submission is working by
27058 # showing multiple RPCs in flight.
27059 test_398g() { #  LU-13798
27060         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27061
27062         # We need to do some i/o first to acquire enough grant to put our RPCs
27063         # in flight; otherwise a new connection may not have enough grant
27064         # available
27065         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27066                 error "parallel dio failed"
27067         stack_trap "rm -f $DIR/$tfile"
27068
27069         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27070         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27071         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27072         stack_trap "$LCTL set_param -n $pages_per_rpc"
27073
27074         # Recreate file so it's empty
27075         rm -f $DIR/$tfile
27076         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27077         #Pause rpc completion to guarantee we see multiple rpcs in flight
27078         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27079         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27080         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27081
27082         # Clear rpc stats
27083         $LCTL set_param osc.*.rpc_stats=c
27084
27085         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27086                 error "parallel dio failed"
27087         stack_trap "rm -f $DIR/$tfile"
27088
27089         $LCTL get_param osc.*-OST0000-*.rpc_stats
27090         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27091                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27092                 grep "8:" | awk '{print $8}')
27093         # We look at the "8 rpcs in flight" field, and verify A) it is present
27094         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27095         # as expected for an 8M DIO to a file with 1M stripes.
27096         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
27097
27098         # Verify turning off parallel dio works as expected
27099         # Clear rpc stats
27100         $LCTL set_param osc.*.rpc_stats=c
27101         $LCTL set_param llite.*.parallel_dio=0
27102         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27103
27104         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27105                 error "dio with parallel dio disabled failed"
27106
27107         # Ideally, we would see only one RPC in flight here, but there is an
27108         # unavoidable race between i/o completion and RPC in flight counting,
27109         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27110         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27111         # So instead we just verify it's always < 8.
27112         $LCTL get_param osc.*-OST0000-*.rpc_stats
27113         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27114                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27115                 grep '^$' -B1 | grep . | awk '{print $1}')
27116         [ $ret != "8:" ] ||
27117                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27118 }
27119 run_test 398g "verify parallel dio async RPC submission"
27120
27121 test_398h() { #  LU-13798
27122         local dio_file=$DIR/$tfile.dio
27123
27124         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27125
27126         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27127         stack_trap "rm -f $DIR/$tfile $dio_file"
27128
27129         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27130                 error "parallel dio failed"
27131         diff $DIR/$tfile $dio_file
27132         [[ $? == 0 ]] || error "file diff after aiocp"
27133 }
27134 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27135
27136 test_398i() { #  LU-13798
27137         local dio_file=$DIR/$tfile.dio
27138
27139         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27140
27141         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27142         stack_trap "rm -f $DIR/$tfile $dio_file"
27143
27144         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27145         $LCTL set_param fail_loc=0x1418
27146         # make sure we don't crash and fail properly
27147         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27148                 error "parallel dio page allocation failure succeeded"
27149         diff $DIR/$tfile $dio_file
27150         [[ $? != 0 ]] || error "no diff after failed aiocp"
27151 }
27152 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27153
27154 test_398j() { #  LU-13798
27155         # Stripe size > RPC size but less than i/o size tests split across
27156         # stripes and RPCs for individual i/o op
27157         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27158
27159         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27160         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27161         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27162         stack_trap "$LCTL set_param -n $pages_per_rpc"
27163
27164         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27165                 error "parallel dio write failed"
27166         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27167
27168         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27169                 error "parallel dio read failed"
27170         diff $DIR/$tfile $DIR/$tfile.2
27171         [[ $? == 0 ]] || error "file diff after parallel dio read"
27172 }
27173 run_test 398j "test parallel dio where stripe size > rpc_size"
27174
27175 test_398k() { #  LU-13798
27176         wait_delete_completed
27177         wait_mds_ost_sync
27178
27179         # 4 stripe file; we will cause out of space on OST0
27180         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27181
27182         # Fill OST0 (if it's not too large)
27183         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27184                    head -n1)
27185         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27186                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27187         fi
27188         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27189         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27190                 error "dd should fill OST0"
27191         stack_trap "rm -f $DIR/$tfile.1"
27192
27193         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27194         err=$?
27195
27196         ls -la $DIR/$tfile
27197         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27198                 error "file is not 0 bytes in size"
27199
27200         # dd above should not succeed, but don't error until here so we can
27201         # get debug info above
27202         [[ $err != 0 ]] ||
27203                 error "parallel dio write with enospc succeeded"
27204         stack_trap "rm -f $DIR/$tfile"
27205 }
27206 run_test 398k "test enospc on first stripe"
27207
27208 test_398l() { #  LU-13798
27209         wait_delete_completed
27210         wait_mds_ost_sync
27211
27212         # 4 stripe file; we will cause out of space on OST0
27213         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27214         # happens on the second i/o chunk we issue
27215         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27216
27217         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27218         stack_trap "rm -f $DIR/$tfile"
27219
27220         # Fill OST0 (if it's not too large)
27221         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27222                    head -n1)
27223         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27224                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27225         fi
27226         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27227         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27228                 error "dd should fill OST0"
27229         stack_trap "rm -f $DIR/$tfile.1"
27230
27231         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27232         err=$?
27233         stack_trap "rm -f $DIR/$tfile.2"
27234
27235         # Check that short write completed as expected
27236         ls -la $DIR/$tfile.2
27237         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27238                 error "file is not 1M in size"
27239
27240         # dd above should not succeed, but don't error until here so we can
27241         # get debug info above
27242         [[ $err != 0 ]] ||
27243                 error "parallel dio write with enospc succeeded"
27244
27245         # Truncate source file to same length as output file and diff them
27246         $TRUNCATE $DIR/$tfile 1048576
27247         diff $DIR/$tfile $DIR/$tfile.2
27248         [[ $? == 0 ]] || error "data incorrect after short write"
27249 }
27250 run_test 398l "test enospc on intermediate stripe/RPC"
27251
27252 test_398m() { #  LU-13798
27253         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27254
27255         # Set up failure on OST0, the first stripe:
27256         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27257         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27258         # OST0 is on ost1, OST1 is on ost2.
27259         # So this fail_val specifies OST0
27260         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27261         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27262
27263         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27264                 error "parallel dio write with failure on first stripe succeeded"
27265         stack_trap "rm -f $DIR/$tfile"
27266         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27267
27268         # Place data in file for read
27269         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27270                 error "parallel dio write failed"
27271
27272         # Fail read on OST0, first stripe
27273         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27274         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27275         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27276                 error "parallel dio read with error on first stripe succeeded"
27277         rm -f $DIR/$tfile.2
27278         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27279
27280         # Switch to testing on OST1, second stripe
27281         # Clear file contents, maintain striping
27282         echo > $DIR/$tfile
27283         # Set up failure on OST1, second stripe:
27284         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27285         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27286
27287         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27288                 error "parallel dio write with failure on second stripe succeeded"
27289         stack_trap "rm -f $DIR/$tfile"
27290         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27291
27292         # Place data in file for read
27293         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27294                 error "parallel dio write failed"
27295
27296         # Fail read on OST1, second stripe
27297         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27298         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27299         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27300                 error "parallel dio read with error on second stripe succeeded"
27301         rm -f $DIR/$tfile.2
27302         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27303 }
27304 run_test 398m "test RPC failures with parallel dio"
27305
27306 # Parallel submission of DIO should not cause problems for append, but it's
27307 # important to verify.
27308 test_398n() { #  LU-13798
27309         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27310
27311         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27312                 error "dd to create source file failed"
27313         stack_trap "rm -f $DIR/$tfile"
27314
27315         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27316                 error "parallel dio write with failure on second stripe succeeded"
27317         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27318         diff $DIR/$tfile $DIR/$tfile.1
27319         [[ $? == 0 ]] || error "data incorrect after append"
27320
27321 }
27322 run_test 398n "test append with parallel DIO"
27323
27324 test_398o() {
27325         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27326 }
27327 run_test 398o "right kms with DIO"
27328
27329 test_398p()
27330 {
27331         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27332         which aiocp || skip_env "no aiocp installed"
27333
27334         local stripe_size=$((1024 * 1024)) #1 MiB
27335         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27336         local file_size=$((25 * stripe_size))
27337
27338         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27339         stack_trap "rm -f $DIR/$tfile*"
27340         # Just a bit bigger than the largest size in the test set below
27341         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27342                 error "buffered i/o to create file failed"
27343
27344         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27345                 $((stripe_size * 4)); do
27346
27347                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27348
27349                 echo "bs: $bs, file_size $file_size"
27350                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27351                         $DIR/$tfile.1 $DIR/$tfile.2 &
27352                 pid_dio1=$!
27353                 # Buffered I/O with similar but not the same block size
27354                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27355                         conv=notrunc &
27356                 pid_bio2=$!
27357                 wait $pid_dio1
27358                 rc1=$?
27359                 wait $pid_bio2
27360                 rc2=$?
27361                 if (( rc1 != 0 )); then
27362                         error "aio copy 1 w/bsize $bs failed: $rc1"
27363                 fi
27364                 if (( rc2 != 0 )); then
27365                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27366                 fi
27367
27368                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27369                         error "size incorrect"
27370                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27371                         error "files differ, bsize $bs"
27372                 rm -f $DIR/$tfile.2
27373         done
27374 }
27375 run_test 398p "race aio with buffered i/o"
27376
27377 test_398q()
27378 {
27379         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27380
27381         local stripe_size=$((1024 * 1024)) #1 MiB
27382         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27383         local file_size=$((25 * stripe_size))
27384
27385         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27386         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27387
27388         # Just a bit bigger than the largest size in the test set below
27389         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27390                 error "buffered i/o to create file failed"
27391
27392         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27393                 $((stripe_size * 4)); do
27394
27395                 echo "bs: $bs, file_size $file_size"
27396                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27397                         conv=notrunc oflag=direct iflag=direct &
27398                 pid_dio1=$!
27399                 # Buffered I/O with similar but not the same block size
27400                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27401                         conv=notrunc &
27402                 pid_bio2=$!
27403                 wait $pid_dio1
27404                 rc1=$?
27405                 wait $pid_bio2
27406                 rc2=$?
27407                 if (( rc1 != 0 )); then
27408                         error "dio copy 1 w/bsize $bs failed: $rc1"
27409                 fi
27410                 if (( rc2 != 0 )); then
27411                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27412                 fi
27413
27414                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27415                         error "size incorrect"
27416                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27417                         error "files differ, bsize $bs"
27418         done
27419
27420         rm -f $DIR/$tfile*
27421 }
27422 run_test 398q "race dio with buffered i/o"
27423
27424 test_fake_rw() {
27425         local read_write=$1
27426         if [ "$read_write" = "write" ]; then
27427                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27428         elif [ "$read_write" = "read" ]; then
27429                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27430         else
27431                 error "argument error"
27432         fi
27433
27434         # turn off debug for performance testing
27435         local saved_debug=$($LCTL get_param -n debug)
27436         $LCTL set_param debug=0
27437
27438         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27439
27440         # get ost1 size - $FSNAME-OST0000
27441         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27442         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27443         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27444
27445         if [ "$read_write" = "read" ]; then
27446                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27447         fi
27448
27449         local start_time=$(date +%s.%N)
27450         $dd_cmd bs=1M count=$blocks oflag=sync ||
27451                 error "real dd $read_write error"
27452         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27453
27454         if [ "$read_write" = "write" ]; then
27455                 rm -f $DIR/$tfile
27456         fi
27457
27458         # define OBD_FAIL_OST_FAKE_RW           0x238
27459         do_facet ost1 $LCTL set_param fail_loc=0x238
27460
27461         local start_time=$(date +%s.%N)
27462         $dd_cmd bs=1M count=$blocks oflag=sync ||
27463                 error "fake dd $read_write error"
27464         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27465
27466         if [ "$read_write" = "write" ]; then
27467                 # verify file size
27468                 cancel_lru_locks osc
27469                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27470                         error "$tfile size not $blocks MB"
27471         fi
27472         do_facet ost1 $LCTL set_param fail_loc=0
27473
27474         echo "fake $read_write $duration_fake vs. normal $read_write" \
27475                 "$duration in seconds"
27476         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27477                 error_not_in_vm "fake write is slower"
27478
27479         $LCTL set_param -n debug="$saved_debug"
27480         rm -f $DIR/$tfile
27481 }
27482 test_399a() { # LU-7655 for OST fake write
27483         remote_ost_nodsh && skip "remote OST with nodsh"
27484
27485         test_fake_rw write
27486 }
27487 run_test 399a "fake write should not be slower than normal write"
27488
27489 test_399b() { # LU-8726 for OST fake read
27490         remote_ost_nodsh && skip "remote OST with nodsh"
27491         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27492                 skip_env "ldiskfs only test"
27493         fi
27494
27495         test_fake_rw read
27496 }
27497 run_test 399b "fake read should not be slower than normal read"
27498
27499 test_400a() { # LU-1606, was conf-sanity test_74
27500         if ! which $CC > /dev/null 2>&1; then
27501                 skip_env "$CC is not installed"
27502         fi
27503
27504         local extra_flags=''
27505         local out=$TMP/$tfile
27506         local prefix=/usr/include/lustre
27507         local prog
27508
27509         # Oleg removes .c files in his test rig so test if any c files exist
27510         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27511                 skip_env "Needed .c test files are missing"
27512
27513         if ! [[ -d $prefix ]]; then
27514                 # Assume we're running in tree and fixup the include path.
27515                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27516                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27517                 extra_flags+=" -L$LUSTRE/utils/.libs"
27518         fi
27519
27520         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27521                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27522                         error "client api broken"
27523         done
27524         rm -f $out
27525 }
27526 run_test 400a "Lustre client api program can compile and link"
27527
27528 test_400b() { # LU-1606, LU-5011
27529         local header
27530         local out=$TMP/$tfile
27531         local prefix=/usr/include/linux/lustre
27532
27533         # We use a hard coded prefix so that this test will not fail
27534         # when run in tree. There are headers in lustre/include/lustre/
27535         # that are not packaged (like lustre_idl.h) and have more
27536         # complicated include dependencies (like config.h and lnet/types.h).
27537         # Since this test about correct packaging we just skip them when
27538         # they don't exist (see below) rather than try to fixup cppflags.
27539
27540         if ! which $CC > /dev/null 2>&1; then
27541                 skip_env "$CC is not installed"
27542         fi
27543
27544         for header in $prefix/*.h; do
27545                 if ! [[ -f "$header" ]]; then
27546                         continue
27547                 fi
27548
27549                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27550                         continue # lustre_ioctl.h is internal header
27551                 fi
27552
27553                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27554                         error "cannot compile '$header'"
27555         done
27556         rm -f $out
27557 }
27558 run_test 400b "packaged headers can be compiled"
27559
27560 test_401a() { #LU-7437
27561         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27562         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27563
27564         #count the number of parameters by "list_param -R"
27565         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27566         #count the number of parameters by listing proc files
27567         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27568         echo "proc_dirs='$proc_dirs'"
27569         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27570         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27571                       sort -u | wc -l)
27572
27573         [ $params -eq $procs ] ||
27574                 error "found $params parameters vs. $procs proc files"
27575
27576         # test the list_param -D option only returns directories
27577         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27578         #count the number of parameters by listing proc directories
27579         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27580                 sort -u | wc -l)
27581
27582         [ $params -eq $procs ] ||
27583                 error "found $params parameters vs. $procs proc files"
27584 }
27585 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27586
27587 test_401b() {
27588         # jobid_var may not allow arbitrary values, so use jobid_name
27589         # if available
27590         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27591                 local testname=jobid_name tmp='testing%p'
27592         else
27593                 local testname=jobid_var tmp=testing
27594         fi
27595
27596         local save=$($LCTL get_param -n $testname)
27597
27598         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27599                 error "no error returned when setting bad parameters"
27600
27601         local jobid_new=$($LCTL get_param -n foe $testname baz)
27602         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27603
27604         $LCTL set_param -n fog=bam $testname=$save bat=fog
27605         local jobid_old=$($LCTL get_param -n foe $testname bag)
27606         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27607 }
27608 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27609
27610 test_401c() {
27611         # jobid_var may not allow arbitrary values, so use jobid_name
27612         # if available
27613         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27614                 local testname=jobid_name
27615         else
27616                 local testname=jobid_var
27617         fi
27618
27619         local jobid_var_old=$($LCTL get_param -n $testname)
27620         local jobid_var_new
27621
27622         $LCTL set_param $testname= &&
27623                 error "no error returned for 'set_param a='"
27624
27625         jobid_var_new=$($LCTL get_param -n $testname)
27626         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27627                 error "$testname was changed by setting without value"
27628
27629         $LCTL set_param $testname &&
27630                 error "no error returned for 'set_param a'"
27631
27632         jobid_var_new=$($LCTL get_param -n $testname)
27633         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27634                 error "$testname was changed by setting without value"
27635 }
27636 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27637
27638 test_401d() {
27639         # jobid_var may not allow arbitrary values, so use jobid_name
27640         # if available
27641         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27642                 local testname=jobid_name new_value='foo=bar%p'
27643         else
27644                 local testname=jobid_var new_valuie=foo=bar
27645         fi
27646
27647         local jobid_var_old=$($LCTL get_param -n $testname)
27648         local jobid_var_new
27649
27650         $LCTL set_param $testname=$new_value ||
27651                 error "'set_param a=b' did not accept a value containing '='"
27652
27653         jobid_var_new=$($LCTL get_param -n $testname)
27654         [[ "$jobid_var_new" == "$new_value" ]] ||
27655                 error "'set_param a=b' failed on a value containing '='"
27656
27657         # Reset the $testname to test the other format
27658         $LCTL set_param $testname=$jobid_var_old
27659         jobid_var_new=$($LCTL get_param -n $testname)
27660         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27661                 error "failed to reset $testname"
27662
27663         $LCTL set_param $testname $new_value ||
27664                 error "'set_param a b' did not accept a value containing '='"
27665
27666         jobid_var_new=$($LCTL get_param -n $testname)
27667         [[ "$jobid_var_new" == "$new_value" ]] ||
27668                 error "'set_param a b' failed on a value containing '='"
27669
27670         $LCTL set_param $testname $jobid_var_old
27671         jobid_var_new=$($LCTL get_param -n $testname)
27672         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27673                 error "failed to reset $testname"
27674 }
27675 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27676
27677 test_401e() { # LU-14779
27678         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27679                 error "lctl list_param MGC* failed"
27680         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27681         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27682                 error "lctl get_param lru_size failed"
27683 }
27684 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27685
27686 test_402() {
27687         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27688         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27689                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27690         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27691                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27692                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27693         remote_mds_nodsh && skip "remote MDS with nodsh"
27694
27695         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27696 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27697         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27698         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27699                 echo "Touch failed - OK"
27700 }
27701 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27702
27703 test_403() {
27704         local file1=$DIR/$tfile.1
27705         local file2=$DIR/$tfile.2
27706         local tfile=$TMP/$tfile
27707
27708         rm -f $file1 $file2 $tfile
27709
27710         touch $file1
27711         ln $file1 $file2
27712
27713         # 30 sec OBD_TIMEOUT in ll_getattr()
27714         # right before populating st_nlink
27715         $LCTL set_param fail_loc=0x80001409
27716         stat -c %h $file1 > $tfile &
27717
27718         # create an alias, drop all locks and reclaim the dentry
27719         < $file2
27720         cancel_lru_locks mdc
27721         cancel_lru_locks osc
27722         sysctl -w vm.drop_caches=2
27723
27724         wait
27725
27726         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27727
27728         rm -f $tfile $file1 $file2
27729 }
27730 run_test 403 "i_nlink should not drop to zero due to aliasing"
27731
27732 test_404() { # LU-6601
27733         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27734                 skip "Need server version newer than 2.8.52"
27735         remote_mds_nodsh && skip "remote MDS with nodsh"
27736
27737         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27738                 awk '/osp .*-osc-MDT/ { print $4}')
27739
27740         local osp
27741         for osp in $mosps; do
27742                 echo "Deactivate: " $osp
27743                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27744                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27745                         awk -vp=$osp '$4 == p { print $2 }')
27746                 [ $stat = IN ] || {
27747                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27748                         error "deactivate error"
27749                 }
27750                 echo "Activate: " $osp
27751                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27752                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27753                         awk -vp=$osp '$4 == p { print $2 }')
27754                 [ $stat = UP ] || {
27755                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27756                         error "activate error"
27757                 }
27758         done
27759 }
27760 run_test 404 "validate manual {de}activated works properly for OSPs"
27761
27762 test_405() {
27763         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27764         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27765                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27766                         skip "Layout swap lock is not supported"
27767
27768         check_swap_layouts_support
27769         check_swap_layout_no_dom $DIR
27770
27771         test_mkdir $DIR/$tdir
27772         swap_lock_test -d $DIR/$tdir ||
27773                 error "One layout swap locked test failed"
27774 }
27775 run_test 405 "Various layout swap lock tests"
27776
27777 test_406() {
27778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27779         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27780         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27782         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27783                 skip "Need MDS version at least 2.8.50"
27784
27785         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27786         local test_pool=$TESTNAME
27787
27788         pool_add $test_pool || error "pool_add failed"
27789         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27790                 error "pool_add_targets failed"
27791
27792         save_layout_restore_at_exit $MOUNT
27793
27794         # parent set default stripe count only, child will stripe from both
27795         # parent and fs default
27796         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27797                 error "setstripe $MOUNT failed"
27798         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27799         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27800         for i in $(seq 10); do
27801                 local f=$DIR/$tdir/$tfile.$i
27802                 touch $f || error "touch failed"
27803                 local count=$($LFS getstripe -c $f)
27804                 [ $count -eq $OSTCOUNT ] ||
27805                         error "$f stripe count $count != $OSTCOUNT"
27806                 local offset=$($LFS getstripe -i $f)
27807                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27808                 local size=$($LFS getstripe -S $f)
27809                 [ $size -eq $((def_stripe_size * 2)) ] ||
27810                         error "$f stripe size $size != $((def_stripe_size * 2))"
27811                 local pool=$($LFS getstripe -p $f)
27812                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27813         done
27814
27815         # change fs default striping, delete parent default striping, now child
27816         # will stripe from new fs default striping only
27817         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27818                 error "change $MOUNT default stripe failed"
27819         $LFS setstripe -c 0 $DIR/$tdir ||
27820                 error "delete $tdir default stripe failed"
27821         for i in $(seq 11 20); do
27822                 local f=$DIR/$tdir/$tfile.$i
27823                 touch $f || error "touch $f failed"
27824                 local count=$($LFS getstripe -c $f)
27825                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27826                 local offset=$($LFS getstripe -i $f)
27827                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27828                 local size=$($LFS getstripe -S $f)
27829                 [ $size -eq $def_stripe_size ] ||
27830                         error "$f stripe size $size != $def_stripe_size"
27831                 local pool=$($LFS getstripe -p $f)
27832                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27833         done
27834
27835         unlinkmany $DIR/$tdir/$tfile. 1 20
27836
27837         local f=$DIR/$tdir/$tfile
27838         pool_remove_all_targets $test_pool $f
27839         pool_remove $test_pool $f
27840 }
27841 run_test 406 "DNE support fs default striping"
27842
27843 test_407() {
27844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27845         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27846                 skip "Need MDS version at least 2.8.55"
27847         remote_mds_nodsh && skip "remote MDS with nodsh"
27848
27849         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27850                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27851         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27852                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27853         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27854
27855         #define OBD_FAIL_DT_TXN_STOP    0x2019
27856         for idx in $(seq $MDSCOUNT); do
27857                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27858         done
27859         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27860         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27861                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27862         true
27863 }
27864 run_test 407 "transaction fail should cause operation fail"
27865
27866 test_408() {
27867         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27868
27869         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27870         lctl set_param fail_loc=0x8000040a
27871         # let ll_prepare_partial_page() fail
27872         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27873
27874         rm -f $DIR/$tfile
27875
27876         # create at least 100 unused inodes so that
27877         # shrink_icache_memory(0) should not return 0
27878         touch $DIR/$tfile-{0..100}
27879         rm -f $DIR/$tfile-{0..100}
27880         sync
27881
27882         echo 2 > /proc/sys/vm/drop_caches
27883 }
27884 run_test 408 "drop_caches should not hang due to page leaks"
27885
27886 test_409()
27887 {
27888         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27889
27890         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27891         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27892         touch $DIR/$tdir/guard || error "(2) Fail to create"
27893
27894         local PREFIX=$(str_repeat 'A' 128)
27895         echo "Create 1K hard links start at $(date)"
27896         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27897                 error "(3) Fail to hard link"
27898
27899         echo "Links count should be right although linkEA overflow"
27900         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27901         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27902         [ $linkcount -eq 1001 ] ||
27903                 error "(5) Unexpected hard links count: $linkcount"
27904
27905         echo "List all links start at $(date)"
27906         ls -l $DIR/$tdir/foo > /dev/null ||
27907                 error "(6) Fail to list $DIR/$tdir/foo"
27908
27909         echo "Unlink hard links start at $(date)"
27910         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27911                 error "(7) Fail to unlink"
27912         echo "Unlink hard links finished at $(date)"
27913 }
27914 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27915
27916 test_410()
27917 {
27918         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27919                 skip "Need client version at least 2.9.59"
27920         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27921                 skip "Need MODULES build"
27922
27923         # Create a file, and stat it from the kernel
27924         local testfile=$DIR/$tfile
27925         touch $testfile
27926
27927         local run_id=$RANDOM
27928         local my_ino=$(stat --format "%i" $testfile)
27929
27930         # Try to insert the module. This will always fail as the
27931         # module is designed to not be inserted.
27932         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27933             &> /dev/null
27934
27935         # Anything but success is a test failure
27936         dmesg | grep -q \
27937             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27938             error "no inode match"
27939 }
27940 run_test 410 "Test inode number returned from kernel thread"
27941
27942 cleanup_test411_cgroup() {
27943         trap 0
27944         cat $1/memory.stat
27945         rmdir "$1"
27946 }
27947
27948 test_411a() {
27949         local cg_basedir=/sys/fs/cgroup/memory
27950         # LU-9966
27951         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27952                 skip "no setup for cgroup"
27953
27954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27955                 error "test file creation failed"
27956         cancel_lru_locks osc
27957
27958         # Create a very small memory cgroup to force a slab allocation error
27959         local cgdir=$cg_basedir/osc_slab_alloc
27960         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27961         trap "cleanup_test411_cgroup $cgdir" EXIT
27962         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27963         echo 1M > $cgdir/memory.limit_in_bytes
27964
27965         # Should not LBUG, just be killed by oom-killer
27966         # dd will return 0 even allocation failure in some environment.
27967         # So don't check return value
27968         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27969         cleanup_test411_cgroup $cgdir
27970
27971         return 0
27972 }
27973 run_test 411a "Slab allocation error with cgroup does not LBUG"
27974
27975 test_411b() {
27976         local cg_basedir=/sys/fs/cgroup/memory
27977         # LU-9966
27978         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27979                 skip "no setup for cgroup"
27980         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27981         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27982         # limit, so we have 384M in cgroup
27983         # (arm) this seems to hit OOM more often than x86, so 1024M
27984         if [[ $(uname -m) = aarch64 ]]; then
27985                 local memlimit_mb=1024
27986         else
27987                 local memlimit_mb=384
27988         fi
27989
27990         # Create a cgroup and set memory limit
27991         # (tfile is used as an easy way to get a recognizable cgroup name)
27992         local cgdir=$cg_basedir/$tfile
27993         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27994         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27995         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27996
27997         echo "writing first file"
27998         # Write a file 4x the memory limit in size
27999         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28000                 error "(1) failed to write successfully"
28001
28002         sync
28003         cancel_lru_locks osc
28004
28005         rm -f $DIR/$tfile
28006         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28007
28008         # Try writing at a larger block size
28009         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28010         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28011         # need *some* memory to do IO in)
28012         echo "writing at larger block size"
28013         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28014                 error "(3) failed to write successfully"
28015
28016         sync
28017         cancel_lru_locks osc
28018         rm -f $DIR/$tfile
28019         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28020
28021         # Try writing multiple files at once
28022         echo "writing multiple files"
28023         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28024         local pid1=$!
28025         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28026         local pid2=$!
28027         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28028         local pid3=$!
28029         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28030         local pid4=$!
28031
28032         wait $pid1
28033         local rc1=$?
28034         wait $pid2
28035         local rc2=$?
28036         wait $pid3
28037         local rc3=$?
28038         wait $pid4
28039         local rc4=$?
28040         if (( rc1 != 0)); then
28041                 error "error $rc1 writing to file from $pid1"
28042         fi
28043         if (( rc2 != 0)); then
28044                 error "error $rc2 writing to file from $pid2"
28045         fi
28046         if (( rc3 != 0)); then
28047                 error "error $rc3 writing to file from $pid3"
28048         fi
28049         if (( rc4 != 0)); then
28050                 error "error $rc4 writing to file from $pid4"
28051         fi
28052
28053         sync
28054         cancel_lru_locks osc
28055
28056         # These files can be large-ish (~1 GiB total), so delete them rather
28057         # than leave for later cleanup
28058         rm -f $DIR/$tfile.*
28059         return 0
28060 }
28061 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28062
28063 test_412() {
28064         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28065         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28066                 skip "Need server version at least 2.10.55"
28067
28068         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28069                 error "mkdir failed"
28070         $LFS getdirstripe $DIR/$tdir
28071         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28072         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28073                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28074         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28075         [ $stripe_count -eq 2 ] ||
28076                 error "expect 2 get $stripe_count"
28077
28078         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28079
28080         local index
28081         local index2
28082
28083         # subdirs should be on the same MDT as parent
28084         for i in $(seq 0 $((MDSCOUNT - 1))); do
28085                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28086                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28087                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28088                 (( index == i )) || error "mdt$i/sub on MDT$index"
28089         done
28090
28091         # stripe offset -1, ditto
28092         for i in {1..10}; do
28093                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28094                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28095                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28096                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28097                 (( index == index2 )) ||
28098                         error "qos$i on MDT$index, sub on MDT$index2"
28099         done
28100
28101         local testdir=$DIR/$tdir/inherit
28102
28103         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28104         # inherit 2 levels
28105         for i in 1 2; do
28106                 testdir=$testdir/s$i
28107                 mkdir $testdir || error "mkdir $testdir failed"
28108                 index=$($LFS getstripe -m $testdir)
28109                 (( index == 1 )) ||
28110                         error "$testdir on MDT$index"
28111         done
28112
28113         # not inherit any more
28114         testdir=$testdir/s3
28115         mkdir $testdir || error "mkdir $testdir failed"
28116         getfattr -d -m dmv $testdir | grep dmv &&
28117                 error "default LMV set on $testdir" || true
28118 }
28119 run_test 412 "mkdir on specific MDTs"
28120
28121 TEST413_COUNT=${TEST413_COUNT:-200}
28122
28123 #
28124 # set_maxage() is used by test_413 only.
28125 # This is a helper function to set maxage. Does not return any value.
28126 # Input: maxage to set
28127 #
28128 set_maxage() {
28129         local lmv_qos_maxage
28130         local lod_qos_maxage
28131         local new_maxage=$1
28132
28133         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28134         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28135         stack_trap "$LCTL set_param \
28136                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28137         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28138                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28139         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28140                 lod.*.mdt_qos_maxage=$new_maxage
28141         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28142                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28143 }
28144
28145 generate_uneven_mdts() {
28146         local threshold=$1
28147         local ffree
28148         local bavail
28149         local max
28150         local min
28151         local max_index
28152         local min_index
28153         local tmp
28154         local i
28155
28156         echo
28157         echo "Check for uneven MDTs: "
28158
28159         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28160         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28161         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28162
28163         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28164         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28165         max_index=0
28166         min_index=0
28167         for ((i = 1; i < ${#ffree[@]}; i++)); do
28168                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28169                 if [ $tmp -gt $max ]; then
28170                         max=$tmp
28171                         max_index=$i
28172                 fi
28173                 if [ $tmp -lt $min ]; then
28174                         min=$tmp
28175                         min_index=$i
28176                 fi
28177         done
28178
28179         (( min > 0 )) || skip "low space on MDT$min_index"
28180         (( ${ffree[min_index]} > 0 )) ||
28181                 skip "no free files on MDT$min_index"
28182         (( ${ffree[min_index]} < 10000000 )) ||
28183                 skip "too many free files on MDT$min_index"
28184
28185         # Check if we need to generate uneven MDTs
28186         local diff=$(((max - min) * 100 / min))
28187         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28188         local testdir # individual folder within $testdirp
28189         local start
28190         local cmd
28191
28192         # fallocate is faster to consume space on MDT, if available
28193         if check_fallocate_supported mds$((min_index + 1)); then
28194                 cmd="fallocate -l 128K "
28195         else
28196                 cmd="dd if=/dev/zero bs=128K count=1 of="
28197         fi
28198
28199         echo "using cmd $cmd"
28200         for (( i = 0; diff < threshold; i++ )); do
28201                 testdir=${testdirp}/$i
28202                 [ -d $testdir ] && continue
28203
28204                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28205
28206                 mkdir -p $testdirp
28207                 # generate uneven MDTs, create till $threshold% diff
28208                 echo -n "weight diff=$diff% must be > $threshold% ..."
28209                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28210                 $LFS mkdir -i $min_index $testdir ||
28211                         error "mkdir $testdir failed"
28212                 $LFS setstripe -E 1M -L mdt $testdir ||
28213                         error "setstripe $testdir failed"
28214                 start=$SECONDS
28215                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28216                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28217                 done
28218                 sync; sleep 1; sync
28219
28220                 # wait for QOS to update
28221                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28222
28223                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28224                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28225                 max=$(((${ffree[max_index]} >> 8) *
28226                         (${bavail[max_index]} * bsize >> 16)))
28227                 min=$(((${ffree[min_index]} >> 8) *
28228                         (${bavail[min_index]} * bsize >> 16)))
28229                 (( min > 0 )) || skip "low space on MDT$min_index"
28230                 diff=$(((max - min) * 100 / min))
28231         done
28232
28233         echo "MDT filesfree available: ${ffree[*]}"
28234         echo "MDT blocks available: ${bavail[*]}"
28235         echo "weight diff=$diff%"
28236 }
28237
28238 test_qos_mkdir() {
28239         local mkdir_cmd=$1
28240         local stripe_count=$2
28241         local mdts=$(comma_list $(mdts_nodes))
28242
28243         local testdir
28244         local lmv_qos_prio_free
28245         local lmv_qos_threshold_rr
28246         local lod_qos_prio_free
28247         local lod_qos_threshold_rr
28248         local total
28249         local count
28250         local i
28251
28252         # @total is total directories created if it's testing plain
28253         # directories, otherwise it's total stripe object count for
28254         # striped directories test.
28255         # remote/striped directory unlinking is slow on zfs and may
28256         # timeout, test with fewer directories
28257         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28258
28259         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28260         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28261         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28262                 head -n1)
28263         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28264         stack_trap "$LCTL set_param \
28265                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28266         stack_trap "$LCTL set_param \
28267                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28268
28269         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28270                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28271         lod_qos_prio_free=${lod_qos_prio_free%%%}
28272         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28273                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28274         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28275         stack_trap "do_nodes $mdts $LCTL set_param \
28276                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28277         stack_trap "do_nodes $mdts $LCTL set_param \
28278                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28279
28280         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28281         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28282
28283         testdir=$DIR/$tdir-s$stripe_count/rr
28284
28285         local stripe_index=$($LFS getstripe -m $testdir)
28286         local test_mkdir_rr=true
28287
28288         getfattr -d -m dmv -e hex $testdir | grep dmv
28289         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28290                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28291                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28292                         test_mkdir_rr=false
28293         fi
28294
28295         echo
28296         $test_mkdir_rr &&
28297                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28298                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28299
28300         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28301         for (( i = 0; i < total / stripe_count; i++ )); do
28302                 eval $mkdir_cmd $testdir/subdir$i ||
28303                         error "$mkdir_cmd subdir$i failed"
28304         done
28305
28306         for (( i = 0; i < $MDSCOUNT; i++ )); do
28307                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28308                 echo "$count directories created on MDT$i"
28309                 if $test_mkdir_rr; then
28310                         (( count == total / stripe_count / MDSCOUNT )) ||
28311                                 error "subdirs are not evenly distributed"
28312                 elif (( i == stripe_index )); then
28313                         (( count == total / stripe_count )) ||
28314                                 error "$count subdirs created on MDT$i"
28315                 else
28316                         (( count == 0 )) ||
28317                                 error "$count subdirs created on MDT$i"
28318                 fi
28319
28320                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28321                         count=$($LFS getdirstripe $testdir/* |
28322                                 grep -c -P "^\s+$i\t")
28323                         echo "$count stripes created on MDT$i"
28324                         # deviation should < 5% of average
28325                         delta=$((count - total / MDSCOUNT))
28326                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28327                                 error "stripes are not evenly distributed"
28328                 fi
28329         done
28330
28331         echo
28332         echo "Check for uneven MDTs: "
28333
28334         local ffree
28335         local bavail
28336         local max
28337         local min
28338         local max_index
28339         local min_index
28340         local tmp
28341
28342         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28343         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28344         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28345
28346         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28347         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28348         max_index=0
28349         min_index=0
28350         for ((i = 1; i < ${#ffree[@]}; i++)); do
28351                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28352                 if [ $tmp -gt $max ]; then
28353                         max=$tmp
28354                         max_index=$i
28355                 fi
28356                 if [ $tmp -lt $min ]; then
28357                         min=$tmp
28358                         min_index=$i
28359                 fi
28360         done
28361         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28362
28363         (( min > 0 )) || skip "low space on MDT$min_index"
28364         (( ${ffree[min_index]} < 10000000 )) ||
28365                 skip "too many free files on MDT$min_index"
28366
28367         generate_uneven_mdts 120
28368
28369         echo "MDT filesfree available: ${ffree[*]}"
28370         echo "MDT blocks available: ${bavail[*]}"
28371         echo "weight diff=$(((max - min) * 100 / min))%"
28372         echo
28373         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28374
28375         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28376         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28377         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28378         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28379         # decrease statfs age, so that it can be updated in time
28380         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28381         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28382
28383         sleep 1
28384
28385         testdir=$DIR/$tdir-s$stripe_count/qos
28386
28387         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28388         for (( i = 0; i < total / stripe_count; i++ )); do
28389                 eval $mkdir_cmd $testdir/subdir$i ||
28390                         error "$mkdir_cmd subdir$i failed"
28391         done
28392
28393         max=0
28394         for (( i = 0; i < $MDSCOUNT; i++ )); do
28395                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28396                 (( count > max )) && max=$count
28397                 echo "$count directories created on MDT$i : curmax=$max"
28398         done
28399
28400         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28401
28402         # D-value should > 10% of average
28403         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28404                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28405
28406         # ditto for stripes
28407         if (( stripe_count > 1 )); then
28408                 max=0
28409                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28410                         count=$($LFS getdirstripe $testdir/* |
28411                                 grep -c -P "^\s+$i\t")
28412                         (( count > max )) && max=$count
28413                         echo "$count stripes created on MDT$i"
28414                 done
28415
28416                 min=$($LFS getdirstripe $testdir/* |
28417                         grep -c -P "^\s+$min_index\t")
28418                 (( max - min > total / MDSCOUNT / 10 )) ||
28419                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28420         fi
28421 }
28422
28423 most_full_mdt() {
28424         local ffree
28425         local bavail
28426         local bsize
28427         local min
28428         local min_index
28429         local tmp
28430
28431         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28432         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28433         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28434
28435         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28436         min_index=0
28437         for ((i = 1; i < ${#ffree[@]}; i++)); do
28438                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28439                 (( tmp < min )) && min=$tmp && min_index=$i
28440         done
28441
28442         echo -n $min_index
28443 }
28444
28445 test_413a() {
28446         [ $MDSCOUNT -lt 2 ] &&
28447                 skip "We need at least 2 MDTs for this test"
28448
28449         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28450                 skip "Need server version at least 2.12.52"
28451
28452         local stripe_max=$((MDSCOUNT - 1))
28453         local stripe_count
28454
28455         # let caller set maxage for latest result
28456         set_maxage 1
28457
28458         # fill MDT unevenly
28459         generate_uneven_mdts 120
28460
28461         # test 4-stripe directory at most, otherwise it's too slow
28462         # We are being very defensive. Although Autotest uses 4 MDTs.
28463         # We make sure stripe_max does not go over 4.
28464         (( stripe_max > 4 )) && stripe_max=4
28465         # unlinking striped directory is slow on zfs, and may timeout, only test
28466         # plain directory
28467         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28468         for stripe_count in $(seq 1 $stripe_max); do
28469                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28470                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28471                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28472                         error "mkdir failed"
28473                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28474         done
28475 }
28476 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28477
28478 test_413b() {
28479         [ $MDSCOUNT -lt 2 ] &&
28480                 skip "We need at least 2 MDTs for this test"
28481
28482         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28483                 skip "Need server version at least 2.12.52"
28484
28485         local stripe_max=$((MDSCOUNT - 1))
28486         local testdir
28487         local stripe_count
28488
28489         # let caller set maxage for latest result
28490         set_maxage 1
28491
28492         # fill MDT unevenly
28493         generate_uneven_mdts 120
28494
28495         # test 4-stripe directory at most, otherwise it's too slow
28496         # We are being very defensive. Although Autotest uses 4 MDTs.
28497         # We make sure stripe_max does not go over 4.
28498         (( stripe_max > 4 )) && stripe_max=4
28499         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28500         for stripe_count in $(seq 1 $stripe_max); do
28501                 testdir=$DIR/$tdir-s$stripe_count
28502                 mkdir $testdir || error "mkdir $testdir failed"
28503                 mkdir $testdir/rr || error "mkdir rr failed"
28504                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28505                         error "mkdir qos failed"
28506                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28507                         $testdir/rr || error "setdirstripe rr failed"
28508                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28509                         error "setdirstripe failed"
28510                 test_qos_mkdir "mkdir" $stripe_count
28511         done
28512 }
28513 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28514
28515 test_413c() {
28516         (( $MDSCOUNT >= 2 )) ||
28517                 skip "We need at least 2 MDTs for this test"
28518
28519         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28520                 skip "Need server version at least 2.14.51"
28521
28522         local testdir
28523         local inherit
28524         local inherit_rr
28525         local lmv_qos_maxage
28526         local lod_qos_maxage
28527
28528         # let caller set maxage for latest result
28529         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28530         $LCTL set_param lmv.*.qos_maxage=1
28531         stack_trap "$LCTL set_param \
28532                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28533         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28534                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28535         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28536                 lod.*.mdt_qos_maxage=1
28537         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28538                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28539
28540         # fill MDT unevenly
28541         generate_uneven_mdts 120
28542
28543         testdir=$DIR/${tdir}-s1
28544         mkdir $testdir || error "mkdir $testdir failed"
28545         mkdir $testdir/rr || error "mkdir rr failed"
28546         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28547         # default max_inherit is -1, default max_inherit_rr is 0
28548         $LFS setdirstripe -D -c 1 $testdir/rr ||
28549                 error "setdirstripe rr failed"
28550         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28551                 error "setdirstripe qos failed"
28552         test_qos_mkdir "mkdir" 1
28553
28554         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28555         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28556         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28557         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28558         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28559
28560         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28561         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28562         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28563         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28564         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28565         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28566         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28567                 error "level2 shouldn't have default LMV" || true
28568 }
28569 run_test 413c "mkdir with default LMV max inherit rr"
28570
28571 test_413d() {
28572         (( MDSCOUNT >= 2 )) ||
28573                 skip "We need at least 2 MDTs for this test"
28574
28575         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28576                 skip "Need server version at least 2.14.51"
28577
28578         local lmv_qos_threshold_rr
28579
28580         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28581                 head -n1)
28582         stack_trap "$LCTL set_param \
28583                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28584
28585         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28586         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28587         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28588                 error "$tdir shouldn't have default LMV"
28589         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28590                 error "mkdir sub failed"
28591
28592         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28593
28594         (( count == 100 )) || error "$count subdirs on MDT0"
28595 }
28596 run_test 413d "inherit ROOT default LMV"
28597
28598 test_413e() {
28599         (( MDSCOUNT >= 2 )) ||
28600                 skip "We need at least 2 MDTs for this test"
28601         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28602                 skip "Need server version at least 2.14.55"
28603
28604         local testdir=$DIR/$tdir
28605         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28606         local max_inherit
28607         local sub_max_inherit
28608
28609         mkdir -p $testdir || error "failed to create $testdir"
28610
28611         # set default max-inherit to -1 if stripe count is 0 or 1
28612         $LFS setdirstripe -D -c 1 $testdir ||
28613                 error "failed to set default LMV"
28614         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28615         (( max_inherit == -1 )) ||
28616                 error "wrong max_inherit value $max_inherit"
28617
28618         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28619         $LFS setdirstripe -D -c -1 $testdir ||
28620                 error "failed to set default LMV"
28621         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28622         (( max_inherit > 0 )) ||
28623                 error "wrong max_inherit value $max_inherit"
28624
28625         # and the subdir will decrease the max_inherit by 1
28626         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28627         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28628         (( sub_max_inherit == max_inherit - 1)) ||
28629                 error "wrong max-inherit of subdir $sub_max_inherit"
28630
28631         # check specified --max-inherit and warning message
28632         stack_trap "rm -f $tmpfile"
28633         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28634                 error "failed to set default LMV"
28635         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28636         (( max_inherit == -1 )) ||
28637                 error "wrong max_inherit value $max_inherit"
28638
28639         # check the warning messages
28640         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28641                 error "failed to detect warning string"
28642         fi
28643 }
28644 run_test 413e "check default max-inherit value"
28645
28646 test_fs_dmv_inherit()
28647 {
28648         local testdir=$DIR/$tdir
28649
28650         local count
28651         local inherit
28652         local inherit_rr
28653
28654         for i in 1 2; do
28655                 mkdir $testdir || error "mkdir $testdir failed"
28656                 count=$($LFS getdirstripe -D -c $testdir)
28657                 (( count == 1 )) ||
28658                         error "$testdir default LMV count mismatch $count != 1"
28659                 inherit=$($LFS getdirstripe -D -X $testdir)
28660                 (( inherit == 3 - i )) ||
28661                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28662                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28663                 (( inherit_rr == 3 - i )) ||
28664                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28665                 testdir=$testdir/sub
28666         done
28667
28668         mkdir $testdir || error "mkdir $testdir failed"
28669         count=$($LFS getdirstripe -D -c $testdir)
28670         (( count == 0 )) ||
28671                 error "$testdir default LMV count not zero: $count"
28672 }
28673
28674 test_413f() {
28675         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28676
28677         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28678                 skip "Need server version at least 2.14.55"
28679
28680         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28681                 error "dump $DIR default LMV failed"
28682         stack_trap "setfattr --restore=$TMP/dmv.ea"
28683
28684         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28685                 error "set $DIR default LMV failed"
28686
28687         test_fs_dmv_inherit
28688 }
28689 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28690
28691 test_413g() {
28692         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28693
28694         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28695         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28696                 error "dump $DIR default LMV failed"
28697         stack_trap "setfattr --restore=$TMP/dmv.ea"
28698
28699         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28700                 error "set $DIR default LMV failed"
28701
28702         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28703                 error "mount $MOUNT2 failed"
28704         stack_trap "umount_client $MOUNT2"
28705
28706         local saved_DIR=$DIR
28707
28708         export DIR=$MOUNT2
28709
28710         stack_trap "export DIR=$saved_DIR"
28711
28712         # first check filesystem-wide default LMV inheritance
28713         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28714
28715         # then check subdirs are spread to all MDTs
28716         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28717
28718         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28719
28720         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28721 }
28722 run_test 413g "enforce ROOT default LMV on subdir mount"
28723
28724 test_413h() {
28725         (( MDSCOUNT >= 2 )) ||
28726                 skip "We need at least 2 MDTs for this test"
28727
28728         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28729                 skip "Need server version at least 2.15.50.6"
28730
28731         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28732
28733         stack_trap "$LCTL set_param \
28734                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28735         $LCTL set_param lmv.*.qos_maxage=1
28736
28737         local depth=5
28738         local rr_depth=4
28739         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28740         local count=$((MDSCOUNT * 20))
28741
28742         generate_uneven_mdts 50
28743
28744         mkdir -p $dir || error "mkdir $dir failed"
28745         stack_trap "rm -rf $dir"
28746         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28747                 --max-inherit-rr=$rr_depth $dir
28748
28749         for ((d=0; d < depth + 2; d++)); do
28750                 log "dir=$dir:"
28751                 for ((sub=0; sub < count; sub++)); do
28752                         mkdir $dir/d$sub
28753                 done
28754                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28755                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28756                 # subdirs within $rr_depth should be created round-robin
28757                 if (( d < rr_depth )); then
28758                         (( ${num[0]} != count )) ||
28759                                 error "all objects created on MDT ${num[1]}"
28760                 fi
28761
28762                 dir=$dir/d0
28763         done
28764 }
28765 run_test 413h "don't stick to parent for round-robin dirs"
28766
28767 test_413i() {
28768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28769
28770         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28771                 skip "Need server version at least 2.14.55"
28772
28773         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28774                 error "dump $DIR default LMV failed"
28775         stack_trap "setfattr --restore=$TMP/dmv.ea"
28776
28777         local testdir=$DIR/$tdir
28778         local def_max_rr=1
28779         local def_max=3
28780         local count
28781
28782         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28783                 --max-inherit-rr=$def_max_rr $DIR ||
28784                 error "set $DIR default LMV failed"
28785
28786         for i in $(seq 2 3); do
28787                 def_max=$((def_max - 1))
28788                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28789
28790                 mkdir $testdir
28791                 # RR is decremented and keeps zeroed once exhausted
28792                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28793                 (( count == def_max_rr )) ||
28794                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28795
28796                 # max-inherit is decremented
28797                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28798                 (( count == def_max )) ||
28799                         error_noexit "$testdir: max-inherit $count != $def_max"
28800
28801                 testdir=$testdir/d$i
28802         done
28803
28804         # d3 is the last inherited from ROOT, no inheritance anymore
28805         # i.e. no the default layout anymore
28806         mkdir -p $testdir/d4/d5
28807         count=$($LFS getdirstripe -D --max-inherit $testdir)
28808         (( count == -1 )) ||
28809                 error_noexit "$testdir: max-inherit $count != -1"
28810
28811         local p_count=$($LFS getdirstripe -i $testdir)
28812
28813         for i in $(seq 4 5); do
28814                 testdir=$testdir/d$i
28815
28816                 # the root default layout is not applied once exhausted
28817                 count=$($LFS getdirstripe -i $testdir)
28818                 (( count == p_count )) ||
28819                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28820         done
28821
28822         $LFS setdirstripe -i 0 $DIR/d2
28823         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28824         (( count == -1 )) ||
28825                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28826 }
28827 run_test 413i "check default layout inheritance"
28828
28829 test_413j()
28830 {
28831         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28832
28833         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28834         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
28835                 error "setdirstripe $tdir failed"
28836
28837         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
28838                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28839
28840         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
28841         # setfattr dmv calls setdirstripe -D
28842         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
28843                 error "setfattr sub failed"
28844         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
28845                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28846
28847         [ $value == $value2 ] || error "dmv mismatch"
28848
28849         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
28850
28851         # do not allow remove dmv by setfattr -x
28852         do_nodes $(comma_list $(mdts_nodes)) \
28853                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28854         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28855         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
28856
28857         # allow remove dmv by setfattr -x
28858         do_nodes $(comma_list $(mdts_nodes)) \
28859                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
28860         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28861         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
28862         do_nodes $(comma_list $(mdts_nodes)) \
28863                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28864 }
28865 run_test 413j "set default LMV by setxattr"
28866
28867 test_413z() {
28868         local pids=""
28869         local subdir
28870         local pid
28871
28872         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28873                 unlinkmany $subdir/f. $TEST413_COUNT &
28874                 pids="$pids $!"
28875         done
28876
28877         for pid in $pids; do
28878                 wait $pid
28879         done
28880
28881         true
28882 }
28883 run_test 413z "413 test cleanup"
28884
28885 test_414() {
28886 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28887         $LCTL set_param fail_loc=0x80000521
28888         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28889         rm -f $DIR/$tfile
28890 }
28891 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28892
28893 test_415() {
28894         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28895         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28896                 skip "Need server version at least 2.11.52"
28897
28898         # LU-11102
28899         local total=500
28900         local max=120
28901
28902         # this test may be slow on ZFS
28903         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28904
28905         # though this test is designed for striped directory, let's test normal
28906         # directory too since lock is always saved as CoS lock.
28907         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28908         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28909         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28910         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28911         wait_delete_completed_mds
28912
28913         # run a loop without concurrent touch to measure rename duration.
28914         # only for test debug/robustness, NOT part of COS functional test.
28915         local start_time=$SECONDS
28916         for ((i = 0; i < total; i++)); do
28917                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28918                         > /dev/null
28919         done
28920         local baseline=$((SECONDS - start_time))
28921         echo "rename $total files without 'touch' took $baseline sec"
28922
28923         (
28924                 while true; do
28925                         touch $DIR/$tdir
28926                 done
28927         ) &
28928         local setattr_pid=$!
28929
28930         # rename files back to original name so unlinkmany works
28931         start_time=$SECONDS
28932         for ((i = 0; i < total; i++)); do
28933                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28934                         > /dev/null
28935         done
28936         local duration=$((SECONDS - start_time))
28937
28938         kill -9 $setattr_pid
28939
28940         echo "rename $total files with 'touch' took $duration sec"
28941         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28942         (( duration <= max )) ||
28943                 error_not_in_vm "rename took $duration > $max sec"
28944 }
28945 run_test 415 "lock revoke is not missing"
28946
28947 test_416() {
28948         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28949                 skip "Need server version at least 2.11.55"
28950
28951         # define OBD_FAIL_OSD_TXN_START    0x19a
28952         do_facet mds1 lctl set_param fail_loc=0x19a
28953
28954         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28955
28956         true
28957 }
28958 run_test 416 "transaction start failure won't cause system hung"
28959
28960 cleanup_417() {
28961         trap 0
28962         do_nodes $(comma_list $(mdts_nodes)) \
28963                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28964         do_nodes $(comma_list $(mdts_nodes)) \
28965                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28966         do_nodes $(comma_list $(mdts_nodes)) \
28967                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28968 }
28969
28970 test_417() {
28971         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28972         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28973                 skip "Need MDS version at least 2.11.56"
28974
28975         trap cleanup_417 RETURN EXIT
28976
28977         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28978         do_nodes $(comma_list $(mdts_nodes)) \
28979                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28980         $LFS migrate -m 0 $DIR/$tdir.1 &&
28981                 error "migrate dir $tdir.1 should fail"
28982
28983         do_nodes $(comma_list $(mdts_nodes)) \
28984                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28985         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28986                 error "create remote dir $tdir.2 should fail"
28987
28988         do_nodes $(comma_list $(mdts_nodes)) \
28989                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28990         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28991                 error "create striped dir $tdir.3 should fail"
28992         true
28993 }
28994 run_test 417 "disable remote dir, striped dir and dir migration"
28995
28996 # Checks that the outputs of df [-i] and lfs df [-i] match
28997 #
28998 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28999 check_lfs_df() {
29000         local dir=$2
29001         local inodes
29002         local df_out
29003         local lfs_df_out
29004         local count
29005         local passed=false
29006
29007         # blocks or inodes
29008         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29009
29010         for count in {1..100}; do
29011                 do_nodes "$CLIENTS" \
29012                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29013                 sync; sleep 0.2
29014
29015                 # read the lines of interest
29016                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29017                         error "df $inodes $dir | tail -n +2 failed"
29018                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29019                         error "lfs df $inodes $dir | grep summary: failed"
29020
29021                 # skip first substrings of each output as they are different
29022                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29023                 # compare the two outputs
29024                 passed=true
29025                 #  skip "available" on MDT until LU-13997 is fixed.
29026                 #for i in {1..5}; do
29027                 for i in 1 2 4 5; do
29028                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29029                 done
29030                 $passed && break
29031         done
29032
29033         if ! $passed; then
29034                 df -P $inodes $dir
29035                 echo
29036                 lfs df $inodes $dir
29037                 error "df and lfs df $1 output mismatch: "      \
29038                       "df ${inodes}: ${df_out[*]}, "            \
29039                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29040         fi
29041 }
29042
29043 test_418() {
29044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29045
29046         local dir=$DIR/$tdir
29047         local numfiles=$((RANDOM % 4096 + 2))
29048         local numblocks=$((RANDOM % 256 + 1))
29049
29050         wait_delete_completed
29051         test_mkdir $dir
29052
29053         # check block output
29054         check_lfs_df blocks $dir
29055         # check inode output
29056         check_lfs_df inodes $dir
29057
29058         # create a single file and retest
29059         echo "Creating a single file and testing"
29060         createmany -o $dir/$tfile- 1 &>/dev/null ||
29061                 error "creating 1 file in $dir failed"
29062         check_lfs_df blocks $dir
29063         check_lfs_df inodes $dir
29064
29065         # create a random number of files
29066         echo "Creating $((numfiles - 1)) files and testing"
29067         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29068                 error "creating $((numfiles - 1)) files in $dir failed"
29069
29070         # write a random number of blocks to the first test file
29071         echo "Writing $numblocks 4K blocks and testing"
29072         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29073                 count=$numblocks &>/dev/null ||
29074                 error "dd to $dir/${tfile}-0 failed"
29075
29076         # retest
29077         check_lfs_df blocks $dir
29078         check_lfs_df inodes $dir
29079
29080         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29081                 error "unlinking $numfiles files in $dir failed"
29082 }
29083 run_test 418 "df and lfs df outputs match"
29084
29085 test_419()
29086 {
29087         local dir=$DIR/$tdir
29088
29089         mkdir -p $dir
29090         touch $dir/file
29091
29092         cancel_lru_locks mdc
29093
29094         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29095         $LCTL set_param fail_loc=0x1410
29096         cat $dir/file
29097         $LCTL set_param fail_loc=0
29098         rm -rf $dir
29099 }
29100 run_test 419 "Verify open file by name doesn't crash kernel"
29101
29102 test_420()
29103 {
29104         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29105                 skip "Need MDS version at least 2.12.53"
29106
29107         local SAVE_UMASK=$(umask)
29108         local dir=$DIR/$tdir
29109         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29110
29111         mkdir -p $dir
29112         umask 0000
29113         mkdir -m03777 $dir/testdir
29114         ls -dn $dir/testdir
29115         # Need to remove trailing '.' when SELinux is enabled
29116         local dirperms=$(ls -dn $dir/testdir |
29117                          awk '{ sub(/\.$/, "", $1); print $1}')
29118         [ $dirperms == "drwxrwsrwt" ] ||
29119                 error "incorrect perms on $dir/testdir"
29120
29121         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29122                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29123         ls -n $dir/testdir/testfile
29124         local fileperms=$(ls -n $dir/testdir/testfile |
29125                           awk '{ sub(/\.$/, "", $1); print $1}')
29126         [ $fileperms == "-rwxr-xr-x" ] ||
29127                 error "incorrect perms on $dir/testdir/testfile"
29128
29129         umask $SAVE_UMASK
29130 }
29131 run_test 420 "clear SGID bit on non-directories for non-members"
29132
29133 test_421a() {
29134         local cnt
29135         local fid1
29136         local fid2
29137
29138         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29139                 skip "Need MDS version at least 2.12.54"
29140
29141         test_mkdir $DIR/$tdir
29142         createmany -o $DIR/$tdir/f 3
29143         cnt=$(ls -1 $DIR/$tdir | wc -l)
29144         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29145
29146         fid1=$(lfs path2fid $DIR/$tdir/f1)
29147         fid2=$(lfs path2fid $DIR/$tdir/f2)
29148         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29149
29150         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29151         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29152
29153         cnt=$(ls -1 $DIR/$tdir | wc -l)
29154         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29155
29156         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29157         createmany -o $DIR/$tdir/f 3
29158         cnt=$(ls -1 $DIR/$tdir | wc -l)
29159         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29160
29161         fid1=$(lfs path2fid $DIR/$tdir/f1)
29162         fid2=$(lfs path2fid $DIR/$tdir/f2)
29163         echo "remove using fsname $FSNAME"
29164         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29165
29166         cnt=$(ls -1 $DIR/$tdir | wc -l)
29167         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29168 }
29169 run_test 421a "simple rm by fid"
29170
29171 test_421b() {
29172         local cnt
29173         local FID1
29174         local FID2
29175
29176         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29177                 skip "Need MDS version at least 2.12.54"
29178
29179         test_mkdir $DIR/$tdir
29180         createmany -o $DIR/$tdir/f 3
29181         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29182         MULTIPID=$!
29183
29184         FID1=$(lfs path2fid $DIR/$tdir/f1)
29185         FID2=$(lfs path2fid $DIR/$tdir/f2)
29186         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29187
29188         kill -USR1 $MULTIPID
29189         wait
29190
29191         cnt=$(ls $DIR/$tdir | wc -l)
29192         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29193 }
29194 run_test 421b "rm by fid on open file"
29195
29196 test_421c() {
29197         local cnt
29198         local FIDS
29199
29200         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29201                 skip "Need MDS version at least 2.12.54"
29202
29203         test_mkdir $DIR/$tdir
29204         createmany -o $DIR/$tdir/f 3
29205         touch $DIR/$tdir/$tfile
29206         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29207         cnt=$(ls -1 $DIR/$tdir | wc -l)
29208         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29209
29210         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29211         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29212
29213         cnt=$(ls $DIR/$tdir | wc -l)
29214         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29215 }
29216 run_test 421c "rm by fid against hardlinked files"
29217
29218 test_421d() {
29219         local cnt
29220         local FIDS
29221
29222         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29223                 skip "Need MDS version at least 2.12.54"
29224
29225         test_mkdir $DIR/$tdir
29226         createmany -o $DIR/$tdir/f 4097
29227         cnt=$(ls -1 $DIR/$tdir | wc -l)
29228         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29229
29230         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29231         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29232
29233         cnt=$(ls $DIR/$tdir | wc -l)
29234         rm -rf $DIR/$tdir
29235         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29236 }
29237 run_test 421d "rmfid en masse"
29238
29239 test_421e() {
29240         local cnt
29241         local FID
29242
29243         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29244         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29245                 skip "Need MDS version at least 2.12.54"
29246
29247         mkdir -p $DIR/$tdir
29248         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29249         createmany -o $DIR/$tdir/striped_dir/f 512
29250         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29251         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29252
29253         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29254                 sed "s/[/][^:]*://g")
29255         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29256
29257         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29258         rm -rf $DIR/$tdir
29259         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29260 }
29261 run_test 421e "rmfid in DNE"
29262
29263 test_421f() {
29264         local cnt
29265         local FID
29266
29267         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29268                 skip "Need MDS version at least 2.12.54"
29269
29270         test_mkdir $DIR/$tdir
29271         touch $DIR/$tdir/f
29272         cnt=$(ls -1 $DIR/$tdir | wc -l)
29273         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29274
29275         FID=$(lfs path2fid $DIR/$tdir/f)
29276         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29277         # rmfid should fail
29278         cnt=$(ls -1 $DIR/$tdir | wc -l)
29279         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29280
29281         chmod a+rw $DIR/$tdir
29282         ls -la $DIR/$tdir
29283         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29284         # rmfid should fail
29285         cnt=$(ls -1 $DIR/$tdir | wc -l)
29286         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29287
29288         rm -f $DIR/$tdir/f
29289         $RUNAS touch $DIR/$tdir/f
29290         FID=$(lfs path2fid $DIR/$tdir/f)
29291         echo "rmfid as root"
29292         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29293         cnt=$(ls -1 $DIR/$tdir | wc -l)
29294         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29295
29296         rm -f $DIR/$tdir/f
29297         $RUNAS touch $DIR/$tdir/f
29298         cnt=$(ls -1 $DIR/$tdir | wc -l)
29299         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29300         FID=$(lfs path2fid $DIR/$tdir/f)
29301         # rmfid w/o user_fid2path mount option should fail
29302         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29303         cnt=$(ls -1 $DIR/$tdir | wc -l)
29304         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29305
29306         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29307         stack_trap "rmdir $tmpdir"
29308         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29309                 error "failed to mount client'"
29310         stack_trap "umount_client $tmpdir"
29311
29312         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29313         # rmfid should succeed
29314         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29315         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29316
29317         # rmfid shouldn't allow to remove files due to dir's permission
29318         chmod a+rwx $tmpdir/$tdir
29319         touch $tmpdir/$tdir/f
29320         ls -la $tmpdir/$tdir
29321         FID=$(lfs path2fid $tmpdir/$tdir/f)
29322         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29323         return 0
29324 }
29325 run_test 421f "rmfid checks permissions"
29326
29327 test_421g() {
29328         local cnt
29329         local FIDS
29330
29331         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29332         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29333                 skip "Need MDS version at least 2.12.54"
29334
29335         mkdir -p $DIR/$tdir
29336         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29337         createmany -o $DIR/$tdir/striped_dir/f 512
29338         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29339         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29340
29341         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29342                 sed "s/[/][^:]*://g")
29343
29344         rm -f $DIR/$tdir/striped_dir/f1*
29345         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29346         removed=$((512 - cnt))
29347
29348         # few files have been just removed, so we expect
29349         # rmfid to fail on their fids
29350         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29351         [ $removed != $errors ] && error "$errors != $removed"
29352
29353         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29354         rm -rf $DIR/$tdir
29355         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29356 }
29357 run_test 421g "rmfid to return errors properly"
29358
29359 test_421h() {
29360         local mount_other
29361         local mount_ret
29362         local rmfid_ret
29363         local old_fid
29364         local fidA
29365         local fidB
29366         local fidC
29367         local fidD
29368
29369         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29370                 skip "Need MDS version at least 2.15.53"
29371
29372         test_mkdir $DIR/$tdir
29373         test_mkdir $DIR/$tdir/subdir
29374         touch $DIR/$tdir/subdir/file0
29375         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29376         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29377         rm -f $DIR/$tdir/subdir/file0
29378         touch $DIR/$tdir/subdir/fileA
29379         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29380         echo File $DIR/$tdir/subdir/fileA FID $fidA
29381         touch $DIR/$tdir/subdir/fileB
29382         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29383         echo File $DIR/$tdir/subdir/fileB FID $fidB
29384         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29385         touch $DIR/$tdir/subdir/fileC
29386         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29387         echo File $DIR/$tdir/subdir/fileC FID $fidC
29388         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29389         touch $DIR/$tdir/fileD
29390         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29391         echo File $DIR/$tdir/fileD FID $fidD
29392
29393         # mount another client mount point with subdirectory mount
29394         export FILESET=/$tdir/subdir
29395         mount_other=${MOUNT}_other
29396         mount_client $mount_other ${MOUNT_OPTS}
29397         mount_ret=$?
29398         export FILESET=""
29399         (( mount_ret == 0 )) || error "mount $mount_other failed"
29400
29401         echo Removing FIDs:
29402         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29403         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29404         rmfid_ret=$?
29405
29406         umount_client $mount_other || error "umount $mount_other failed"
29407
29408         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29409
29410         # fileA should have been deleted
29411         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29412
29413         # fileB should have been deleted
29414         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29415
29416         # fileC should not have been deleted, fid also exists outside of fileset
29417         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29418
29419         # fileD should not have been deleted, it exists outside of fileset
29420         stat $DIR/$tdir/fileD || error "fileD deleted"
29421 }
29422 run_test 421h "rmfid with fileset mount"
29423
29424 test_422() {
29425         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29426         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29427         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29428         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29429         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29430
29431         local amc=$(at_max_get client)
29432         local amo=$(at_max_get mds1)
29433         local timeout=`lctl get_param -n timeout`
29434
29435         at_max_set 0 client
29436         at_max_set 0 mds1
29437
29438 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29439         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29440                         fail_val=$(((2*timeout + 10)*1000))
29441         touch $DIR/$tdir/d3/file &
29442         sleep 2
29443 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29444         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29445                         fail_val=$((2*timeout + 5))
29446         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29447         local pid=$!
29448         sleep 1
29449         kill -9 $pid
29450         sleep $((2 * timeout))
29451         echo kill $pid
29452         kill -9 $pid
29453         lctl mark touch
29454         touch $DIR/$tdir/d2/file3
29455         touch $DIR/$tdir/d2/file4
29456         touch $DIR/$tdir/d2/file5
29457
29458         wait
29459         at_max_set $amc client
29460         at_max_set $amo mds1
29461
29462         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29463         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29464                 error "Watchdog is always throttled"
29465 }
29466 run_test 422 "kill a process with RPC in progress"
29467
29468 stat_test() {
29469     df -h $MOUNT &
29470     df -h $MOUNT &
29471     df -h $MOUNT &
29472     df -h $MOUNT &
29473     df -h $MOUNT &
29474     df -h $MOUNT &
29475 }
29476
29477 test_423() {
29478     local _stats
29479     # ensure statfs cache is expired
29480     sleep 2;
29481
29482     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29483     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29484
29485     return 0
29486 }
29487 run_test 423 "statfs should return a right data"
29488
29489 test_424() {
29490 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29491         $LCTL set_param fail_loc=0x80000522
29492         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29493         rm -f $DIR/$tfile
29494 }
29495 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29496
29497 test_425() {
29498         test_mkdir -c -1 $DIR/$tdir
29499         $LFS setstripe -c -1 $DIR/$tdir
29500
29501         lru_resize_disable "" 100
29502         stack_trap "lru_resize_enable" EXIT
29503
29504         sleep 5
29505
29506         for i in $(seq $((MDSCOUNT * 125))); do
29507                 local t=$DIR/$tdir/$tfile_$i
29508
29509                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29510                         error_noexit "Create file $t"
29511         done
29512         stack_trap "rm -rf $DIR/$tdir" EXIT
29513
29514         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29515                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29516                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29517
29518                 [ $lock_count -le $lru_size ] ||
29519                         error "osc lock count $lock_count > lru size $lru_size"
29520         done
29521
29522         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29523                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29524                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29525
29526                 [ $lock_count -le $lru_size ] ||
29527                         error "mdc lock count $lock_count > lru size $lru_size"
29528         done
29529 }
29530 run_test 425 "lock count should not exceed lru size"
29531
29532 test_426() {
29533         splice-test -r $DIR/$tfile
29534         splice-test -rd $DIR/$tfile
29535         splice-test $DIR/$tfile
29536         splice-test -d $DIR/$tfile
29537 }
29538 run_test 426 "splice test on Lustre"
29539
29540 test_427() {
29541         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29542         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29543                 skip "Need MDS version at least 2.12.4"
29544         local log
29545
29546         mkdir $DIR/$tdir
29547         mkdir $DIR/$tdir/1
29548         mkdir $DIR/$tdir/2
29549         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29550         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29551
29552         $LFS getdirstripe $DIR/$tdir/1/dir
29553
29554         #first setfattr for creating updatelog
29555         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29556
29557 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29558         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29559         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29560         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29561
29562         sleep 2
29563         fail mds2
29564         wait_recovery_complete mds2 $((2*TIMEOUT))
29565
29566         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29567         echo $log | grep "get update log failed" &&
29568                 error "update log corruption is detected" || true
29569 }
29570 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29571
29572 test_428() {
29573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29574         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29575                               awk '/^max_cached_mb/ { print $2 }')
29576         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29577
29578         $LCTL set_param -n llite.*.max_cached_mb=64
29579
29580         mkdir $DIR/$tdir
29581         $LFS setstripe -c 1 $DIR/$tdir
29582         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29583         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29584         #test write
29585         for f in $(seq 4); do
29586                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29587         done
29588         wait
29589
29590         cancel_lru_locks osc
29591         # Test read
29592         for f in $(seq 4); do
29593                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29594         done
29595         wait
29596 }
29597 run_test 428 "large block size IO should not hang"
29598
29599 test_429() { # LU-7915 / LU-10948
29600         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29601         local testfile=$DIR/$tfile
29602         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29603         local new_flag=1
29604         local first_rpc
29605         local second_rpc
29606         local third_rpc
29607
29608         $LCTL get_param $ll_opencache_threshold_count ||
29609                 skip "client does not have opencache parameter"
29610
29611         set_opencache $new_flag
29612         stack_trap "restore_opencache"
29613         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29614                 error "enable opencache failed"
29615         touch $testfile
29616         # drop MDC DLM locks
29617         cancel_lru_locks mdc
29618         # clear MDC RPC stats counters
29619         $LCTL set_param $mdc_rpcstats=clear
29620
29621         # According to the current implementation, we need to run 3 times
29622         # open & close file to verify if opencache is enabled correctly.
29623         # 1st, RPCs are sent for lookup/open and open handle is released on
29624         #      close finally.
29625         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29626         #      so open handle won't be released thereafter.
29627         # 3rd, No RPC is sent out.
29628         $MULTIOP $testfile oc || error "multiop failed"
29629         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29630         echo "1st: $first_rpc RPCs in flight"
29631
29632         $MULTIOP $testfile oc || error "multiop failed"
29633         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29634         echo "2nd: $second_rpc RPCs in flight"
29635
29636         $MULTIOP $testfile oc || error "multiop failed"
29637         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29638         echo "3rd: $third_rpc RPCs in flight"
29639
29640         #verify no MDC RPC is sent
29641         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29642 }
29643 run_test 429 "verify if opencache flag on client side does work"
29644
29645 lseek_test_430() {
29646         local offset
29647         local file=$1
29648
29649         # data at [200K, 400K)
29650         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29651                 error "256K->512K dd fails"
29652         # data at [2M, 3M)
29653         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29654                 error "2M->3M dd fails"
29655         # data at [4M, 5M)
29656         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29657                 error "4M->5M dd fails"
29658         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29659         # start at first component hole #1
29660         printf "Seeking hole from 1000 ... "
29661         offset=$(lseek_test -l 1000 $file)
29662         echo $offset
29663         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29664         printf "Seeking data from 1000 ... "
29665         offset=$(lseek_test -d 1000 $file)
29666         echo $offset
29667         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29668
29669         # start at first component data block
29670         printf "Seeking hole from 300000 ... "
29671         offset=$(lseek_test -l 300000 $file)
29672         echo $offset
29673         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29674         printf "Seeking data from 300000 ... "
29675         offset=$(lseek_test -d 300000 $file)
29676         echo $offset
29677         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29678
29679         # start at the first component but beyond end of object size
29680         printf "Seeking hole from 1000000 ... "
29681         offset=$(lseek_test -l 1000000 $file)
29682         echo $offset
29683         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29684         printf "Seeking data from 1000000 ... "
29685         offset=$(lseek_test -d 1000000 $file)
29686         echo $offset
29687         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29688
29689         # start at second component stripe 2 (empty file)
29690         printf "Seeking hole from 1500000 ... "
29691         offset=$(lseek_test -l 1500000 $file)
29692         echo $offset
29693         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29694         printf "Seeking data from 1500000 ... "
29695         offset=$(lseek_test -d 1500000 $file)
29696         echo $offset
29697         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29698
29699         # start at second component stripe 1 (all data)
29700         printf "Seeking hole from 3000000 ... "
29701         offset=$(lseek_test -l 3000000 $file)
29702         echo $offset
29703         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29704         printf "Seeking data from 3000000 ... "
29705         offset=$(lseek_test -d 3000000 $file)
29706         echo $offset
29707         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29708
29709         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29710                 error "2nd dd fails"
29711         echo "Add data block at 640K...1280K"
29712
29713         # start at before new data block, in hole
29714         printf "Seeking hole from 600000 ... "
29715         offset=$(lseek_test -l 600000 $file)
29716         echo $offset
29717         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29718         printf "Seeking data from 600000 ... "
29719         offset=$(lseek_test -d 600000 $file)
29720         echo $offset
29721         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29722
29723         # start at the first component new data block
29724         printf "Seeking hole from 1000000 ... "
29725         offset=$(lseek_test -l 1000000 $file)
29726         echo $offset
29727         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29728         printf "Seeking data from 1000000 ... "
29729         offset=$(lseek_test -d 1000000 $file)
29730         echo $offset
29731         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29732
29733         # start at second component stripe 2, new data
29734         printf "Seeking hole from 1200000 ... "
29735         offset=$(lseek_test -l 1200000 $file)
29736         echo $offset
29737         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29738         printf "Seeking data from 1200000 ... "
29739         offset=$(lseek_test -d 1200000 $file)
29740         echo $offset
29741         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29742
29743         # start beyond file end
29744         printf "Using offset > filesize ... "
29745         lseek_test -l 4000000 $file && error "lseek should fail"
29746         printf "Using offset > filesize ... "
29747         lseek_test -d 4000000 $file && error "lseek should fail"
29748
29749         printf "Done\n\n"
29750 }
29751
29752 test_430a() {
29753         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29754                 skip "MDT does not support SEEK_HOLE"
29755
29756         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29757                 skip "OST does not support SEEK_HOLE"
29758
29759         local file=$DIR/$tdir/$tfile
29760
29761         mkdir -p $DIR/$tdir
29762
29763         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29764         # OST stripe #1 will have continuous data at [1M, 3M)
29765         # OST stripe #2 is empty
29766         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29767         lseek_test_430 $file
29768         rm $file
29769         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29770         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29771         lseek_test_430 $file
29772         rm $file
29773         $LFS setstripe -c2 -S 512K $file
29774         echo "Two stripes, stripe size 512K"
29775         lseek_test_430 $file
29776         rm $file
29777         # FLR with stale mirror
29778         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29779                        -N -c2 -S 1M $file
29780         echo "Mirrored file:"
29781         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29782         echo "Plain 2 stripes 1M"
29783         lseek_test_430 $file
29784         rm $file
29785 }
29786 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29787
29788 test_430b() {
29789         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29790                 skip "OST does not support SEEK_HOLE"
29791
29792         local offset
29793         local file=$DIR/$tdir/$tfile
29794
29795         mkdir -p $DIR/$tdir
29796         # Empty layout lseek should fail
29797         $MCREATE $file
29798         # seek from 0
29799         printf "Seeking hole from 0 ... "
29800         lseek_test -l 0 $file && error "lseek should fail"
29801         printf "Seeking data from 0 ... "
29802         lseek_test -d 0 $file && error "lseek should fail"
29803         rm $file
29804
29805         # 1M-hole file
29806         $LFS setstripe -E 1M -c2 -E eof $file
29807         $TRUNCATE $file 1048576
29808         printf "Seeking hole from 1000000 ... "
29809         offset=$(lseek_test -l 1000000 $file)
29810         echo $offset
29811         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29812         printf "Seeking data from 1000000 ... "
29813         lseek_test -d 1000000 $file && error "lseek should fail"
29814         rm $file
29815
29816         # full component followed by non-inited one
29817         $LFS setstripe -E 1M -c2 -E eof $file
29818         dd if=/dev/urandom of=$file bs=1M count=1
29819         printf "Seeking hole from 1000000 ... "
29820         offset=$(lseek_test -l 1000000 $file)
29821         echo $offset
29822         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29823         printf "Seeking hole from 1048576 ... "
29824         lseek_test -l 1048576 $file && error "lseek should fail"
29825         # init second component and truncate back
29826         echo "123" >> $file
29827         $TRUNCATE $file 1048576
29828         printf "Seeking hole from 1000000 ... "
29829         offset=$(lseek_test -l 1000000 $file)
29830         echo $offset
29831         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29832         printf "Seeking hole from 1048576 ... "
29833         lseek_test -l 1048576 $file && error "lseek should fail"
29834         # boundary checks for big values
29835         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29836         offset=$(lseek_test -d 0 $file.10g)
29837         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29838         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29839         offset=$(lseek_test -d 0 $file.100g)
29840         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29841         return 0
29842 }
29843 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29844
29845 test_430c() {
29846         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29847                 skip "OST does not support SEEK_HOLE"
29848
29849         local file=$DIR/$tdir/$tfile
29850         local start
29851
29852         mkdir -p $DIR/$tdir
29853         stack_trap "rm -f $file $file.tmp"
29854         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29855
29856         # cp version 8.33+ prefers lseek over fiemap
29857         local ver=$(cp --version | awk '{ print $4; exit; }')
29858
29859         echo "cp $ver installed"
29860         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29861                 start=$SECONDS
29862                 time cp -v $file $file.tmp || error "cp $file failed"
29863                 (( SECONDS - start < 5 )) || {
29864                         strace cp $file $file.tmp |&
29865                                 grep -E "open|read|seek|FIEMAP" |
29866                                 grep -A 100 $file
29867                         error "cp: too long runtime $((SECONDS - start))"
29868                 }
29869         else
29870                 echo "cp test skipped due to $ver < 8.33"
29871         fi
29872
29873         # tar version 1.29+ supports SEEK_HOLE/DATA
29874         ver=$(tar --version | awk '{ print $4; exit; }')
29875         echo "tar $ver installed"
29876         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29877                 start=$SECONDS
29878                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29879                 (( SECONDS - start < 5 )) || {
29880                         strace tar cf $file.tmp --sparse $file |&
29881                                 grep -E "open|read|seek|FIEMAP" |
29882                                 grep -A 100 $file
29883                         error "tar: too long runtime $((SECONDS - start))"
29884                 }
29885         else
29886                 echo "tar test skipped due to $ver < 1.29"
29887         fi
29888 }
29889 run_test 430c "lseek: external tools check"
29890
29891 test_431() { # LU-14187
29892         local file=$DIR/$tdir/$tfile
29893
29894         mkdir -p $DIR/$tdir
29895         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29896         dd if=/dev/urandom of=$file bs=4k count=1
29897         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29898         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29899         #define OBD_FAIL_OST_RESTART_IO 0x251
29900         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29901         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29902         cp $file $file.0
29903         cancel_lru_locks
29904         sync_all_data
29905         echo 3 > /proc/sys/vm/drop_caches
29906         diff  $file $file.0 || error "data diff"
29907 }
29908 run_test 431 "Restart transaction for IO"
29909
29910 cleanup_test_432() {
29911         do_facet mgs $LCTL nodemap_activate 0
29912         wait_nm_sync active
29913 }
29914
29915 test_432() {
29916         local tmpdir=$TMP/dir432
29917
29918         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29919                 skip "Need MDS version at least 2.14.52"
29920
29921         stack_trap cleanup_test_432 EXIT
29922         mkdir $DIR/$tdir
29923         mkdir $tmpdir
29924
29925         do_facet mgs $LCTL nodemap_activate 1
29926         wait_nm_sync active
29927         do_facet mgs $LCTL nodemap_modify --name default \
29928                 --property admin --value 1
29929         do_facet mgs $LCTL nodemap_modify --name default \
29930                 --property trusted --value 1
29931         cancel_lru_locks mdc
29932         wait_nm_sync default admin_nodemap
29933         wait_nm_sync default trusted_nodemap
29934
29935         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29936                grep -ci "Operation not permitted") -ne 0 ]; then
29937                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29938         fi
29939 }
29940 run_test 432 "mv dir from outside Lustre"
29941
29942 test_433() {
29943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29944
29945         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29946                 skip "inode cache not supported"
29947
29948         $LCTL set_param llite.*.inode_cache=0
29949         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29950
29951         local count=256
29952         local before
29953         local after
29954
29955         cancel_lru_locks mdc
29956         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29957         createmany -m $DIR/$tdir/f $count
29958         createmany -d $DIR/$tdir/d $count
29959         ls -l $DIR/$tdir > /dev/null
29960         stack_trap "rm -rf $DIR/$tdir"
29961
29962         before=$(num_objects)
29963         cancel_lru_locks mdc
29964         after=$(num_objects)
29965
29966         # sometimes even @before is less than 2 * count
29967         while (( before - after < count )); do
29968                 sleep 1
29969                 after=$(num_objects)
29970                 wait=$((wait + 1))
29971                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29972                 if (( wait > 60 )); then
29973                         error "inode slab grew from $before to $after"
29974                 fi
29975         done
29976
29977         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29978 }
29979 run_test 433 "ldlm lock cancel releases dentries and inodes"
29980
29981 test_434() {
29982         local file
29983         local getxattr_count
29984         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29985         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29986
29987         [[ $(getenforce) == "Disabled" ]] ||
29988                 skip "lsm selinux module have to be disabled for this test"
29989
29990         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29991                 error "fail to create $DIR/$tdir/ on MDT0000"
29992
29993         touch $DIR/$tdir/$tfile-{001..100}
29994
29995         # disable the xattr cache
29996         save_lustre_params client "llite.*.xattr_cache" > $p
29997         lctl set_param llite.*.xattr_cache=0
29998         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29999
30000         # clear clients mdc stats
30001         clear_stats $mdc_stat_param ||
30002                 error "fail to clear stats on mdc MDT0000"
30003
30004         for file in $DIR/$tdir/$tfile-{001..100}; do
30005                 getfattr -n security.selinux $file |&
30006                         grep -q "Operation not supported" ||
30007                         error "getxattr on security.selinux should return EOPNOTSUPP"
30008         done
30009
30010         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30011         (( getxattr_count < 100 )) ||
30012                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30013 }
30014 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30015
30016 test_440() {
30017         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30018                 source $LUSTRE/scripts/bash-completion/lustre
30019         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30020                 source /usr/share/bash-completion/completions/lustre
30021         else
30022                 skip "bash completion scripts not found"
30023         fi
30024
30025         local lctl_completions
30026         local lfs_completions
30027
30028         lctl_completions=$(_lustre_cmds lctl)
30029         if [[ ! $lctl_completions =~ "get_param" ]]; then
30030                 error "lctl bash completion failed"
30031         fi
30032
30033         lfs_completions=$(_lustre_cmds lfs)
30034         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30035                 error "lfs bash completion failed"
30036         fi
30037 }
30038 run_test 440 "bash completion for lfs, lctl"
30039
30040 test_442() {
30041         local pid1
30042         local pid2
30043         mkdir -p $DIR/$tdir
30044         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30045         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30046         sleep 1
30047         touch $DIR/$tdir/$tfile.2
30048         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30049         $LCTL set_param fail_loc=0x1430
30050         kill -USR1 $pid1
30051         sleep 1
30052         kill -USR1 $pid2
30053         wait
30054 }
30055 run_test 442 "truncate vs read/write should not panic"
30056
30057 prep_801() {
30058         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30059         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30060                 skip "Need server version at least 2.9.55"
30061
30062         start_full_debug_logging
30063 }
30064
30065 post_801() {
30066         stop_full_debug_logging
30067 }
30068
30069 barrier_stat() {
30070         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30071                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30072                            awk '/The barrier for/ { print $7 }')
30073                 echo $st
30074         else
30075                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30076                 echo \'$st\'
30077         fi
30078 }
30079
30080 barrier_expired() {
30081         local expired
30082
30083         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30084                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30085                           awk '/will be expired/ { print $7 }')
30086         else
30087                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30088         fi
30089
30090         echo $expired
30091 }
30092
30093 test_801a() {
30094         prep_801
30095
30096         echo "Start barrier_freeze at: $(date)"
30097         #define OBD_FAIL_BARRIER_DELAY          0x2202
30098         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30099         # Do not reduce barrier time - See LU-11873
30100         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30101
30102         sleep 2
30103         local b_status=$(barrier_stat)
30104         echo "Got barrier status at: $(date)"
30105         [ "$b_status" = "'freezing_p1'" ] ||
30106                 error "(1) unexpected barrier status $b_status"
30107
30108         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30109         wait
30110         b_status=$(barrier_stat)
30111         [ "$b_status" = "'frozen'" ] ||
30112                 error "(2) unexpected barrier status $b_status"
30113
30114         local expired=$(barrier_expired)
30115         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30116         sleep $((expired + 3))
30117
30118         b_status=$(barrier_stat)
30119         [ "$b_status" = "'expired'" ] ||
30120                 error "(3) unexpected barrier status $b_status"
30121
30122         # Do not reduce barrier time - See LU-11873
30123         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30124                 error "(4) fail to freeze barrier"
30125
30126         b_status=$(barrier_stat)
30127         [ "$b_status" = "'frozen'" ] ||
30128                 error "(5) unexpected barrier status $b_status"
30129
30130         echo "Start barrier_thaw at: $(date)"
30131         #define OBD_FAIL_BARRIER_DELAY          0x2202
30132         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30133         do_facet mgs $LCTL barrier_thaw $FSNAME &
30134
30135         sleep 2
30136         b_status=$(barrier_stat)
30137         echo "Got barrier status at: $(date)"
30138         [ "$b_status" = "'thawing'" ] ||
30139                 error "(6) unexpected barrier status $b_status"
30140
30141         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30142         wait
30143         b_status=$(barrier_stat)
30144         [ "$b_status" = "'thawed'" ] ||
30145                 error "(7) unexpected barrier status $b_status"
30146
30147         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30148         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30149         do_facet mgs $LCTL barrier_freeze $FSNAME
30150
30151         b_status=$(barrier_stat)
30152         [ "$b_status" = "'failed'" ] ||
30153                 error "(8) unexpected barrier status $b_status"
30154
30155         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30156         do_facet mgs $LCTL barrier_thaw $FSNAME
30157
30158         post_801
30159 }
30160 run_test 801a "write barrier user interfaces and stat machine"
30161
30162 test_801b() {
30163         prep_801
30164
30165         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30166         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30167         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30168         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30169         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30170
30171         cancel_lru_locks mdc
30172
30173         # 180 seconds should be long enough
30174         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30175
30176         local b_status=$(barrier_stat)
30177         [ "$b_status" = "'frozen'" ] ||
30178                 error "(6) unexpected barrier status $b_status"
30179
30180         mkdir $DIR/$tdir/d0/d10 &
30181         mkdir_pid=$!
30182
30183         touch $DIR/$tdir/d1/f13 &
30184         touch_pid=$!
30185
30186         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30187         ln_pid=$!
30188
30189         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30190         mv_pid=$!
30191
30192         rm -f $DIR/$tdir/d4/f12 &
30193         rm_pid=$!
30194
30195         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30196
30197         # To guarantee taht the 'stat' is not blocked
30198         b_status=$(barrier_stat)
30199         [ "$b_status" = "'frozen'" ] ||
30200                 error "(8) unexpected barrier status $b_status"
30201
30202         # let above commands to run at background
30203         sleep 5
30204
30205         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30206         ps -p $touch_pid || error "(10) touch should be blocked"
30207         ps -p $ln_pid || error "(11) link should be blocked"
30208         ps -p $mv_pid || error "(12) rename should be blocked"
30209         ps -p $rm_pid || error "(13) unlink should be blocked"
30210
30211         b_status=$(barrier_stat)
30212         [ "$b_status" = "'frozen'" ] ||
30213                 error "(14) unexpected barrier status $b_status"
30214
30215         do_facet mgs $LCTL barrier_thaw $FSNAME
30216         b_status=$(barrier_stat)
30217         [ "$b_status" = "'thawed'" ] ||
30218                 error "(15) unexpected barrier status $b_status"
30219
30220         wait $mkdir_pid || error "(16) mkdir should succeed"
30221         wait $touch_pid || error "(17) touch should succeed"
30222         wait $ln_pid || error "(18) link should succeed"
30223         wait $mv_pid || error "(19) rename should succeed"
30224         wait $rm_pid || error "(20) unlink should succeed"
30225
30226         post_801
30227 }
30228 run_test 801b "modification will be blocked by write barrier"
30229
30230 test_801c() {
30231         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30232
30233         prep_801
30234
30235         stop mds2 || error "(1) Fail to stop mds2"
30236
30237         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30238
30239         local b_status=$(barrier_stat)
30240         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30241                 do_facet mgs $LCTL barrier_thaw $FSNAME
30242                 error "(2) unexpected barrier status $b_status"
30243         }
30244
30245         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30246                 error "(3) Fail to rescan barrier bitmap"
30247
30248         # Do not reduce barrier time - See LU-11873
30249         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30250
30251         b_status=$(barrier_stat)
30252         [ "$b_status" = "'frozen'" ] ||
30253                 error "(4) unexpected barrier status $b_status"
30254
30255         do_facet mgs $LCTL barrier_thaw $FSNAME
30256         b_status=$(barrier_stat)
30257         [ "$b_status" = "'thawed'" ] ||
30258                 error "(5) unexpected barrier status $b_status"
30259
30260         local devname=$(mdsdevname 2)
30261
30262         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30263
30264         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30265                 error "(7) Fail to rescan barrier bitmap"
30266
30267         post_801
30268 }
30269 run_test 801c "rescan barrier bitmap"
30270
30271 test_802b() {
30272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30273         remote_mds_nodsh && skip "remote MDS with nodsh"
30274
30275         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30276                 skip "readonly option not available"
30277
30278         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30279
30280         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30281                 error "(2) Fail to copy"
30282
30283         # write back all cached data before setting MDT to readonly
30284         cancel_lru_locks
30285         sync_all_data
30286
30287         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30288         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30289
30290         echo "Modify should be refused"
30291         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30292
30293         echo "Read should be allowed"
30294         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30295                 error "(7) Read should succeed under ro mode"
30296
30297         # disable readonly
30298         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30299 }
30300 run_test 802b "be able to set MDTs to readonly"
30301
30302 test_803a() {
30303         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30304         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30305                 skip "MDS needs to be newer than 2.10.54"
30306
30307         mkdir_on_mdt0 $DIR/$tdir
30308         # Create some objects on all MDTs to trigger related logs objects
30309         for idx in $(seq $MDSCOUNT); do
30310                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30311                         $DIR/$tdir/dir${idx} ||
30312                         error "Fail to create $DIR/$tdir/dir${idx}"
30313         done
30314
30315         wait_delete_completed # ensure old test cleanups are finished
30316         sleep 3
30317         echo "before create:"
30318         $LFS df -i $MOUNT
30319         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30320
30321         for i in {1..10}; do
30322                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30323                         error "Fail to create $DIR/$tdir/foo$i"
30324         done
30325
30326         # sync ZFS-on-MDS to refresh statfs data
30327         wait_zfs_commit mds1
30328         sleep 3
30329         echo "after create:"
30330         $LFS df -i $MOUNT
30331         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30332
30333         # allow for an llog to be cleaned up during the test
30334         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30335                 error "before ($before_used) + 10 > after ($after_used)"
30336
30337         for i in {1..10}; do
30338                 rm -rf $DIR/$tdir/foo$i ||
30339                         error "Fail to remove $DIR/$tdir/foo$i"
30340         done
30341
30342         # sync ZFS-on-MDS to refresh statfs data
30343         wait_zfs_commit mds1
30344         wait_delete_completed
30345         sleep 3 # avoid MDT return cached statfs
30346         echo "after unlink:"
30347         $LFS df -i $MOUNT
30348         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30349
30350         # allow for an llog to be created during the test
30351         [ $after_used -le $((before_used + 1)) ] ||
30352                 error "after ($after_used) > before ($before_used) + 1"
30353 }
30354 run_test 803a "verify agent object for remote object"
30355
30356 test_803b() {
30357         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30358         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30359                 skip "MDS needs to be newer than 2.13.56"
30360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30361
30362         for i in $(seq 0 $((MDSCOUNT - 1))); do
30363                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30364         done
30365
30366         local before=0
30367         local after=0
30368
30369         local tmp
30370
30371         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30372         for i in $(seq 0 $((MDSCOUNT - 1))); do
30373                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30374                         awk '/getattr/ { print $2 }')
30375                 before=$((before + tmp))
30376         done
30377         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30378         for i in $(seq 0 $((MDSCOUNT - 1))); do
30379                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30380                         awk '/getattr/ { print $2 }')
30381                 after=$((after + tmp))
30382         done
30383
30384         [ $before -eq $after ] || error "getattr count $before != $after"
30385 }
30386 run_test 803b "remote object can getattr from cache"
30387
30388 test_804() {
30389         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30390         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30391                 skip "MDS needs to be newer than 2.10.54"
30392         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30393
30394         mkdir -p $DIR/$tdir
30395         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30396                 error "Fail to create $DIR/$tdir/dir0"
30397
30398         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30399         local dev=$(mdsdevname 2)
30400
30401         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30402                 grep ${fid} || error "NOT found agent entry for dir0"
30403
30404         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30405                 error "Fail to create $DIR/$tdir/dir1"
30406
30407         touch $DIR/$tdir/dir1/foo0 ||
30408                 error "Fail to create $DIR/$tdir/dir1/foo0"
30409         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30410         local rc=0
30411
30412         for idx in $(seq $MDSCOUNT); do
30413                 dev=$(mdsdevname $idx)
30414                 do_facet mds${idx} \
30415                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30416                         grep ${fid} && rc=$idx
30417         done
30418
30419         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30420                 error "Fail to rename foo0 to foo1"
30421         if [ $rc -eq 0 ]; then
30422                 for idx in $(seq $MDSCOUNT); do
30423                         dev=$(mdsdevname $idx)
30424                         do_facet mds${idx} \
30425                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30426                         grep ${fid} && rc=$idx
30427                 done
30428         fi
30429
30430         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30431                 error "Fail to rename foo1 to foo2"
30432         if [ $rc -eq 0 ]; then
30433                 for idx in $(seq $MDSCOUNT); do
30434                         dev=$(mdsdevname $idx)
30435                         do_facet mds${idx} \
30436                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30437                         grep ${fid} && rc=$idx
30438                 done
30439         fi
30440
30441         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30442
30443         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30444                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30445         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30446                 error "Fail to rename foo2 to foo0"
30447         unlink $DIR/$tdir/dir1/foo0 ||
30448                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30449         rm -rf $DIR/$tdir/dir0 ||
30450                 error "Fail to rm $DIR/$tdir/dir0"
30451
30452         for idx in $(seq $MDSCOUNT); do
30453                 rc=0
30454
30455                 stop mds${idx}
30456                 dev=$(mdsdevname $idx)
30457                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30458                         rc=$?
30459                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30460                         error "mount mds$idx failed"
30461                 df $MOUNT > /dev/null 2>&1
30462
30463                 # e2fsck should not return error
30464                 [ $rc -eq 0 ] ||
30465                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30466         done
30467 }
30468 run_test 804 "verify agent entry for remote entry"
30469
30470 cleanup_805() {
30471         do_facet $SINGLEMDS zfs set quota=$old $fsset
30472         unlinkmany $DIR/$tdir/f- 1000000
30473         trap 0
30474 }
30475
30476 test_805() {
30477         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30478         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30479         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30480                 skip "netfree not implemented before 0.7"
30481         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30482                 skip "Need MDS version at least 2.10.57"
30483
30484         local fsset
30485         local freekb
30486         local usedkb
30487         local old
30488         local quota
30489         local pref="osd-zfs.$FSNAME-MDT0000."
30490
30491         # limit available space on MDS dataset to meet nospace issue
30492         # quickly. then ZFS 0.7.2 can use reserved space if asked
30493         # properly (using netfree flag in osd_declare_destroy()
30494         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30495         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30496                 gawk '{print $3}')
30497         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30498         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30499         let "usedkb=usedkb-freekb"
30500         let "freekb=freekb/2"
30501         if let "freekb > 5000"; then
30502                 let "freekb=5000"
30503         fi
30504         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30505         trap cleanup_805 EXIT
30506         mkdir_on_mdt0 $DIR/$tdir
30507         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30508                 error "Can't set PFL layout"
30509         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30510         rm -rf $DIR/$tdir || error "not able to remove"
30511         do_facet $SINGLEMDS zfs set quota=$old $fsset
30512         trap 0
30513 }
30514 run_test 805 "ZFS can remove from full fs"
30515
30516 # Size-on-MDS test
30517 check_lsom_data()
30518 {
30519         local file=$1
30520         local expect=$(stat -c %s $file)
30521
30522         check_lsom_size $1 $expect
30523
30524         local blocks=$($LFS getsom -b $file)
30525         expect=$(stat -c %b $file)
30526         [[ $blocks == $expect ]] ||
30527                 error "$file expected blocks: $expect, got: $blocks"
30528 }
30529
30530 check_lsom_size()
30531 {
30532         local size
30533         local expect=$2
30534
30535         cancel_lru_locks mdc
30536
30537         size=$($LFS getsom -s $1)
30538         [[ $size == $expect ]] ||
30539                 error "$file expected size: $expect, got: $size"
30540 }
30541
30542 test_806() {
30543         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30544                 skip "Need MDS version at least 2.11.52"
30545
30546         local bs=1048576
30547
30548         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30549
30550         disable_opencache
30551         stack_trap "restore_opencache"
30552
30553         # single-threaded write
30554         echo "Test SOM for single-threaded write"
30555         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30556                 error "write $tfile failed"
30557         check_lsom_size $DIR/$tfile $bs
30558
30559         local num=32
30560         local size=$(($num * $bs))
30561         local offset=0
30562         local i
30563
30564         echo "Test SOM for single client multi-threaded($num) write"
30565         $TRUNCATE $DIR/$tfile 0
30566         for ((i = 0; i < $num; i++)); do
30567                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30568                 local pids[$i]=$!
30569                 offset=$((offset + $bs))
30570         done
30571         for (( i=0; i < $num; i++ )); do
30572                 wait ${pids[$i]}
30573         done
30574         check_lsom_size $DIR/$tfile $size
30575
30576         $TRUNCATE $DIR/$tfile 0
30577         for ((i = 0; i < $num; i++)); do
30578                 offset=$((offset - $bs))
30579                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30580                 local pids[$i]=$!
30581         done
30582         for (( i=0; i < $num; i++ )); do
30583                 wait ${pids[$i]}
30584         done
30585         check_lsom_size $DIR/$tfile $size
30586
30587         # multi-client writes
30588         num=$(get_node_count ${CLIENTS//,/ })
30589         size=$(($num * $bs))
30590         offset=0
30591         i=0
30592
30593         echo "Test SOM for multi-client ($num) writes"
30594         $TRUNCATE $DIR/$tfile 0
30595         for client in ${CLIENTS//,/ }; do
30596                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30597                 local pids[$i]=$!
30598                 i=$((i + 1))
30599                 offset=$((offset + $bs))
30600         done
30601         for (( i=0; i < $num; i++ )); do
30602                 wait ${pids[$i]}
30603         done
30604         check_lsom_size $DIR/$tfile $offset
30605
30606         i=0
30607         $TRUNCATE $DIR/$tfile 0
30608         for client in ${CLIENTS//,/ }; do
30609                 offset=$((offset - $bs))
30610                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30611                 local pids[$i]=$!
30612                 i=$((i + 1))
30613         done
30614         for (( i=0; i < $num; i++ )); do
30615                 wait ${pids[$i]}
30616         done
30617         check_lsom_size $DIR/$tfile $size
30618
30619         # verify SOM blocks count
30620         echo "Verify SOM block count"
30621         $TRUNCATE $DIR/$tfile 0
30622         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30623                 error "failed to write file $tfile with fdatasync and fstat"
30624         check_lsom_data $DIR/$tfile
30625
30626         $TRUNCATE $DIR/$tfile 0
30627         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30628                 error "failed to write file $tfile with fdatasync"
30629         check_lsom_data $DIR/$tfile
30630
30631         $TRUNCATE $DIR/$tfile 0
30632         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30633                 error "failed to write file $tfile with sync IO"
30634         check_lsom_data $DIR/$tfile
30635
30636         # verify truncate
30637         echo "Test SOM for truncate"
30638         # use ftruncate to sync blocks on close request
30639         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30640         check_lsom_size $DIR/$tfile 16384
30641         check_lsom_data $DIR/$tfile
30642
30643         $TRUNCATE $DIR/$tfile 1234
30644         check_lsom_size $DIR/$tfile 1234
30645         # sync blocks on the MDT
30646         $MULTIOP $DIR/$tfile oc
30647         check_lsom_data $DIR/$tfile
30648 }
30649 run_test 806 "Verify Lazy Size on MDS"
30650
30651 test_807() {
30652         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30653         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30654                 skip "Need MDS version at least 2.11.52"
30655
30656         # Registration step
30657         changelog_register || error "changelog_register failed"
30658         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30659         changelog_users $SINGLEMDS | grep -q $cl_user ||
30660                 error "User $cl_user not found in changelog_users"
30661
30662         rm -rf $DIR/$tdir || error "rm $tdir failed"
30663         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30664         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30665         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30666         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30667                 error "truncate $tdir/trunc failed"
30668
30669         local bs=1048576
30670         echo "Test SOM for single-threaded write with fsync"
30671         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30672                 error "write $tfile failed"
30673         sync;sync;sync
30674
30675         # multi-client wirtes
30676         local num=$(get_node_count ${CLIENTS//,/ })
30677         local offset=0
30678         local i=0
30679
30680         echo "Test SOM for multi-client ($num) writes"
30681         touch $DIR/$tfile || error "touch $tfile failed"
30682         $TRUNCATE $DIR/$tfile 0
30683         for client in ${CLIENTS//,/ }; do
30684                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30685                 local pids[$i]=$!
30686                 i=$((i + 1))
30687                 offset=$((offset + $bs))
30688         done
30689         for (( i=0; i < $num; i++ )); do
30690                 wait ${pids[$i]}
30691         done
30692
30693         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30694         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30695         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30696         check_lsom_data $DIR/$tdir/trunc
30697         check_lsom_data $DIR/$tdir/single_dd
30698         check_lsom_data $DIR/$tfile
30699
30700         rm -rf $DIR/$tdir
30701         # Deregistration step
30702         changelog_deregister || error "changelog_deregister failed"
30703 }
30704 run_test 807 "verify LSOM syncing tool"
30705
30706 check_som_nologged()
30707 {
30708         local lines=$($LFS changelog $FSNAME-MDT0000 |
30709                 grep 'x=trusted.som' | wc -l)
30710         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30711 }
30712
30713 test_808() {
30714         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30715                 skip "Need MDS version at least 2.11.55"
30716
30717         # Registration step
30718         changelog_register || error "changelog_register failed"
30719
30720         touch $DIR/$tfile || error "touch $tfile failed"
30721         check_som_nologged
30722
30723         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30724                 error "write $tfile failed"
30725         check_som_nologged
30726
30727         $TRUNCATE $DIR/$tfile 1234
30728         check_som_nologged
30729
30730         $TRUNCATE $DIR/$tfile 1048576
30731         check_som_nologged
30732
30733         # Deregistration step
30734         changelog_deregister || error "changelog_deregister failed"
30735 }
30736 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30737
30738 check_som_nodata()
30739 {
30740         $LFS getsom $1
30741         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30742 }
30743
30744 test_809() {
30745         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30746                 skip "Need MDS version at least 2.11.56"
30747
30748         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30749                 error "failed to create DoM-only file $DIR/$tfile"
30750         touch $DIR/$tfile || error "touch $tfile failed"
30751         check_som_nodata $DIR/$tfile
30752
30753         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30754                 error "write $tfile failed"
30755         check_som_nodata $DIR/$tfile
30756
30757         $TRUNCATE $DIR/$tfile 1234
30758         check_som_nodata $DIR/$tfile
30759
30760         $TRUNCATE $DIR/$tfile 4097
30761         check_som_nodata $DIR/$file
30762 }
30763 run_test 809 "Verify no SOM xattr store for DoM-only files"
30764
30765 test_810() {
30766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30767         $GSS && skip_env "could not run with gss"
30768         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30769                 skip "OST < 2.12.58 doesn't align checksum"
30770
30771         set_checksums 1
30772         stack_trap "set_checksums $ORIG_CSUM" EXIT
30773         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30774
30775         local csum
30776         local before
30777         local after
30778         for csum in $CKSUM_TYPES; do
30779                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30780                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30781                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30782                         eval set -- $i
30783                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30784                         before=$(md5sum $DIR/$tfile)
30785                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30786                         after=$(md5sum $DIR/$tfile)
30787                         [ "$before" == "$after" ] ||
30788                                 error "$csum: $before != $after bs=$1 seek=$2"
30789                 done
30790         done
30791 }
30792 run_test 810 "partial page writes on ZFS (LU-11663)"
30793
30794 test_812a() {
30795         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30796                 skip "OST < 2.12.51 doesn't support this fail_loc"
30797
30798         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30799         # ensure ost1 is connected
30800         stat $DIR/$tfile >/dev/null || error "can't stat"
30801         wait_osc_import_state client ost1 FULL
30802         # no locks, no reqs to let the connection idle
30803         cancel_lru_locks osc
30804
30805         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30806 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30807         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30808         wait_osc_import_state client ost1 CONNECTING
30809         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30810
30811         stat $DIR/$tfile >/dev/null || error "can't stat file"
30812 }
30813 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30814
30815 test_812b() { # LU-12378
30816         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30817                 skip "OST < 2.12.51 doesn't support this fail_loc"
30818
30819         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30820         # ensure ost1 is connected
30821         stat $DIR/$tfile >/dev/null || error "can't stat"
30822         wait_osc_import_state client ost1 FULL
30823         # no locks, no reqs to let the connection idle
30824         cancel_lru_locks osc
30825
30826         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30827 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30828         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30829         wait_osc_import_state client ost1 CONNECTING
30830         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30831
30832         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30833         wait_osc_import_state client ost1 IDLE
30834 }
30835 run_test 812b "do not drop no resend request for idle connect"
30836
30837 test_812c() {
30838         local old
30839
30840         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30841
30842         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30843         $LFS getstripe $DIR/$tfile
30844         $LCTL set_param osc.*.idle_timeout=10
30845         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30846         # ensure ost1 is connected
30847         stat $DIR/$tfile >/dev/null || error "can't stat"
30848         wait_osc_import_state client ost1 FULL
30849         # no locks, no reqs to let the connection idle
30850         cancel_lru_locks osc
30851
30852 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30853         $LCTL set_param fail_loc=0x80000533
30854         sleep 15
30855         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30856 }
30857 run_test 812c "idle import vs lock enqueue race"
30858
30859 test_813() {
30860         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30861         [ -z "$file_heat_sav" ] && skip "no file heat support"
30862
30863         local readsample
30864         local writesample
30865         local readbyte
30866         local writebyte
30867         local readsample1
30868         local writesample1
30869         local readbyte1
30870         local writebyte1
30871
30872         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30873         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30874
30875         $LCTL set_param -n llite.*.file_heat=1
30876         echo "Turn on file heat"
30877         echo "Period second: $period_second, Decay percentage: $decay_pct"
30878
30879         echo "QQQQ" > $DIR/$tfile
30880         echo "QQQQ" > $DIR/$tfile
30881         echo "QQQQ" > $DIR/$tfile
30882         cat $DIR/$tfile > /dev/null
30883         cat $DIR/$tfile > /dev/null
30884         cat $DIR/$tfile > /dev/null
30885         cat $DIR/$tfile > /dev/null
30886
30887         local out=$($LFS heat_get $DIR/$tfile)
30888
30889         $LFS heat_get $DIR/$tfile
30890         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30891         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30892         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30893         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30894
30895         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30896         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30897         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30898         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30899
30900         sleep $((period_second + 3))
30901         echo "Sleep $((period_second + 3)) seconds..."
30902         # The recursion formula to calculate the heat of the file f is as
30903         # follow:
30904         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30905         # Where Hi is the heat value in the period between time points i*I and
30906         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30907         # to the weight of Ci.
30908         out=$($LFS heat_get $DIR/$tfile)
30909         $LFS heat_get $DIR/$tfile
30910         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30911         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30912         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30913         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30914
30915         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30916                 error "read sample ($readsample) is wrong"
30917         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30918                 error "write sample ($writesample) is wrong"
30919         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30920                 error "read bytes ($readbyte) is wrong"
30921         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30922                 error "write bytes ($writebyte) is wrong"
30923
30924         echo "QQQQ" > $DIR/$tfile
30925         echo "QQQQ" > $DIR/$tfile
30926         echo "QQQQ" > $DIR/$tfile
30927         cat $DIR/$tfile > /dev/null
30928         cat $DIR/$tfile > /dev/null
30929         cat $DIR/$tfile > /dev/null
30930         cat $DIR/$tfile > /dev/null
30931
30932         sleep $((period_second + 3))
30933         echo "Sleep $((period_second + 3)) seconds..."
30934
30935         out=$($LFS heat_get $DIR/$tfile)
30936         $LFS heat_get $DIR/$tfile
30937         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30938         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30939         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30940         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30941
30942         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30943                 4 * $decay_pct) / 100") -eq 1 ] ||
30944                 error "read sample ($readsample1) is wrong"
30945         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30946                 3 * $decay_pct) / 100") -eq 1 ] ||
30947                 error "write sample ($writesample1) is wrong"
30948         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30949                 20 * $decay_pct) / 100") -eq 1 ] ||
30950                 error "read bytes ($readbyte1) is wrong"
30951         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30952                 15 * $decay_pct) / 100") -eq 1 ] ||
30953                 error "write bytes ($writebyte1) is wrong"
30954
30955         echo "Turn off file heat for the file $DIR/$tfile"
30956         $LFS heat_set -o $DIR/$tfile
30957
30958         echo "QQQQ" > $DIR/$tfile
30959         echo "QQQQ" > $DIR/$tfile
30960         echo "QQQQ" > $DIR/$tfile
30961         cat $DIR/$tfile > /dev/null
30962         cat $DIR/$tfile > /dev/null
30963         cat $DIR/$tfile > /dev/null
30964         cat $DIR/$tfile > /dev/null
30965
30966         out=$($LFS heat_get $DIR/$tfile)
30967         $LFS heat_get $DIR/$tfile
30968         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30969         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30970         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30971         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30972
30973         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30974         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30975         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30976         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30977
30978         echo "Trun on file heat for the file $DIR/$tfile"
30979         $LFS heat_set -O $DIR/$tfile
30980
30981         echo "QQQQ" > $DIR/$tfile
30982         echo "QQQQ" > $DIR/$tfile
30983         echo "QQQQ" > $DIR/$tfile
30984         cat $DIR/$tfile > /dev/null
30985         cat $DIR/$tfile > /dev/null
30986         cat $DIR/$tfile > /dev/null
30987         cat $DIR/$tfile > /dev/null
30988
30989         out=$($LFS heat_get $DIR/$tfile)
30990         $LFS heat_get $DIR/$tfile
30991         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30992         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30993         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30994         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30995
30996         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30997         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30998         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30999         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31000
31001         $LFS heat_set -c $DIR/$tfile
31002         $LCTL set_param -n llite.*.file_heat=0
31003         echo "Turn off file heat support for the Lustre filesystem"
31004
31005         echo "QQQQ" > $DIR/$tfile
31006         echo "QQQQ" > $DIR/$tfile
31007         echo "QQQQ" > $DIR/$tfile
31008         cat $DIR/$tfile > /dev/null
31009         cat $DIR/$tfile > /dev/null
31010         cat $DIR/$tfile > /dev/null
31011         cat $DIR/$tfile > /dev/null
31012
31013         out=$($LFS heat_get $DIR/$tfile)
31014         $LFS heat_get $DIR/$tfile
31015         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31016         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31017         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31018         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31019
31020         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31021         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31022         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31023         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31024
31025         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31026         rm -f $DIR/$tfile
31027 }
31028 run_test 813 "File heat verfication"
31029
31030 test_814()
31031 {
31032         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31033         echo -n y >> $DIR/$tfile
31034         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31035         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31036 }
31037 run_test 814 "sparse cp works as expected (LU-12361)"
31038
31039 test_815()
31040 {
31041         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31042         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31043 }
31044 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31045
31046 test_816() {
31047         local ost1_imp=$(get_osc_import_name client ost1)
31048         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31049                          cut -d'.' -f2)
31050
31051         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31052         # ensure ost1 is connected
31053
31054         stat $DIR/$tfile >/dev/null || error "can't stat"
31055         wait_osc_import_state client ost1 FULL
31056         # no locks, no reqs to let the connection idle
31057         cancel_lru_locks osc
31058         lru_resize_disable osc
31059         local before
31060         local now
31061         before=$($LCTL get_param -n \
31062                  ldlm.namespaces.$imp_name.lru_size)
31063
31064         wait_osc_import_state client ost1 IDLE
31065         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31066         now=$($LCTL get_param -n \
31067               ldlm.namespaces.$imp_name.lru_size)
31068         [ $before == $now ] || error "lru_size changed $before != $now"
31069 }
31070 run_test 816 "do not reset lru_resize on idle reconnect"
31071
31072 cleanup_817() {
31073         umount $tmpdir
31074         exportfs -u localhost:$DIR/nfsexp
31075         rm -rf $DIR/nfsexp
31076 }
31077
31078 test_817() {
31079         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31080
31081         mkdir -p $DIR/nfsexp
31082         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31083                 error "failed to export nfs"
31084
31085         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31086         stack_trap cleanup_817 EXIT
31087
31088         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31089                 error "failed to mount nfs to $tmpdir"
31090
31091         cp /bin/true $tmpdir
31092         $DIR/nfsexp/true || error "failed to execute 'true' command"
31093 }
31094 run_test 817 "nfsd won't cache write lock for exec file"
31095
31096 test_818() {
31097         test_mkdir -i0 -c1 $DIR/$tdir
31098         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31099         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31100         stop $SINGLEMDS
31101
31102         # restore osp-syn threads
31103         stack_trap "fail $SINGLEMDS"
31104
31105         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31106         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31107         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31108                 error "start $SINGLEMDS failed"
31109         rm -rf $DIR/$tdir
31110
31111         local testid=$(echo $TESTNAME | tr '_' ' ')
31112
31113         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31114                 grep "run LFSCK" || error "run LFSCK is not suggested"
31115 }
31116 run_test 818 "unlink with failed llog"
31117
31118 test_819a() {
31119         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31120         cancel_lru_locks osc
31121         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31122         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31123         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31124         rm -f $TDIR/$tfile
31125 }
31126 run_test 819a "too big niobuf in read"
31127
31128 test_819b() {
31129         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31130         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31131         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31132         cancel_lru_locks osc
31133         sleep 1
31134         rm -f $TDIR/$tfile
31135 }
31136 run_test 819b "too big niobuf in write"
31137
31138
31139 function test_820_start_ost() {
31140         sleep 5
31141
31142         for num in $(seq $OSTCOUNT); do
31143                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31144         done
31145 }
31146
31147 test_820() {
31148         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31149
31150         mkdir $DIR/$tdir
31151         umount_client $MOUNT || error "umount failed"
31152         for num in $(seq $OSTCOUNT); do
31153                 stop ost$num
31154         done
31155
31156         # mount client with no active OSTs
31157         # so that the client can't initialize max LOV EA size
31158         # from OSC notifications
31159         mount_client $MOUNT || error "mount failed"
31160         # delay OST starting to keep this 0 max EA size for a while
31161         test_820_start_ost &
31162
31163         # create a directory on MDS2
31164         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31165                 error "Failed to create directory"
31166         # open intent should update default EA size
31167         # see mdc_update_max_ea_from_body()
31168         # notice this is the very first RPC to MDS2
31169         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31170         ret=$?
31171         echo $out
31172         # With SSK, this situation can lead to -EPERM being returned.
31173         # In that case, simply retry.
31174         if [ $ret -ne 0 ] && $SHARED_KEY; then
31175                 if echo "$out" | grep -q "not permitted"; then
31176                         cp /etc/services $DIR/$tdir/mds2
31177                         ret=$?
31178                 fi
31179         fi
31180         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31181 }
31182 run_test 820 "update max EA from open intent"
31183
31184 test_823() {
31185         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31186         local OST_MAX_PRECREATE=20000
31187
31188         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31189                 skip "Need MDS version at least 2.14.56"
31190
31191         save_lustre_params mds1 \
31192                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31193         do_facet $SINGLEMDS "$LCTL set_param -n \
31194                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31195         do_facet $SINGLEMDS "$LCTL set_param -n \
31196                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31197
31198         stack_trap "restore_lustre_params < $p; rm $p"
31199
31200         do_facet $SINGLEMDS "$LCTL set_param -n \
31201                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31202
31203         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31204                       osp.$FSNAME-OST0000*MDT0000.create_count")
31205         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31206                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31207         local expect_count=$(((($max/2)/256) * 256))
31208
31209         log "setting create_count to 100200:"
31210         log " -result- count: $count with max: $max, expecting: $expect_count"
31211
31212         [[ $count -eq expect_count ]] ||
31213                 error "Create count not set to max precreate."
31214 }
31215 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31216
31217 test_831() {
31218         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31219                 skip "Need MDS version 2.14.56"
31220
31221         local sync_changes=$(do_facet $SINGLEMDS \
31222                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31223
31224         [ "$sync_changes" -gt 100 ] &&
31225                 skip "Sync changes $sync_changes > 100 already"
31226
31227         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31228
31229         $LFS mkdir -i 0 $DIR/$tdir
31230         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31231
31232         save_lustre_params mds1 \
31233                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31234         save_lustre_params mds1 \
31235                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31236
31237         do_facet mds1 "$LCTL set_param -n \
31238                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31239                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31240         stack_trap "restore_lustre_params < $p" EXIT
31241
31242         createmany -o $DIR/$tdir/f- 1000
31243         unlinkmany $DIR/$tdir/f- 1000 &
31244         local UNLINK_PID=$!
31245
31246         while sleep 1; do
31247                 sync_changes=$(do_facet mds1 \
31248                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31249                 # the check in the code is racy, fail the test
31250                 # if the value above the limit by 10.
31251                 [ $sync_changes -gt 110 ] && {
31252                         kill -2 $UNLINK_PID
31253                         wait
31254                         error "osp changes throttling failed, $sync_changes>110"
31255                 }
31256                 kill -0 $UNLINK_PID 2> /dev/null || break
31257         done
31258         wait
31259 }
31260 run_test 831 "throttling unlink/setattr queuing on OSP"
31261
31262 test_832() {
31263         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31264         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31265                 skip "Need MDS version 2.15.52+"
31266         is_rmentry_supported || skip "rm_entry not supported"
31267
31268         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31269         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31270         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31271                 error "mkdir remote_dir failed"
31272         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31273                 error "mkdir striped_dir failed"
31274         touch $DIR/$tdir/file || error "touch file failed"
31275         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31276         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31277 }
31278 run_test 832 "lfs rm_entry"
31279
31280 test_833() {
31281         local file=$DIR/$tfile
31282
31283         stack_trap "rm -f $file" EXIT
31284         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31285
31286         local wpid
31287         local rpid
31288         local rpid2
31289
31290         # Buffered I/O write
31291         (
31292                 while [ ! -e $DIR/sanity.833.lck ]; do
31293                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31294                                 error "failed to write $file"
31295                         sleep 0.$((RANDOM % 4 + 1))
31296                 done
31297         )&
31298         wpid=$!
31299
31300         # Buffered I/O read
31301         (
31302                 while [ ! -e $DIR/sanity.833.lck ]; do
31303                         dd if=$file of=/dev/null bs=1M count=50 ||
31304                                 error "failed to read $file"
31305                         sleep 0.$((RANDOM % 4 + 1))
31306                 done
31307         )&
31308         rpid=$!
31309
31310         # Direct I/O read
31311         (
31312                 while [ ! -e $DIR/sanity.833.lck ]; do
31313                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31314                                 error "failed to read $file in direct I/O mode"
31315                         sleep 0.$((RANDOM % 4 + 1))
31316                 done
31317         )&
31318         rpid2=$!
31319
31320         sleep 30
31321         touch $DIR/sanity.833.lck
31322         wait $wpid || error "$?: buffered write failed"
31323         wait $rpid || error "$?: buffered read failed"
31324         wait $rpid2 || error "$?: direct read failed"
31325 }
31326 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31327
31328 test_850() {
31329         local dir=$DIR/$tdir
31330         local file=$dir/$tfile
31331         local statsfile=$dir/all_job_stats.txt
31332
31333         test_mkdir -p $dir || error "failed to create dir $dir"
31334         echo "abcdefg" > $file || error "failed to create file $file"
31335
31336         # read job_stats in the living system
31337         lljobstat -n 1 ||
31338                 error "failed to run lljobstat on living system"
31339
31340         $LCTL get_param *.*.job_stats > $statsfile
31341         lljobstat --statsfile=$statsfile ||
31342                 error "failed to run lljobstat on file $statsfile"
31343 }
31344 run_test 850 "lljobstat can parse living and aggregated job_stats"
31345
31346 #
31347 # tests that do cleanup/setup should be run at the end
31348 #
31349
31350 test_900() {
31351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31352         local ls
31353
31354         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31355         $LCTL set_param fail_loc=0x903
31356
31357         cancel_lru_locks MGC
31358
31359         FAIL_ON_ERROR=true cleanup
31360         FAIL_ON_ERROR=true setup
31361 }
31362 run_test 900 "umount should not race with any mgc requeue thread"
31363
31364 # LUS-6253/LU-11185
31365 test_901() {
31366         local old
31367         local count
31368         local oldc
31369         local newc
31370         local olds
31371         local news
31372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31373
31374         # some get_param have a bug to handle dot in param name
31375         cancel_lru_locks MGC
31376         old=$(mount -t lustre | wc -l)
31377         # 1 config+sptlrpc
31378         # 2 params
31379         # 3 nodemap
31380         # 4 IR
31381         old=$((old * 4))
31382         oldc=0
31383         count=0
31384         while [ $old -ne $oldc ]; do
31385                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31386                 sleep 1
31387                 ((count++))
31388                 if [ $count -ge $TIMEOUT ]; then
31389                         error "too large timeout"
31390                 fi
31391         done
31392         umount_client $MOUNT || error "umount failed"
31393         mount_client $MOUNT || error "mount failed"
31394         cancel_lru_locks MGC
31395         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31396
31397         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31398
31399         return 0
31400 }
31401 run_test 901 "don't leak a mgc lock on client umount"
31402
31403 # LU-13377
31404 test_902() {
31405         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31406                 skip "client does not have LU-13377 fix"
31407         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31408         $LCTL set_param fail_loc=0x1415
31409         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31410         cancel_lru_locks osc
31411         rm -f $DIR/$tfile
31412 }
31413 run_test 902 "test short write doesn't hang lustre"
31414
31415 # LU-14711
31416 test_903() {
31417         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31418         echo "blah" > $DIR/${tfile}-2
31419         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31420         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31421         $LCTL set_param fail_loc=0x417 fail_val=20
31422
31423         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31424         sleep 1 # To start the destroy
31425         wait_destroy_complete 150 || error "Destroy taking too long"
31426         cat $DIR/$tfile > /dev/null || error "Evicted"
31427 }
31428 run_test 903 "Test long page discard does not cause evictions"
31429
31430 test_904() {
31431         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31432         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31433                 grep -q project || skip "skip project quota not supported"
31434
31435         local testfile="$DIR/$tdir/$tfile"
31436         local xattr="trusted.projid"
31437         local projid
31438         local mdts=$(comma_list $(mdts_nodes))
31439         local saved=$(do_facet mds1 $LCTL get_param -n \
31440                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31441
31442         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31443         stack_trap "do_nodes $mdts $LCTL set_param \
31444                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31445
31446         mkdir -p $DIR/$tdir
31447         touch $testfile
31448         #hide projid xattr on server
31449         $LFS project -p 1 $testfile ||
31450                 error "set $testfile project id failed"
31451         getfattr -m - $testfile | grep $xattr &&
31452                 error "do not show trusted.projid when disabled on server"
31453         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31454         #should be hidden when projid is 0
31455         $LFS project -p 0 $testfile ||
31456                 error "set $testfile project id failed"
31457         getfattr -m - $testfile | grep $xattr &&
31458                 error "do not show trusted.projid with project ID 0"
31459
31460         #still can getxattr explicitly
31461         projid=$(getfattr -n $xattr $testfile |
31462                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31463         [ $projid == "0" ] ||
31464                 error "projid expected 0 not $projid"
31465
31466         #set the projid via setxattr
31467         setfattr -n $xattr -v "1000" $testfile ||
31468                 error "setattr failed with $?"
31469         projid=($($LFS project $testfile))
31470         [ ${projid[0]} == "1000" ] ||
31471                 error "projid expected 1000 not $projid"
31472
31473         #check the new projid via getxattr
31474         $LFS project -p 1001 $testfile ||
31475                 error "set $testfile project id failed"
31476         getfattr -m - $testfile | grep $xattr ||
31477                 error "should show trusted.projid when project ID != 0"
31478         projid=$(getfattr -n $xattr $testfile |
31479                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31480         [ $projid == "1001" ] ||
31481                 error "projid expected 1001 not $projid"
31482
31483         #try to set invalid projid
31484         setfattr -n $xattr -v "4294967295" $testfile &&
31485                 error "set invalid projid should fail"
31486
31487         #remove the xattr means setting projid to 0
31488         setfattr -x $xattr $testfile ||
31489                 error "setfattr failed with $?"
31490         projid=($($LFS project $testfile))
31491         [ ${projid[0]} == "0" ] ||
31492                 error "projid expected 0 not $projid"
31493
31494         #should be hidden when parent has inherit flag and same projid
31495         $LFS project -srp 1002 $DIR/$tdir ||
31496                 error "set $tdir project id failed"
31497         getfattr -m - $testfile | grep $xattr &&
31498                 error "do not show trusted.projid with inherit flag"
31499
31500         #still can getxattr explicitly
31501         projid=$(getfattr -n $xattr $testfile |
31502                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31503         [ $projid == "1002" ] ||
31504                 error "projid expected 1002 not $projid"
31505 }
31506 run_test 904 "virtual project ID xattr"
31507
31508 # LU-8582
31509 test_905() {
31510         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31511                 skip "need OST version >= 2.15.50.220 for fail_loc"
31512
31513         remote_ost_nodsh && skip "remote OST with nodsh"
31514         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31515
31516         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31517
31518         #define OBD_FAIL_OST_OPCODE 0x253
31519         # OST_LADVISE = 21
31520         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31521         $LFS ladvise -a willread $DIR/$tfile &&
31522                 error "unexpected success of ladvise with fault injection"
31523         $LFS ladvise -a willread $DIR/$tfile |&
31524                 grep -q "Operation not supported"
31525         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31526 }
31527 run_test 905 "bad or new opcode should not stuck client"
31528
31529 test_906() {
31530         grep -q io_uring_setup /proc/kallsyms ||
31531                 skip "Client OS does not support io_uring I/O engine"
31532         io_uring_probe || skip "kernel does not support io_uring fully"
31533         which fio || skip_env "no fio installed"
31534         fio --enghelp | grep -q io_uring ||
31535                 skip_env "fio does not support io_uring I/O engine"
31536
31537         local file=$DIR/$tfile
31538         local ioengine="io_uring"
31539         local numjobs=2
31540         local size=50M
31541
31542         fio --name=seqwrite --ioengine=$ioengine        \
31543                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31544                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31545                 error "fio seqwrite $file failed"
31546
31547         fio --name=seqread --ioengine=$ioengine \
31548                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31549                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31550                 error "fio seqread $file failed"
31551
31552         rm -f $file || error "rm -f $file failed"
31553 }
31554 run_test 906 "Simple test for io_uring I/O engine via fio"
31555
31556 test_907() {
31557         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31558
31559         # set stripe size to max rpc size
31560         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31561         $LFS getstripe $DIR/$tfile
31562 #define OBD_FAIL_OST_EROFS               0x216
31563         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31564
31565         local bs=$((max_pages * PAGE_SIZE / 16))
31566
31567         # write full one stripe and one block
31568         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31569
31570         rm $DIR/$tfile || error "rm failed"
31571 }
31572 run_test 907 "write rpc error during unlink"
31573
31574
31575 complete_test $SECONDS
31576 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31577 check_and_cleanup_lustre
31578 if [ "$I_MOUNTED" != "yes" ]; then
31579         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31580 fi
31581 exit_status