Whamcloud - gitweb
LU-14361 statahead: increase the initial statahead count
[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_161a() {
18742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18743
18744         test_mkdir -c1 $DIR/$tdir
18745         cp /etc/hosts $DIR/$tdir/$tfile
18746         test_mkdir -c1 $DIR/$tdir/foo1
18747         test_mkdir -c1 $DIR/$tdir/foo2
18748         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18749         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18750         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18751         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18752         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18753         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18754                 $LFS fid2path $DIR $FID
18755                 error "bad link ea"
18756         fi
18757         # middle
18758         rm $DIR/$tdir/foo2/zachary
18759         # last
18760         rm $DIR/$tdir/foo2/thor
18761         # first
18762         rm $DIR/$tdir/$tfile
18763         # rename
18764         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18765         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18766                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18767         rm $DIR/$tdir/foo2/maggie
18768
18769         # overflow the EA
18770         local longname=$tfile.avg_len_is_thirty_two_
18771         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18772                 error_noexit 'failed to unlink many hardlinks'" EXIT
18773         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18774                 error "failed to hardlink many files"
18775         links=$($LFS fid2path $DIR $FID | wc -l)
18776         echo -n "${links}/1000 links in link EA"
18777         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18778 }
18779 run_test 161a "link ea sanity"
18780
18781 test_161b() {
18782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18783         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18784
18785         local MDTIDX=1
18786         local remote_dir=$DIR/$tdir/remote_dir
18787
18788         mkdir -p $DIR/$tdir
18789         $LFS mkdir -i $MDTIDX $remote_dir ||
18790                 error "create remote directory failed"
18791
18792         cp /etc/hosts $remote_dir/$tfile
18793         mkdir -p $remote_dir/foo1
18794         mkdir -p $remote_dir/foo2
18795         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18796         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18797         ln $remote_dir/$tfile $remote_dir/foo1/luna
18798         ln $remote_dir/$tfile $remote_dir/foo2/thor
18799
18800         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18801                      tr -d ']')
18802         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18803                 $LFS fid2path $DIR $FID
18804                 error "bad link ea"
18805         fi
18806         # middle
18807         rm $remote_dir/foo2/zachary
18808         # last
18809         rm $remote_dir/foo2/thor
18810         # first
18811         rm $remote_dir/$tfile
18812         # rename
18813         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18814         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18815         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18816                 $LFS fid2path $DIR $FID
18817                 error "bad link rename"
18818         fi
18819         rm $remote_dir/foo2/maggie
18820
18821         # overflow the EA
18822         local longname=filename_avg_len_is_thirty_two_
18823         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18824                 error "failed to hardlink many files"
18825         links=$($LFS fid2path $DIR $FID | wc -l)
18826         echo -n "${links}/1000 links in link EA"
18827         [[ ${links} -gt 60 ]] ||
18828                 error "expected at least 60 links in link EA"
18829         unlinkmany $remote_dir/foo2/$longname 1000 ||
18830         error "failed to unlink many hardlinks"
18831 }
18832 run_test 161b "link ea sanity under remote directory"
18833
18834 test_161c() {
18835         remote_mds_nodsh && skip "remote MDS with nodsh"
18836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18837         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18838                 skip "Need MDS version at least 2.1.5"
18839
18840         # define CLF_RENAME_LAST 0x0001
18841         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18842         changelog_register || error "changelog_register failed"
18843
18844         rm -rf $DIR/$tdir
18845         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18846         touch $DIR/$tdir/foo_161c
18847         touch $DIR/$tdir/bar_161c
18848         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18849         changelog_dump | grep RENME | tail -n 5
18850         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18851         changelog_clear 0 || error "changelog_clear failed"
18852         if [ x$flags != "x0x1" ]; then
18853                 error "flag $flags is not 0x1"
18854         fi
18855
18856         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18857         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18858         touch $DIR/$tdir/foo_161c
18859         touch $DIR/$tdir/bar_161c
18860         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18861         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18862         changelog_dump | grep RENME | tail -n 5
18863         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18864         changelog_clear 0 || error "changelog_clear failed"
18865         if [ x$flags != "x0x0" ]; then
18866                 error "flag $flags is not 0x0"
18867         fi
18868         echo "rename overwrite a target having nlink > 1," \
18869                 "changelog record has flags of $flags"
18870
18871         # rename doesn't overwrite a target (changelog flag 0x0)
18872         touch $DIR/$tdir/foo_161c
18873         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18874         changelog_dump | grep RENME | tail -n 5
18875         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18876         changelog_clear 0 || error "changelog_clear failed"
18877         if [ x$flags != "x0x0" ]; then
18878                 error "flag $flags is not 0x0"
18879         fi
18880         echo "rename doesn't overwrite a target," \
18881                 "changelog record has flags of $flags"
18882
18883         # define CLF_UNLINK_LAST 0x0001
18884         # unlink a file having nlink = 1 (changelog flag 0x1)
18885         rm -f $DIR/$tdir/foo2_161c
18886         changelog_dump | grep UNLNK | tail -n 5
18887         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18888         changelog_clear 0 || error "changelog_clear failed"
18889         if [ x$flags != "x0x1" ]; then
18890                 error "flag $flags is not 0x1"
18891         fi
18892         echo "unlink a file having nlink = 1," \
18893                 "changelog record has flags of $flags"
18894
18895         # unlink a file having nlink > 1 (changelog flag 0x0)
18896         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18897         rm -f $DIR/$tdir/foobar_161c
18898         changelog_dump | grep UNLNK | tail -n 5
18899         flags=$(changelog_dump | grep UNLNK | tail -1 | 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 "unlink a file having nlink > 1, changelog record flags '$flags'"
18905 }
18906 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18907
18908 test_161d() {
18909         remote_mds_nodsh && skip "remote MDS with nodsh"
18910         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18911
18912         local pid
18913         local fid
18914
18915         changelog_register || error "changelog_register failed"
18916
18917         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18918         # interfer with $MOUNT/.lustre/fid/ access
18919         mkdir $DIR/$tdir
18920         [[ $? -eq 0 ]] || error "mkdir failed"
18921
18922         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18923         $LCTL set_param fail_loc=0x8000140c
18924         # 5s pause
18925         $LCTL set_param fail_val=5
18926
18927         # create file
18928         echo foofoo > $DIR/$tdir/$tfile &
18929         pid=$!
18930
18931         # wait for create to be delayed
18932         sleep 2
18933
18934         ps -p $pid
18935         [[ $? -eq 0 ]] || error "create should be blocked"
18936
18937         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18938         stack_trap "rm -f $tempfile"
18939         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18940         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18941         # some delay may occur during ChangeLog publishing and file read just
18942         # above, that could allow file write to happen finally
18943         [[ -s $tempfile ]] && echo "file should be empty"
18944
18945         $LCTL set_param fail_loc=0
18946
18947         wait $pid
18948         [[ $? -eq 0 ]] || error "create failed"
18949 }
18950 run_test 161d "create with concurrent .lustre/fid access"
18951
18952 check_path() {
18953         local expected="$1"
18954         shift
18955         local fid="$2"
18956
18957         local path
18958         path=$($LFS fid2path "$@")
18959         local rc=$?
18960
18961         if [ $rc -ne 0 ]; then
18962                 error "path looked up of '$expected' failed: rc=$rc"
18963         elif [ "$path" != "$expected" ]; then
18964                 error "path looked up '$path' instead of '$expected'"
18965         else
18966                 echo "FID '$fid' resolves to path '$path' as expected"
18967         fi
18968 }
18969
18970 test_162a() { # was test_162
18971         test_mkdir -p -c1 $DIR/$tdir/d2
18972         touch $DIR/$tdir/d2/$tfile
18973         touch $DIR/$tdir/d2/x1
18974         touch $DIR/$tdir/d2/x2
18975         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18976         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18977         # regular file
18978         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18979         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18980
18981         # softlink
18982         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18983         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18984         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18985
18986         # softlink to wrong file
18987         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18988         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18989         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18990
18991         # hardlink
18992         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18993         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18994         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18995         # fid2path dir/fsname should both work
18996         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18997         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18998
18999         # hardlink count: check that there are 2 links
19000         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19001         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19002
19003         # hardlink indexing: remove the first link
19004         rm $DIR/$tdir/d2/p/q/r/hlink
19005         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19006 }
19007 run_test 162a "path lookup sanity"
19008
19009 test_162b() {
19010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19011         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19012
19013         mkdir $DIR/$tdir
19014         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19015                                 error "create striped dir failed"
19016
19017         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19018                                         tail -n 1 | awk '{print $2}')
19019         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19020
19021         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19022         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19023
19024         # regular file
19025         for ((i=0;i<5;i++)); do
19026                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19027                         error "get fid for f$i failed"
19028                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19029
19030                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19031                         error "get fid for d$i failed"
19032                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19033         done
19034
19035         return 0
19036 }
19037 run_test 162b "striped directory path lookup sanity"
19038
19039 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19040 test_162c() {
19041         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19042                 skip "Need MDS version at least 2.7.51"
19043
19044         local lpath=$tdir.local
19045         local rpath=$tdir.remote
19046
19047         test_mkdir $DIR/$lpath
19048         test_mkdir $DIR/$rpath
19049
19050         for ((i = 0; i <= 101; i++)); do
19051                 lpath="$lpath/$i"
19052                 mkdir $DIR/$lpath
19053                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19054                         error "get fid for local directory $DIR/$lpath failed"
19055                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19056
19057                 rpath="$rpath/$i"
19058                 test_mkdir $DIR/$rpath
19059                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19060                         error "get fid for remote directory $DIR/$rpath failed"
19061                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19062         done
19063
19064         return 0
19065 }
19066 run_test 162c "fid2path works with paths 100 or more directories deep"
19067
19068 oalr_event_count() {
19069         local event="${1}"
19070         local trace="${2}"
19071
19072         awk -v name="${FSNAME}-OST0000" \
19073             -v event="${event}" \
19074             '$1 == "TRACE" && $2 == event && $3 == name' \
19075             "${trace}" |
19076         wc -l
19077 }
19078
19079 oalr_expect_event_count() {
19080         local event="${1}"
19081         local trace="${2}"
19082         local expect="${3}"
19083         local count
19084
19085         count=$(oalr_event_count "${event}" "${trace}")
19086         if ((count == expect)); then
19087                 return 0
19088         fi
19089
19090         error_noexit "${event} event count was '${count}', expected ${expect}"
19091         cat "${trace}" >&2
19092         exit 1
19093 }
19094
19095 cleanup_165() {
19096         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19097         stop ost1
19098         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19099 }
19100
19101 setup_165() {
19102         sync # Flush previous IOs so we can count log entries.
19103         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19104         stack_trap cleanup_165 EXIT
19105 }
19106
19107 test_165a() {
19108         local trace="/tmp/${tfile}.trace"
19109         local rc
19110         local count
19111
19112         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19113                 skip "OFD access log unsupported"
19114
19115         setup_165
19116         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19117         sleep 5
19118
19119         do_facet ost1 ofd_access_log_reader --list
19120         stop ost1
19121
19122         do_facet ost1 killall -TERM ofd_access_log_reader
19123         wait
19124         rc=$?
19125
19126         if ((rc != 0)); then
19127                 error "ofd_access_log_reader exited with rc = '${rc}'"
19128         fi
19129
19130         # Parse trace file for discovery events:
19131         oalr_expect_event_count alr_log_add "${trace}" 1
19132         oalr_expect_event_count alr_log_eof "${trace}" 1
19133         oalr_expect_event_count alr_log_free "${trace}" 1
19134 }
19135 run_test 165a "ofd access log discovery"
19136
19137 test_165b() {
19138         local trace="/tmp/${tfile}.trace"
19139         local file="${DIR}/${tfile}"
19140         local pfid1
19141         local pfid2
19142         local -a entry
19143         local rc
19144         local count
19145         local size
19146         local flags
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
19157         lfs setstripe -c 1 -i 0 "${file}"
19158         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19159                 error "cannot create '${file}'"
19160
19161         sleep 5
19162         do_facet ost1 killall -TERM ofd_access_log_reader
19163         wait
19164         rc=$?
19165
19166         if ((rc != 0)); then
19167                 error "ofd_access_log_reader exited with rc = '${rc}'"
19168         fi
19169
19170         oalr_expect_event_count alr_log_entry "${trace}" 1
19171
19172         pfid1=$($LFS path2fid "${file}")
19173
19174         # 1     2             3   4    5     6   7    8    9     10
19175         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19176         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19177
19178         echo "entry = '${entry[*]}'" >&2
19179
19180         pfid2=${entry[4]}
19181         if [[ "${pfid1}" != "${pfid2}" ]]; then
19182                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19183         fi
19184
19185         size=${entry[8]}
19186         if ((size != 1048576)); then
19187                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19188         fi
19189
19190         flags=${entry[10]}
19191         if [[ "${flags}" != "w" ]]; then
19192                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19193         fi
19194
19195         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19196         sleep 5
19197
19198         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19199                 error "cannot read '${file}'"
19200         sleep 5
19201
19202         do_facet ost1 killall -TERM ofd_access_log_reader
19203         wait
19204         rc=$?
19205
19206         if ((rc != 0)); then
19207                 error "ofd_access_log_reader exited with rc = '${rc}'"
19208         fi
19209
19210         oalr_expect_event_count alr_log_entry "${trace}" 1
19211
19212         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19213         echo "entry = '${entry[*]}'" >&2
19214
19215         pfid2=${entry[4]}
19216         if [[ "${pfid1}" != "${pfid2}" ]]; then
19217                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19218         fi
19219
19220         size=${entry[8]}
19221         if ((size != 524288)); then
19222                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19223         fi
19224
19225         flags=${entry[10]}
19226         if [[ "${flags}" != "r" ]]; then
19227                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19228         fi
19229 }
19230 run_test 165b "ofd access log entries are produced and consumed"
19231
19232 test_165c() {
19233         local trace="/tmp/${tfile}.trace"
19234         local file="${DIR}/${tdir}/${tfile}"
19235
19236         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19237                 skip "OFD access log unsupported"
19238
19239         test_mkdir "${DIR}/${tdir}"
19240
19241         setup_165
19242         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19243         sleep 5
19244
19245         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19246
19247         # 4096 / 64 = 64. Create twice as many entries.
19248         for ((i = 0; i < 128; i++)); do
19249                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19250                         error "cannot create file"
19251         done
19252
19253         sync
19254
19255         do_facet ost1 killall -TERM ofd_access_log_reader
19256         wait
19257         rc=$?
19258         if ((rc != 0)); then
19259                 error "ofd_access_log_reader exited with rc = '${rc}'"
19260         fi
19261
19262         unlinkmany  "${file}-%d" 128
19263 }
19264 run_test 165c "full ofd access logs do not block IOs"
19265
19266 oal_get_read_count() {
19267         local stats="$1"
19268
19269         # STATS lustre-OST0001 alr_read_count 1
19270
19271         do_facet ost1 cat "${stats}" |
19272         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19273              END { print count; }'
19274 }
19275
19276 oal_expect_read_count() {
19277         local stats="$1"
19278         local count
19279         local expect="$2"
19280
19281         # Ask ofd_access_log_reader to write stats.
19282         do_facet ost1 killall -USR1 ofd_access_log_reader
19283
19284         # Allow some time for things to happen.
19285         sleep 1
19286
19287         count=$(oal_get_read_count "${stats}")
19288         if ((count == expect)); then
19289                 return 0
19290         fi
19291
19292         error_noexit "bad read count, got ${count}, expected ${expect}"
19293         do_facet ost1 cat "${stats}" >&2
19294         exit 1
19295 }
19296
19297 test_165d() {
19298         local stats="/tmp/${tfile}.stats"
19299         local file="${DIR}/${tdir}/${tfile}"
19300         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19301
19302         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19303                 skip "OFD access log unsupported"
19304
19305         test_mkdir "${DIR}/${tdir}"
19306
19307         setup_165
19308         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19309         sleep 5
19310
19311         lfs setstripe -c 1 -i 0 "${file}"
19312
19313         do_facet ost1 lctl set_param "${param}=rw"
19314         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19315                 error "cannot create '${file}'"
19316         oal_expect_read_count "${stats}" 1
19317
19318         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19319                 error "cannot read '${file}'"
19320         oal_expect_read_count "${stats}" 2
19321
19322         do_facet ost1 lctl set_param "${param}=r"
19323         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19324                 error "cannot create '${file}'"
19325         oal_expect_read_count "${stats}" 2
19326
19327         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19328                 error "cannot read '${file}'"
19329         oal_expect_read_count "${stats}" 3
19330
19331         do_facet ost1 lctl set_param "${param}=w"
19332         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19333                 error "cannot create '${file}'"
19334         oal_expect_read_count "${stats}" 4
19335
19336         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19337                 error "cannot read '${file}'"
19338         oal_expect_read_count "${stats}" 4
19339
19340         do_facet ost1 lctl set_param "${param}=0"
19341         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19342                 error "cannot create '${file}'"
19343         oal_expect_read_count "${stats}" 4
19344
19345         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19346                 error "cannot read '${file}'"
19347         oal_expect_read_count "${stats}" 4
19348
19349         do_facet ost1 killall -TERM ofd_access_log_reader
19350         wait
19351         rc=$?
19352         if ((rc != 0)); then
19353                 error "ofd_access_log_reader exited with rc = '${rc}'"
19354         fi
19355 }
19356 run_test 165d "ofd_access_log mask works"
19357
19358 test_165e() {
19359         local stats="/tmp/${tfile}.stats"
19360         local file0="${DIR}/${tdir}-0/${tfile}"
19361         local file1="${DIR}/${tdir}-1/${tfile}"
19362
19363         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19364                 skip "OFD access log unsupported"
19365
19366         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19367
19368         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19369         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19370
19371         lfs setstripe -c 1 -i 0 "${file0}"
19372         lfs setstripe -c 1 -i 0 "${file1}"
19373
19374         setup_165
19375         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19376         sleep 5
19377
19378         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19379                 error "cannot create '${file0}'"
19380         sync
19381         oal_expect_read_count "${stats}" 0
19382
19383         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19384                 error "cannot create '${file1}'"
19385         sync
19386         oal_expect_read_count "${stats}" 1
19387
19388         do_facet ost1 killall -TERM ofd_access_log_reader
19389         wait
19390         rc=$?
19391         if ((rc != 0)); then
19392                 error "ofd_access_log_reader exited with rc = '${rc}'"
19393         fi
19394 }
19395 run_test 165e "ofd_access_log MDT index filter works"
19396
19397 test_165f() {
19398         local trace="/tmp/${tfile}.trace"
19399         local rc
19400         local count
19401
19402         setup_165
19403         do_facet ost1 timeout 60 ofd_access_log_reader \
19404                 --exit-on-close --debug=- --trace=- > "${trace}" &
19405         sleep 5
19406         stop ost1
19407
19408         wait
19409         rc=$?
19410
19411         if ((rc != 0)); then
19412                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19413                 cat "${trace}"
19414                 exit 1
19415         fi
19416 }
19417 run_test 165f "ofd_access_log_reader --exit-on-close works"
19418
19419 test_169() {
19420         # do directio so as not to populate the page cache
19421         log "creating a 10 Mb file"
19422         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19423                 error "multiop failed while creating a file"
19424         log "starting reads"
19425         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19426         log "truncating the file"
19427         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19428                 error "multiop failed while truncating the file"
19429         log "killing dd"
19430         kill %+ || true # reads might have finished
19431         echo "wait until dd is finished"
19432         wait
19433         log "removing the temporary file"
19434         rm -rf $DIR/$tfile || error "tmp file removal failed"
19435 }
19436 run_test 169 "parallel read and truncate should not deadlock"
19437
19438 test_170() {
19439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19440
19441         $LCTL clear     # bug 18514
19442         $LCTL debug_daemon start $TMP/${tfile}_log_good
19443         touch $DIR/$tfile
19444         $LCTL debug_daemon stop
19445         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19446                 error "sed failed to read log_good"
19447
19448         $LCTL debug_daemon start $TMP/${tfile}_log_good
19449         rm -rf $DIR/$tfile
19450         $LCTL debug_daemon stop
19451
19452         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19453                error "lctl df log_bad failed"
19454
19455         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19456         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19457
19458         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19459         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19460
19461         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19462                 error "bad_line good_line1 good_line2 are empty"
19463
19464         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19465         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19466         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19467
19468         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19469         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19470         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19471
19472         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19473                 error "bad_line_new good_line_new are empty"
19474
19475         local expected_good=$((good_line1 + good_line2*2))
19476
19477         rm -f $TMP/${tfile}*
19478         # LU-231, short malformed line may not be counted into bad lines
19479         if [ $bad_line -ne $bad_line_new ] &&
19480                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19481                 error "expected $bad_line bad lines, but got $bad_line_new"
19482                 return 1
19483         fi
19484
19485         if [ $expected_good -ne $good_line_new ]; then
19486                 error "expected $expected_good good lines, but got $good_line_new"
19487                 return 2
19488         fi
19489         true
19490 }
19491 run_test 170 "test lctl df to handle corrupted log ====================="
19492
19493 test_171() { # bug20592
19494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19495
19496         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19497         $LCTL set_param fail_loc=0x50e
19498         $LCTL set_param fail_val=3000
19499         multiop_bg_pause $DIR/$tfile O_s || true
19500         local MULTIPID=$!
19501         kill -USR1 $MULTIPID
19502         # cause log dump
19503         sleep 3
19504         wait $MULTIPID
19505         if dmesg | grep "recursive fault"; then
19506                 error "caught a recursive fault"
19507         fi
19508         $LCTL set_param fail_loc=0
19509         true
19510 }
19511 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19512
19513 test_172() {
19514
19515         #define OBD_FAIL_OBD_CLEANUP  0x60e
19516         $LCTL set_param fail_loc=0x60e
19517         umount $MOUNT || error "umount $MOUNT failed"
19518         stack_trap "mount_client $MOUNT"
19519
19520         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19521                 error "no client OBDs are remained"
19522
19523         $LCTL dl | while read devno state type name foo; do
19524                 case $type in
19525                 lov|osc|lmv|mdc)
19526                         $LCTL --device $name cleanup
19527                         $LCTL --device $name detach
19528                         ;;
19529                 *)
19530                         # skip server devices
19531                         ;;
19532                 esac
19533         done
19534
19535         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19536                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19537                 error "some client OBDs are still remained"
19538         fi
19539
19540 }
19541 run_test 172 "manual device removal with lctl cleanup/detach ======"
19542
19543 # it would be good to share it with obdfilter-survey/iokit-libecho code
19544 setup_obdecho_osc () {
19545         local rc=0
19546         local ost_nid=$1
19547         local obdfilter_name=$2
19548         echo "Creating new osc for $obdfilter_name on $ost_nid"
19549         # make sure we can find loopback nid
19550         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19551
19552         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19553                            ${obdfilter_name}_osc_UUID || rc=2; }
19554         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19555                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19556         return $rc
19557 }
19558
19559 cleanup_obdecho_osc () {
19560         local obdfilter_name=$1
19561         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19562         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19563         return 0
19564 }
19565
19566 obdecho_test() {
19567         local OBD=$1
19568         local node=$2
19569         local pages=${3:-64}
19570         local rc=0
19571         local id
19572
19573         local count=10
19574         local obd_size=$(get_obd_size $node $OBD)
19575         local page_size=$(get_page_size $node)
19576         if [[ -n "$obd_size" ]]; then
19577                 local new_count=$((obd_size / (pages * page_size / 1024)))
19578                 [[ $new_count -ge $count ]] || count=$new_count
19579         fi
19580
19581         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19582         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19583                            rc=2; }
19584         if [ $rc -eq 0 ]; then
19585             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19586             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19587         fi
19588         echo "New object id is $id"
19589         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19590                            rc=4; }
19591         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19592                            "test_brw $count w v $pages $id" || rc=4; }
19593         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19594                            rc=4; }
19595         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19596                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19597         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19598                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19599         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19600         return $rc
19601 }
19602
19603 test_180a() {
19604         skip "obdecho on osc is no longer supported"
19605 }
19606 run_test 180a "test obdecho on osc"
19607
19608 test_180b() {
19609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19610         remote_ost_nodsh && skip "remote OST with nodsh"
19611
19612         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19613                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19614                 error "failed to load module obdecho"
19615
19616         local target=$(do_facet ost1 $LCTL dl |
19617                        awk '/obdfilter/ { print $4; exit; }')
19618
19619         if [ -n "$target" ]; then
19620                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19621         else
19622                 do_facet ost1 $LCTL dl
19623                 error "there is no obdfilter target on ost1"
19624         fi
19625 }
19626 run_test 180b "test obdecho directly on obdfilter"
19627
19628 test_180c() { # LU-2598
19629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19630         remote_ost_nodsh && skip "remote OST with nodsh"
19631         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19632                 skip "Need MDS version at least 2.4.0"
19633
19634         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19635                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19636                 error "failed to load module obdecho"
19637
19638         local target=$(do_facet ost1 $LCTL dl |
19639                        awk '/obdfilter/ { print $4; exit; }')
19640
19641         if [ -n "$target" ]; then
19642                 local pages=16384 # 64MB bulk I/O RPC size
19643
19644                 obdecho_test "$target" ost1 "$pages" ||
19645                         error "obdecho_test with pages=$pages failed with $?"
19646         else
19647                 do_facet ost1 $LCTL dl
19648                 error "there is no obdfilter target on ost1"
19649         fi
19650 }
19651 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19652
19653 test_181() { # bug 22177
19654         test_mkdir $DIR/$tdir
19655         # create enough files to index the directory
19656         createmany -o $DIR/$tdir/foobar 4000
19657         # print attributes for debug purpose
19658         lsattr -d .
19659         # open dir
19660         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19661         MULTIPID=$!
19662         # remove the files & current working dir
19663         unlinkmany $DIR/$tdir/foobar 4000
19664         rmdir $DIR/$tdir
19665         kill -USR1 $MULTIPID
19666         wait $MULTIPID
19667         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19668         return 0
19669 }
19670 run_test 181 "Test open-unlinked dir ========================"
19671
19672 test_182a() {
19673         local fcount=1000
19674         local tcount=10
19675
19676         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19677
19678         $LCTL set_param mdc.*.rpc_stats=clear
19679
19680         for (( i = 0; i < $tcount; i++ )) ; do
19681                 mkdir $DIR/$tdir/$i
19682         done
19683
19684         for (( i = 0; i < $tcount; i++ )) ; do
19685                 createmany -o $DIR/$tdir/$i/f- $fcount &
19686         done
19687         wait
19688
19689         for (( i = 0; i < $tcount; i++ )) ; do
19690                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19691         done
19692         wait
19693
19694         $LCTL get_param mdc.*.rpc_stats
19695
19696         rm -rf $DIR/$tdir
19697 }
19698 run_test 182a "Test parallel modify metadata operations from mdc"
19699
19700 test_182b() {
19701         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19702         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19703         local dcount=1000
19704         local tcount=10
19705         local stime
19706         local etime
19707         local delta
19708
19709         do_facet mds1 $LCTL list_param \
19710                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19711                 skip "MDS lacks parallel RPC handling"
19712
19713         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19714
19715         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19716                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19717
19718         stime=$(date +%s)
19719         createmany -i 0 -d $DIR/$tdir/t- $tcount
19720
19721         for (( i = 0; i < $tcount; i++ )) ; do
19722                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19723         done
19724         wait
19725         etime=$(date +%s)
19726         delta=$((etime - stime))
19727         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19728
19729         stime=$(date +%s)
19730         for (( i = 0; i < $tcount; i++ )) ; do
19731                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19732         done
19733         wait
19734         etime=$(date +%s)
19735         delta=$((etime - stime))
19736         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19737
19738         rm -rf $DIR/$tdir
19739
19740         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19741
19742         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19743
19744         stime=$(date +%s)
19745         createmany -i 0 -d $DIR/$tdir/t- $tcount
19746
19747         for (( i = 0; i < $tcount; i++ )) ; do
19748                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19749         done
19750         wait
19751         etime=$(date +%s)
19752         delta=$((etime - stime))
19753         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19754
19755         stime=$(date +%s)
19756         for (( i = 0; i < $tcount; i++ )) ; do
19757                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19758         done
19759         wait
19760         etime=$(date +%s)
19761         delta=$((etime - stime))
19762         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19763
19764         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19765 }
19766 run_test 182b "Test parallel modify metadata operations from osp"
19767
19768 test_183() { # LU-2275
19769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19770         remote_mds_nodsh && skip "remote MDS with nodsh"
19771         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19772                 skip "Need MDS version at least 2.3.56"
19773
19774         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19775         echo aaa > $DIR/$tdir/$tfile
19776
19777 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19778         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19779
19780         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19781         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19782
19783         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19784
19785         # Flush negative dentry cache
19786         touch $DIR/$tdir/$tfile
19787
19788         # We are not checking for any leaked references here, they'll
19789         # become evident next time we do cleanup with module unload.
19790         rm -rf $DIR/$tdir
19791 }
19792 run_test 183 "No crash or request leak in case of strange dispositions ========"
19793
19794 # test suite 184 is for LU-2016, LU-2017
19795 test_184a() {
19796         check_swap_layouts_support
19797
19798         dir0=$DIR/$tdir/$testnum
19799         test_mkdir -p -c1 $dir0
19800         ref1=/etc/passwd
19801         ref2=/etc/group
19802         file1=$dir0/f1
19803         file2=$dir0/f2
19804         $LFS setstripe -c1 $file1
19805         cp $ref1 $file1
19806         $LFS setstripe -c2 $file2
19807         cp $ref2 $file2
19808         gen1=$($LFS getstripe -g $file1)
19809         gen2=$($LFS getstripe -g $file2)
19810
19811         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19812         gen=$($LFS getstripe -g $file1)
19813         [[ $gen1 != $gen ]] ||
19814                 error "Layout generation on $file1 does not change"
19815         gen=$($LFS getstripe -g $file2)
19816         [[ $gen2 != $gen ]] ||
19817                 error "Layout generation on $file2 does not change"
19818
19819         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19820         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19821
19822         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19823 }
19824 run_test 184a "Basic layout swap"
19825
19826 test_184b() {
19827         check_swap_layouts_support
19828
19829         dir0=$DIR/$tdir/$testnum
19830         mkdir -p $dir0 || error "creating dir $dir0"
19831         file1=$dir0/f1
19832         file2=$dir0/f2
19833         file3=$dir0/f3
19834         dir1=$dir0/d1
19835         dir2=$dir0/d2
19836         mkdir $dir1 $dir2
19837         $LFS setstripe -c1 $file1
19838         $LFS setstripe -c2 $file2
19839         $LFS setstripe -c1 $file3
19840         chown $RUNAS_ID $file3
19841         gen1=$($LFS getstripe -g $file1)
19842         gen2=$($LFS getstripe -g $file2)
19843
19844         $LFS swap_layouts $dir1 $dir2 &&
19845                 error "swap of directories layouts should fail"
19846         $LFS swap_layouts $dir1 $file1 &&
19847                 error "swap of directory and file layouts should fail"
19848         $RUNAS $LFS swap_layouts $file1 $file2 &&
19849                 error "swap of file we cannot write should fail"
19850         $LFS swap_layouts $file1 $file3 &&
19851                 error "swap of file with different owner should fail"
19852         /bin/true # to clear error code
19853 }
19854 run_test 184b "Forbidden layout swap (will generate errors)"
19855
19856 test_184c() {
19857         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19858         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19859         check_swap_layouts_support
19860         check_swap_layout_no_dom $DIR
19861
19862         local dir0=$DIR/$tdir/$testnum
19863         mkdir -p $dir0 || error "creating dir $dir0"
19864
19865         local ref1=$dir0/ref1
19866         local ref2=$dir0/ref2
19867         local file1=$dir0/file1
19868         local file2=$dir0/file2
19869         # create a file large enough for the concurrent test
19870         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19871         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19872         echo "ref file size: ref1($(stat -c %s $ref1))," \
19873              "ref2($(stat -c %s $ref2))"
19874
19875         cp $ref2 $file2
19876         dd if=$ref1 of=$file1 bs=16k &
19877         local DD_PID=$!
19878
19879         # Make sure dd starts to copy file, but wait at most 5 seconds
19880         local loops=0
19881         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19882
19883         $LFS swap_layouts $file1 $file2
19884         local rc=$?
19885         wait $DD_PID
19886         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19887         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19888
19889         # how many bytes copied before swapping layout
19890         local copied=$(stat -c %s $file2)
19891         local remaining=$(stat -c %s $ref1)
19892         remaining=$((remaining - copied))
19893         echo "Copied $copied bytes before swapping layout..."
19894
19895         cmp -n $copied $file1 $ref2 | grep differ &&
19896                 error "Content mismatch [0, $copied) of ref2 and file1"
19897         cmp -n $copied $file2 $ref1 ||
19898                 error "Content mismatch [0, $copied) of ref1 and file2"
19899         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19900                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19901
19902         # clean up
19903         rm -f $ref1 $ref2 $file1 $file2
19904 }
19905 run_test 184c "Concurrent write and layout swap"
19906
19907 test_184d() {
19908         check_swap_layouts_support
19909         check_swap_layout_no_dom $DIR
19910         [ -z "$(which getfattr 2>/dev/null)" ] &&
19911                 skip_env "no getfattr command"
19912
19913         local file1=$DIR/$tdir/$tfile-1
19914         local file2=$DIR/$tdir/$tfile-2
19915         local file3=$DIR/$tdir/$tfile-3
19916         local lovea1
19917         local lovea2
19918
19919         mkdir -p $DIR/$tdir
19920         touch $file1 || error "create $file1 failed"
19921         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19922                 error "create $file2 failed"
19923         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19924                 error "create $file3 failed"
19925         lovea1=$(get_layout_param $file1)
19926
19927         $LFS swap_layouts $file2 $file3 ||
19928                 error "swap $file2 $file3 layouts failed"
19929         $LFS swap_layouts $file1 $file2 ||
19930                 error "swap $file1 $file2 layouts failed"
19931
19932         lovea2=$(get_layout_param $file2)
19933         echo "$lovea1"
19934         echo "$lovea2"
19935         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19936
19937         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19938         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19939 }
19940 run_test 184d "allow stripeless layouts swap"
19941
19942 test_184e() {
19943         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19944                 skip "Need MDS version at least 2.6.94"
19945         check_swap_layouts_support
19946         check_swap_layout_no_dom $DIR
19947         [ -z "$(which getfattr 2>/dev/null)" ] &&
19948                 skip_env "no getfattr command"
19949
19950         local file1=$DIR/$tdir/$tfile-1
19951         local file2=$DIR/$tdir/$tfile-2
19952         local file3=$DIR/$tdir/$tfile-3
19953         local lovea
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
19962         $LFS swap_layouts $file1 $file2 ||
19963                 error "swap $file1 $file2 layouts failed"
19964
19965         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19966         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19967
19968         echo 123 > $file1 || error "Should be able to write into $file1"
19969
19970         $LFS swap_layouts $file1 $file3 ||
19971                 error "swap $file1 $file3 layouts failed"
19972
19973         echo 123 > $file1 || error "Should be able to write into $file1"
19974
19975         rm -rf $file1 $file2 $file3
19976 }
19977 run_test 184e "Recreate layout after stripeless layout swaps"
19978
19979 test_184f() {
19980         # Create a file with name longer than sizeof(struct stat) ==
19981         # 144 to see if we can get chars from the file name to appear
19982         # in the returned striping. Note that 'f' == 0x66.
19983         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19984
19985         mkdir -p $DIR/$tdir
19986         mcreate $DIR/$tdir/$file
19987         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19988                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19989         fi
19990 }
19991 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19992
19993 test_185() { # LU-2441
19994         # LU-3553 - no volatile file support in old servers
19995         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19996                 skip "Need MDS version at least 2.3.60"
19997
19998         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19999         touch $DIR/$tdir/spoo
20000         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20001         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20002                 error "cannot create/write a volatile file"
20003         [ "$FILESET" == "" ] &&
20004         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20005                 error "FID is still valid after close"
20006
20007         multiop_bg_pause $DIR/$tdir Vw4096_c
20008         local multi_pid=$!
20009
20010         local OLD_IFS=$IFS
20011         IFS=":"
20012         local fidv=($fid)
20013         IFS=$OLD_IFS
20014         # assume that the next FID for this client is sequential, since stdout
20015         # is unfortunately eaten by multiop_bg_pause
20016         local n=$((${fidv[1]} + 1))
20017         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20018         if [ "$FILESET" == "" ]; then
20019                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20020                         error "FID is missing before close"
20021         fi
20022         kill -USR1 $multi_pid
20023         # 1 second delay, so if mtime change we will see it
20024         sleep 1
20025         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20026         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20027 }
20028 run_test 185 "Volatile file support"
20029
20030 function create_check_volatile() {
20031         local idx=$1
20032         local tgt
20033
20034         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20035         local PID=$!
20036         sleep 1
20037         local FID=$(cat /tmp/${tfile}.fid)
20038         [ "$FID" == "" ] && error "can't get FID for volatile"
20039         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20040         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20041         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20042         kill -USR1 $PID
20043         wait
20044         sleep 1
20045         cancel_lru_locks mdc # flush opencache
20046         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20047         return 0
20048 }
20049
20050 test_185a(){
20051         # LU-12516 - volatile creation via .lustre
20052         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20053                 skip "Need MDS version at least 2.3.55"
20054
20055         create_check_volatile 0
20056         [ $MDSCOUNT -lt 2 ] && return 0
20057
20058         # DNE case
20059         create_check_volatile 1
20060
20061         return 0
20062 }
20063 run_test 185a "Volatile file creation in .lustre/fid/"
20064
20065 test_187a() {
20066         remote_mds_nodsh && skip "remote MDS with nodsh"
20067         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20068                 skip "Need MDS version at least 2.3.0"
20069
20070         local dir0=$DIR/$tdir/$testnum
20071         mkdir -p $dir0 || error "creating dir $dir0"
20072
20073         local file=$dir0/file1
20074         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20075         stack_trap "rm -f $file"
20076         local dv1=$($LFS data_version $file)
20077         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20078         local dv2=$($LFS data_version $file)
20079         [[ $dv1 != $dv2 ]] ||
20080                 error "data version did not change on write $dv1 == $dv2"
20081 }
20082 run_test 187a "Test data version change"
20083
20084 test_187b() {
20085         remote_mds_nodsh && skip "remote MDS with nodsh"
20086         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20087                 skip "Need MDS version at least 2.3.0"
20088
20089         local dir0=$DIR/$tdir/$testnum
20090         mkdir -p $dir0 || error "creating dir $dir0"
20091
20092         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20093         [[ ${DV[0]} != ${DV[1]} ]] ||
20094                 error "data version did not change on write"\
20095                       " ${DV[0]} == ${DV[1]}"
20096
20097         # clean up
20098         rm -f $file1
20099 }
20100 run_test 187b "Test data version change on volatile file"
20101
20102 test_200() {
20103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20104         remote_mgs_nodsh && skip "remote MGS with nodsh"
20105         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20106
20107         local POOL=${POOL:-cea1}
20108         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20109         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20110         # Pool OST targets
20111         local first_ost=0
20112         local last_ost=$(($OSTCOUNT - 1))
20113         local ost_step=2
20114         local ost_list=$(seq $first_ost $ost_step $last_ost)
20115         local ost_range="$first_ost $last_ost $ost_step"
20116         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20117         local file_dir=$POOL_ROOT/file_tst
20118         local subdir=$test_path/subdir
20119         local rc=0
20120
20121         while : ; do
20122                 # former test_200a test_200b
20123                 pool_add $POOL                          || { rc=$? ; break; }
20124                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20125                 # former test_200c test_200d
20126                 mkdir -p $test_path
20127                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20128                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20129                 mkdir -p $subdir
20130                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20131                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20132                                                         || { rc=$? ; break; }
20133                 # former test_200e test_200f
20134                 local files=$((OSTCOUNT*3))
20135                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20136                                                         || { rc=$? ; break; }
20137                 pool_create_files $POOL $file_dir $files "$ost_list" \
20138                                                         || { rc=$? ; break; }
20139                 # former test_200g test_200h
20140                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20141                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20142
20143                 # former test_201a test_201b test_201c
20144                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20145
20146                 local f=$test_path/$tfile
20147                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20148                 pool_remove $POOL $f                    || { rc=$? ; break; }
20149                 break
20150         done
20151
20152         destroy_test_pools
20153
20154         return $rc
20155 }
20156 run_test 200 "OST pools"
20157
20158 # usage: default_attr <count | size | offset>
20159 default_attr() {
20160         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20161 }
20162
20163 # usage: check_default_stripe_attr
20164 check_default_stripe_attr() {
20165         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20166         case $1 in
20167         --stripe-count|-c)
20168                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20169         --stripe-size|-S)
20170                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20171         --stripe-index|-i)
20172                 EXPECTED=-1;;
20173         *)
20174                 error "unknown getstripe attr '$1'"
20175         esac
20176
20177         [ $ACTUAL == $EXPECTED ] ||
20178                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20179 }
20180
20181 test_204a() {
20182         test_mkdir $DIR/$tdir
20183         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20184
20185         check_default_stripe_attr --stripe-count
20186         check_default_stripe_attr --stripe-size
20187         check_default_stripe_attr --stripe-index
20188 }
20189 run_test 204a "Print default stripe attributes"
20190
20191 test_204b() {
20192         test_mkdir $DIR/$tdir
20193         $LFS setstripe --stripe-count 1 $DIR/$tdir
20194
20195         check_default_stripe_attr --stripe-size
20196         check_default_stripe_attr --stripe-index
20197 }
20198 run_test 204b "Print default stripe size and offset"
20199
20200 test_204c() {
20201         test_mkdir $DIR/$tdir
20202         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20203
20204         check_default_stripe_attr --stripe-count
20205         check_default_stripe_attr --stripe-index
20206 }
20207 run_test 204c "Print default stripe count and offset"
20208
20209 test_204d() {
20210         test_mkdir $DIR/$tdir
20211         $LFS setstripe --stripe-index 0 $DIR/$tdir
20212
20213         check_default_stripe_attr --stripe-count
20214         check_default_stripe_attr --stripe-size
20215 }
20216 run_test 204d "Print default stripe count and size"
20217
20218 test_204e() {
20219         test_mkdir $DIR/$tdir
20220         $LFS setstripe -d $DIR/$tdir
20221
20222         # LU-16904 check if root is set as PFL layout
20223         local numcomp=$($LFS getstripe --component-count $MOUNT)
20224
20225         if [[ $numcomp -gt 0 ]]; then
20226                 check_default_stripe_attr --stripe-count
20227         else
20228                 check_default_stripe_attr --stripe-count --raw
20229         fi
20230         check_default_stripe_attr --stripe-size --raw
20231         check_default_stripe_attr --stripe-index --raw
20232 }
20233 run_test 204e "Print raw stripe attributes"
20234
20235 test_204f() {
20236         test_mkdir $DIR/$tdir
20237         $LFS setstripe --stripe-count 1 $DIR/$tdir
20238
20239         check_default_stripe_attr --stripe-size --raw
20240         check_default_stripe_attr --stripe-index --raw
20241 }
20242 run_test 204f "Print raw stripe size and offset"
20243
20244 test_204g() {
20245         test_mkdir $DIR/$tdir
20246         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20247
20248         check_default_stripe_attr --stripe-count --raw
20249         check_default_stripe_attr --stripe-index --raw
20250 }
20251 run_test 204g "Print raw stripe count and offset"
20252
20253 test_204h() {
20254         test_mkdir $DIR/$tdir
20255         $LFS setstripe --stripe-index 0 $DIR/$tdir
20256
20257         check_default_stripe_attr --stripe-count --raw
20258         check_default_stripe_attr --stripe-size --raw
20259 }
20260 run_test 204h "Print raw stripe count and size"
20261
20262 # Figure out which job scheduler is being used, if any,
20263 # or use a fake one
20264 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20265         JOBENV=SLURM_JOB_ID
20266 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20267         JOBENV=LSB_JOBID
20268 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20269         JOBENV=PBS_JOBID
20270 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20271         JOBENV=LOADL_STEP_ID
20272 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20273         JOBENV=JOB_ID
20274 else
20275         $LCTL list_param jobid_name > /dev/null 2>&1
20276         if [ $? -eq 0 ]; then
20277                 JOBENV=nodelocal
20278         else
20279                 JOBENV=FAKE_JOBID
20280         fi
20281 fi
20282 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20283
20284 verify_jobstats() {
20285         local cmd=($1)
20286         shift
20287         local facets="$@"
20288
20289 # we don't really need to clear the stats for this test to work, since each
20290 # command has a unique jobid, but it makes debugging easier if needed.
20291 #       for facet in $facets; do
20292 #               local dev=$(convert_facet2label $facet)
20293 #               # clear old jobstats
20294 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20295 #       done
20296
20297         # use a new JobID for each test, or we might see an old one
20298         [ "$JOBENV" = "FAKE_JOBID" ] &&
20299                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20300
20301         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20302
20303         [ "$JOBENV" = "nodelocal" ] && {
20304                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20305                 $LCTL set_param jobid_name=$FAKE_JOBID
20306                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20307         }
20308
20309         log "Test: ${cmd[*]}"
20310         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20311
20312         if [ $JOBENV = "FAKE_JOBID" ]; then
20313                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20314         else
20315                 ${cmd[*]}
20316         fi
20317
20318         # all files are created on OST0000
20319         for facet in $facets; do
20320                 local stats="*.$(convert_facet2label $facet).job_stats"
20321
20322                 # strip out libtool wrappers for in-tree executables
20323                 if (( $(do_facet $facet lctl get_param $stats |
20324                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20325                         do_facet $facet lctl get_param $stats
20326                         error "No jobstats for $JOBVAL found on $facet::$stats"
20327                 fi
20328         done
20329 }
20330
20331 jobstats_set() {
20332         local new_jobenv=$1
20333
20334         set_persistent_param_and_check client "jobid_var" \
20335                 "$FSNAME.sys.jobid_var" $new_jobenv
20336 }
20337
20338 test_205a() { # Job stats
20339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20340         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20341                 skip "Need MDS version with at least 2.7.1"
20342         remote_mgs_nodsh && skip "remote MGS with nodsh"
20343         remote_mds_nodsh && skip "remote MDS with nodsh"
20344         remote_ost_nodsh && skip "remote OST with nodsh"
20345         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20346                 skip "Server doesn't support jobstats"
20347         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20348
20349         local old_jobenv=$($LCTL get_param -n jobid_var)
20350         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20351         stack_trap "jobstats_set $old_jobenv" EXIT
20352
20353         changelog_register
20354
20355         local old_jobid_name=$($LCTL get_param jobid_name)
20356         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20357
20358         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20359                                 mdt.*.job_cleanup_interval | head -n 1)
20360         local new_interval=5
20361         do_facet $SINGLEMDS \
20362                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20363         stack_trap "do_facet $SINGLEMDS \
20364                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20365         local start=$SECONDS
20366
20367         local cmd
20368         # mkdir
20369         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20370         verify_jobstats "$cmd" "$SINGLEMDS"
20371         # rmdir
20372         cmd="rmdir $DIR/$tdir"
20373         verify_jobstats "$cmd" "$SINGLEMDS"
20374         # mkdir on secondary MDT
20375         if [ $MDSCOUNT -gt 1 ]; then
20376                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20377                 verify_jobstats "$cmd" "mds2"
20378         fi
20379         # mknod
20380         cmd="mknod $DIR/$tfile c 1 3"
20381         verify_jobstats "$cmd" "$SINGLEMDS"
20382         # unlink
20383         cmd="rm -f $DIR/$tfile"
20384         verify_jobstats "$cmd" "$SINGLEMDS"
20385         # create all files on OST0000 so verify_jobstats can find OST stats
20386         # open & close
20387         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20388         verify_jobstats "$cmd" "$SINGLEMDS"
20389         # setattr
20390         cmd="touch $DIR/$tfile"
20391         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20392         # write
20393         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20394         verify_jobstats "$cmd" "ost1"
20395         # read
20396         cancel_lru_locks osc
20397         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20398         verify_jobstats "$cmd" "ost1"
20399         # truncate
20400         cmd="$TRUNCATE $DIR/$tfile 0"
20401         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20402         # rename
20403         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20404         verify_jobstats "$cmd" "$SINGLEMDS"
20405         # jobstats expiry - sleep until old stats should be expired
20406         local left=$((new_interval + 5 - (SECONDS - start)))
20407         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20408                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20409                         "0" $left
20410         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20411         verify_jobstats "$cmd" "$SINGLEMDS"
20412         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20413             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20414
20415         # Ensure that jobid are present in changelog (if supported by MDS)
20416         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20417                 changelog_dump | tail -10
20418                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20419                 [ $jobids -eq 9 ] ||
20420                         error "Wrong changelog jobid count $jobids != 9"
20421
20422                 # LU-5862
20423                 JOBENV="disable"
20424                 jobstats_set $JOBENV
20425                 touch $DIR/$tfile
20426                 changelog_dump | grep $tfile
20427                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20428                 [ $jobids -eq 0 ] ||
20429                         error "Unexpected jobids when jobid_var=$JOBENV"
20430         fi
20431
20432         # test '%j' access to environment variable - if supported
20433         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20434                 JOBENV="JOBCOMPLEX"
20435                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20436
20437                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20438         fi
20439
20440         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20441                 JOBENV="JOBCOMPLEX"
20442                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20443
20444                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20445         fi
20446
20447         # test '%j' access to per-session jobid - if supported
20448         if lctl list_param jobid_this_session > /dev/null 2>&1
20449         then
20450                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20451                 lctl set_param jobid_this_session=$USER
20452
20453                 JOBENV="JOBCOMPLEX"
20454                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20455
20456                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20457         fi
20458 }
20459 run_test 205a "Verify job stats"
20460
20461 # LU-13117, LU-13597, LU-16599
20462 test_205b() {
20463         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20464                 skip "Need MDS version at least 2.13.54.91"
20465
20466         local job_stats="mdt.*.job_stats"
20467         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20468
20469         do_facet mds1 $LCTL set_param $job_stats=clear
20470
20471         # Setting jobid_var to USER might not be supported
20472         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20473         $LCTL set_param jobid_var=USER || true
20474         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20475         $LCTL set_param jobid_name="%j.%e.%u"
20476
20477         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20478         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20479                 { do_facet mds1 $LCTL get_param $job_stats;
20480                   error "Unexpected jobid found"; }
20481         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20482                 { do_facet mds1 $LCTL get_param $job_stats;
20483                   error "wrong job_stats format found"; }
20484
20485         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20486                 echo "MDS does not yet escape jobid" && return 0
20487
20488         mkdir_on_mdt0 $DIR/$tdir
20489         $LCTL set_param jobid_var=TEST205b
20490         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20491         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20492                       awk '/has\\x20sp/ {print $3}')
20493         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20494                   error "jobid not escaped"; }
20495
20496         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20497                 # need to run such a command on mds1:
20498                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20499                 #
20500                 # there might be multiple MDTs on single mds server, so need to
20501                 # specifiy MDT0000. Or the command will fail due to other MDTs
20502                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20503                         error "cannot clear escaped jobid in job_stats";
20504         else
20505                 echo "MDS does not support clearing escaped jobid"
20506         fi
20507 }
20508 run_test 205b "Verify job stats jobid and output format"
20509
20510 # LU-13733
20511 test_205c() {
20512         $LCTL set_param llite.*.stats=0
20513         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20514         $LCTL get_param llite.*.stats
20515         $LCTL get_param llite.*.stats | grep \
20516                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20517                         error "wrong client stats format found"
20518 }
20519 run_test 205c "Verify client stats format"
20520
20521 test_205d() {
20522         local file=$DIR/$tdir/$tfile
20523
20524         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20525                 skip "need lustre >= 2.15.53 for lljobstat"
20526         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20527                 skip "need lustre >= 2.15.53 for lljobstat"
20528         verify_yaml_available || skip_env "YAML verification not installed"
20529
20530         test_mkdir -i 0 $DIR/$tdir
20531         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20532         stack_trap "rm -rf $DIR/$tdir"
20533
20534         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20535                 error "failed to write data to $file"
20536         mv $file $file.2
20537
20538         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20539         echo -n 'verify rename_stats...'
20540         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20541                 verify_yaml || error "rename_stats is not valid YAML"
20542         echo " OK"
20543
20544         echo -n 'verify mdt job_stats...'
20545         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20546                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20547         echo " OK"
20548
20549         echo -n 'verify ost job_stats...'
20550         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20551                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20552         echo " OK"
20553 }
20554 run_test 205d "verify the format of some stats files"
20555
20556 test_205e() {
20557         local ops_comma
20558         local file=$DIR/$tdir/$tfile
20559         local -a cli_params
20560
20561         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20562                 skip "need lustre >= 2.15.53 for lljobstat"
20563         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20564                 skip "need lustre >= 2.15.53 for lljobstat"
20565         verify_yaml_available || skip_env "YAML verification not installed"
20566
20567         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20568         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20569         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20570
20571         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20572         stack_trap "rm -rf $DIR/$tdir"
20573
20574         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20575                 error "failed to create $file on ost1"
20576         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20577                 error "failed to write data to $file"
20578
20579         do_facet mds1 "$LCTL get_param *.*.job_stats"
20580         do_facet ost1 "$LCTL get_param *.*.job_stats"
20581
20582         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20583         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20584                 error "The output of lljobstat is not an valid YAML"
20585
20586         # verify that job dd.0 does exist and has some ops on ost1
20587         # typically this line is like:
20588         # - 205e.dd.0:            {ops: 20, ...}
20589         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20590                     awk '$2=="205e.dd.0:" {print $4}')
20591
20592         (( ${ops_comma%,} >= 10 )) ||
20593                 error "cannot find job 205e.dd.0 with ops >= 10"
20594 }
20595 run_test 205e "verify the output of lljobstat"
20596
20597 test_205f() {
20598         verify_yaml_available || skip_env "YAML verification not installed"
20599
20600         # check both qos_ost_weights and qos_mdt_weights
20601         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20602         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20603                 error "qos_ost_weights is not valid YAML"
20604 }
20605 run_test 205f "verify qos_ost_weights YAML format "
20606
20607 __test_205_jobstats_dump() {
20608         local -a pids
20609         local nbr_instance=$1
20610
20611         while true; do
20612                 if (( ${#pids[@]} >= nbr_instance )); then
20613                         wait ${pids[@]}
20614                         pids=()
20615                 fi
20616
20617                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20618                 pids+=( $! )
20619         done
20620 }
20621
20622 __test_205_cleanup() {
20623         kill $@
20624         # Clear all job entries
20625         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20626 }
20627
20628 test_205g() {
20629         local -a mds1_params
20630         local -a cli_params
20631         local pids
20632         local interval=5
20633
20634         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20635         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20636         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20637
20638         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20639         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20640         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20641
20642         # start jobs loop
20643         export TEST205G_ID=205g
20644         stack_trap "unset TEST205G_ID" EXIT
20645         while true; do
20646                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20647         done & pids="$! "
20648
20649         __test_205_jobstats_dump 4 & pids+="$! "
20650         stack_trap "__test_205_cleanup $pids" EXIT INT
20651
20652         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20653 }
20654 run_test 205g "stress test for job_stats procfile"
20655
20656 test_205h() {
20657         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20658                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20659         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20660
20661         local dir=$DIR/$tdir
20662         local f=$dir/$tfile
20663         local f2=$dir/$tfile-2
20664         local f3=$dir/$tfile-3
20665         local subdir=$DIR/dir
20666         local val
20667
20668         local mdts=$(comma_list $(mdts_nodes))
20669         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20670         local client_saved=$($LCTL get_param -n jobid_var)
20671
20672         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20673         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20674
20675         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20676                 error "failed to set job_xattr parameter to user.job"
20677         $LCTL set_param jobid_var=procname.uid ||
20678                 error "failed to set jobid_var parameter"
20679
20680         test_mkdir $dir
20681
20682         touch $f
20683         val=$(getfattr -n user.job $f | grep user.job)
20684         [[ $val = user.job=\"touch.0\" ]] ||
20685                 error "expected user.job=\"touch.0\", got '$val'"
20686
20687         mkdir $subdir
20688         val=$(getfattr -n user.job $subdir | grep user.job)
20689         [[ $val = user.job=\"mkdir.0\" ]] ||
20690                 error "expected user.job=\"mkdir.0\", got '$val'"
20691
20692         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20693                 error "failed to set job_xattr parameter to NONE"
20694
20695         touch $f2
20696         val=$(getfattr -d $f2)
20697         [[ -z $val ]] ||
20698                 error "expected no user xattr, got '$val'"
20699
20700         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20701                 error "failed to set job_xattr parameter to trusted.job"
20702
20703         touch $f3
20704         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20705         [[ $val = trusted.job=\"touch.0\" ]] ||
20706                 error "expected trusted.job=\"touch.0\", got '$val'"
20707 }
20708 run_test 205h "check jobid xattr is stored correctly"
20709
20710 test_205i() {
20711         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20712                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20713
20714         local mdts=$(comma_list $(mdts_nodes))
20715         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20716
20717         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20718
20719         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20720                 error "failed to set mdt.*.job_xattr to user.1234567"
20721
20722         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20723                 error "failed to reject too long job_xattr name"
20724
20725         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20726                 error "failed to reject job_xattr name in bad format"
20727
20728         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20729                 error "failed to reject job_xattr name with invalid character"
20730
20731         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20732                         xargs $LCTL set_param" &&
20733                 error "failed to reject job_xattr name with non-ascii character"
20734
20735         return 0
20736 }
20737 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20738
20739 # LU-1480, LU-1773 and LU-1657
20740 test_206() {
20741         mkdir -p $DIR/$tdir
20742         $LFS setstripe -c -1 $DIR/$tdir
20743 #define OBD_FAIL_LOV_INIT 0x1403
20744         $LCTL set_param fail_loc=0xa0001403
20745         $LCTL set_param fail_val=1
20746         touch $DIR/$tdir/$tfile || true
20747 }
20748 run_test 206 "fail lov_init_raid0() doesn't lbug"
20749
20750 test_207a() {
20751         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20752         local fsz=`stat -c %s $DIR/$tfile`
20753         cancel_lru_locks mdc
20754
20755         # do not return layout in getattr intent
20756 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20757         $LCTL set_param fail_loc=0x170
20758         local sz=`stat -c %s $DIR/$tfile`
20759
20760         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20761
20762         rm -rf $DIR/$tfile
20763 }
20764 run_test 207a "can refresh layout at glimpse"
20765
20766 test_207b() {
20767         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20768         local cksum=`md5sum $DIR/$tfile`
20769         local fsz=`stat -c %s $DIR/$tfile`
20770         cancel_lru_locks mdc
20771         cancel_lru_locks osc
20772
20773         # do not return layout in getattr intent
20774 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20775         $LCTL set_param fail_loc=0x171
20776
20777         # it will refresh layout after the file is opened but before read issues
20778         echo checksum is "$cksum"
20779         echo "$cksum" |md5sum -c --quiet || error "file differs"
20780
20781         rm -rf $DIR/$tfile
20782 }
20783 run_test 207b "can refresh layout at open"
20784
20785 test_208() {
20786         # FIXME: in this test suite, only RD lease is used. This is okay
20787         # for now as only exclusive open is supported. After generic lease
20788         # is done, this test suite should be revised. - Jinshan
20789
20790         remote_mds_nodsh && skip "remote MDS with nodsh"
20791         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20792                 skip "Need MDS version at least 2.4.52"
20793
20794         echo "==== test 1: verify get lease work"
20795         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20796
20797         echo "==== test 2: verify lease can be broken by upcoming open"
20798         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20799         local PID=$!
20800         sleep 2
20801
20802         $MULTIOP $DIR/$tfile oO_RDWR:c
20803         kill -USR1 $PID && wait $PID || error "break lease error"
20804
20805         echo "==== test 3: verify lease can't be granted if an open already exists"
20806         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20807         local PID=$!
20808         sleep 2
20809
20810         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20811         kill -USR1 $PID && wait $PID || error "open file error"
20812
20813         echo "==== test 4: lease can sustain over recovery"
20814         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20815         PID=$!
20816         sleep 2
20817
20818         fail mds1
20819
20820         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20821
20822         echo "==== test 5: lease broken can't be regained by replay"
20823         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20824         PID=$!
20825         sleep 2
20826
20827         # open file to break lease and then recovery
20828         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20829         fail mds1
20830
20831         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20832
20833         rm -f $DIR/$tfile
20834 }
20835 run_test 208 "Exclusive open"
20836
20837 test_209() {
20838         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20839                 skip_env "must have disp_stripe"
20840
20841         touch $DIR/$tfile
20842         sync; sleep 5; sync;
20843
20844         echo 3 > /proc/sys/vm/drop_caches
20845         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20846                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20847         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20848
20849         # open/close 500 times
20850         for i in $(seq 500); do
20851                 cat $DIR/$tfile
20852         done
20853
20854         echo 3 > /proc/sys/vm/drop_caches
20855         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20856                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20857         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20858
20859         echo "before: $req_before, after: $req_after"
20860         [ $((req_after - req_before)) -ge 300 ] &&
20861                 error "open/close requests are not freed"
20862         return 0
20863 }
20864 run_test 209 "read-only open/close requests should be freed promptly"
20865
20866 test_210() {
20867         local pid
20868
20869         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20870         pid=$!
20871         sleep 1
20872
20873         $LFS getstripe $DIR/$tfile
20874         kill -USR1 $pid
20875         wait $pid || error "multiop failed"
20876
20877         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20878         pid=$!
20879         sleep 1
20880
20881         $LFS getstripe $DIR/$tfile
20882         kill -USR1 $pid
20883         wait $pid || error "multiop failed"
20884 }
20885 run_test 210 "lfs getstripe does not break leases"
20886
20887 function test_211() {
20888         local PID
20889         local id
20890         local rc
20891
20892         stack_trap "rm -f $DIR/$tfile" EXIT
20893         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20894                 error "can't create file"
20895         $LFS mirror extend -N $DIR/$tfile ||
20896                 error "can't create a replica"
20897         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20898         $LFS getstripe $DIR/$tfile
20899         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20900         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20901
20902         $MULTIOP $DIR/$tfile OeW_E+eUc &
20903         PID=$!
20904         sleep 0.3
20905
20906         id=$($LFS getstripe $DIR/$tfile |
20907                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20908         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20909                 error "removed last in-sync replica?"
20910
20911         kill -USR1 $PID
20912         wait $PID
20913         (( $? == 0 )) || error "failed split broke the lease"
20914 }
20915 run_test 211 "failed mirror split doesn't break write lease"
20916
20917 test_212() {
20918         size=`date +%s`
20919         size=$((size % 8192 + 1))
20920         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20921         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20922         rm -f $DIR/f212 $DIR/f212.xyz
20923 }
20924 run_test 212 "Sendfile test ============================================"
20925
20926 test_213() {
20927         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20928         cancel_lru_locks osc
20929         lctl set_param fail_loc=0x8000040f
20930         # generate a read lock
20931         cat $DIR/$tfile > /dev/null
20932         # write to the file, it will try to cancel the above read lock.
20933         cat /etc/hosts >> $DIR/$tfile
20934 }
20935 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20936
20937 test_214() { # for bug 20133
20938         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20939         for (( i=0; i < 340; i++ )) ; do
20940                 touch $DIR/$tdir/d214c/a$i
20941         done
20942
20943         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20944         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20945         ls $DIR/d214c || error "ls $DIR/d214c failed"
20946         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20947         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20948 }
20949 run_test 214 "hash-indexed directory test - bug 20133"
20950
20951 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20952 create_lnet_proc_files() {
20953         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20954 }
20955
20956 # counterpart of create_lnet_proc_files
20957 remove_lnet_proc_files() {
20958         rm -f $TMP/lnet_$1.sys
20959 }
20960
20961 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20962 # 3rd arg as regexp for body
20963 check_lnet_proc_stats() {
20964         local l=$(cat "$TMP/lnet_$1" |wc -l)
20965         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20966
20967         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20968 }
20969
20970 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20971 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20972 # optional and can be regexp for 2nd line (lnet.routes case)
20973 check_lnet_proc_entry() {
20974         local blp=2          # blp stands for 'position of 1st line of body'
20975         [ -z "$5" ] || blp=3 # lnet.routes case
20976
20977         local l=$(cat "$TMP/lnet_$1" |wc -l)
20978         # subtracting one from $blp because the body can be empty
20979         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20980
20981         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20982                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20983
20984         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20985                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20986
20987         # bail out if any unexpected line happened
20988         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20989         [ "$?" != 0 ] || error "$2 misformatted"
20990 }
20991
20992 test_215() { # for bugs 18102, 21079, 21517
20993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20994
20995         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20996         local P='[1-9][0-9]*'           # positive numeric
20997         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20998         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20999         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
21000         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
21001
21002         local L1 # regexp for 1st line
21003         local L2 # regexp for 2nd line (optional)
21004         local BR # regexp for the rest (body)
21005
21006         # lnet.stats should look as 11 space-separated non-negative numerics
21007         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21008         create_lnet_proc_files "stats"
21009         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21010         remove_lnet_proc_files "stats"
21011
21012         # lnet.routes should look like this:
21013         # Routing disabled/enabled
21014         # net hops priority state router
21015         # where net is a string like tcp0, hops > 0, priority >= 0,
21016         # state is up/down,
21017         # router is a string like 192.168.1.1@tcp2
21018         L1="^Routing (disabled|enabled)$"
21019         L2="^net +hops +priority +state +router$"
21020         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
21021         create_lnet_proc_files "routes"
21022         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21023         remove_lnet_proc_files "routes"
21024
21025         # lnet.routers should look like this:
21026         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21027         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21028         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21029         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21030         L1="^ref +rtr_ref +alive +router$"
21031         BR="^$P +$P +(up|down) +$NID$"
21032         create_lnet_proc_files "routers"
21033         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21034         remove_lnet_proc_files "routers"
21035
21036         # lnet.peers should look like this:
21037         # nid refs state last max rtr min tx min queue
21038         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21039         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21040         # numeric (0 or >0 or <0), queue >= 0.
21041         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21042         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21043         create_lnet_proc_files "peers"
21044         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21045         remove_lnet_proc_files "peers"
21046
21047         # lnet.buffers  should look like this:
21048         # pages count credits min
21049         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21050         L1="^pages +count +credits +min$"
21051         BR="^ +$N +$N +$I +$I$"
21052         create_lnet_proc_files "buffers"
21053         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21054         remove_lnet_proc_files "buffers"
21055
21056         # lnet.nis should look like this:
21057         # nid status alive refs peer rtr max tx min
21058         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21059         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21060         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21061         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21062         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21063         create_lnet_proc_files "nis"
21064         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21065         remove_lnet_proc_files "nis"
21066
21067         # can we successfully write to lnet.stats?
21068         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21069 }
21070 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21071
21072 test_216() { # bug 20317
21073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21074         remote_ost_nodsh && skip "remote OST with nodsh"
21075
21076         local node
21077         local facets=$(get_facets OST)
21078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21079
21080         save_lustre_params client "osc.*.contention_seconds" > $p
21081         save_lustre_params $facets \
21082                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21083         save_lustre_params $facets \
21084                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21085         save_lustre_params $facets \
21086                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21087         clear_stats osc.*.osc_stats
21088
21089         # agressive lockless i/o settings
21090         do_nodes $(comma_list $(osts_nodes)) \
21091                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21092                         ldlm.namespaces.filter-*.contended_locks=0 \
21093                         ldlm.namespaces.filter-*.contention_seconds=60"
21094         lctl set_param -n osc.*.contention_seconds=60
21095
21096         $DIRECTIO write $DIR/$tfile 0 10 4096
21097         $CHECKSTAT -s 40960 $DIR/$tfile
21098
21099         # disable lockless i/o
21100         do_nodes $(comma_list $(osts_nodes)) \
21101                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21102                         ldlm.namespaces.filter-*.contended_locks=32 \
21103                         ldlm.namespaces.filter-*.contention_seconds=0"
21104         lctl set_param -n osc.*.contention_seconds=0
21105         clear_stats osc.*.osc_stats
21106
21107         dd if=/dev/zero of=$DIR/$tfile count=0
21108         $CHECKSTAT -s 0 $DIR/$tfile
21109
21110         restore_lustre_params <$p
21111         rm -f $p
21112         rm $DIR/$tfile
21113 }
21114 run_test 216 "check lockless direct write updates file size and kms correctly"
21115
21116 test_217() { # bug 22430
21117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21118
21119         local node
21120
21121         for node in $(nodes_list); do
21122                 local nid=$(host_nids_address $node $NETTYPE)
21123                 local node_ip=$(do_node $node getent ahostsv4 $node |
21124                                 awk '{ print $1; exit; }')
21125
21126                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21127                 # if hostname matches any NID, use hostname for better testing
21128                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21129                         echo "lctl ping node $node@$NETTYPE"
21130                         lctl ping $node@$NETTYPE
21131                 else # otherwise, at least test 'lctl ping' is working
21132                         echo "lctl ping nid $(h2nettype $nid)"
21133                         lctl ping $(h2nettype $nid)
21134                         echo "skipping $node (no hyphen detected)"
21135                 fi
21136         done
21137 }
21138 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21139
21140 test_218() {
21141         # do directio so as not to populate the page cache
21142         log "creating a 10 Mb file"
21143         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21144                 error "multiop failed while creating a file"
21145         log "starting reads"
21146         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21147         log "truncating the file"
21148         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21149                 error "multiop failed while truncating the file"
21150         log "killing dd"
21151         kill %+ || true # reads might have finished
21152         echo "wait until dd is finished"
21153         wait
21154         log "removing the temporary file"
21155         rm -rf $DIR/$tfile || error "tmp file removal failed"
21156 }
21157 run_test 218 "parallel read and truncate should not deadlock"
21158
21159 test_219() {
21160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21161
21162         # write one partial page
21163         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21164         # set no grant so vvp_io_commit_write will do sync write
21165         $LCTL set_param fail_loc=0x411
21166         # write a full page at the end of file
21167         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21168
21169         $LCTL set_param fail_loc=0
21170         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21171         $LCTL set_param fail_loc=0x411
21172         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21173
21174         # LU-4201
21175         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21176         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21177 }
21178 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21179
21180 test_220() { #LU-325
21181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21182         remote_ost_nodsh && skip "remote OST with nodsh"
21183         remote_mds_nodsh && skip "remote MDS with nodsh"
21184         remote_mgs_nodsh && skip "remote MGS with nodsh"
21185
21186         local OSTIDX=0
21187
21188         # create on MDT0000 so the last_id and next_id are correct
21189         mkdir_on_mdt0 $DIR/$tdir
21190         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21191         OST=${OST%_UUID}
21192
21193         # on the mdt's osc
21194         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21195         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21196                         osp.$mdtosc_proc1.prealloc_last_id)
21197         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21198                         osp.$mdtosc_proc1.prealloc_next_id)
21199
21200         $LFS df -i
21201
21202         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21203         #define OBD_FAIL_OST_ENOINO              0x229
21204         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21205         create_pool $FSNAME.$TESTNAME || return 1
21206         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21207
21208         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21209
21210         MDSOBJS=$((last_id - next_id))
21211         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21212
21213         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21214         echo "OST still has $count kbytes free"
21215
21216         echo "create $MDSOBJS files @next_id..."
21217         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21218
21219         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21220                         osp.$mdtosc_proc1.prealloc_last_id)
21221         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21222                         osp.$mdtosc_proc1.prealloc_next_id)
21223
21224         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21225         $LFS df -i
21226
21227         echo "cleanup..."
21228
21229         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21230         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21231
21232         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21233                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21234         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21235                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21236         echo "unlink $MDSOBJS files @$next_id..."
21237         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21238 }
21239 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21240
21241 test_221() {
21242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21243
21244         dd if=`which date` of=$MOUNT/date oflag=sync
21245         chmod +x $MOUNT/date
21246
21247         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21248         $LCTL set_param fail_loc=0x80001401
21249
21250         $MOUNT/date > /dev/null
21251         rm -f $MOUNT/date
21252 }
21253 run_test 221 "make sure fault and truncate race to not cause OOM"
21254
21255 test_222a () {
21256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21257
21258         rm -rf $DIR/$tdir
21259         test_mkdir $DIR/$tdir
21260         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21261         createmany -o $DIR/$tdir/$tfile 10
21262         cancel_lru_locks mdc
21263         cancel_lru_locks osc
21264         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21265         $LCTL set_param fail_loc=0x31a
21266         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21267         $LCTL set_param fail_loc=0
21268         rm -r $DIR/$tdir
21269 }
21270 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21271
21272 test_222b () {
21273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21274
21275         rm -rf $DIR/$tdir
21276         test_mkdir $DIR/$tdir
21277         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21278         createmany -o $DIR/$tdir/$tfile 10
21279         cancel_lru_locks mdc
21280         cancel_lru_locks osc
21281         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21282         $LCTL set_param fail_loc=0x31a
21283         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21284         $LCTL set_param fail_loc=0
21285 }
21286 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21287
21288 test_223 () {
21289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21290
21291         rm -rf $DIR/$tdir
21292         test_mkdir $DIR/$tdir
21293         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21294         createmany -o $DIR/$tdir/$tfile 10
21295         cancel_lru_locks mdc
21296         cancel_lru_locks osc
21297         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21298         $LCTL set_param fail_loc=0x31b
21299         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21300         $LCTL set_param fail_loc=0
21301         rm -r $DIR/$tdir
21302 }
21303 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21304
21305 test_224a() { # LU-1039, MRP-303
21306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21307         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21308         $LCTL set_param fail_loc=0x508
21309         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21310         $LCTL set_param fail_loc=0
21311         df $DIR
21312 }
21313 run_test 224a "Don't panic on bulk IO failure"
21314
21315 test_224bd_sub() { # LU-1039, MRP-303
21316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21317         local timeout=$1
21318
21319         shift
21320         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21321
21322         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21323
21324         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21325         cancel_lru_locks osc
21326         set_checksums 0
21327         stack_trap "set_checksums $ORIG_CSUM" EXIT
21328         local at_max_saved=0
21329
21330         # adaptive timeouts may prevent seeing the issue
21331         if at_is_enabled; then
21332                 at_max_saved=$(at_max_get mds)
21333                 at_max_set 0 mds client
21334                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21335         fi
21336
21337         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21338         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21339         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21340
21341         do_facet ost1 $LCTL set_param fail_loc=0
21342         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21343         df $DIR
21344 }
21345
21346 test_224b() {
21347         test_224bd_sub 3 error "dd failed"
21348 }
21349 run_test 224b "Don't panic on bulk IO failure"
21350
21351 test_224c() { # LU-6441
21352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21353         remote_mds_nodsh && skip "remote MDS with nodsh"
21354
21355         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21356         save_writethrough $p
21357         set_cache writethrough on
21358
21359         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21360         local at_max=$($LCTL get_param -n at_max)
21361         local timeout=$($LCTL get_param -n timeout)
21362         local test_at="at_max"
21363         local param_at="$FSNAME.sys.at_max"
21364         local test_timeout="timeout"
21365         local param_timeout="$FSNAME.sys.timeout"
21366
21367         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21368
21369         set_persistent_param_and_check client "$test_at" "$param_at" 0
21370         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21371
21372         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21373         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21374         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21375         stack_trap "rm -f $DIR/$tfile"
21376         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21377         sync
21378         do_facet ost1 "$LCTL set_param fail_loc=0"
21379
21380         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21381         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21382                 $timeout
21383
21384         $LCTL set_param -n $pages_per_rpc
21385         restore_lustre_params < $p
21386         rm -f $p
21387 }
21388 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21389
21390 test_224d() { # LU-11169
21391         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21392 }
21393 run_test 224d "Don't corrupt data on bulk IO timeout"
21394
21395 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21396 test_225a () {
21397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21398         if [ -z ${MDSSURVEY} ]; then
21399                 skip_env "mds-survey not found"
21400         fi
21401         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21402                 skip "Need MDS version at least 2.2.51"
21403
21404         local mds=$(facet_host $SINGLEMDS)
21405         local target=$(do_nodes $mds 'lctl dl' |
21406                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21407
21408         local cmd1="file_count=1000 thrhi=4"
21409         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21410         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21411         local cmd="$cmd1 $cmd2 $cmd3"
21412
21413         rm -f ${TMP}/mds_survey*
21414         echo + $cmd
21415         eval $cmd || error "mds-survey with zero-stripe failed"
21416         cat ${TMP}/mds_survey*
21417         rm -f ${TMP}/mds_survey*
21418 }
21419 run_test 225a "Metadata survey sanity with zero-stripe"
21420
21421 test_225b () {
21422         if [ -z ${MDSSURVEY} ]; then
21423                 skip_env "mds-survey not found"
21424         fi
21425         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21426                 skip "Need MDS version at least 2.2.51"
21427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21428         remote_mds_nodsh && skip "remote MDS with nodsh"
21429         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21430                 skip_env "Need to mount OST to test"
21431         fi
21432
21433         local mds=$(facet_host $SINGLEMDS)
21434         local target=$(do_nodes $mds 'lctl dl' |
21435                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21436
21437         local cmd1="file_count=1000 thrhi=4"
21438         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21439         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21440         local cmd="$cmd1 $cmd2 $cmd3"
21441
21442         rm -f ${TMP}/mds_survey*
21443         echo + $cmd
21444         eval $cmd || error "mds-survey with stripe_count failed"
21445         cat ${TMP}/mds_survey*
21446         rm -f ${TMP}/mds_survey*
21447 }
21448 run_test 225b "Metadata survey sanity with stripe_count = 1"
21449
21450 mcreate_path2fid () {
21451         local mode=$1
21452         local major=$2
21453         local minor=$3
21454         local name=$4
21455         local desc=$5
21456         local path=$DIR/$tdir/$name
21457         local fid
21458         local rc
21459         local fid_path
21460
21461         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21462                 error "cannot create $desc"
21463
21464         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21465         rc=$?
21466         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21467
21468         fid_path=$($LFS fid2path $MOUNT $fid)
21469         rc=$?
21470         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21471
21472         [ "$path" == "$fid_path" ] ||
21473                 error "fid2path returned $fid_path, expected $path"
21474
21475         echo "pass with $path and $fid"
21476 }
21477
21478 test_226a () {
21479         rm -rf $DIR/$tdir
21480         mkdir -p $DIR/$tdir
21481
21482         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21483         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21484         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21485         mcreate_path2fid 0040666 0 0 dir "directory"
21486         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21487         mcreate_path2fid 0100666 0 0 file "regular file"
21488         mcreate_path2fid 0120666 0 0 link "symbolic link"
21489         mcreate_path2fid 0140666 0 0 sock "socket"
21490 }
21491 run_test 226a "call path2fid and fid2path on files of all type"
21492
21493 test_226b () {
21494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21495
21496         local MDTIDX=1
21497
21498         rm -rf $DIR/$tdir
21499         mkdir -p $DIR/$tdir
21500         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21501                 error "create remote directory failed"
21502         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21503         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21504                                 "character special file (null)"
21505         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21506                                 "character special file (no device)"
21507         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21508         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21509                                 "block special file (loop)"
21510         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21511         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21512         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21513 }
21514 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21515
21516 test_226c () {
21517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21518         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21519                 skip "Need MDS version at least 2.13.55"
21520
21521         local submnt=/mnt/submnt
21522         local srcfile=/etc/passwd
21523         local dstfile=$submnt/passwd
21524         local path
21525         local fid
21526
21527         rm -rf $DIR/$tdir
21528         rm -rf $submnt
21529         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21530                 error "create remote directory failed"
21531         mkdir -p $submnt || error "create $submnt failed"
21532         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21533                 error "mount $submnt failed"
21534         stack_trap "umount $submnt" EXIT
21535
21536         cp $srcfile $dstfile
21537         fid=$($LFS path2fid $dstfile)
21538         path=$($LFS fid2path $submnt "$fid")
21539         [ "$path" = "$dstfile" ] ||
21540                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21541 }
21542 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21543
21544 test_226d () {
21545         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21546                 skip "Need client at least version 2.15.57"
21547
21548         # Define First test dataset
21549         local testdirs_01=$DIR/$tdir
21550         local testdata_01=$testdirs_01/${tdir}_01
21551         local testresult_01=${tdir}_01
21552         # Define Second test dataset
21553         local testdirs_02=$DIR/$tdir/$tdir
21554         local testdata_02=$testdirs_02/${tdir}_02
21555         local testresult_02=${tdir}_02
21556         # Define third test dataset (top level)
21557         local testdata_03=$DIR/${tdir}_03
21558         local testresult_03=${tdir}_03
21559
21560         # Create first test dataset
21561         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21562         touch $testdata_01 || error "cannot create file $testdata_01"
21563
21564         # Create second test dataset
21565         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21566         touch $testdata_02 || error "cannot create file $testdata_02"
21567
21568         # Create third test dataset
21569         touch $testdata_03 || error "cannot create file $testdata_03"
21570
21571         local fid01=$($LFS getstripe -F "$testdata_01") ||
21572                 error "getstripe failed on $testdata_01"
21573         local fid02=$($LFS getstripe -F "$testdata_02") ||
21574                 error "getstripe failed on $testdata_01"
21575         local fid03=$($LFS getstripe -F "$testdata_03") ||
21576                 error "getstripe failed on $testdata_03"
21577
21578         # Verify only -n option
21579         local out1=$($LFS fid2path -n $DIR $fid01) ||
21580                 error "fid2path failed on $fid01"
21581         local out2=$($LFS fid2path -n $DIR $fid02) ||
21582                 error "fid2path failed on $fid02"
21583         local out3=$($LFS fid2path -n $DIR $fid03) ||
21584                 error "fid2path failed on $fid03"
21585
21586         [[ "$out1" == "$testresult_01" ]] ||
21587                 error "fid2path failed: Expected $testresult_01 got $out1"
21588         [[ "$out2" == "$testresult_02" ]] ||
21589                 error "fid2path failed: Expected $testresult_02 got $out2"
21590         [[ "$out3" == "$testresult_03" ]] ||
21591                 error "fid2path failed: Expected $testresult_03 got $out3"
21592
21593         # Verify with option -fn together
21594         out1=$($LFS fid2path -fn $DIR $fid01) ||
21595                 error "fid2path -fn failed on $fid01"
21596         out2=$($LFS fid2path -fn $DIR $fid02) ||
21597                 error "fid2path -fn failed on $fid02"
21598         out3=$($LFS fid2path -fn $DIR $fid03) ||
21599                 error "fid2path -fn failed on $fid03"
21600
21601         local tmpout=$(echo $out1 | cut -d" " -f2)
21602         [[ "$tmpout" == "$testresult_01" ]] ||
21603                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21604
21605         tmpout=$(echo $out2 | cut -d" " -f2)
21606         [[ "$tmpout" == "$testresult_02" ]] ||
21607                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21608
21609         tmpout=$(echo $out3 | cut -d" " -f2)
21610         [[ "$tmpout" == "$testresult_03" ]] ||
21611                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21612 }
21613 run_test 226d "verify fid2path with -n and -fn option"
21614
21615 test_226e () {
21616         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21617                 skip "Need client at least version 2.15.56"
21618
21619         # Define filename with 'newline' and a space
21620         local testfile="Test"$'\n'"file 01"
21621         # Define link name with multiple 'newline' and a space
21622         local linkfile="Link"$'\n'"file "$'\n'"01"
21623         # Remove prior hard link
21624         rm -f $DIR/"$linkfile"
21625
21626         # Create file
21627         touch $DIR/"$testfile"
21628         # Create link
21629         ln $DIR/"$testfile" $DIR/"$linkfile"
21630
21631         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21632                 error "getstripe failed on $DIR/$testfile"
21633
21634         # Call with -0 option
21635         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21636                 echo "FILE:" | grep -c "FILE:")
21637
21638         # With -0 option the output should be exactly 2 lines.
21639         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21640 }
21641 run_test 226e "Verify path2fid -0 option with newline and space"
21642
21643 # LU-1299 Executing or running ldd on a truncated executable does not
21644 # cause an out-of-memory condition.
21645 test_227() {
21646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21647         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21648
21649         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21650         chmod +x $MOUNT/date
21651
21652         $MOUNT/date > /dev/null
21653         ldd $MOUNT/date > /dev/null
21654         rm -f $MOUNT/date
21655 }
21656 run_test 227 "running truncated executable does not cause OOM"
21657
21658 # LU-1512 try to reuse idle OI blocks
21659 test_228a() {
21660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21661         remote_mds_nodsh && skip "remote MDS with nodsh"
21662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21663
21664         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21665         local myDIR=$DIR/$tdir
21666
21667         mkdir -p $myDIR
21668         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21669         $LCTL set_param fail_loc=0x80001002
21670         createmany -o $myDIR/t- 10000
21671         $LCTL set_param fail_loc=0
21672         # The guard is current the largest FID holder
21673         touch $myDIR/guard
21674         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21675                     tr -d '[')
21676         local IDX=$(($SEQ % 64))
21677
21678         do_facet $SINGLEMDS sync
21679         # Make sure journal flushed.
21680         sleep 6
21681         local blk1=$(do_facet $SINGLEMDS \
21682                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21683                      grep Blockcount | awk '{print $4}')
21684
21685         # Remove old files, some OI blocks will become idle.
21686         unlinkmany $myDIR/t- 10000
21687         # Create new files, idle OI blocks should be reused.
21688         createmany -o $myDIR/t- 2000
21689         do_facet $SINGLEMDS sync
21690         # Make sure journal flushed.
21691         sleep 6
21692         local blk2=$(do_facet $SINGLEMDS \
21693                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21694                      grep Blockcount | awk '{print $4}')
21695
21696         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21697 }
21698 run_test 228a "try to reuse idle OI blocks"
21699
21700 test_228b() {
21701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21702         remote_mds_nodsh && skip "remote MDS with nodsh"
21703         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21704
21705         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21706         local myDIR=$DIR/$tdir
21707
21708         mkdir -p $myDIR
21709         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21710         $LCTL set_param fail_loc=0x80001002
21711         createmany -o $myDIR/t- 10000
21712         $LCTL set_param fail_loc=0
21713         # The guard is current the largest FID holder
21714         touch $myDIR/guard
21715         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21716                     tr -d '[')
21717         local IDX=$(($SEQ % 64))
21718
21719         do_facet $SINGLEMDS sync
21720         # Make sure journal flushed.
21721         sleep 6
21722         local blk1=$(do_facet $SINGLEMDS \
21723                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21724                      grep Blockcount | awk '{print $4}')
21725
21726         # Remove old files, some OI blocks will become idle.
21727         unlinkmany $myDIR/t- 10000
21728
21729         # stop the MDT
21730         stop $SINGLEMDS || error "Fail to stop MDT."
21731         # remount the MDT
21732         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21733                 error "Fail to start MDT."
21734
21735         client_up || error "Fail to df."
21736         # Create new files, idle OI blocks should be reused.
21737         createmany -o $myDIR/t- 2000
21738         do_facet $SINGLEMDS sync
21739         # Make sure journal flushed.
21740         sleep 6
21741         local blk2=$(do_facet $SINGLEMDS \
21742                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21743                      grep Blockcount | awk '{print $4}')
21744
21745         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21746 }
21747 run_test 228b "idle OI blocks can be reused after MDT restart"
21748
21749 #LU-1881
21750 test_228c() {
21751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21752         remote_mds_nodsh && skip "remote MDS with nodsh"
21753         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21754
21755         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21756         local myDIR=$DIR/$tdir
21757
21758         mkdir -p $myDIR
21759         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21760         $LCTL set_param fail_loc=0x80001002
21761         # 20000 files can guarantee there are index nodes in the OI file
21762         createmany -o $myDIR/t- 20000
21763         $LCTL set_param fail_loc=0
21764         # The guard is current the largest FID holder
21765         touch $myDIR/guard
21766         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21767                     tr -d '[')
21768         local IDX=$(($SEQ % 64))
21769
21770         do_facet $SINGLEMDS sync
21771         # Make sure journal flushed.
21772         sleep 6
21773         local blk1=$(do_facet $SINGLEMDS \
21774                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21775                      grep Blockcount | awk '{print $4}')
21776
21777         # Remove old files, some OI blocks will become idle.
21778         unlinkmany $myDIR/t- 20000
21779         rm -f $myDIR/guard
21780         # The OI file should become empty now
21781
21782         # Create new files, idle OI blocks should be reused.
21783         createmany -o $myDIR/t- 2000
21784         do_facet $SINGLEMDS sync
21785         # Make sure journal flushed.
21786         sleep 6
21787         local blk2=$(do_facet $SINGLEMDS \
21788                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21789                      grep Blockcount | awk '{print $4}')
21790
21791         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21792 }
21793 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21794
21795 test_229() { # LU-2482, LU-3448
21796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21797         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21798         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21799                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21800
21801         rm -f $DIR/$tfile
21802
21803         # Create a file with a released layout and stripe count 2.
21804         $MULTIOP $DIR/$tfile H2c ||
21805                 error "failed to create file with released layout"
21806
21807         $LFS getstripe -v $DIR/$tfile
21808
21809         local pattern=$($LFS getstripe -L $DIR/$tfile)
21810         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21811
21812         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21813                 error "getstripe"
21814         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21815         stat $DIR/$tfile || error "failed to stat released file"
21816
21817         chown $RUNAS_ID $DIR/$tfile ||
21818                 error "chown $RUNAS_ID $DIR/$tfile failed"
21819
21820         chgrp $RUNAS_ID $DIR/$tfile ||
21821                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21822
21823         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21824         rm $DIR/$tfile || error "failed to remove released file"
21825 }
21826 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21827
21828 test_230a() {
21829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21830         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21831         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21832                 skip "Need MDS version at least 2.11.52"
21833
21834         local MDTIDX=1
21835
21836         test_mkdir $DIR/$tdir
21837         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21838         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21839         [ $mdt_idx -ne 0 ] &&
21840                 error "create local directory on wrong MDT $mdt_idx"
21841
21842         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21843                         error "create remote directory failed"
21844         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21845         [ $mdt_idx -ne $MDTIDX ] &&
21846                 error "create remote directory on wrong MDT $mdt_idx"
21847
21848         createmany -o $DIR/$tdir/test_230/t- 10 ||
21849                 error "create files on remote directory failed"
21850         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21851         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21852         rm -r $DIR/$tdir || error "unlink remote directory failed"
21853 }
21854 run_test 230a "Create remote directory and files under the remote directory"
21855
21856 test_230b() {
21857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21859         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21860                 skip "Need MDS version at least 2.11.52"
21861
21862         local MDTIDX=1
21863         local mdt_index
21864         local i
21865         local file
21866         local pid
21867         local stripe_count
21868         local migrate_dir=$DIR/$tdir/migrate_dir
21869         local other_dir=$DIR/$tdir/other_dir
21870
21871         test_mkdir $DIR/$tdir
21872         test_mkdir -i0 -c1 $migrate_dir
21873         test_mkdir -i0 -c1 $other_dir
21874         for ((i=0; i<10; i++)); do
21875                 mkdir -p $migrate_dir/dir_${i}
21876                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21877                         error "create files under remote dir failed $i"
21878         done
21879
21880         cp /etc/passwd $migrate_dir/$tfile
21881         cp /etc/passwd $other_dir/$tfile
21882         chattr +SAD $migrate_dir
21883         chattr +SAD $migrate_dir/$tfile
21884
21885         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21886         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21887         local old_dir_mode=$(stat -c%f $migrate_dir)
21888         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21889
21890         mkdir -p $migrate_dir/dir_default_stripe2
21891         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21892         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21893
21894         mkdir -p $other_dir
21895         ln $migrate_dir/$tfile $other_dir/luna
21896         ln $migrate_dir/$tfile $migrate_dir/sofia
21897         ln $other_dir/$tfile $migrate_dir/david
21898         ln -s $migrate_dir/$tfile $other_dir/zachary
21899         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21900         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21901
21902         local len
21903         local lnktgt
21904
21905         # inline symlink
21906         for len in 58 59 60; do
21907                 lnktgt=$(str_repeat 'l' $len)
21908                 touch $migrate_dir/$lnktgt
21909                 ln -s $lnktgt $migrate_dir/${len}char_ln
21910         done
21911
21912         # PATH_MAX
21913         for len in 4094 4095; do
21914                 lnktgt=$(str_repeat 'l' $len)
21915                 ln -s $lnktgt $migrate_dir/${len}char_ln
21916         done
21917
21918         # NAME_MAX
21919         for len in 254 255; do
21920                 touch $migrate_dir/$(str_repeat 'l' $len)
21921         done
21922
21923         $LFS migrate -m $MDTIDX $migrate_dir ||
21924                 error "fails on migrating remote dir to MDT1"
21925
21926         echo "migratate to MDT1, then checking.."
21927         for ((i = 0; i < 10; i++)); do
21928                 for file in $(find $migrate_dir/dir_${i}); do
21929                         mdt_index=$($LFS getstripe -m $file)
21930                         # broken symlink getstripe will fail
21931                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21932                                 error "$file is not on MDT${MDTIDX}"
21933                 done
21934         done
21935
21936         # the multiple link file should still in MDT0
21937         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21938         [ $mdt_index == 0 ] ||
21939                 error "$file is not on MDT${MDTIDX}"
21940
21941         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21942         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21943                 error " expect $old_dir_flag get $new_dir_flag"
21944
21945         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21946         [ "$old_file_flag" = "$new_file_flag" ] ||
21947                 error " expect $old_file_flag get $new_file_flag"
21948
21949         local new_dir_mode=$(stat -c%f $migrate_dir)
21950         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21951                 error "expect mode $old_dir_mode get $new_dir_mode"
21952
21953         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21954         [ "$old_file_mode" = "$new_file_mode" ] ||
21955                 error "expect mode $old_file_mode get $new_file_mode"
21956
21957         diff /etc/passwd $migrate_dir/$tfile ||
21958                 error "$tfile different after migration"
21959
21960         diff /etc/passwd $other_dir/luna ||
21961                 error "luna different after migration"
21962
21963         diff /etc/passwd $migrate_dir/sofia ||
21964                 error "sofia different after migration"
21965
21966         diff /etc/passwd $migrate_dir/david ||
21967                 error "david different after migration"
21968
21969         diff /etc/passwd $other_dir/zachary ||
21970                 error "zachary different after migration"
21971
21972         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21973                 error "${tfile}_ln different after migration"
21974
21975         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21976                 error "${tfile}_ln_other different after migration"
21977
21978         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21979         [ $stripe_count = 2 ] ||
21980                 error "dir strpe_count $d != 2 after migration."
21981
21982         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21983         [ $stripe_count = 2 ] ||
21984                 error "file strpe_count $d != 2 after migration."
21985
21986         #migrate back to MDT0
21987         MDTIDX=0
21988
21989         $LFS migrate -m $MDTIDX $migrate_dir ||
21990                 error "fails on migrating remote dir to MDT0"
21991
21992         echo "migrate back to MDT0, checking.."
21993         for file in $(find $migrate_dir); do
21994                 mdt_index=$($LFS getstripe -m $file)
21995                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21996                         error "$file is not on MDT${MDTIDX}"
21997         done
21998
21999         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22000         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22001                 error " expect $old_dir_flag get $new_dir_flag"
22002
22003         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22004         [ "$old_file_flag" = "$new_file_flag" ] ||
22005                 error " expect $old_file_flag get $new_file_flag"
22006
22007         local new_dir_mode=$(stat -c%f $migrate_dir)
22008         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22009                 error "expect mode $old_dir_mode get $new_dir_mode"
22010
22011         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22012         [ "$old_file_mode" = "$new_file_mode" ] ||
22013                 error "expect mode $old_file_mode get $new_file_mode"
22014
22015         diff /etc/passwd ${migrate_dir}/$tfile ||
22016                 error "$tfile different after migration"
22017
22018         diff /etc/passwd ${other_dir}/luna ||
22019                 error "luna different after migration"
22020
22021         diff /etc/passwd ${migrate_dir}/sofia ||
22022                 error "sofia different after migration"
22023
22024         diff /etc/passwd ${other_dir}/zachary ||
22025                 error "zachary different after migration"
22026
22027         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22028                 error "${tfile}_ln different after migration"
22029
22030         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22031                 error "${tfile}_ln_other different after migration"
22032
22033         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22034         [ $stripe_count = 2 ] ||
22035                 error "dir strpe_count $d != 2 after migration."
22036
22037         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22038         [ $stripe_count = 2 ] ||
22039                 error "file strpe_count $d != 2 after migration."
22040
22041         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22042 }
22043 run_test 230b "migrate directory"
22044
22045 test_230c() {
22046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22048         remote_mds_nodsh && skip "remote MDS with nodsh"
22049         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22050                 skip "Need MDS version at least 2.11.52"
22051
22052         local MDTIDX=1
22053         local total=3
22054         local mdt_index
22055         local file
22056         local migrate_dir=$DIR/$tdir/migrate_dir
22057
22058         #If migrating directory fails in the middle, all entries of
22059         #the directory is still accessiable.
22060         test_mkdir $DIR/$tdir
22061         test_mkdir -i0 -c1 $migrate_dir
22062         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22063         stat $migrate_dir
22064         createmany -o $migrate_dir/f $total ||
22065                 error "create files under ${migrate_dir} failed"
22066
22067         # fail after migrating top dir, and this will fail only once, so the
22068         # first sub file migration will fail (currently f3), others succeed.
22069         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22070         do_facet mds1 lctl set_param fail_loc=0x1801
22071         local t=$(ls $migrate_dir | wc -l)
22072         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22073                 error "migrate should fail"
22074         local u=$(ls $migrate_dir | wc -l)
22075         [ "$u" == "$t" ] || error "$u != $t during migration"
22076
22077         # add new dir/file should succeed
22078         mkdir $migrate_dir/dir ||
22079                 error "mkdir failed under migrating directory"
22080         touch $migrate_dir/file ||
22081                 error "create file failed under migrating directory"
22082
22083         # add file with existing name should fail
22084         for file in $migrate_dir/f*; do
22085                 stat $file > /dev/null || error "stat $file failed"
22086                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22087                         error "open(O_CREAT|O_EXCL) $file should fail"
22088                 $MULTIOP $file m && error "create $file should fail"
22089                 touch $DIR/$tdir/remote_dir/$tfile ||
22090                         error "touch $tfile failed"
22091                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22092                         error "link $file should fail"
22093                 mdt_index=$($LFS getstripe -m $file)
22094                 if [ $mdt_index == 0 ]; then
22095                         # file failed to migrate is not allowed to rename to
22096                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22097                                 error "rename to $file should fail"
22098                 else
22099                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22100                                 error "rename to $file failed"
22101                 fi
22102                 echo hello >> $file || error "write $file failed"
22103         done
22104
22105         # resume migration with different options should fail
22106         $LFS migrate -m 0 $migrate_dir &&
22107                 error "migrate -m 0 $migrate_dir should fail"
22108
22109         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22110                 error "migrate -c 2 $migrate_dir should fail"
22111
22112         # resume migration should succeed
22113         $LFS migrate -m $MDTIDX $migrate_dir ||
22114                 error "migrate $migrate_dir failed"
22115
22116         echo "Finish migration, then checking.."
22117         for file in $(find $migrate_dir); do
22118                 mdt_index=$($LFS getstripe -m $file)
22119                 [ $mdt_index == $MDTIDX ] ||
22120                         error "$file is not on MDT${MDTIDX}"
22121         done
22122
22123         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22124 }
22125 run_test 230c "check directory accessiblity if migration failed"
22126
22127 test_230d() {
22128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22129         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22130         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22131                 skip "Need MDS version at least 2.11.52"
22132         # LU-11235
22133         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22134
22135         local migrate_dir=$DIR/$tdir/migrate_dir
22136         local old_index
22137         local new_index
22138         local old_count
22139         local new_count
22140         local new_hash
22141         local mdt_index
22142         local i
22143         local j
22144
22145         old_index=$((RANDOM % MDSCOUNT))
22146         old_count=$((MDSCOUNT - old_index))
22147         new_index=$((RANDOM % MDSCOUNT))
22148         new_count=$((MDSCOUNT - new_index))
22149         new_hash=1 # for all_char
22150
22151         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22152         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22153
22154         test_mkdir $DIR/$tdir
22155         test_mkdir -i $old_index -c $old_count $migrate_dir
22156
22157         for ((i=0; i<100; i++)); do
22158                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22159                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22160                         error "create files under remote dir failed $i"
22161         done
22162
22163         echo -n "Migrate from MDT$old_index "
22164         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22165         echo -n "to MDT$new_index"
22166         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22167         echo
22168
22169         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22170         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22171                 error "migrate remote dir error"
22172
22173         echo "Finish migration, then checking.."
22174         for file in $(find $migrate_dir -maxdepth 1); do
22175                 mdt_index=$($LFS getstripe -m $file)
22176                 if [ $mdt_index -lt $new_index ] ||
22177                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22178                         error "$file is on MDT$mdt_index"
22179                 fi
22180         done
22181
22182         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22183 }
22184 run_test 230d "check migrate big directory"
22185
22186 test_230e() {
22187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22188         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22189         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22190                 skip "Need MDS version at least 2.11.52"
22191
22192         local i
22193         local j
22194         local a_fid
22195         local b_fid
22196
22197         mkdir_on_mdt0 $DIR/$tdir
22198         mkdir $DIR/$tdir/migrate_dir
22199         mkdir $DIR/$tdir/other_dir
22200         touch $DIR/$tdir/migrate_dir/a
22201         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22202         ls $DIR/$tdir/other_dir
22203
22204         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22205                 error "migrate dir fails"
22206
22207         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22208         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22209
22210         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22211         [ $mdt_index == 0 ] || error "a is not on MDT0"
22212
22213         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22214                 error "migrate dir fails"
22215
22216         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22217         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22218
22219         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22220         [ $mdt_index == 1 ] || error "a is not on MDT1"
22221
22222         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22223         [ $mdt_index == 1 ] || error "b is not on MDT1"
22224
22225         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22226         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22227
22228         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22229
22230         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22231 }
22232 run_test 230e "migrate mulitple local link files"
22233
22234 test_230f() {
22235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22237         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22238                 skip "Need MDS version at least 2.11.52"
22239
22240         local a_fid
22241         local ln_fid
22242
22243         mkdir -p $DIR/$tdir
22244         mkdir $DIR/$tdir/migrate_dir
22245         $LFS mkdir -i1 $DIR/$tdir/other_dir
22246         touch $DIR/$tdir/migrate_dir/a
22247         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22248         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22249         ls $DIR/$tdir/other_dir
22250
22251         # a should be migrated to MDT1, since no other links on MDT0
22252         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22253                 error "#1 migrate dir fails"
22254         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22255         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22256         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22257         [ $mdt_index == 1 ] || error "a is not on MDT1"
22258
22259         # a should stay on MDT1, because it is a mulitple link file
22260         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22261                 error "#2 migrate dir fails"
22262         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22263         [ $mdt_index == 1 ] || error "a is not on MDT1"
22264
22265         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22266                 error "#3 migrate dir fails"
22267
22268         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22269         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22270         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22271
22272         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22273         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22274
22275         # a should be migrated to MDT0, since no other links on MDT1
22276         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22277                 error "#4 migrate dir fails"
22278         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22279         [ $mdt_index == 0 ] || error "a is not on MDT0"
22280
22281         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22282 }
22283 run_test 230f "migrate mulitple remote link files"
22284
22285 test_230g() {
22286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22289                 skip "Need MDS version at least 2.11.52"
22290
22291         mkdir -p $DIR/$tdir/migrate_dir
22292
22293         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22294                 error "migrating dir to non-exist MDT succeeds"
22295         true
22296 }
22297 run_test 230g "migrate dir to non-exist MDT"
22298
22299 test_230h() {
22300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22302         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22303                 skip "Need MDS version at least 2.11.52"
22304
22305         local mdt_index
22306
22307         mkdir -p $DIR/$tdir/migrate_dir
22308
22309         $LFS migrate -m1 $DIR &&
22310                 error "migrating mountpoint1 should fail"
22311
22312         $LFS migrate -m1 $DIR/$tdir/.. &&
22313                 error "migrating mountpoint2 should fail"
22314
22315         # same as mv
22316         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22317                 error "migrating $tdir/migrate_dir/.. should fail"
22318
22319         true
22320 }
22321 run_test 230h "migrate .. and root"
22322
22323 test_230i() {
22324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22326         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22327                 skip "Need MDS version at least 2.11.52"
22328
22329         mkdir -p $DIR/$tdir/migrate_dir
22330
22331         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22332                 error "migration fails with a tailing slash"
22333
22334         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22335                 error "migration fails with two tailing slashes"
22336 }
22337 run_test 230i "lfs migrate -m tolerates trailing slashes"
22338
22339 test_230j() {
22340         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22341         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22342                 skip "Need MDS version at least 2.11.52"
22343
22344         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22345         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22346                 error "create $tfile failed"
22347         cat /etc/passwd > $DIR/$tdir/$tfile
22348
22349         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22350
22351         cmp /etc/passwd $DIR/$tdir/$tfile ||
22352                 error "DoM file mismatch after migration"
22353 }
22354 run_test 230j "DoM file data not changed after dir migration"
22355
22356 test_230k() {
22357         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22358         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22359                 skip "Need MDS version at least 2.11.56"
22360
22361         local total=20
22362         local files_on_starting_mdt=0
22363
22364         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22365         $LFS getdirstripe $DIR/$tdir
22366         for i in $(seq $total); do
22367                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22368                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22369                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22370         done
22371
22372         echo "$files_on_starting_mdt files on MDT0"
22373
22374         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22375         $LFS getdirstripe $DIR/$tdir
22376
22377         files_on_starting_mdt=0
22378         for i in $(seq $total); do
22379                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22380                         error "file $tfile.$i mismatch after migration"
22381                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22382                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22383         done
22384
22385         echo "$files_on_starting_mdt files on MDT1 after migration"
22386         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22387
22388         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22389         $LFS getdirstripe $DIR/$tdir
22390
22391         files_on_starting_mdt=0
22392         for i in $(seq $total); do
22393                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22394                         error "file $tfile.$i mismatch after 2nd migration"
22395                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22396                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22397         done
22398
22399         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22400         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22401
22402         true
22403 }
22404 run_test 230k "file data not changed after dir migration"
22405
22406 test_230l() {
22407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22408         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22409                 skip "Need MDS version at least 2.11.56"
22410
22411         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22412         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22413                 error "create files under remote dir failed $i"
22414         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22415 }
22416 run_test 230l "readdir between MDTs won't crash"
22417
22418 test_230m() {
22419         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22420         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22421                 skip "Need MDS version at least 2.11.56"
22422
22423         local MDTIDX=1
22424         local mig_dir=$DIR/$tdir/migrate_dir
22425         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22426         local shortstr="b"
22427         local val
22428
22429         echo "Creating files and dirs with xattrs"
22430         test_mkdir $DIR/$tdir
22431         test_mkdir -i0 -c1 $mig_dir
22432         mkdir $mig_dir/dir
22433         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22434                 error "cannot set xattr attr1 on dir"
22435         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22436                 error "cannot set xattr attr2 on dir"
22437         touch $mig_dir/dir/f0
22438         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22439                 error "cannot set xattr attr1 on file"
22440         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22441                 error "cannot set xattr attr2 on file"
22442         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22443         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22444         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22445         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22446         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22447         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22448         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22449         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22450         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22451
22452         echo "Migrating to MDT1"
22453         $LFS migrate -m $MDTIDX $mig_dir ||
22454                 error "fails on migrating dir to MDT1"
22455
22456         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22457         echo "Checking xattrs"
22458         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22459         [ "$val" = $longstr ] ||
22460                 error "expecting xattr1 $longstr on dir, found $val"
22461         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22462         [ "$val" = $shortstr ] ||
22463                 error "expecting xattr2 $shortstr on dir, found $val"
22464         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22465         [ "$val" = $longstr ] ||
22466                 error "expecting xattr1 $longstr on file, found $val"
22467         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22468         [ "$val" = $shortstr ] ||
22469                 error "expecting xattr2 $shortstr on file, found $val"
22470 }
22471 run_test 230m "xattrs not changed after dir migration"
22472
22473 test_230n() {
22474         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22475         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22476                 skip "Need MDS version at least 2.13.53"
22477
22478         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22479         cat /etc/hosts > $DIR/$tdir/$tfile
22480         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22481         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22482
22483         cmp /etc/hosts $DIR/$tdir/$tfile ||
22484                 error "File data mismatch after migration"
22485 }
22486 run_test 230n "Dir migration with mirrored file"
22487
22488 test_230o() {
22489         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22490         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22491                 skip "Need MDS version at least 2.13.52"
22492
22493         local mdts=$(comma_list $(mdts_nodes))
22494         local timeout=100
22495         local restripe_status
22496         local delta
22497         local i
22498
22499         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22500
22501         # in case "crush" hash type is not set
22502         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22503
22504         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22505                            mdt.*MDT0000.enable_dir_restripe)
22506         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22507         stack_trap "do_nodes $mdts $LCTL set_param \
22508                     mdt.*.enable_dir_restripe=$restripe_status"
22509
22510         mkdir $DIR/$tdir
22511         createmany -m $DIR/$tdir/f 100 ||
22512                 error "create files under remote dir failed $i"
22513         createmany -d $DIR/$tdir/d 100 ||
22514                 error "create dirs under remote dir failed $i"
22515
22516         for i in $(seq 2 $MDSCOUNT); do
22517                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22518                 $LFS setdirstripe -c $i $DIR/$tdir ||
22519                         error "split -c $i $tdir failed"
22520                 wait_update $HOSTNAME \
22521                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22522                         error "dir split not finished"
22523                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22524                         awk '/migrate/ {sum += $2} END { print sum }')
22525                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22526                 # delta is around total_files/stripe_count
22527                 (( $delta < 200 / (i - 1) + 4 )) ||
22528                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22529         done
22530 }
22531 run_test 230o "dir split"
22532
22533 test_230p() {
22534         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22535         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22536                 skip "Need MDS version at least 2.13.52"
22537
22538         local mdts=$(comma_list $(mdts_nodes))
22539         local timeout=100
22540         local restripe_status
22541         local delta
22542         local c
22543
22544         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22545
22546         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22547
22548         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22549                            mdt.*MDT0000.enable_dir_restripe)
22550         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22551         stack_trap "do_nodes $mdts $LCTL set_param \
22552                     mdt.*.enable_dir_restripe=$restripe_status"
22553
22554         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22555         createmany -m $DIR/$tdir/f 100 ||
22556                 error "create files under remote dir failed"
22557         createmany -d $DIR/$tdir/d 100 ||
22558                 error "create dirs under remote dir failed"
22559
22560         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22561                 local mdt_hash="crush"
22562
22563                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22564                 $LFS setdirstripe -c $c $DIR/$tdir ||
22565                         error "split -c $c $tdir failed"
22566                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22567                         mdt_hash="$mdt_hash,fixed"
22568                 elif [ $c -eq 1 ]; then
22569                         mdt_hash="none"
22570                 fi
22571                 wait_update $HOSTNAME \
22572                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22573                         error "dir merge not finished"
22574                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22575                         awk '/migrate/ {sum += $2} END { print sum }')
22576                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22577                 # delta is around total_files/stripe_count
22578                 (( delta < 200 / c + 4 )) ||
22579                         error "$delta files migrated >= $((200 / c + 4))"
22580         done
22581 }
22582 run_test 230p "dir merge"
22583
22584 test_230q() {
22585         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22586         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22587                 skip "Need MDS version at least 2.13.52"
22588
22589         local mdts=$(comma_list $(mdts_nodes))
22590         local saved_threshold=$(do_facet mds1 \
22591                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22592         local saved_delta=$(do_facet mds1 \
22593                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22594         local threshold=100
22595         local delta=2
22596         local total=0
22597         local stripe_count=0
22598         local stripe_index
22599         local nr_files
22600         local create
22601
22602         # test with fewer files on ZFS
22603         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22604
22605         stack_trap "do_nodes $mdts $LCTL set_param \
22606                     mdt.*.dir_split_count=$saved_threshold"
22607         stack_trap "do_nodes $mdts $LCTL set_param \
22608                     mdt.*.dir_split_delta=$saved_delta"
22609         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22610         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22611         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22612         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22613         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22614         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22615
22616         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22617         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22618
22619         create=$((threshold * 3 / 2))
22620         while [ $stripe_count -lt $MDSCOUNT ]; do
22621                 createmany -m $DIR/$tdir/f $total $create ||
22622                         error "create sub files failed"
22623                 stat $DIR/$tdir > /dev/null
22624                 total=$((total + create))
22625                 stripe_count=$((stripe_count + delta))
22626                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22627
22628                 wait_update $HOSTNAME \
22629                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22630                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22631
22632                 wait_update $HOSTNAME \
22633                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22634                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22635
22636                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22637                 echo "$nr_files/$total files on MDT$stripe_index after split"
22638                 # allow 10% margin of imbalance with crush hash
22639                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22640                         error "$nr_files files on MDT$stripe_index after split"
22641
22642                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22643                 [ $nr_files -eq $total ] ||
22644                         error "total sub files $nr_files != $total"
22645         done
22646
22647         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22648
22649         echo "fixed layout directory won't auto split"
22650         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22651         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22652                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22653         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22654                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22655 }
22656 run_test 230q "dir auto split"
22657
22658 test_230r() {
22659         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22660         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22661         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22662                 skip "Need MDS version at least 2.13.54"
22663
22664         # maximum amount of local locks:
22665         # parent striped dir - 2 locks
22666         # new stripe in parent to migrate to - 1 lock
22667         # source and target - 2 locks
22668         # Total 5 locks for regular file
22669         mkdir -p $DIR/$tdir
22670         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22671         touch $DIR/$tdir/dir1/eee
22672
22673         # create 4 hardlink for 4 more locks
22674         # Total: 9 locks > RS_MAX_LOCKS (8)
22675         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22676         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22677         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22678         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22679         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22680         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22681         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22682         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22683
22684         cancel_lru_locks mdc
22685
22686         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22687                 error "migrate dir fails"
22688
22689         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22690 }
22691 run_test 230r "migrate with too many local locks"
22692
22693 test_230s() {
22694         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22695                 skip "Need MDS version at least 2.14.52"
22696
22697         local mdts=$(comma_list $(mdts_nodes))
22698         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22699                                 mdt.*MDT0000.enable_dir_restripe)
22700
22701         stack_trap "do_nodes $mdts $LCTL set_param \
22702                     mdt.*.enable_dir_restripe=$restripe_status"
22703
22704         local st
22705         for st in 0 1; do
22706                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22707                 test_mkdir $DIR/$tdir
22708                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22709                         error "$LFS mkdir should return EEXIST if target exists"
22710                 rmdir $DIR/$tdir
22711         done
22712 }
22713 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22714
22715 test_230t()
22716 {
22717         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22718         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22719                 skip "Need MDS version at least 2.14.50"
22720
22721         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22722         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22723         $LFS project -p 1 -s $DIR/$tdir ||
22724                 error "set $tdir project id failed"
22725         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22726                 error "set subdir project id failed"
22727         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22728 }
22729 run_test 230t "migrate directory with project ID set"
22730
22731 test_230u()
22732 {
22733         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22734         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22735                 skip "Need MDS version at least 2.14.53"
22736
22737         local count
22738
22739         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22740         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22741         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22742         for i in $(seq 0 $((MDSCOUNT - 1))); do
22743                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22744                 echo "$count dirs migrated to MDT$i"
22745         done
22746         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22747         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22748 }
22749 run_test 230u "migrate directory by QOS"
22750
22751 test_230v()
22752 {
22753         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22754         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22755                 skip "Need MDS version at least 2.14.53"
22756
22757         local count
22758
22759         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22760         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22761         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22762         for i in $(seq 0 $((MDSCOUNT - 1))); do
22763                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22764                 echo "$count subdirs migrated to MDT$i"
22765                 (( i == 3 )) && (( count > 0 )) &&
22766                         error "subdir shouldn't be migrated to MDT3"
22767         done
22768         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22769         (( count == 3 )) || error "dirs migrated to $count MDTs"
22770 }
22771 run_test 230v "subdir migrated to the MDT where its parent is located"
22772
22773 test_230w() {
22774         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22775         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22776                 skip "Need MDS version at least 2.15.0"
22777
22778         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22779         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22780         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22781
22782         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22783                 error "migrate failed"
22784
22785         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22786                 error "$tdir stripe count mismatch"
22787
22788         for i in $(seq 0 9); do
22789                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22790                         error "d$i is striped"
22791         done
22792 }
22793 run_test 230w "non-recursive mode dir migration"
22794
22795 test_230x() {
22796         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22797         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22798                 skip "Need MDS version at least 2.15.0"
22799
22800         mkdir -p $DIR/$tdir || error "mkdir failed"
22801         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22802
22803         local mdt_name=$(mdtname_from_index 0)
22804         local low=$(do_facet mds2 $LCTL get_param -n \
22805                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22806         local high=$(do_facet mds2 $LCTL get_param -n \
22807                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22808         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22809         local maxage=$(do_facet mds2 $LCTL get_param -n \
22810                 osp.*$mdt_name-osp-MDT0001.maxage)
22811
22812         stack_trap "do_facet mds2 $LCTL set_param -n \
22813                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22814                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22815         stack_trap "do_facet mds2 $LCTL set_param -n \
22816                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22817
22818         do_facet mds2 $LCTL set_param -n \
22819                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22820         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22821         sleep 4
22822         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22823                 error "migrate $tdir should fail"
22824
22825         do_facet mds2 $LCTL set_param -n \
22826                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22827         do_facet mds2 $LCTL set_param -n \
22828                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22829         sleep 4
22830         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22831                 error "migrate failed"
22832         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22833                 error "$tdir stripe count mismatch"
22834 }
22835 run_test 230x "dir migration check space"
22836
22837 test_230y() {
22838         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22839         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22840                 skip "Need MDS version at least 2.15.55.45"
22841
22842         local pid
22843
22844         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22845         $LFS getdirstripe $DIR/$tdir
22846         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22847         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22848         pid=$!
22849         sleep 1
22850
22851         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22852         do_facet mds2 lctl set_param fail_loc=0x1802
22853
22854         wait $pid
22855         do_facet mds2 lctl set_param fail_loc=0
22856         $LFS getdirstripe $DIR/$tdir
22857         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22858         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22859 }
22860 run_test 230y "unlink dir with bad hash type"
22861
22862 test_230z() {
22863         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22864         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22865                 skip "Need MDS version at least 2.15.55.45"
22866
22867         local pid
22868
22869         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22870         $LFS getdirstripe $DIR/$tdir
22871         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22872         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22873         pid=$!
22874         sleep 1
22875
22876         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22877         do_facet mds2 lctl set_param fail_loc=0x1802
22878
22879         wait $pid
22880         do_facet mds2 lctl set_param fail_loc=0
22881         $LFS getdirstripe $DIR/$tdir
22882
22883         # resume migration
22884         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22885                 error "resume migration failed"
22886         $LFS getdirstripe $DIR/$tdir
22887         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22888                 error "migration is not finished"
22889 }
22890 run_test 230z "resume dir migration with bad hash type"
22891
22892 test_231a()
22893 {
22894         # For simplicity this test assumes that max_pages_per_rpc
22895         # is the same across all OSCs
22896         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22897         local bulk_size=$((max_pages * PAGE_SIZE))
22898         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22899                                        head -n 1)
22900
22901         mkdir -p $DIR/$tdir
22902         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22903                 error "failed to set stripe with -S ${brw_size}M option"
22904         stack_trap "rm -rf $DIR/$tdir"
22905
22906         # clear the OSC stats
22907         $LCTL set_param osc.*.stats=0 &>/dev/null
22908         stop_writeback
22909
22910         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22911         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22912                 oflag=direct &>/dev/null || error "dd failed"
22913
22914         sync; sleep 1; sync # just to be safe
22915         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22916         if [ x$nrpcs != "x1" ]; then
22917                 $LCTL get_param osc.*.stats
22918                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22919         fi
22920
22921         start_writeback
22922         # Drop the OSC cache, otherwise we will read from it
22923         cancel_lru_locks osc
22924
22925         # clear the OSC stats
22926         $LCTL set_param osc.*.stats=0 &>/dev/null
22927
22928         # Client reads $bulk_size.
22929         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22930                 iflag=direct &>/dev/null || error "dd failed"
22931
22932         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22933         if [ x$nrpcs != "x1" ]; then
22934                 $LCTL get_param osc.*.stats
22935                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22936         fi
22937 }
22938 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22939
22940 test_231b() {
22941         mkdir -p $DIR/$tdir
22942         stack_trap "rm -rf $DIR/$tdir"
22943         local i
22944         for i in {0..1023}; do
22945                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22946                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22947                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22948         done
22949         sync
22950 }
22951 run_test 231b "must not assert on fully utilized OST request buffer"
22952
22953 test_232a() {
22954         mkdir -p $DIR/$tdir
22955         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22956
22957         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22958         do_facet ost1 $LCTL set_param fail_loc=0x31c
22959
22960         # ignore dd failure
22961         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22962         stack_trap "rm -f $DIR/$tdir/$tfile"
22963
22964         do_facet ost1 $LCTL set_param fail_loc=0
22965         umount_client $MOUNT || error "umount failed"
22966         mount_client $MOUNT || error "mount failed"
22967         stop ost1 || error "cannot stop ost1"
22968         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22969 }
22970 run_test 232a "failed lock should not block umount"
22971
22972 test_232b() {
22973         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22974                 skip "Need MDS version at least 2.10.58"
22975
22976         mkdir -p $DIR/$tdir
22977         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22978         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22979         stack_trap "rm -f $DIR/$tdir/$tfile"
22980         sync
22981         cancel_lru_locks osc
22982
22983         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22984         do_facet ost1 $LCTL set_param fail_loc=0x31c
22985
22986         # ignore failure
22987         $LFS data_version $DIR/$tdir/$tfile || true
22988
22989         do_facet ost1 $LCTL set_param fail_loc=0
22990         umount_client $MOUNT || error "umount failed"
22991         mount_client $MOUNT || error "mount failed"
22992         stop ost1 || error "cannot stop ost1"
22993         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22994 }
22995 run_test 232b "failed data version lock should not block umount"
22996
22997 test_233a() {
22998         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22999                 skip "Need MDS version at least 2.3.64"
23000         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23001
23002         local fid=$($LFS path2fid $MOUNT)
23003
23004         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23005                 error "cannot access $MOUNT using its FID '$fid'"
23006 }
23007 run_test 233a "checking that OBF of the FS root succeeds"
23008
23009 test_233b() {
23010         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23011                 skip "Need MDS version at least 2.5.90"
23012         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23013
23014         local fid=$($LFS path2fid $MOUNT/.lustre)
23015
23016         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23017                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23018
23019         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23020         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23021                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23022 }
23023 run_test 233b "checking that OBF of the FS .lustre succeeds"
23024
23025 test_234() {
23026         local p="$TMP/sanityN-$TESTNAME.parameters"
23027         save_lustre_params client "llite.*.xattr_cache" > $p
23028         lctl set_param llite.*.xattr_cache 1 ||
23029                 skip_env "xattr cache is not supported"
23030
23031         mkdir -p $DIR/$tdir || error "mkdir failed"
23032         touch $DIR/$tdir/$tfile || error "touch failed"
23033         # OBD_FAIL_LLITE_XATTR_ENOMEM
23034         $LCTL set_param fail_loc=0x1405
23035         getfattr -n user.attr $DIR/$tdir/$tfile &&
23036                 error "getfattr should have failed with ENOMEM"
23037         $LCTL set_param fail_loc=0x0
23038         rm -rf $DIR/$tdir
23039
23040         restore_lustre_params < $p
23041         rm -f $p
23042 }
23043 run_test 234 "xattr cache should not crash on ENOMEM"
23044
23045 test_235() {
23046         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23047                 skip "Need MDS version at least 2.4.52"
23048
23049         flock_deadlock $DIR/$tfile
23050         local RC=$?
23051         case $RC in
23052                 0)
23053                 ;;
23054                 124) error "process hangs on a deadlock"
23055                 ;;
23056                 *) error "error executing flock_deadlock $DIR/$tfile"
23057                 ;;
23058         esac
23059 }
23060 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23061
23062 #LU-2935
23063 test_236() {
23064         check_swap_layouts_support
23065
23066         local ref1=/etc/passwd
23067         local ref2=/etc/group
23068         local file1=$DIR/$tdir/f1
23069         local file2=$DIR/$tdir/f2
23070
23071         test_mkdir -c1 $DIR/$tdir
23072         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23073         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23074         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23075         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23076         local fd=$(free_fd)
23077         local cmd="exec $fd<>$file2"
23078         eval $cmd
23079         rm $file2
23080         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23081                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23082         cmd="exec $fd>&-"
23083         eval $cmd
23084         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23085
23086         #cleanup
23087         rm -rf $DIR/$tdir
23088 }
23089 run_test 236 "Layout swap on open unlinked file"
23090
23091 # LU-4659 linkea consistency
23092 test_238() {
23093         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23094                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23095                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23096                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23097
23098         touch $DIR/$tfile
23099         ln $DIR/$tfile $DIR/$tfile.lnk
23100         touch $DIR/$tfile.new
23101         mv $DIR/$tfile.new $DIR/$tfile
23102         local fid1=$($LFS path2fid $DIR/$tfile)
23103         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23104         local path1=$($LFS fid2path $FSNAME "$fid1")
23105         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23106         local path2=$($LFS fid2path $FSNAME "$fid2")
23107         [ $tfile.lnk == $path2 ] ||
23108                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23109         rm -f $DIR/$tfile*
23110 }
23111 run_test 238 "Verify linkea consistency"
23112
23113 test_239A() { # was test_239
23114         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23115                 skip "Need MDS version at least 2.5.60"
23116
23117         local list=$(comma_list $(mdts_nodes))
23118
23119         mkdir -p $DIR/$tdir
23120         createmany -o $DIR/$tdir/f- 5000
23121         unlinkmany $DIR/$tdir/f- 5000
23122         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23123                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23124         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23125                         osp.*MDT*.sync_in_flight" | calc_sum)
23126         [ "$changes" -eq 0 ] || error "$changes not synced"
23127 }
23128 run_test 239A "osp_sync test"
23129
23130 test_239a() { #LU-5297
23131         remote_mds_nodsh && skip "remote MDS with nodsh"
23132
23133         touch $DIR/$tfile
23134         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23135         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23136         chgrp $RUNAS_GID $DIR/$tfile
23137         wait_delete_completed
23138 }
23139 run_test 239a "process invalid osp sync record correctly"
23140
23141 test_239b() { #LU-5297
23142         remote_mds_nodsh && skip "remote MDS with nodsh"
23143
23144         touch $DIR/$tfile1
23145         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23146         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23147         chgrp $RUNAS_GID $DIR/$tfile1
23148         wait_delete_completed
23149         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23150         touch $DIR/$tfile2
23151         chgrp $RUNAS_GID $DIR/$tfile2
23152         wait_delete_completed
23153 }
23154 run_test 239b "process osp sync record with ENOMEM error correctly"
23155
23156 test_240() {
23157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23158         remote_mds_nodsh && skip "remote MDS with nodsh"
23159
23160         mkdir -p $DIR/$tdir
23161
23162         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23163                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23164         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23165                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23166
23167         umount_client $MOUNT || error "umount failed"
23168         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23169         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23170         mount_client $MOUNT || error "failed to mount client"
23171
23172         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23173         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23174 }
23175 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23176
23177 test_241_bio() {
23178         local count=$1
23179         local bsize=$2
23180
23181         for LOOP in $(seq $count); do
23182                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23183                 cancel_lru_locks $OSC || true
23184         done
23185 }
23186
23187 test_241_dio() {
23188         local count=$1
23189         local bsize=$2
23190
23191         for LOOP in $(seq $1); do
23192                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23193                         2>/dev/null
23194         done
23195 }
23196
23197 test_241a() { # was test_241
23198         local bsize=$PAGE_SIZE
23199
23200         (( bsize < 40960 )) && bsize=40960
23201         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23202         ls -la $DIR/$tfile
23203         cancel_lru_locks $OSC
23204         test_241_bio 1000 $bsize &
23205         PID=$!
23206         test_241_dio 1000 $bsize
23207         wait $PID
23208 }
23209 run_test 241a "bio vs dio"
23210
23211 test_241b() {
23212         local bsize=$PAGE_SIZE
23213
23214         (( bsize < 40960 )) && bsize=40960
23215         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23216         ls -la $DIR/$tfile
23217         test_241_dio 1000 $bsize &
23218         PID=$!
23219         test_241_dio 1000 $bsize
23220         wait $PID
23221 }
23222 run_test 241b "dio vs dio"
23223
23224 test_242() {
23225         remote_mds_nodsh && skip "remote MDS with nodsh"
23226
23227         mkdir_on_mdt0 $DIR/$tdir
23228         touch $DIR/$tdir/$tfile
23229
23230         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23231         do_facet mds1 lctl set_param fail_loc=0x105
23232         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23233
23234         do_facet mds1 lctl set_param fail_loc=0
23235         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23236 }
23237 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23238
23239 test_243()
23240 {
23241         test_mkdir $DIR/$tdir
23242         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23243 }
23244 run_test 243 "various group lock tests"
23245
23246 test_244a()
23247 {
23248         test_mkdir $DIR/$tdir
23249         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23250         sendfile_grouplock $DIR/$tdir/$tfile || \
23251                 error "sendfile+grouplock failed"
23252         rm -rf $DIR/$tdir
23253 }
23254 run_test 244a "sendfile with group lock tests"
23255
23256 test_244b()
23257 {
23258         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23259
23260         local threads=50
23261         local size=$((1024*1024))
23262
23263         test_mkdir $DIR/$tdir
23264         for i in $(seq 1 $threads); do
23265                 local file=$DIR/$tdir/file_$((i / 10))
23266                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23267                 local pids[$i]=$!
23268         done
23269         for i in $(seq 1 $threads); do
23270                 wait ${pids[$i]}
23271         done
23272 }
23273 run_test 244b "multi-threaded write with group lock"
23274
23275 test_245a() {
23276         local flagname="multi_mod_rpcs"
23277         local connect_data_name="max_mod_rpcs"
23278         local out
23279
23280         # check if multiple modify RPCs flag is set
23281         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23282                 grep "connect_flags:")
23283         echo "$out"
23284
23285         echo "$out" | grep -qw $flagname
23286         if [ $? -ne 0 ]; then
23287                 echo "connect flag $flagname is not set"
23288                 return
23289         fi
23290
23291         # check if multiple modify RPCs data is set
23292         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23293         echo "$out"
23294
23295         echo "$out" | grep -qw $connect_data_name ||
23296                 error "import should have connect data $connect_data_name"
23297 }
23298 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23299
23300 test_245b() {
23301         local flagname="multi_mod_rpcs"
23302         local connect_data_name="max_mod_rpcs"
23303         local out
23304
23305         remote_mds_nodsh && skip "remote MDS with nodsh"
23306         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23307
23308         # check if multiple modify RPCs flag is set
23309         out=$(do_facet mds1 \
23310               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23311               grep "connect_flags:")
23312         echo "$out"
23313
23314         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23315
23316         # check if multiple modify RPCs data is set
23317         out=$(do_facet mds1 \
23318               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23319
23320         [[ "$out" =~ $connect_data_name ]] ||
23321                 {
23322                         echo "$out"
23323                         error "missing connect data $connect_data_name"
23324                 }
23325 }
23326 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23327
23328 cleanup_247() {
23329         local submount=$1
23330
23331         trap 0
23332         umount_client $submount
23333         rmdir $submount
23334 }
23335
23336 test_247a() {
23337         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23338                 grep -q subtree ||
23339                 skip_env "Fileset feature is not supported"
23340
23341         local submount=${MOUNT}_$tdir
23342
23343         mkdir $MOUNT/$tdir
23344         mkdir -p $submount || error "mkdir $submount failed"
23345         FILESET="$FILESET/$tdir" mount_client $submount ||
23346                 error "mount $submount failed"
23347         trap "cleanup_247 $submount" EXIT
23348         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23349         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23350                 error "read $MOUNT/$tdir/$tfile failed"
23351         cleanup_247 $submount
23352 }
23353 run_test 247a "mount subdir as fileset"
23354
23355 test_247b() {
23356         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23357                 skip_env "Fileset feature is not supported"
23358
23359         local submount=${MOUNT}_$tdir
23360
23361         rm -rf $MOUNT/$tdir
23362         mkdir -p $submount || error "mkdir $submount failed"
23363         SKIP_FILESET=1
23364         FILESET="$FILESET/$tdir" mount_client $submount &&
23365                 error "mount $submount should fail"
23366         rmdir $submount
23367 }
23368 run_test 247b "mount subdir that dose not exist"
23369
23370 test_247c() {
23371         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23372                 skip_env "Fileset feature is not supported"
23373
23374         local submount=${MOUNT}_$tdir
23375
23376         mkdir -p $MOUNT/$tdir/dir1
23377         mkdir -p $submount || error "mkdir $submount failed"
23378         trap "cleanup_247 $submount" EXIT
23379         FILESET="$FILESET/$tdir" mount_client $submount ||
23380                 error "mount $submount failed"
23381         local fid=$($LFS path2fid $MOUNT/)
23382         $LFS fid2path $submount $fid && error "fid2path should fail"
23383         cleanup_247 $submount
23384 }
23385 run_test 247c "running fid2path outside subdirectory root"
23386
23387 test_247d() {
23388         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23389                 skip "Fileset feature is not supported"
23390
23391         local submount=${MOUNT}_$tdir
23392
23393         mkdir -p $MOUNT/$tdir/dir1
23394         mkdir -p $submount || error "mkdir $submount failed"
23395         FILESET="$FILESET/$tdir" mount_client $submount ||
23396                 error "mount $submount failed"
23397         trap "cleanup_247 $submount" EXIT
23398
23399         local td=$submount/dir1
23400         local fid=$($LFS path2fid $td)
23401         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23402
23403         # check that we get the same pathname back
23404         local rootpath
23405         local found
23406         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23407                 echo "$rootpath $fid"
23408                 found=$($LFS fid2path $rootpath "$fid")
23409                 [ -n "$found" ] || error "fid2path should succeed"
23410                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23411         done
23412         # check wrong root path format
23413         rootpath=$submount"_wrong"
23414         found=$($LFS fid2path $rootpath "$fid")
23415         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23416
23417         cleanup_247 $submount
23418 }
23419 run_test 247d "running fid2path inside subdirectory root"
23420
23421 # LU-8037
23422 test_247e() {
23423         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23424                 grep -q subtree ||
23425                 skip "Fileset feature is not supported"
23426
23427         local submount=${MOUNT}_$tdir
23428
23429         mkdir $MOUNT/$tdir
23430         mkdir -p $submount || error "mkdir $submount failed"
23431         FILESET="$FILESET/.." mount_client $submount &&
23432                 error "mount $submount should fail"
23433         rmdir $submount
23434 }
23435 run_test 247e "mount .. as fileset"
23436
23437 test_247f() {
23438         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23439         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23440                 skip "Need at least version 2.14.50.162"
23441         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23442                 skip "Fileset feature is not supported"
23443
23444         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23445         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23446                 error "mkdir remote failed"
23447         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23448                 error "mkdir remote/subdir failed"
23449         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23450                 error "mkdir striped failed"
23451         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23452
23453         local submount=${MOUNT}_$tdir
23454
23455         mkdir -p $submount || error "mkdir $submount failed"
23456         stack_trap "rmdir $submount"
23457
23458         local dir
23459         local fileset=$FILESET
23460         local mdts=$(comma_list $(mdts_nodes))
23461
23462         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23463         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23464                 $tdir/striped/subdir $tdir/striped/.; do
23465                 FILESET="$fileset/$dir" mount_client $submount ||
23466                         error "mount $dir failed"
23467                 umount_client $submount
23468         done
23469 }
23470 run_test 247f "mount striped or remote directory as fileset"
23471
23472 test_subdir_mount_lock()
23473 {
23474         local testdir=$1
23475         local submount=${MOUNT}_$(basename $testdir)
23476
23477         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23478
23479         mkdir -p $submount || error "mkdir $submount failed"
23480         stack_trap "rmdir $submount"
23481
23482         FILESET="$fileset/$testdir" mount_client $submount ||
23483                 error "mount $FILESET failed"
23484         stack_trap "umount $submount"
23485
23486         local mdts=$(comma_list $(mdts_nodes))
23487
23488         local nrpcs
23489
23490         stat $submount > /dev/null || error "stat $submount failed"
23491         cancel_lru_locks $MDC
23492         stat $submount > /dev/null || error "stat $submount failed"
23493         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23494         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23495         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23496         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23497                 awk '/getattr/ {sum += $2} END {print sum}')
23498
23499         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23500 }
23501
23502 test_247g() {
23503         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23504
23505         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23506                 error "mkdir $tdir failed"
23507         test_subdir_mount_lock $tdir
23508 }
23509 run_test 247g "striped directory submount revalidate ROOT from cache"
23510
23511 test_247h() {
23512         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23513         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23514                 skip "Need MDS version at least 2.15.51"
23515
23516         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23517         test_subdir_mount_lock $tdir
23518         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23519         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23520                 error "mkdir $tdir.1 failed"
23521         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23522 }
23523 run_test 247h "remote directory submount revalidate ROOT from cache"
23524
23525 test_248a() {
23526         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23527         [ -z "$fast_read_sav" ] && skip "no fast read support"
23528
23529         # create a large file for fast read verification
23530         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23531
23532         # make sure the file is created correctly
23533         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23534                 { rm -f $DIR/$tfile; skip "file creation error"; }
23535
23536         echo "Test 1: verify that fast read is 4 times faster on cache read"
23537
23538         # small read with fast read enabled
23539         $LCTL set_param -n llite.*.fast_read=1
23540         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23541                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23542                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23543         # small read with fast read disabled
23544         $LCTL set_param -n llite.*.fast_read=0
23545         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23546                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23547                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23548
23549         # verify that fast read is 4 times faster for cache read
23550         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23551                 error_not_in_vm "fast read was not 4 times faster: " \
23552                            "$t_fast vs $t_slow"
23553
23554         echo "Test 2: verify the performance between big and small read"
23555         $LCTL set_param -n llite.*.fast_read=1
23556
23557         # 1k non-cache read
23558         cancel_lru_locks osc
23559         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23560                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23561                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23562
23563         # 1M non-cache read
23564         cancel_lru_locks osc
23565         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23566                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23567                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23568
23569         # verify that big IO is not 4 times faster than small IO
23570         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23571                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23572
23573         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23574         rm -f $DIR/$tfile
23575 }
23576 run_test 248a "fast read verification"
23577
23578 test_248b() {
23579         # Default short_io_bytes=16384, try both smaller and larger sizes.
23580         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23581         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23582         echo "bs=53248 count=113 normal buffered write"
23583         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23584                 error "dd of initial data file failed"
23585         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23586
23587         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23588         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23589                 error "dd with sync normal writes failed"
23590         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23591
23592         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23593         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23594                 error "dd with sync small writes failed"
23595         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23596
23597         cancel_lru_locks osc
23598
23599         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23600         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23601         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23602         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23603                 iflag=direct || error "dd with O_DIRECT small read failed"
23604         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23605         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23606                 error "compare $TMP/$tfile.1 failed"
23607
23608         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23609         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23610
23611         # just to see what the maximum tunable value is, and test parsing
23612         echo "test invalid parameter 2MB"
23613         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23614                 error "too-large short_io_bytes allowed"
23615         echo "test maximum parameter 512KB"
23616         # if we can set a larger short_io_bytes, run test regardless of version
23617         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23618                 # older clients may not allow setting it this large, that's OK
23619                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23620                         skip "Need at least client version 2.13.50"
23621                 error "medium short_io_bytes failed"
23622         fi
23623         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23624         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23625
23626         echo "test large parameter 64KB"
23627         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23628         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23629
23630         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23631         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23632                 error "dd with sync large writes failed"
23633         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23634
23635         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23636         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23637         num=$((113 * 4096 / PAGE_SIZE))
23638         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23639         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23640                 error "dd with O_DIRECT large writes failed"
23641         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23642                 error "compare $DIR/$tfile.3 failed"
23643
23644         cancel_lru_locks osc
23645
23646         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23647         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23648                 error "dd with O_DIRECT large read failed"
23649         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23650                 error "compare $TMP/$tfile.2 failed"
23651
23652         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23653         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23654                 error "dd with O_DIRECT large read failed"
23655         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23656                 error "compare $TMP/$tfile.3 failed"
23657 }
23658 run_test 248b "test short_io read and write for both small and large sizes"
23659
23660 test_249() { # LU-7890
23661         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23662                 skip "Need at least version 2.8.54"
23663
23664         rm -f $DIR/$tfile
23665         $LFS setstripe -c 1 $DIR/$tfile
23666         # Offset 2T == 4k * 512M
23667         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23668                 error "dd to 2T offset failed"
23669 }
23670 run_test 249 "Write above 2T file size"
23671
23672 test_250() {
23673         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23674          && skip "no 16TB file size limit on ZFS"
23675
23676         $LFS setstripe -c 1 $DIR/$tfile
23677         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23678         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23679         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23680         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23681                 conv=notrunc,fsync && error "append succeeded"
23682         return 0
23683 }
23684 run_test 250 "Write above 16T limit"
23685
23686 test_251() {
23687         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23688
23689         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23690         #Skip once - writing the first stripe will succeed
23691         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23692         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23693                 error "short write happened"
23694
23695         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23696         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23697                 error "short read happened"
23698
23699         rm -f $DIR/$tfile
23700 }
23701 run_test 251 "Handling short read and write correctly"
23702
23703 test_252() {
23704         remote_mds_nodsh && skip "remote MDS with nodsh"
23705         remote_ost_nodsh && skip "remote OST with nodsh"
23706         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23707                 skip_env "ldiskfs only test"
23708         fi
23709
23710         local tgt
23711         local dev
23712         local out
23713         local uuid
23714         local num
23715         local gen
23716
23717         # check lr_reader on OST0000
23718         tgt=ost1
23719         dev=$(facet_device $tgt)
23720         out=$(do_facet $tgt $LR_READER $dev)
23721         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23722         echo "$out"
23723         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23724         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23725                 error "Invalid uuid returned by $LR_READER on target $tgt"
23726         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23727
23728         # check lr_reader -c on MDT0000
23729         tgt=mds1
23730         dev=$(facet_device $tgt)
23731         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23732                 skip "$LR_READER does not support additional options"
23733         fi
23734         out=$(do_facet $tgt $LR_READER -c $dev)
23735         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23736         echo "$out"
23737         num=$(echo "$out" | grep -c "mdtlov")
23738         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23739                 error "Invalid number of mdtlov clients returned by $LR_READER"
23740         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23741
23742         # check lr_reader -cr on MDT0000
23743         out=$(do_facet $tgt $LR_READER -cr $dev)
23744         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23745         echo "$out"
23746         echo "$out" | grep -q "^reply_data:$" ||
23747                 error "$LR_READER should have returned 'reply_data' section"
23748         num=$(echo "$out" | grep -c "client_generation")
23749         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23750 }
23751 run_test 252 "check lr_reader tool"
23752
23753 test_253() {
23754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23755         remote_mds_nodsh && skip "remote MDS with nodsh"
23756         remote_mgs_nodsh && skip "remote MGS with nodsh"
23757
23758         local ostidx=0
23759         local rc=0
23760         local ost_name=$(ostname_from_index $ostidx)
23761
23762         # on the mdt's osc
23763         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23764         do_facet $SINGLEMDS $LCTL get_param -n \
23765                 osp.$mdtosc_proc1.reserved_mb_high ||
23766                 skip  "remote MDS does not support reserved_mb_high"
23767
23768         rm -rf $DIR/$tdir
23769         wait_mds_ost_sync
23770         wait_delete_completed
23771         mkdir $DIR/$tdir
23772         stack_trap "rm -rf $DIR/$tdir"
23773
23774         pool_add $TESTNAME || error "Pool creation failed"
23775         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23776
23777         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23778                 error "Setstripe failed"
23779
23780         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23781
23782         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23783                     grep "watermarks")
23784         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23785
23786         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23787                         osp.$mdtosc_proc1.prealloc_status)
23788         echo "prealloc_status $oa_status"
23789
23790         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23791                 error "File creation should fail"
23792
23793         #object allocation was stopped, but we still able to append files
23794         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23795                 oflag=append || error "Append failed"
23796
23797         rm -f $DIR/$tdir/$tfile.0
23798
23799         # For this test, we want to delete the files we created to go out of
23800         # space but leave the watermark, so we remain nearly out of space
23801         ost_watermarks_enospc_delete_files $tfile $ostidx
23802
23803         wait_delete_completed
23804
23805         sleep_maxage
23806
23807         for i in $(seq 10 12); do
23808                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23809                         2>/dev/null || error "File creation failed after rm"
23810         done
23811
23812         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23813                         osp.$mdtosc_proc1.prealloc_status)
23814         echo "prealloc_status $oa_status"
23815
23816         if (( oa_status != 0 )); then
23817                 error "Object allocation still disable after rm"
23818         fi
23819 }
23820 run_test 253 "Check object allocation limit"
23821
23822 test_254() {
23823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23824         remote_mds_nodsh && skip "remote MDS with nodsh"
23825
23826         local mdt=$(facet_svc $SINGLEMDS)
23827
23828         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23829                 skip "MDS does not support changelog_size"
23830
23831         local cl_user
23832
23833         changelog_register || error "changelog_register failed"
23834
23835         changelog_clear 0 || error "changelog_clear failed"
23836
23837         local size1=$(do_facet $SINGLEMDS \
23838                       $LCTL get_param -n mdd.$mdt.changelog_size)
23839         echo "Changelog size $size1"
23840
23841         rm -rf $DIR/$tdir
23842         $LFS mkdir -i 0 $DIR/$tdir
23843         # change something
23844         mkdir -p $DIR/$tdir/pics/2008/zachy
23845         touch $DIR/$tdir/pics/2008/zachy/timestamp
23846         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23847         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23848         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23849         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23850         rm $DIR/$tdir/pics/desktop.jpg
23851
23852         local size2=$(do_facet $SINGLEMDS \
23853                       $LCTL get_param -n mdd.$mdt.changelog_size)
23854         echo "Changelog size after work $size2"
23855
23856         (( $size2 > $size1 )) ||
23857                 error "new Changelog size=$size2 less than old size=$size1"
23858 }
23859 run_test 254 "Check changelog size"
23860
23861 ladvise_no_type()
23862 {
23863         local type=$1
23864         local file=$2
23865
23866         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23867                 awk -F: '{print $2}' | grep $type > /dev/null
23868         if [ $? -ne 0 ]; then
23869                 return 0
23870         fi
23871         return 1
23872 }
23873
23874 ladvise_no_ioctl()
23875 {
23876         local file=$1
23877
23878         lfs ladvise -a willread $file > /dev/null 2>&1
23879         if [ $? -eq 0 ]; then
23880                 return 1
23881         fi
23882
23883         lfs ladvise -a willread $file 2>&1 |
23884                 grep "Inappropriate ioctl for device" > /dev/null
23885         if [ $? -eq 0 ]; then
23886                 return 0
23887         fi
23888         return 1
23889 }
23890
23891 percent() {
23892         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23893 }
23894
23895 # run a random read IO workload
23896 # usage: random_read_iops <filename> <filesize> <iosize>
23897 random_read_iops() {
23898         local file=$1
23899         local fsize=$2
23900         local iosize=${3:-4096}
23901
23902         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23903                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23904 }
23905
23906 drop_file_oss_cache() {
23907         local file="$1"
23908         local nodes="$2"
23909
23910         $LFS ladvise -a dontneed $file 2>/dev/null ||
23911                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23912 }
23913
23914 ladvise_willread_performance()
23915 {
23916         local repeat=10
23917         local average_origin=0
23918         local average_cache=0
23919         local average_ladvise=0
23920
23921         for ((i = 1; i <= $repeat; i++)); do
23922                 echo "Iter $i/$repeat: reading without willread hint"
23923                 cancel_lru_locks osc
23924                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23925                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23926                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23927                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23928
23929                 cancel_lru_locks osc
23930                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23931                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23932                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23933
23934                 cancel_lru_locks osc
23935                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23936                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23937                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23938                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23939                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23940         done
23941         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23942         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23943         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23944
23945         speedup_cache=$(percent $average_cache $average_origin)
23946         speedup_ladvise=$(percent $average_ladvise $average_origin)
23947
23948         echo "Average uncached read: $average_origin"
23949         echo "Average speedup with OSS cached read: " \
23950                 "$average_cache = +$speedup_cache%"
23951         echo "Average speedup with ladvise willread: " \
23952                 "$average_ladvise = +$speedup_ladvise%"
23953
23954         local lowest_speedup=20
23955         if (( ${average_cache%.*} < $lowest_speedup )); then
23956                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23957                      " got $average_cache%. Skipping ladvise willread check."
23958                 return 0
23959         fi
23960
23961         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23962         # it is still good to run until then to exercise 'ladvise willread'
23963         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23964                 [ "$ost1_FSTYPE" = "zfs" ] &&
23965                 echo "osd-zfs does not support dontneed or drop_caches" &&
23966                 return 0
23967
23968         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23969         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23970                 error_not_in_vm "Speedup with willread is less than " \
23971                         "$lowest_speedup%, got $average_ladvise%"
23972 }
23973
23974 test_255a() {
23975         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23976                 skip "lustre < 2.8.54 does not support ladvise "
23977         remote_ost_nodsh && skip "remote OST with nodsh"
23978
23979         stack_trap "rm -f $DIR/$tfile"
23980         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23981
23982         ladvise_no_type willread $DIR/$tfile &&
23983                 skip "willread ladvise is not supported"
23984
23985         ladvise_no_ioctl $DIR/$tfile &&
23986                 skip "ladvise ioctl is not supported"
23987
23988         local size_mb=100
23989         local size=$((size_mb * 1048576))
23990         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23991                 error "dd to $DIR/$tfile failed"
23992
23993         lfs ladvise -a willread $DIR/$tfile ||
23994                 error "Ladvise failed with no range argument"
23995
23996         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23997                 error "Ladvise failed with no -l or -e argument"
23998
23999         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24000                 error "Ladvise failed with only -e argument"
24001
24002         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24003                 error "Ladvise failed with only -l argument"
24004
24005         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24006                 error "End offset should not be smaller than start offset"
24007
24008         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24009                 error "End offset should not be equal to start offset"
24010
24011         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24012                 error "Ladvise failed with overflowing -s argument"
24013
24014         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24015                 error "Ladvise failed with overflowing -e argument"
24016
24017         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24018                 error "Ladvise failed with overflowing -l argument"
24019
24020         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24021                 error "Ladvise succeeded with conflicting -l and -e arguments"
24022
24023         echo "Synchronous ladvise should wait"
24024         local delay=8
24025 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24026         do_nodes $(comma_list $(osts_nodes)) \
24027                 $LCTL set_param fail_val=$delay fail_loc=0x237
24028         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24029                 $LCTL set_param fail_loc=0"
24030
24031         local start_ts=$SECONDS
24032         lfs ladvise -a willread $DIR/$tfile ||
24033                 error "Ladvise failed with no range argument"
24034         local end_ts=$SECONDS
24035         local inteval_ts=$((end_ts - start_ts))
24036
24037         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24038                 error "Synchronous advice didn't wait reply"
24039         fi
24040
24041         echo "Asynchronous ladvise shouldn't wait"
24042         local start_ts=$SECONDS
24043         lfs ladvise -a willread -b $DIR/$tfile ||
24044                 error "Ladvise failed with no range argument"
24045         local end_ts=$SECONDS
24046         local inteval_ts=$((end_ts - start_ts))
24047
24048         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24049                 error "Asynchronous advice blocked"
24050         fi
24051
24052         ladvise_willread_performance
24053 }
24054 run_test 255a "check 'lfs ladvise -a willread'"
24055
24056 facet_meminfo() {
24057         local facet=$1
24058         local info=$2
24059
24060         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24061 }
24062
24063 test_255b() {
24064         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24065                 skip "lustre < 2.8.54 does not support ladvise "
24066         remote_ost_nodsh && skip "remote OST with nodsh"
24067
24068         stack_trap "rm -f $DIR/$tfile"
24069         lfs setstripe -c 1 -i 0 $DIR/$tfile
24070
24071         ladvise_no_type dontneed $DIR/$tfile &&
24072                 skip "dontneed ladvise is not supported"
24073
24074         ladvise_no_ioctl $DIR/$tfile &&
24075                 skip "ladvise ioctl is not supported"
24076
24077         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24078                 [ "$ost1_FSTYPE" = "zfs" ] &&
24079                 skip "zfs-osd does not support 'ladvise dontneed'"
24080
24081         local size_mb=100
24082         local size=$((size_mb * 1048576))
24083         # In order to prevent disturbance of other processes, only check 3/4
24084         # of the memory usage
24085         local kibibytes=$((size_mb * 1024 * 3 / 4))
24086
24087         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24088                 error "dd to $DIR/$tfile failed"
24089
24090         #force write to complete before dropping OST cache & checking memory
24091         sync
24092
24093         local total=$(facet_meminfo ost1 MemTotal)
24094         echo "Total memory: $total KiB"
24095
24096         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24097         local before_read=$(facet_meminfo ost1 Cached)
24098         echo "Cache used before read: $before_read KiB"
24099
24100         lfs ladvise -a willread $DIR/$tfile ||
24101                 error "Ladvise willread failed"
24102         local after_read=$(facet_meminfo ost1 Cached)
24103         echo "Cache used after read: $after_read KiB"
24104
24105         lfs ladvise -a dontneed $DIR/$tfile ||
24106                 error "Ladvise dontneed again failed"
24107         local no_read=$(facet_meminfo ost1 Cached)
24108         echo "Cache used after dontneed ladvise: $no_read KiB"
24109
24110         if [ $total -lt $((before_read + kibibytes)) ]; then
24111                 echo "Memory is too small, abort checking"
24112                 return 0
24113         fi
24114
24115         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24116                 error "Ladvise willread should use more memory" \
24117                         "than $kibibytes KiB"
24118         fi
24119
24120         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24121                 error "Ladvise dontneed should release more memory" \
24122                         "than $kibibytes KiB"
24123         fi
24124 }
24125 run_test 255b "check 'lfs ladvise -a dontneed'"
24126
24127 test_255c() {
24128         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24129                 skip "lustre < 2.10.50 does not support lockahead"
24130
24131         local ost1_imp=$(get_osc_import_name client ost1)
24132         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24133                          cut -d'.' -f2)
24134         local count
24135         local new_count
24136         local difference
24137         local i
24138         local rc
24139
24140         test_mkdir -p $DIR/$tdir
24141         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24142
24143         #test 10 returns only success/failure
24144         i=10
24145         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24146         rc=$?
24147         if [ $rc -eq 255 ]; then
24148                 error "Ladvise test${i} failed, ${rc}"
24149         fi
24150
24151         #test 11 counts lock enqueue requests, all others count new locks
24152         i=11
24153         count=$(do_facet ost1 \
24154                 $LCTL get_param -n ost.OSS.ost.stats)
24155         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24156
24157         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24158         rc=$?
24159         if [ $rc -eq 255 ]; then
24160                 error "Ladvise test${i} failed, ${rc}"
24161         fi
24162
24163         new_count=$(do_facet ost1 \
24164                 $LCTL get_param -n ost.OSS.ost.stats)
24165         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24166                    awk '{ print $2 }')
24167
24168         difference="$((new_count - count))"
24169         if [ $difference -ne $rc ]; then
24170                 error "Ladvise test${i}, bad enqueue count, returned " \
24171                       "${rc}, actual ${difference}"
24172         fi
24173
24174         for i in $(seq 12 21); do
24175                 # If we do not do this, we run the risk of having too many
24176                 # locks and starting lock cancellation while we are checking
24177                 # lock counts.
24178                 cancel_lru_locks osc
24179
24180                 count=$($LCTL get_param -n \
24181                        ldlm.namespaces.$imp_name.lock_unused_count)
24182
24183                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24184                 rc=$?
24185                 if [ $rc -eq 255 ]; then
24186                         error "Ladvise test ${i} failed, ${rc}"
24187                 fi
24188
24189                 new_count=$($LCTL get_param -n \
24190                        ldlm.namespaces.$imp_name.lock_unused_count)
24191                 difference="$((new_count - count))"
24192
24193                 # Test 15 output is divided by 100 to map down to valid return
24194                 if [ $i -eq 15 ]; then
24195                         rc="$((rc * 100))"
24196                 fi
24197
24198                 if [ $difference -ne $rc ]; then
24199                         error "Ladvise test ${i}, bad lock count, returned " \
24200                               "${rc}, actual ${difference}"
24201                 fi
24202         done
24203
24204         #test 22 returns only success/failure
24205         i=22
24206         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24207         rc=$?
24208         if [ $rc -eq 255 ]; then
24209                 error "Ladvise test${i} failed, ${rc}"
24210         fi
24211 }
24212 run_test 255c "suite of ladvise lockahead tests"
24213
24214 test_256() {
24215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24216         remote_mds_nodsh && skip "remote MDS with nodsh"
24217         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24218         changelog_users $SINGLEMDS | grep "^cl" &&
24219                 skip "active changelog user"
24220
24221         local cl_user
24222         local cat_sl
24223         local mdt_dev
24224
24225         mdt_dev=$(facet_device $SINGLEMDS)
24226         echo $mdt_dev
24227
24228         changelog_register || error "changelog_register failed"
24229
24230         rm -rf $DIR/$tdir
24231         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24232
24233         changelog_clear 0 || error "changelog_clear failed"
24234
24235         # change something
24236         touch $DIR/$tdir/{1..10}
24237
24238         # stop the MDT
24239         stop $SINGLEMDS || error "Fail to stop MDT"
24240
24241         # remount the MDT
24242         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24243                 error "Fail to start MDT"
24244
24245         #after mount new plainllog is used
24246         touch $DIR/$tdir/{11..19}
24247         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24248         stack_trap "rm -f $tmpfile"
24249         cat_sl=$(do_facet $SINGLEMDS "sync; \
24250                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24251                  llog_reader $tmpfile | grep -c type=1064553b")
24252         do_facet $SINGLEMDS llog_reader $tmpfile
24253
24254         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24255
24256         changelog_clear 0 || error "changelog_clear failed"
24257
24258         cat_sl=$(do_facet $SINGLEMDS "sync; \
24259                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24260                  llog_reader $tmpfile | grep -c type=1064553b")
24261
24262         if (( cat_sl == 2 )); then
24263                 error "Empty plain llog was not deleted from changelog catalog"
24264         elif (( cat_sl != 1 )); then
24265                 error "Active plain llog shouldn't be deleted from catalog"
24266         fi
24267 }
24268 run_test 256 "Check llog delete for empty and not full state"
24269
24270 test_257() {
24271         remote_mds_nodsh && skip "remote MDS with nodsh"
24272         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24273                 skip "Need MDS version at least 2.8.55"
24274
24275         test_mkdir $DIR/$tdir
24276
24277         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24278                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24279         stat $DIR/$tdir
24280
24281 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24282         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24283         local facet=mds$((mdtidx + 1))
24284         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24285         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24286
24287         stop $facet || error "stop MDS failed"
24288         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24289                 error "start MDS fail"
24290         wait_recovery_complete $facet
24291 }
24292 run_test 257 "xattr locks are not lost"
24293
24294 # Verify we take the i_mutex when security requires it
24295 test_258a() {
24296 #define OBD_FAIL_IMUTEX_SEC 0x141c
24297         $LCTL set_param fail_loc=0x141c
24298         touch $DIR/$tfile
24299         chmod u+s $DIR/$tfile
24300         chmod a+rwx $DIR/$tfile
24301         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24302         RC=$?
24303         if [ $RC -ne 0 ]; then
24304                 error "error, failed to take i_mutex, rc=$?"
24305         fi
24306         rm -f $DIR/$tfile
24307 }
24308 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24309
24310 # Verify we do NOT take the i_mutex in the normal case
24311 test_258b() {
24312 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24313         $LCTL set_param fail_loc=0x141d
24314         touch $DIR/$tfile
24315         chmod a+rwx $DIR
24316         chmod a+rw $DIR/$tfile
24317         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24318         RC=$?
24319         if [ $RC -ne 0 ]; then
24320                 error "error, took i_mutex unnecessarily, rc=$?"
24321         fi
24322         rm -f $DIR/$tfile
24323
24324 }
24325 run_test 258b "verify i_mutex security behavior"
24326
24327 test_259() {
24328         local file=$DIR/$tfile
24329         local before
24330         local after
24331
24332         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24333
24334         stack_trap "rm -f $file" EXIT
24335
24336         wait_delete_completed
24337         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24338         echo "before: $before"
24339
24340         $LFS setstripe -i 0 -c 1 $file
24341         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24342         sync_all_data
24343         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24344         echo "after write: $after"
24345
24346 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24347         do_facet ost1 $LCTL set_param fail_loc=0x2301
24348         $TRUNCATE $file 0
24349         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24350         echo "after truncate: $after"
24351
24352         stop ost1
24353         do_facet ost1 $LCTL set_param fail_loc=0
24354         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24355         sleep 2
24356         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24357         echo "after restart: $after"
24358         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24359                 error "missing truncate?"
24360
24361         return 0
24362 }
24363 run_test 259 "crash at delayed truncate"
24364
24365 test_260() {
24366 #define OBD_FAIL_MDC_CLOSE               0x806
24367         $LCTL set_param fail_loc=0x80000806
24368         touch $DIR/$tfile
24369
24370 }
24371 run_test 260 "Check mdc_close fail"
24372
24373 ### Data-on-MDT sanity tests ###
24374 test_270a() {
24375         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24376                 skip "Need MDS version at least 2.10.55 for DoM"
24377
24378         # create DoM file
24379         local dom=$DIR/$tdir/dom_file
24380         local tmp=$DIR/$tdir/tmp_file
24381
24382         mkdir_on_mdt0 $DIR/$tdir
24383
24384         # basic checks for DoM component creation
24385         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24386                 error "Can set MDT layout to non-first entry"
24387
24388         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24389                 error "Can define multiple entries as MDT layout"
24390
24391         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24392
24393         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24394         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24395         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24396
24397         local mdtidx=$($LFS getstripe -m $dom)
24398         local mdtname=MDT$(printf %04x $mdtidx)
24399         local facet=mds$((mdtidx + 1))
24400         local space_check=1
24401
24402         # Skip free space checks with ZFS
24403         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24404
24405         # write
24406         sync
24407         local size_tmp=$((65536 * 3))
24408         local mdtfree1=$(do_facet $facet \
24409                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24410
24411         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24412         # check also direct IO along write
24413         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24414         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24415         sync
24416         cmp $tmp $dom || error "file data is different"
24417         [ $(stat -c%s $dom) == $size_tmp ] ||
24418                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24419         if [ $space_check == 1 ]; then
24420                 local mdtfree2=$(do_facet $facet \
24421                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24422
24423                 # increase in usage from by $size_tmp
24424                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24425                         error "MDT free space wrong after write: " \
24426                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24427         fi
24428
24429         # truncate
24430         local size_dom=10000
24431
24432         $TRUNCATE $dom $size_dom
24433         [ $(stat -c%s $dom) == $size_dom ] ||
24434                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24435         if [ $space_check == 1 ]; then
24436                 mdtfree1=$(do_facet $facet \
24437                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24438                 # decrease in usage from $size_tmp to new $size_dom
24439                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24440                   $(((size_tmp - size_dom) / 1024)) ] ||
24441                         error "MDT free space is wrong after truncate: " \
24442                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24443         fi
24444
24445         # append
24446         cat $tmp >> $dom
24447         sync
24448         size_dom=$((size_dom + size_tmp))
24449         [ $(stat -c%s $dom) == $size_dom ] ||
24450                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24451         if [ $space_check == 1 ]; then
24452                 mdtfree2=$(do_facet $facet \
24453                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24454                 # increase in usage by $size_tmp from previous
24455                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24456                         error "MDT free space is wrong after append: " \
24457                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24458         fi
24459
24460         # delete
24461         rm $dom
24462         if [ $space_check == 1 ]; then
24463                 mdtfree1=$(do_facet $facet \
24464                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24465                 # decrease in usage by $size_dom from previous
24466                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24467                         error "MDT free space is wrong after removal: " \
24468                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24469         fi
24470
24471         # combined striping
24472         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24473                 error "Can't create DoM + OST striping"
24474
24475         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24476         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24477         # check also direct IO along write
24478         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24479         sync
24480         cmp $tmp $dom || error "file data is different"
24481         [ $(stat -c%s $dom) == $size_tmp ] ||
24482                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24483         rm $dom $tmp
24484
24485         return 0
24486 }
24487 run_test 270a "DoM: basic functionality tests"
24488
24489 test_270b() {
24490         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24491                 skip "Need MDS version at least 2.10.55"
24492
24493         local dom=$DIR/$tdir/dom_file
24494         local max_size=1048576
24495
24496         mkdir -p $DIR/$tdir
24497         $LFS setstripe -E $max_size -L mdt $dom
24498
24499         # truncate over the limit
24500         $TRUNCATE $dom $(($max_size + 1)) &&
24501                 error "successful truncate over the maximum size"
24502         # write over the limit
24503         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24504                 error "successful write over the maximum size"
24505         # append over the limit
24506         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24507         echo "12345" >> $dom && error "successful append over the maximum size"
24508         rm $dom
24509
24510         return 0
24511 }
24512 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24513
24514 test_270c() {
24515         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24516                 skip "Need MDS version at least 2.10.55"
24517
24518         mkdir -p $DIR/$tdir
24519         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24520
24521         # check files inherit DoM EA
24522         touch $DIR/$tdir/first
24523         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24524                 error "bad pattern"
24525         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24526                 error "bad stripe count"
24527         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24528                 error "bad stripe size"
24529
24530         # check directory inherits DoM EA and uses it as default
24531         mkdir $DIR/$tdir/subdir
24532         touch $DIR/$tdir/subdir/second
24533         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24534                 error "bad pattern in sub-directory"
24535         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24536                 error "bad stripe count in sub-directory"
24537         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24538                 error "bad stripe size in sub-directory"
24539         return 0
24540 }
24541 run_test 270c "DoM: DoM EA inheritance tests"
24542
24543 test_270d() {
24544         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24545                 skip "Need MDS version at least 2.10.55"
24546
24547         mkdir -p $DIR/$tdir
24548         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24549
24550         # inherit default DoM striping
24551         mkdir $DIR/$tdir/subdir
24552         touch $DIR/$tdir/subdir/f1
24553
24554         # change default directory striping
24555         $LFS setstripe -c 1 $DIR/$tdir/subdir
24556         touch $DIR/$tdir/subdir/f2
24557         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24558                 error "wrong default striping in file 2"
24559         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24560                 error "bad pattern in file 2"
24561         return 0
24562 }
24563 run_test 270d "DoM: change striping from DoM to RAID0"
24564
24565 test_270e() {
24566         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24567                 skip "Need MDS version at least 2.10.55"
24568
24569         mkdir -p $DIR/$tdir/dom
24570         mkdir -p $DIR/$tdir/norm
24571         DOMFILES=20
24572         NORMFILES=10
24573         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24574         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24575
24576         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24577         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24578
24579         # find DoM files by layout
24580         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24581         [ $NUM -eq  $DOMFILES ] ||
24582                 error "lfs find -L: found $NUM, expected $DOMFILES"
24583         echo "Test 1: lfs find 20 DOM files by layout: OK"
24584
24585         # there should be 1 dir with default DOM striping
24586         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24587         [ $NUM -eq  1 ] ||
24588                 error "lfs find -L: found $NUM, expected 1 dir"
24589         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24590
24591         # find DoM files by stripe size
24592         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24593         [ $NUM -eq  $DOMFILES ] ||
24594                 error "lfs find -S: found $NUM, expected $DOMFILES"
24595         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24596
24597         # find files by stripe offset except DoM files
24598         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24599         [ $NUM -eq  $NORMFILES ] ||
24600                 error "lfs find -i: found $NUM, expected $NORMFILES"
24601         echo "Test 5: lfs find no DOM files by stripe index: OK"
24602         return 0
24603 }
24604 run_test 270e "DoM: lfs find with DoM files test"
24605
24606 test_270f() {
24607         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24608                 skip "Need MDS version at least 2.10.55"
24609
24610         local mdtname=${FSNAME}-MDT0000-mdtlov
24611         local dom=$DIR/$tdir/dom_file
24612         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24613                                                 lod.$mdtname.dom_stripesize)
24614         local dom_limit=131072
24615
24616         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24617         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24618                                                 lod.$mdtname.dom_stripesize)
24619         [ ${dom_limit} -eq ${dom_current} ] ||
24620                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24621
24622         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24623         $LFS setstripe -d $DIR/$tdir
24624         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24625                 error "Can't set directory default striping"
24626
24627         # exceed maximum stripe size
24628         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24629                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24630         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24631                 error "Able to create DoM component size more than LOD limit"
24632
24633         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24634         dom_current=$(do_facet mds1 $LCTL get_param -n \
24635                                                 lod.$mdtname.dom_stripesize)
24636         [ 0 -eq ${dom_current} ] ||
24637                 error "Can't set zero DoM stripe limit"
24638         rm $dom
24639
24640         # attempt to create DoM file on server with disabled DoM should
24641         # remove DoM entry from layout and be succeed
24642         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24643                 error "Can't create DoM file (DoM is disabled)"
24644         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24645                 error "File has DoM component while DoM is disabled"
24646         rm $dom
24647
24648         # attempt to create DoM file with only DoM stripe should return error
24649         $LFS setstripe -E $dom_limit -L mdt $dom &&
24650                 error "Able to create DoM-only file while DoM is disabled"
24651
24652         # too low values to be aligned with smallest stripe size 64K
24653         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24654         dom_current=$(do_facet mds1 $LCTL get_param -n \
24655                                                 lod.$mdtname.dom_stripesize)
24656         [ 30000 -eq ${dom_current} ] &&
24657                 error "Can set too small DoM stripe limit"
24658
24659         # 64K is a minimal stripe size in Lustre, expect limit of that size
24660         [ 65536 -eq ${dom_current} ] ||
24661                 error "Limit is not set to 64K but ${dom_current}"
24662
24663         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24664         dom_current=$(do_facet mds1 $LCTL get_param -n \
24665                                                 lod.$mdtname.dom_stripesize)
24666         echo $dom_current
24667         [ 2147483648 -eq ${dom_current} ] &&
24668                 error "Can set too large DoM stripe limit"
24669
24670         do_facet mds1 $LCTL set_param -n \
24671                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24672         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24673                 error "Can't create DoM component size after limit change"
24674         do_facet mds1 $LCTL set_param -n \
24675                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24676         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24677                 error "Can't create DoM file after limit decrease"
24678         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24679                 error "Can create big DoM component after limit decrease"
24680         touch ${dom}_def ||
24681                 error "Can't create file with old default layout"
24682
24683         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24684         return 0
24685 }
24686 run_test 270f "DoM: maximum DoM stripe size checks"
24687
24688 test_270g() {
24689         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24690                 skip "Need MDS version at least 2.13.52"
24691         local dom=$DIR/$tdir/$tfile
24692
24693         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24694         local lodname=${FSNAME}-MDT0000-mdtlov
24695
24696         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24697         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24698         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24699         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24700
24701         local dom_limit=1024
24702         local dom_threshold="50%"
24703
24704         $LFS setstripe -d $DIR/$tdir
24705         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24706                 error "Can't set directory default striping"
24707
24708         do_facet mds1 $LCTL set_param -n \
24709                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24710         # set 0 threshold and create DOM file to change tunable stripesize
24711         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24712         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24713                 error "Failed to create $dom file"
24714         # now tunable dom_cur_stripesize should reach maximum
24715         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24716                                         lod.${lodname}.dom_stripesize_cur_kb)
24717         [[ $dom_current == $dom_limit ]] ||
24718                 error "Current DOM stripesize is not maximum"
24719         rm $dom
24720
24721         # set threshold for further tests
24722         do_facet mds1 $LCTL set_param -n \
24723                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24724         echo "DOM threshold is $dom_threshold free space"
24725         local dom_def
24726         local dom_set
24727         # Spoof bfree to exceed threshold
24728         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24729         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24730         for spfree in 40 20 0 15 30 55; do
24731                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24732                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24733                         error "Failed to create $dom file"
24734                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24735                                         lod.${lodname}.dom_stripesize_cur_kb)
24736                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24737                 [[ $dom_def != $dom_current ]] ||
24738                         error "Default stripe size was not changed"
24739                 if (( spfree > 0 )) ; then
24740                         dom_set=$($LFS getstripe -S $dom)
24741                         (( dom_set == dom_def * 1024 )) ||
24742                                 error "DOM component size is still old"
24743                 else
24744                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24745                                 error "DoM component is set with no free space"
24746                 fi
24747                 rm $dom
24748                 dom_current=$dom_def
24749         done
24750 }
24751 run_test 270g "DoM: default DoM stripe size depends on free space"
24752
24753 test_270h() {
24754         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24755                 skip "Need MDS version at least 2.13.53"
24756
24757         local mdtname=${FSNAME}-MDT0000-mdtlov
24758         local dom=$DIR/$tdir/$tfile
24759         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24760
24761         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24762         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24763
24764         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24765         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24766                 error "can't create OST file"
24767         # mirrored file with DOM entry in the second mirror
24768         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24769                 error "can't create mirror with DoM component"
24770
24771         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24772
24773         # DOM component in the middle and has other enries in the same mirror,
24774         # should succeed but lost DoM component
24775         $LFS setstripe --copy=${dom}_1 $dom ||
24776                 error "Can't create file from OST|DOM mirror layout"
24777         # check new file has no DoM layout after all
24778         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24779                 error "File has DoM component while DoM is disabled"
24780 }
24781 run_test 270h "DoM: DoM stripe removal when disabled on server"
24782
24783 test_270i() {
24784         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24785                 skip "Need MDS version at least 2.14.54"
24786
24787         mkdir $DIR/$tdir
24788         # DoM with plain layout
24789         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24790                 error "default plain layout with DoM must fail"
24791         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24792                 error "setstripe plain file layout with DoM must fail"
24793         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24794                 error "default DoM layout with bad striping must fail"
24795         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24796                 error "setstripe to DoM layout with bad striping must fail"
24797         return 0
24798 }
24799 run_test 270i "DoM: setting invalid DoM striping should fail"
24800
24801 test_270j() {
24802         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24803                 skip "Need MDS version at least 2.15.55.203"
24804
24805         local dom=$DIR/$tdir/$tfile
24806         local odv
24807         local ndv
24808
24809         mkdir -p $DIR/$tdir
24810
24811         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24812
24813         odv=$($LFS data_version $dom)
24814         chmod 666 $dom
24815         mv $dom ${dom}_moved
24816         link ${dom}_moved $dom
24817         setfattr -n user.attrx -v "some_attr" $dom
24818         ndv=$($LFS data_version $dom)
24819         (( $ndv == $odv )) ||
24820                 error "data version was changed by metadata operations"
24821
24822         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24823                 error "failed to write data into $dom"
24824         cancel_lru_locks mdc
24825         ndv=$($LFS data_version $dom)
24826         (( $ndv != $odv )) ||
24827                 error "data version wasn't changed on write"
24828
24829         odv=$ndv
24830         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24831         ndv=$($LFS data_version $dom)
24832         (( $ndv != $odv )) ||
24833                 error "data version wasn't changed on truncate down"
24834
24835         odv=$ndv
24836         $TRUNCATE $dom 25000
24837         ndv=$($LFS data_version $dom)
24838         (( $ndv != $odv )) ||
24839                 error "data version wasn't changed on truncate up"
24840
24841         # check also fallocate for ldiskfs
24842         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24843                 odv=$ndv
24844                 fallocate -l 1048576 $dom
24845                 ndv=$($LFS data_version $dom)
24846                 (( $ndv != $odv )) ||
24847                         error "data version wasn't changed on fallocate"
24848
24849                 odv=$ndv
24850                 fallocate -p --offset 4096 -l 4096 $dom
24851                 ndv=$($LFS data_version $dom)
24852                 (( $ndv != $odv )) ||
24853                         error "data version wasn't changed on fallocate punch"
24854         fi
24855 }
24856 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24857
24858 test_271a() {
24859         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24860                 skip "Need MDS version at least 2.10.55"
24861
24862         local dom=$DIR/$tdir/dom
24863
24864         mkdir -p $DIR/$tdir
24865
24866         $LFS setstripe -E 1024K -L mdt $dom
24867
24868         lctl set_param -n mdc.*.stats=clear
24869         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24870         cat $dom > /dev/null
24871         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24872         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24873         ls $dom
24874         rm -f $dom
24875 }
24876 run_test 271a "DoM: data is cached for read after write"
24877
24878 test_271b() {
24879         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24880                 skip "Need MDS version at least 2.10.55"
24881
24882         local dom=$DIR/$tdir/dom
24883
24884         mkdir -p $DIR/$tdir
24885
24886         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24887
24888         lctl set_param -n mdc.*.stats=clear
24889         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24890         cancel_lru_locks mdc
24891         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24892         # second stat to check size is cached on client
24893         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24894         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24895         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24896         rm -f $dom
24897 }
24898 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24899
24900 test_271ba() {
24901         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24902                 skip "Need MDS version at least 2.10.55"
24903
24904         local dom=$DIR/$tdir/dom
24905
24906         mkdir -p $DIR/$tdir
24907
24908         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24909
24910         lctl set_param -n mdc.*.stats=clear
24911         lctl set_param -n osc.*.stats=clear
24912         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24913         cancel_lru_locks mdc
24914         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24915         # second stat to check size is cached on client
24916         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24917         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24918         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24919         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24920         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24921         rm -f $dom
24922 }
24923 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24924
24925
24926 get_mdc_stats() {
24927         local mdtidx=$1
24928         local param=$2
24929         local mdt=MDT$(printf %04x $mdtidx)
24930
24931         if [ -z $param ]; then
24932                 lctl get_param -n mdc.*$mdt*.stats
24933         else
24934                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24935         fi
24936 }
24937
24938 test_271c() {
24939         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24940                 skip "Need MDS version at least 2.10.55"
24941
24942         local dom=$DIR/$tdir/dom
24943
24944         mkdir -p $DIR/$tdir
24945
24946         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24947
24948         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24949         local facet=mds$((mdtidx + 1))
24950
24951         cancel_lru_locks mdc
24952         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24953         createmany -o $dom 1000
24954         lctl set_param -n mdc.*.stats=clear
24955         smalliomany -w $dom 1000 200
24956         get_mdc_stats $mdtidx
24957         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24958         # Each file has 1 open, 1 IO enqueues, total 2000
24959         # but now we have also +1 getxattr for security.capability, total 3000
24960         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24961         unlinkmany $dom 1000
24962
24963         cancel_lru_locks mdc
24964         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24965         createmany -o $dom 1000
24966         lctl set_param -n mdc.*.stats=clear
24967         smalliomany -w $dom 1000 200
24968         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24969         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24970         # for OPEN and IO lock.
24971         [ $((enq - enq_2)) -ge 1000 ] ||
24972                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24973         unlinkmany $dom 1000
24974         return 0
24975 }
24976 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24977
24978 cleanup_271def_tests() {
24979         trap 0
24980         rm -f $1
24981 }
24982
24983 test_271d() {
24984         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24985                 skip "Need MDS version at least 2.10.57"
24986
24987         local dom=$DIR/$tdir/dom
24988         local tmp=$TMP/$tfile
24989         trap "cleanup_271def_tests $tmp" EXIT
24990
24991         mkdir -p $DIR/$tdir
24992
24993         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24994
24995         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24996
24997         cancel_lru_locks mdc
24998         dd if=/dev/urandom of=$tmp bs=1000 count=1
24999         dd if=$tmp of=$dom bs=1000 count=1
25000         cancel_lru_locks mdc
25001
25002         cat /etc/hosts >> $tmp
25003         lctl set_param -n mdc.*.stats=clear
25004
25005         # append data to the same file it should update local page
25006         echo "Append to the same page"
25007         cat /etc/hosts >> $dom
25008         local num=$(get_mdc_stats $mdtidx ost_read)
25009         local ra=$(get_mdc_stats $mdtidx req_active)
25010         local rw=$(get_mdc_stats $mdtidx req_waittime)
25011
25012         [ -z $num ] || error "$num READ RPC occured"
25013         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25014         echo "... DONE"
25015
25016         # compare content
25017         cmp $tmp $dom || error "file miscompare"
25018
25019         cancel_lru_locks mdc
25020         lctl set_param -n mdc.*.stats=clear
25021
25022         echo "Open and read file"
25023         cat $dom > /dev/null
25024         local num=$(get_mdc_stats $mdtidx ost_read)
25025         local ra=$(get_mdc_stats $mdtidx req_active)
25026         local rw=$(get_mdc_stats $mdtidx req_waittime)
25027
25028         [ -z $num ] || error "$num READ RPC occured"
25029         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25030         echo "... DONE"
25031
25032         # compare content
25033         cmp $tmp $dom || error "file miscompare"
25034
25035         return 0
25036 }
25037 run_test 271d "DoM: read on open (1K file in reply buffer)"
25038
25039 test_271f() {
25040         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25041                 skip "Need MDS version at least 2.10.57"
25042
25043         local dom=$DIR/$tdir/dom
25044         local tmp=$TMP/$tfile
25045         trap "cleanup_271def_tests $tmp" EXIT
25046
25047         mkdir -p $DIR/$tdir
25048
25049         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25050
25051         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25052
25053         cancel_lru_locks mdc
25054         dd if=/dev/urandom of=$tmp bs=265000 count=1
25055         dd if=$tmp of=$dom bs=265000 count=1
25056         cancel_lru_locks mdc
25057         cat /etc/hosts >> $tmp
25058         lctl set_param -n mdc.*.stats=clear
25059
25060         echo "Append to the same page"
25061         cat /etc/hosts >> $dom
25062         local num=$(get_mdc_stats $mdtidx ost_read)
25063         local ra=$(get_mdc_stats $mdtidx req_active)
25064         local rw=$(get_mdc_stats $mdtidx req_waittime)
25065
25066         [ -z $num ] || error "$num READ RPC occured"
25067         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25068         echo "... DONE"
25069
25070         # compare content
25071         cmp $tmp $dom || error "file miscompare"
25072
25073         cancel_lru_locks mdc
25074         lctl set_param -n mdc.*.stats=clear
25075
25076         echo "Open and read file"
25077         cat $dom > /dev/null
25078         local num=$(get_mdc_stats $mdtidx ost_read)
25079         local ra=$(get_mdc_stats $mdtidx req_active)
25080         local rw=$(get_mdc_stats $mdtidx req_waittime)
25081
25082         [ -z $num ] && num=0
25083         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25084         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25085         echo "... DONE"
25086
25087         # compare content
25088         cmp $tmp $dom || error "file miscompare"
25089
25090         return 0
25091 }
25092 run_test 271f "DoM: read on open (200K file and read tail)"
25093
25094 test_271g() {
25095         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25096                 skip "Skipping due to old client or server version"
25097
25098         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25099         # to get layout
25100         $CHECKSTAT -t file $DIR1/$tfile
25101
25102         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25103         MULTIOP_PID=$!
25104         sleep 1
25105         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25106         $LCTL set_param fail_loc=0x80000314
25107         rm $DIR1/$tfile || error "Unlink fails"
25108         RC=$?
25109         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25110         [ $RC -eq 0 ] || error "Failed write to stale object"
25111 }
25112 run_test 271g "Discard DoM data vs client flush race"
25113
25114 test_272a() {
25115         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25116                 skip "Need MDS version at least 2.11.50"
25117
25118         local dom=$DIR/$tdir/dom
25119         mkdir -p $DIR/$tdir
25120
25121         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25122         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25123                 error "failed to write data into $dom"
25124         local old_md5=$(md5sum $dom)
25125
25126         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25127                 error "failed to migrate to the same DoM component"
25128
25129         local new_md5=$(md5sum $dom)
25130
25131         [ "$old_md5" == "$new_md5" ] ||
25132                 error "md5sum differ: $old_md5, $new_md5"
25133
25134         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25135                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25136 }
25137 run_test 272a "DoM migration: new layout with the same DOM component"
25138
25139 test_272b() {
25140         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25141                 skip "Need MDS version at least 2.11.50"
25142
25143         local dom=$DIR/$tdir/dom
25144         mkdir -p $DIR/$tdir
25145         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25146         stack_trap "rm -rf $DIR/$tdir"
25147
25148         local mdtidx=$($LFS getstripe -m $dom)
25149         local mdtname=MDT$(printf %04x $mdtidx)
25150         local facet=mds$((mdtidx + 1))
25151
25152         local mdtfree1=$(do_facet $facet \
25153                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25154         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25155                 error "failed to write data into $dom"
25156         local old_md5=$(md5sum $dom)
25157         cancel_lru_locks mdc
25158         local mdtfree1=$(do_facet $facet \
25159                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25160
25161         $LFS migrate -c2 $dom ||
25162                 error "failed to migrate to the new composite layout"
25163         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25164                 error "MDT stripe was not removed"
25165         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25166                 error "$dir1 shouldn't have DATAVER EA"
25167
25168         cancel_lru_locks mdc
25169         local new_md5=$(md5sum $dom)
25170         [ "$old_md5" == "$new_md5" ] ||
25171                 error "$old_md5 != $new_md5"
25172
25173         # Skip free space checks with ZFS
25174         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25175                 local mdtfree2=$(do_facet $facet \
25176                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25177                 [ $mdtfree2 -gt $mdtfree1 ] ||
25178                         error "MDT space is not freed after migration"
25179         fi
25180         return 0
25181 }
25182 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25183
25184 test_272c() {
25185         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25186                 skip "Need MDS version at least 2.11.50"
25187
25188         local dom=$DIR/$tdir/$tfile
25189         mkdir -p $DIR/$tdir
25190         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25191         stack_trap "rm -rf $DIR/$tdir"
25192
25193         local mdtidx=$($LFS getstripe -m $dom)
25194         local mdtname=MDT$(printf %04x $mdtidx)
25195         local facet=mds$((mdtidx + 1))
25196
25197         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25198                 error "failed to write data into $dom"
25199         local old_md5=$(md5sum $dom)
25200         cancel_lru_locks mdc
25201         local mdtfree1=$(do_facet $facet \
25202                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25203
25204         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25205                 error "failed to migrate to the new composite layout"
25206         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25207                 error "MDT stripe was not removed"
25208
25209         cancel_lru_locks mdc
25210         local new_md5=$(md5sum $dom)
25211         [ "$old_md5" == "$new_md5" ] ||
25212                 error "$old_md5 != $new_md5"
25213
25214         # Skip free space checks with ZFS
25215         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25216                 local mdtfree2=$(do_facet $facet \
25217                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25218                 [ $mdtfree2 -gt $mdtfree1 ] ||
25219                         error "MDS space is not freed after migration"
25220         fi
25221         return 0
25222 }
25223 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25224
25225 test_272d() {
25226         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25227                 skip "Need MDS version at least 2.12.55"
25228
25229         local dom=$DIR/$tdir/$tfile
25230         mkdir -p $DIR/$tdir
25231         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25232
25233         local mdtidx=$($LFS getstripe -m $dom)
25234         local mdtname=MDT$(printf %04x $mdtidx)
25235         local facet=mds$((mdtidx + 1))
25236
25237         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25238                 error "failed to write data into $dom"
25239         local old_md5=$(md5sum $dom)
25240         cancel_lru_locks mdc
25241         local mdtfree1=$(do_facet $facet \
25242                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25243
25244         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25245                 error "failed mirroring to the new composite layout"
25246         $LFS mirror resync $dom ||
25247                 error "failed mirror resync"
25248         $LFS mirror split --mirror-id 1 -d $dom ||
25249                 error "failed mirror split"
25250
25251         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25252                 error "MDT stripe was not removed"
25253
25254         cancel_lru_locks mdc
25255         local new_md5=$(md5sum $dom)
25256         [ "$old_md5" == "$new_md5" ] ||
25257                 error "$old_md5 != $new_md5"
25258
25259         # Skip free space checks with ZFS
25260         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25261                 local mdtfree2=$(do_facet $facet \
25262                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25263                 [ $mdtfree2 -gt $mdtfree1 ] ||
25264                         error "MDS space is not freed after DOM mirror deletion"
25265         fi
25266         return 0
25267 }
25268 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25269
25270 test_272e() {
25271         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25272                 skip "Need MDS version at least 2.12.55"
25273
25274         local dom=$DIR/$tdir/$tfile
25275         mkdir -p $DIR/$tdir
25276         $LFS setstripe -c 2 $dom
25277
25278         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25279                 error "failed to write data into $dom"
25280         local old_md5=$(md5sum $dom)
25281         cancel_lru_locks
25282
25283         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25284                 error "failed mirroring to the DOM layout"
25285         $LFS mirror resync $dom ||
25286                 error "failed mirror resync"
25287         $LFS mirror split --mirror-id 1 -d $dom ||
25288                 error "failed mirror split"
25289
25290         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25291                 error "MDT stripe wasn't set"
25292
25293         cancel_lru_locks
25294         local new_md5=$(md5sum $dom)
25295         [ "$old_md5" == "$new_md5" ] ||
25296                 error "$old_md5 != $new_md5"
25297
25298         return 0
25299 }
25300 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25301
25302 test_272f() {
25303         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25304                 skip "Need MDS version at least 2.12.55"
25305
25306         local dom=$DIR/$tdir/$tfile
25307         mkdir -p $DIR/$tdir
25308         $LFS setstripe -c 2 $dom
25309
25310         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25311                 error "failed to write data into $dom"
25312         local old_md5=$(md5sum $dom)
25313         cancel_lru_locks
25314
25315         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25316                 error "failed migrating to the DOM file"
25317
25318         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25319                 error "MDT stripe wasn't set"
25320
25321         cancel_lru_locks
25322         local new_md5=$(md5sum $dom)
25323         [ "$old_md5" != "$new_md5" ] &&
25324                 error "$old_md5 != $new_md5"
25325
25326         return 0
25327 }
25328 run_test 272f "DoM migration: OST-striped file to DOM file"
25329
25330 test_273a() {
25331         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25332                 skip "Need MDS version at least 2.11.50"
25333
25334         # Layout swap cannot be done if either file has DOM component,
25335         # this will never be supported, migration should be used instead
25336
25337         local dom=$DIR/$tdir/$tfile
25338         mkdir -p $DIR/$tdir
25339
25340         $LFS setstripe -c2 ${dom}_plain
25341         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25342         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25343                 error "can swap layout with DoM component"
25344         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25345                 error "can swap layout with DoM component"
25346
25347         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25348         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25349                 error "can swap layout with DoM component"
25350         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25351                 error "can swap layout with DoM component"
25352         return 0
25353 }
25354 run_test 273a "DoM: layout swapping should fail with DOM"
25355
25356 test_273b() {
25357         mkdir -p $DIR/$tdir
25358         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25359
25360 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25361         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25362
25363         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25364 }
25365 run_test 273b "DoM: race writeback and object destroy"
25366
25367 test_273c() {
25368         mkdir -p $DIR/$tdir
25369         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25370
25371         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25372         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25373
25374         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25375 }
25376 run_test 273c "race writeback and object destroy"
25377
25378 test_275() {
25379         remote_ost_nodsh && skip "remote OST with nodsh"
25380         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25381                 skip "Need OST version >= 2.10.57"
25382
25383         local file=$DIR/$tfile
25384         local oss
25385
25386         oss=$(comma_list $(osts_nodes))
25387
25388         dd if=/dev/urandom of=$file bs=1M count=2 ||
25389                 error "failed to create a file"
25390         stack_trap "rm -f $file"
25391         cancel_lru_locks osc
25392
25393         #lock 1
25394         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25395                 error "failed to read a file"
25396
25397 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25398         $LCTL set_param fail_loc=0x8000031f
25399
25400         cancel_lru_locks osc &
25401         sleep 1
25402
25403 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25404         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25405         #IO takes another lock, but matches the PENDING one
25406         #and places it to the IO RPC
25407         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25408                 error "failed to read a file with PENDING lock"
25409 }
25410 run_test 275 "Read on a canceled duplicate lock"
25411
25412 test_276() {
25413         remote_ost_nodsh && skip "remote OST with nodsh"
25414         local pid
25415
25416         do_facet ost1 "(while true; do \
25417                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25418                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25419         pid=$!
25420
25421         for LOOP in $(seq 20); do
25422                 stop ost1
25423                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25424         done
25425         kill -9 $pid
25426         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25427                 rm $TMP/sanity_276_pid"
25428 }
25429 run_test 276 "Race between mount and obd_statfs"
25430
25431 test_277() {
25432         $LCTL set_param ldlm.namespaces.*.lru_size=0
25433         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25434         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25435                           awk '/^used_mb/ { print $2 }')
25436         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25437         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25438                 oflag=direct conv=notrunc
25439         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25440                     awk '/^used_mb/ { print $2 }')
25441         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25442 }
25443 run_test 277 "Direct IO shall drop page cache"
25444
25445 test_278() {
25446         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25447         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25448         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25449                 skip "needs the same host for mdt1 mdt2" && return
25450
25451         local pid1
25452         local pid2
25453
25454 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25455         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25456         stop mds2 &
25457         pid2=$!
25458
25459         stop mds1
25460
25461         echo "Starting MDTs"
25462         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25463         wait $pid2
25464 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25465 #will return NULL
25466         do_facet mds2 $LCTL set_param fail_loc=0
25467
25468         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25469         wait_recovery_complete mds2
25470 }
25471 run_test 278 "Race starting MDS between MDTs stop/start"
25472
25473 test_280() {
25474         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25475                 skip "Need MGS version at least 2.13.52"
25476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25477         combined_mgs_mds || skip "needs combined MGS/MDT"
25478
25479         umount_client $MOUNT
25480 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25481         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25482
25483         mount_client $MOUNT &
25484         sleep 1
25485         stop mgs || error "stop mgs failed"
25486         #for a race mgs would crash
25487         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25488         # make sure we unmount client before remounting
25489         wait
25490         umount_client $MOUNT
25491         mount_client $MOUNT || error "mount client failed"
25492 }
25493 run_test 280 "Race between MGS umount and client llog processing"
25494
25495 cleanup_test_300() {
25496         trap 0
25497         umask $SAVE_UMASK
25498 }
25499 test_striped_dir() {
25500         local mdt_index=$1
25501         local stripe_count
25502         local stripe_index
25503
25504         mkdir -p $DIR/$tdir
25505
25506         SAVE_UMASK=$(umask)
25507         trap cleanup_test_300 RETURN EXIT
25508
25509         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25510                                                 $DIR/$tdir/striped_dir ||
25511                 error "set striped dir error"
25512
25513         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25514         [ "$mode" = "755" ] || error "expect 755 got $mode"
25515
25516         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25517                 error "getdirstripe failed"
25518         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25519         if [ "$stripe_count" != "2" ]; then
25520                 error "1:stripe_count is $stripe_count, expect 2"
25521         fi
25522         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25523         if [ "$stripe_count" != "2" ]; then
25524                 error "2:stripe_count is $stripe_count, expect 2"
25525         fi
25526
25527         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25528         if [ "$stripe_index" != "$mdt_index" ]; then
25529                 error "stripe_index is $stripe_index, expect $mdt_index"
25530         fi
25531
25532         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25533                 error "nlink error after create striped dir"
25534
25535         mkdir $DIR/$tdir/striped_dir/a
25536         mkdir $DIR/$tdir/striped_dir/b
25537
25538         stat $DIR/$tdir/striped_dir/a ||
25539                 error "create dir under striped dir failed"
25540         stat $DIR/$tdir/striped_dir/b ||
25541                 error "create dir under striped dir failed"
25542
25543         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25544                 error "nlink error after mkdir"
25545
25546         rmdir $DIR/$tdir/striped_dir/a
25547         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25548                 error "nlink error after rmdir"
25549
25550         rmdir $DIR/$tdir/striped_dir/b
25551         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25552                 error "nlink error after rmdir"
25553
25554         chattr +i $DIR/$tdir/striped_dir
25555         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25556                 error "immutable flags not working under striped dir!"
25557         chattr -i $DIR/$tdir/striped_dir
25558
25559         rmdir $DIR/$tdir/striped_dir ||
25560                 error "rmdir striped dir error"
25561
25562         cleanup_test_300
25563
25564         true
25565 }
25566
25567 test_300a() {
25568         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25569                 skip "skipped for lustre < 2.7.0"
25570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25572
25573         test_striped_dir 0 || error "failed on striped dir on MDT0"
25574         test_striped_dir 1 || error "failed on striped dir on MDT0"
25575 }
25576 run_test 300a "basic striped dir sanity test"
25577
25578 test_300b() {
25579         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25580                 skip "skipped for lustre < 2.7.0"
25581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25582         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25583
25584         local i
25585         local mtime1
25586         local mtime2
25587         local mtime3
25588
25589         test_mkdir $DIR/$tdir || error "mkdir fail"
25590         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25591                 error "set striped dir error"
25592         for i in {0..9}; do
25593                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25594                 sleep 1
25595                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25596                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25597                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25598                 sleep 1
25599                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25600                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25601                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25602         done
25603         true
25604 }
25605 run_test 300b "check ctime/mtime for striped dir"
25606
25607 test_300c() {
25608         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25609                 skip "skipped for lustre < 2.7.0"
25610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25612
25613         local file_count
25614
25615         mkdir_on_mdt0 $DIR/$tdir
25616         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25617                 error "set striped dir error"
25618
25619         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25620                 error "chown striped dir failed"
25621
25622         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25623                 error "create 5k files failed"
25624
25625         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25626
25627         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25628
25629         rm -rf $DIR/$tdir
25630 }
25631 run_test 300c "chown && check ls under striped directory"
25632
25633 test_300d() {
25634         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25635                 skip "skipped for lustre < 2.7.0"
25636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25638
25639         local stripe_count
25640         local file
25641
25642         mkdir -p $DIR/$tdir
25643         $LFS setstripe -c 2 $DIR/$tdir
25644
25645         #local striped directory
25646         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25647                 error "set striped dir error"
25648         #look at the directories for debug purposes
25649         ls -l $DIR/$tdir
25650         $LFS getdirstripe $DIR/$tdir
25651         ls -l $DIR/$tdir/striped_dir
25652         $LFS getdirstripe $DIR/$tdir/striped_dir
25653         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25654                 error "create 10 files failed"
25655
25656         #remote striped directory
25657         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25658                 error "set striped dir error"
25659         #look at the directories for debug purposes
25660         ls -l $DIR/$tdir
25661         $LFS getdirstripe $DIR/$tdir
25662         ls -l $DIR/$tdir/remote_striped_dir
25663         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25664         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25665                 error "create 10 files failed"
25666
25667         for file in $(find $DIR/$tdir); do
25668                 stripe_count=$($LFS getstripe -c $file)
25669                 [ $stripe_count -eq 2 ] ||
25670                         error "wrong stripe $stripe_count for $file"
25671         done
25672
25673         rm -rf $DIR/$tdir
25674 }
25675 run_test 300d "check default stripe under striped directory"
25676
25677 test_300e() {
25678         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25679                 skip "Need MDS version at least 2.7.55"
25680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25681         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25682
25683         local stripe_count
25684         local file
25685
25686         mkdir -p $DIR/$tdir
25687
25688         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25689                 error "set striped dir error"
25690
25691         touch $DIR/$tdir/striped_dir/a
25692         touch $DIR/$tdir/striped_dir/b
25693         touch $DIR/$tdir/striped_dir/c
25694
25695         mkdir $DIR/$tdir/striped_dir/dir_a
25696         mkdir $DIR/$tdir/striped_dir/dir_b
25697         mkdir $DIR/$tdir/striped_dir/dir_c
25698
25699         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25700                 error "set striped adir under striped dir error"
25701
25702         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25703                 error "set striped bdir under striped dir error"
25704
25705         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25706                 error "set striped cdir under striped dir error"
25707
25708         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25709                 error "rename dir under striped dir fails"
25710
25711         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25712                 error "rename dir under different stripes fails"
25713
25714         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25715                 error "rename file under striped dir should succeed"
25716
25717         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25718                 error "rename dir under striped dir should succeed"
25719
25720         rm -rf $DIR/$tdir
25721 }
25722 run_test 300e "check rename under striped directory"
25723
25724 test_300f() {
25725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25726         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25727         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25728                 skip "Need MDS version at least 2.7.55"
25729
25730         local stripe_count
25731         local file
25732
25733         rm -rf $DIR/$tdir
25734         mkdir -p $DIR/$tdir
25735
25736         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25737                 error "set striped dir error"
25738
25739         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25740                 error "set striped dir error"
25741
25742         touch $DIR/$tdir/striped_dir/a
25743         mkdir $DIR/$tdir/striped_dir/dir_a
25744         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25745                 error "create striped dir under striped dir fails"
25746
25747         touch $DIR/$tdir/striped_dir1/b
25748         mkdir $DIR/$tdir/striped_dir1/dir_b
25749         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25750                 error "create striped dir under striped dir fails"
25751
25752         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25753                 error "rename dir under different striped dir should fail"
25754
25755         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25756                 error "rename striped dir under diff striped dir should fail"
25757
25758         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25759                 error "rename file under diff striped dirs fails"
25760
25761         rm -rf $DIR/$tdir
25762 }
25763 run_test 300f "check rename cross striped directory"
25764
25765 test_300_check_default_striped_dir()
25766 {
25767         local dirname=$1
25768         local default_count=$2
25769         local default_index=$3
25770         local stripe_count
25771         local stripe_index
25772         local dir_stripe_index
25773         local dir
25774
25775         echo "checking $dirname $default_count $default_index"
25776         $LFS setdirstripe -D -c $default_count -i $default_index \
25777                                 -H all_char $DIR/$tdir/$dirname ||
25778                 error "set default stripe on striped dir error"
25779         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25780         [ $stripe_count -eq $default_count ] ||
25781                 error "expect $default_count get $stripe_count for $dirname"
25782
25783         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25784         [ $stripe_index -eq $default_index ] ||
25785                 error "expect $default_index get $stripe_index for $dirname"
25786
25787         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25788                                                 error "create dirs failed"
25789
25790         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25791         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25792         for dir in $(find $DIR/$tdir/$dirname/*); do
25793                 stripe_count=$($LFS getdirstripe -c $dir)
25794                 (( $stripe_count == $default_count )) ||
25795                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25796                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25797                 error "stripe count $default_count != $stripe_count for $dir"
25798
25799                 stripe_index=$($LFS getdirstripe -i $dir)
25800                 [ $default_index -eq -1 ] ||
25801                         [ $stripe_index -eq $default_index ] ||
25802                         error "$stripe_index != $default_index for $dir"
25803
25804                 #check default stripe
25805                 stripe_count=$($LFS getdirstripe -D -c $dir)
25806                 [ $stripe_count -eq $default_count ] ||
25807                 error "default count $default_count != $stripe_count for $dir"
25808
25809                 stripe_index=$($LFS getdirstripe -D -i $dir)
25810                 [ $stripe_index -eq $default_index ] ||
25811                 error "default index $default_index != $stripe_index for $dir"
25812         done
25813         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25814 }
25815
25816 test_300g() {
25817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25818         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25819                 skip "Need MDS version at least 2.7.55"
25820
25821         local dir
25822         local stripe_count
25823         local stripe_index
25824
25825         mkdir_on_mdt0 $DIR/$tdir
25826         mkdir $DIR/$tdir/normal_dir
25827
25828         #Checking when client cache stripe index
25829         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25830         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25831                 error "create striped_dir failed"
25832
25833         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25834                 error "create dir0 fails"
25835         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25836         [ $stripe_index -eq 0 ] ||
25837                 error "dir0 expect index 0 got $stripe_index"
25838
25839         mkdir $DIR/$tdir/striped_dir/dir1 ||
25840                 error "create dir1 fails"
25841         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25842         [ $stripe_index -eq 1 ] ||
25843                 error "dir1 expect index 1 got $stripe_index"
25844
25845         #check default stripe count/stripe index
25846         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25847         test_300_check_default_striped_dir normal_dir 1 0
25848         test_300_check_default_striped_dir normal_dir -1 1
25849         test_300_check_default_striped_dir normal_dir 2 -1
25850
25851         #delete default stripe information
25852         echo "delete default stripeEA"
25853         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25854                 error "set default stripe on striped dir error"
25855
25856         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25857         for dir in $(find $DIR/$tdir/normal_dir/*); do
25858                 stripe_count=$($LFS getdirstripe -c $dir)
25859                 [ $stripe_count -eq 0 ] ||
25860                         error "expect 1 get $stripe_count for $dir"
25861         done
25862 }
25863 run_test 300g "check default striped directory for normal directory"
25864
25865 test_300h() {
25866         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25867         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25868                 skip "Need MDS version at least 2.7.55"
25869
25870         local dir
25871         local stripe_count
25872
25873         mkdir $DIR/$tdir
25874         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25875                 error "set striped dir error"
25876
25877         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25878         test_300_check_default_striped_dir striped_dir 1 0
25879         test_300_check_default_striped_dir striped_dir -1 1
25880         test_300_check_default_striped_dir striped_dir 2 -1
25881
25882         #delete default stripe information
25883         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25884                 error "set default stripe on striped dir error"
25885
25886         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25887         for dir in $(find $DIR/$tdir/striped_dir/*); do
25888                 stripe_count=$($LFS getdirstripe -c $dir)
25889                 [ $stripe_count -eq 0 ] ||
25890                         error "expect 1 get $stripe_count for $dir"
25891         done
25892 }
25893 run_test 300h "check default striped directory for striped directory"
25894
25895 test_300i() {
25896         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25897         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25898         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25899                 skip "Need MDS version at least 2.7.55"
25900
25901         local stripe_count
25902         local file
25903
25904         mkdir $DIR/$tdir
25905
25906         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25907                 error "set striped dir error"
25908
25909         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25910                 error "create files under striped dir failed"
25911
25912         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25913                 error "set striped hashdir error"
25914
25915         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25916                 error "create dir0 under hash dir failed"
25917         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25918                 error "create dir1 under hash dir failed"
25919         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25920                 error "create dir2 under hash dir failed"
25921
25922         # unfortunately, we need to umount to clear dir layout cache for now
25923         # once we fully implement dir layout, we can drop this
25924         umount_client $MOUNT || error "umount failed"
25925         mount_client $MOUNT || error "mount failed"
25926
25927         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25928         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25929         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25930
25931         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25932                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25933                         error "create crush2 dir $tdir/hashdir/d3 failed"
25934                 $LFS find -H crush2 $DIR/$tdir/hashdir
25935                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25936                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25937
25938                 # mkdir with an invalid hash type (hash=fail_val) from client
25939                 # should be replaced on MDS with a valid (default) hash type
25940                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25941                 $LCTL set_param fail_loc=0x1901 fail_val=99
25942                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25943
25944                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25945                 local expect=$(do_facet mds1 \
25946                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25947                 [[ $hash == $expect ]] ||
25948                         error "d99 hash '$hash' != expected hash '$expect'"
25949         fi
25950
25951         #set the stripe to be unknown hash type on read
25952         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25953         $LCTL set_param fail_loc=0x1901 fail_val=99
25954         for ((i = 0; i < 10; i++)); do
25955                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25956                         error "stat f-$i failed"
25957                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25958         done
25959
25960         touch $DIR/$tdir/striped_dir/f0 &&
25961                 error "create under striped dir with unknown hash should fail"
25962
25963         $LCTL set_param fail_loc=0
25964
25965         umount_client $MOUNT || error "umount failed"
25966         mount_client $MOUNT || error "mount failed"
25967
25968         return 0
25969 }
25970 run_test 300i "client handle unknown hash type striped directory"
25971
25972 test_300j() {
25973         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25975         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25976                 skip "Need MDS version at least 2.7.55"
25977
25978         local stripe_count
25979         local file
25980
25981         mkdir $DIR/$tdir
25982
25983         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25984         $LCTL set_param fail_loc=0x1702
25985         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25986                 error "set striped dir error"
25987
25988         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25989                 error "create files under striped dir failed"
25990
25991         $LCTL set_param fail_loc=0
25992
25993         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25994
25995         return 0
25996 }
25997 run_test 300j "test large update record"
25998
25999 test_300k() {
26000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26002         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26003                 skip "Need MDS version at least 2.7.55"
26004
26005         # this test needs a huge transaction
26006         local kb
26007         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26008              osd*.$FSNAME-MDT0000.kbytestotal")
26009         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26010
26011         local stripe_count
26012         local file
26013
26014         mkdir $DIR/$tdir
26015
26016         #define OBD_FAIL_LARGE_STRIPE   0x1703
26017         $LCTL set_param fail_loc=0x1703
26018         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26019                 error "set striped dir error"
26020         $LCTL set_param fail_loc=0
26021
26022         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26023                 error "getstripeddir fails"
26024         rm -rf $DIR/$tdir/striped_dir ||
26025                 error "unlink striped dir fails"
26026
26027         return 0
26028 }
26029 run_test 300k "test large striped directory"
26030
26031 test_300l() {
26032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26033         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26034         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26035                 skip "Need MDS version at least 2.7.55"
26036
26037         local stripe_index
26038
26039         test_mkdir -p $DIR/$tdir/striped_dir
26040         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26041                         error "chown $RUNAS_ID failed"
26042         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26043                 error "set default striped dir failed"
26044
26045         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26046         $LCTL set_param fail_loc=0x80000158
26047         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26048
26049         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26050         [ $stripe_index -eq 1 ] ||
26051                 error "expect 1 get $stripe_index for $dir"
26052 }
26053 run_test 300l "non-root user to create dir under striped dir with stale layout"
26054
26055 test_300m() {
26056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26057         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26058         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26059                 skip "Need MDS version at least 2.7.55"
26060
26061         mkdir -p $DIR/$tdir/striped_dir
26062         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26063                 error "set default stripes dir error"
26064
26065         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26066
26067         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26068         [ $stripe_count -eq 0 ] ||
26069                         error "expect 0 get $stripe_count for a"
26070
26071         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26072                 error "set default stripes dir error"
26073
26074         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26075
26076         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26077         [ $stripe_count -eq 0 ] ||
26078                         error "expect 0 get $stripe_count for b"
26079
26080         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26081                 error "set default stripes dir error"
26082
26083         mkdir $DIR/$tdir/striped_dir/c &&
26084                 error "default stripe_index is invalid, mkdir c should fails"
26085
26086         rm -rf $DIR/$tdir || error "rmdir fails"
26087 }
26088 run_test 300m "setstriped directory on single MDT FS"
26089
26090 cleanup_300n() {
26091         local list=$(comma_list $(mdts_nodes))
26092
26093         trap 0
26094         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26095 }
26096
26097 test_300n() {
26098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26099         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26100         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26101                 skip "Need MDS version at least 2.7.55"
26102         remote_mds_nodsh && skip "remote MDS with nodsh"
26103
26104         local stripe_index
26105         local list=$(comma_list $(mdts_nodes))
26106
26107         trap cleanup_300n RETURN EXIT
26108         mkdir -p $DIR/$tdir
26109         chmod 777 $DIR/$tdir
26110         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26111                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26112                 error "create striped dir succeeds with gid=0"
26113
26114         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26115         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26116                 error "create striped dir fails with gid=-1"
26117
26118         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26119         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26120                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26121                 error "set default striped dir succeeds with gid=0"
26122
26123
26124         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26125         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26126                 error "set default striped dir fails with gid=-1"
26127
26128
26129         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26130         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26131                                         error "create test_dir fails"
26132         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26133                                         error "create test_dir1 fails"
26134         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26135                                         error "create test_dir2 fails"
26136         cleanup_300n
26137 }
26138 run_test 300n "non-root user to create dir under striped dir with default EA"
26139
26140 test_300o() {
26141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26142         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26143         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26144                 skip "Need MDS version at least 2.7.55"
26145
26146         local numfree1
26147         local numfree2
26148
26149         mkdir -p $DIR/$tdir
26150
26151         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26152         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26153         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26154                 skip "not enough free inodes $numfree1 $numfree2"
26155         fi
26156
26157         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26158         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26159         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26160                 skip "not enough free space $numfree1 $numfree2"
26161         fi
26162
26163         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26164                 error "setdirstripe fails"
26165
26166         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26167                 error "create dirs fails"
26168
26169         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26170         ls $DIR/$tdir/striped_dir > /dev/null ||
26171                 error "ls striped dir fails"
26172         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26173                 error "unlink big striped dir fails"
26174 }
26175 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26176
26177 test_300p() {
26178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26180         remote_mds_nodsh && skip "remote MDS with nodsh"
26181
26182         mkdir_on_mdt0 $DIR/$tdir
26183
26184         #define OBD_FAIL_OUT_ENOSPC     0x1704
26185         do_facet mds2 lctl set_param fail_loc=0x80001704
26186         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26187                  && error "create striped directory should fail"
26188
26189         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26190
26191         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26192         true
26193 }
26194 run_test 300p "create striped directory without space"
26195
26196 test_300q() {
26197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26199
26200         local fd=$(free_fd)
26201         local cmd="exec $fd<$tdir"
26202         cd $DIR
26203         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26204         eval $cmd
26205         cmd="exec $fd<&-"
26206         trap "eval $cmd" EXIT
26207         cd $tdir || error "cd $tdir fails"
26208         rmdir  ../$tdir || error "rmdir $tdir fails"
26209         mkdir local_dir && error "create dir succeeds"
26210         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26211         eval $cmd
26212         return 0
26213 }
26214 run_test 300q "create remote directory under orphan directory"
26215
26216 test_300r() {
26217         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26218                 skip "Need MDS version at least 2.7.55" && return
26219         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26220
26221         mkdir $DIR/$tdir
26222
26223         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26224                 error "set striped dir error"
26225
26226         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26227                 error "getstripeddir fails"
26228
26229         local stripe_count
26230         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26231                       awk '/lmv_stripe_count:/ { print $2 }')
26232
26233         [ $MDSCOUNT -ne $stripe_count ] &&
26234                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26235
26236         rm -rf $DIR/$tdir/striped_dir ||
26237                 error "unlink striped dir fails"
26238 }
26239 run_test 300r "test -1 striped directory"
26240
26241 test_300s_helper() {
26242         local count=$1
26243
26244         local stripe_dir=$DIR/$tdir/striped_dir.$count
26245
26246         $LFS mkdir -c $count $stripe_dir ||
26247                 error "lfs mkdir -c error"
26248
26249         $LFS getdirstripe $stripe_dir ||
26250                 error "lfs getdirstripe fails"
26251
26252         local stripe_count
26253         stripe_count=$($LFS getdirstripe $stripe_dir |
26254                       awk '/lmv_stripe_count:/ { print $2 }')
26255
26256         [ $count -ne $stripe_count ] &&
26257                 error_noexit "bad stripe count $stripe_count expected $count"
26258
26259         local dupe_stripes
26260         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26261                 awk '/0x/ {count[$1] += 1}; END {
26262                         for (idx in count) {
26263                                 if (count[idx]>1) {
26264                                         print "index " idx " count " count[idx]
26265                                 }
26266                         }
26267                 }')
26268
26269         if [[ -n "$dupe_stripes" ]] ; then
26270                 lfs getdirstripe $stripe_dir
26271                 error_noexit "Dupe MDT above: $dupe_stripes "
26272         fi
26273
26274         rm -rf $stripe_dir ||
26275                 error_noexit "unlink $stripe_dir fails"
26276 }
26277
26278 test_300s() {
26279         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26280                 skip "Need MDS version at least 2.7.55" && return
26281         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26282
26283         mkdir $DIR/$tdir
26284         for count in $(seq 2 $MDSCOUNT); do
26285                 test_300s_helper $count
26286         done
26287 }
26288 run_test 300s "test lfs mkdir -c without -i"
26289
26290 test_300t() {
26291         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26292                 skip "need MDS 2.14.55 or later"
26293         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26294
26295         local testdir="$DIR/$tdir/striped_dir"
26296         local dir1=$testdir/dir1
26297         local dir2=$testdir/dir2
26298
26299         mkdir -p $testdir
26300
26301         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26302                 error "failed to set default stripe count for $testdir"
26303
26304         mkdir $dir1
26305         local stripe_count=$($LFS getdirstripe -c $dir1)
26306
26307         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26308
26309         local max_count=$((MDSCOUNT - 1))
26310         local mdts=$(comma_list $(mdts_nodes))
26311
26312         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26313         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26314
26315         mkdir $dir2
26316         stripe_count=$($LFS getdirstripe -c $dir2)
26317
26318         (( $stripe_count == $max_count )) || error "wrong stripe count"
26319 }
26320 run_test 300t "test max_mdt_stripecount"
26321
26322 prepare_remote_file() {
26323         mkdir $DIR/$tdir/src_dir ||
26324                 error "create remote source failed"
26325
26326         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26327                  error "cp to remote source failed"
26328         touch $DIR/$tdir/src_dir/a
26329
26330         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26331                 error "create remote target dir failed"
26332
26333         touch $DIR/$tdir/tgt_dir/b
26334
26335         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26336                 error "rename dir cross MDT failed!"
26337
26338         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26339                 error "src_child still exists after rename"
26340
26341         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26342                 error "missing file(a) after rename"
26343
26344         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26345                 error "diff after rename"
26346 }
26347
26348 test_310a() {
26349         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26351
26352         local remote_file=$DIR/$tdir/tgt_dir/b
26353
26354         mkdir -p $DIR/$tdir
26355
26356         prepare_remote_file || error "prepare remote file failed"
26357
26358         #open-unlink file
26359         $OPENUNLINK $remote_file $remote_file ||
26360                 error "openunlink $remote_file failed"
26361         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26362 }
26363 run_test 310a "open unlink remote file"
26364
26365 test_310b() {
26366         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26368
26369         local remote_file=$DIR/$tdir/tgt_dir/b
26370
26371         mkdir -p $DIR/$tdir
26372
26373         prepare_remote_file || error "prepare remote file failed"
26374
26375         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26376         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26377         $CHECKSTAT -t file $remote_file || error "check file failed"
26378 }
26379 run_test 310b "unlink remote file with multiple links while open"
26380
26381 test_310c() {
26382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26383         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26384
26385         local remote_file=$DIR/$tdir/tgt_dir/b
26386
26387         mkdir -p $DIR/$tdir
26388
26389         prepare_remote_file || error "prepare remote file failed"
26390
26391         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26392         multiop_bg_pause $remote_file O_uc ||
26393                         error "mulitop failed for remote file"
26394         MULTIPID=$!
26395         $MULTIOP $DIR/$tfile Ouc
26396         kill -USR1 $MULTIPID
26397         wait $MULTIPID
26398 }
26399 run_test 310c "open-unlink remote file with multiple links"
26400
26401 #LU-4825
26402 test_311() {
26403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26404         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26405         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26406                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26407         remote_mds_nodsh && skip "remote MDS with nodsh"
26408
26409         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26410         local mdts=$(comma_list $(mdts_nodes))
26411
26412         mkdir -p $DIR/$tdir
26413         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26414         createmany -o $DIR/$tdir/$tfile. 1000
26415
26416         # statfs data is not real time, let's just calculate it
26417         old_iused=$((old_iused + 1000))
26418
26419         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26420                         osp.*OST0000*MDT0000.create_count")
26421         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26422                                 osp.*OST0000*MDT0000.max_create_count")
26423         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26424
26425         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26426         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26427         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26428
26429         unlinkmany $DIR/$tdir/$tfile. 1000
26430
26431         do_nodes $mdts "$LCTL set_param -n \
26432                         osp.*OST0000*.max_create_count=$max_count"
26433         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26434                 do_nodes $mdts "$LCTL set_param -n \
26435                                 osp.*OST0000*.create_count=$count"
26436         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26437                         grep "=0" && error "create_count is zero"
26438
26439         local new_iused
26440         for i in $(seq 120); do
26441                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26442                 # system may be too busy to destroy all objs in time, use
26443                 # a somewhat small value to not fail autotest
26444                 [ $((old_iused - new_iused)) -gt 400 ] && break
26445                 sleep 1
26446         done
26447
26448         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26449         [ $((old_iused - new_iused)) -gt 400 ] ||
26450                 error "objs not destroyed after unlink"
26451 }
26452 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26453
26454 zfs_get_objid()
26455 {
26456         local ost=$1
26457         local tf=$2
26458         local fid=($($LFS getstripe $tf | grep 0x))
26459         local seq=${fid[3]#0x}
26460         local objid=${fid[1]}
26461
26462         local vdevdir=$(dirname $(facet_vdevice $ost))
26463         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26464         local zfs_zapid=$(do_facet $ost $cmd |
26465                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26466                           awk '/Object/{getline; print $1}')
26467         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26468                           awk "/$objid = /"'{printf $3}')
26469
26470         echo $zfs_objid
26471 }
26472
26473 zfs_object_blksz() {
26474         local ost=$1
26475         local objid=$2
26476
26477         local vdevdir=$(dirname $(facet_vdevice $ost))
26478         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26479         local blksz=$(do_facet $ost $cmd $objid |
26480                       awk '/dblk/{getline; printf $4}')
26481
26482         case "${blksz: -1}" in
26483                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26484                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26485                 *) ;;
26486         esac
26487
26488         echo $blksz
26489 }
26490
26491 test_312() { # LU-4856
26492         remote_ost_nodsh && skip "remote OST with nodsh"
26493         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26494
26495         local max_blksz=$(do_facet ost1 \
26496                           $ZFS get -p recordsize $(facet_device ost1) |
26497                           awk '!/VALUE/{print $3}')
26498         local tf=$DIR/$tfile
26499
26500         $LFS setstripe -c1 $tf
26501         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26502
26503         # Get ZFS object id
26504         local zfs_objid=$(zfs_get_objid $facet $tf)
26505         # block size change by sequential overwrite
26506         local bs
26507
26508         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26509                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26510
26511                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26512                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26513         done
26514         rm -f $tf
26515
26516         $LFS setstripe -c1 $tf
26517         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26518
26519         # block size change by sequential append write
26520         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26521         zfs_objid=$(zfs_get_objid $facet $tf)
26522         local count
26523
26524         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26525                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26526                         oflag=sync conv=notrunc
26527
26528                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26529                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26530                         error "blksz error, actual $blksz, " \
26531                                 "expected: 2 * $count * $PAGE_SIZE"
26532         done
26533         rm -f $tf
26534
26535         # random write
26536         $LFS setstripe -c1 $tf
26537         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26538         zfs_objid=$(zfs_get_objid $facet $tf)
26539
26540         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26541         blksz=$(zfs_object_blksz $facet $zfs_objid)
26542         (( blksz == PAGE_SIZE )) ||
26543                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26544
26545         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26546         blksz=$(zfs_object_blksz $facet $zfs_objid)
26547         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26548
26549         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26550         blksz=$(zfs_object_blksz $facet $zfs_objid)
26551         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26552 }
26553 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26554
26555 test_313() {
26556         remote_ost_nodsh && skip "remote OST with nodsh"
26557
26558         local file=$DIR/$tfile
26559
26560         rm -f $file
26561         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26562
26563         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26564         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26565         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26566                 error "write should failed"
26567         do_facet ost1 "$LCTL set_param fail_loc=0"
26568         rm -f $file
26569 }
26570 run_test 313 "io should fail after last_rcvd update fail"
26571
26572 test_314() {
26573         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26574
26575         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26576         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26577         rm -f $DIR/$tfile
26578         wait_delete_completed
26579         do_facet ost1 "$LCTL set_param fail_loc=0"
26580 }
26581 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26582
26583 test_315() { # LU-618
26584         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26585
26586         local file=$DIR/$tfile
26587         rm -f $file
26588
26589         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26590                 error "multiop file write failed"
26591         $MULTIOP $file oO_RDONLY:r4063232_c &
26592         PID=$!
26593
26594         sleep 2
26595
26596         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26597         kill -USR1 $PID
26598
26599         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26600         rm -f $file
26601 }
26602 run_test 315 "read should be accounted"
26603
26604 test_316() {
26605         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26606         large_xattr_enabled || skip "ea_inode feature disabled"
26607
26608         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26609         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26610         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26611         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26612
26613         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26614 }
26615 run_test 316 "lfs migrate of file with large_xattr enabled"
26616
26617 test_317() {
26618         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26619                 skip "Need MDS version at least 2.11.53"
26620         if [ "$ost1_FSTYPE" == "zfs" ]; then
26621                 skip "LU-10370: no implementation for ZFS"
26622         fi
26623
26624         local trunc_sz
26625         local grant_blk_size
26626
26627         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26628                         awk '/grant_block_size:/ { print $2; exit; }')
26629         #
26630         # Create File of size 5M. Truncate it to below size's and verify
26631         # blocks count.
26632         #
26633         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26634                 error "Create file $DIR/$tfile failed"
26635         stack_trap "rm -f $DIR/$tfile" EXIT
26636
26637         for trunc_sz in 2097152 4097 4000 509 0; do
26638                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26639                         error "truncate $tfile to $trunc_sz failed"
26640                 local sz=$(stat --format=%s $DIR/$tfile)
26641                 local blk=$(stat --format=%b $DIR/$tfile)
26642                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26643                                      grant_blk_size) * 8))
26644
26645                 if [[ $blk -ne $trunc_blk ]]; then
26646                         $(which stat) $DIR/$tfile
26647                         error "Expected Block $trunc_blk got $blk for $tfile"
26648                 fi
26649
26650                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26651                         error "Expected Size $trunc_sz got $sz for $tfile"
26652         done
26653
26654         #
26655         # sparse file test
26656         # Create file with a hole and write actual 65536 bytes which aligned
26657         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26658         #
26659         local bs=65536
26660         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26661                 error "Create file : $DIR/$tfile"
26662
26663         #
26664         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26665         # blocks. The block count must drop to 8.
26666         #
26667         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26668                 ((bs - grant_blk_size) + 1)))
26669         $TRUNCATE $DIR/$tfile $trunc_sz ||
26670                 error "truncate $tfile to $trunc_sz failed"
26671
26672         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26673         sz=$(stat --format=%s $DIR/$tfile)
26674         blk=$(stat --format=%b $DIR/$tfile)
26675
26676         if [[ $blk -ne $trunc_bsz ]]; then
26677                 $(which stat) $DIR/$tfile
26678                 error "Expected Block $trunc_bsz got $blk for $tfile"
26679         fi
26680
26681         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26682                 error "Expected Size $trunc_sz got $sz for $tfile"
26683 }
26684 run_test 317 "Verify blocks get correctly update after truncate"
26685
26686 test_318() {
26687         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26688         local old_max_active=$($LCTL get_param -n \
26689                             ${llite_name}.max_read_ahead_async_active \
26690                             2>/dev/null)
26691
26692         $LCTL set_param llite.*.max_read_ahead_async_active=256
26693         local max_active=$($LCTL get_param -n \
26694                            ${llite_name}.max_read_ahead_async_active \
26695                            2>/dev/null)
26696         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26697
26698         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26699                 error "set max_read_ahead_async_active should succeed"
26700
26701         $LCTL set_param llite.*.max_read_ahead_async_active=512
26702         max_active=$($LCTL get_param -n \
26703                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26704         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26705
26706         # restore @max_active
26707         [ $old_max_active -ne 0 ] && $LCTL set_param \
26708                 llite.*.max_read_ahead_async_active=$old_max_active
26709
26710         local old_threshold=$($LCTL get_param -n \
26711                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26712         local max_per_file_mb=$($LCTL get_param -n \
26713                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26714
26715         local invalid=$(($max_per_file_mb + 1))
26716         $LCTL set_param \
26717                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26718                         && error "set $invalid should fail"
26719
26720         local valid=$(($invalid - 1))
26721         $LCTL set_param \
26722                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26723                         error "set $valid should succeed"
26724         local threshold=$($LCTL get_param -n \
26725                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26726         [ $threshold -eq $valid ] || error \
26727                 "expect threshold $valid got $threshold"
26728         $LCTL set_param \
26729                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26730 }
26731 run_test 318 "Verify async readahead tunables"
26732
26733 test_319() {
26734         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26735
26736         local before=$(date +%s)
26737         local evict
26738         local mdir=$DIR/$tdir
26739         local file=$mdir/xxx
26740
26741         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26742         touch $file
26743
26744 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26745         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26746         $LFS migrate -m1 $mdir &
26747
26748         sleep 1
26749         dd if=$file of=/dev/null
26750         wait
26751         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26752           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26753
26754         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26755 }
26756 run_test 319 "lost lease lock on migrate error"
26757
26758 test_360() {
26759         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
26760                 skip "Need OST version at least 2.15.58.96"
26761         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
26762
26763         check_set_fallocate_or_skip
26764         local param="osd-ldiskfs.delayed_unlink_mb"
26765         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
26766
26767         do_facet ost1 "$LCTL set_param $param=1MiB"
26768         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
26769
26770         mkdir $DIR/$tdir/
26771         do_facet ost1 $LCTL set_param debug=+inode
26772         do_facet ost1 $LCTL clear
26773         local files=100
26774
26775         for ((i = 0; i < $files; i++)); do
26776                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
26777                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
26778         done
26779         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
26780
26781         for ((i = 0; i < $files; i++)); do
26782                 unlink $DIR/$tdir/$tfile.$i ||
26783                         error "unlink $DIR/$tdir/$tfile.$i failed"
26784         done
26785
26786         local count=0
26787         local loop
26788
26789         for (( loop = 0; loop < 30 && count < min; loop++)); do
26790                 sleep 1
26791                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
26792                 echo "Count[$loop]: $count"
26793         done
26794         (( count >= min )) || error "$count < $min delayed iput after $loop s"
26795 }
26796 run_test 360 "ldiskfs unlink in a separate thread"
26797
26798 test_398a() { # LU-4198
26799         local ost1_imp=$(get_osc_import_name client ost1)
26800         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26801                          cut -d'.' -f2)
26802
26803         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26804         stack_trap "rm -f $DIR/$tfile"
26805         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26806
26807         # request a new lock on client
26808         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26809
26810         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26811         local lock_count=$($LCTL get_param -n \
26812                            ldlm.namespaces.$imp_name.lru_size)
26813         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26814
26815         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26816
26817         # no lock cached, should use lockless DIO and not enqueue new lock
26818         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26819         lock_count=$($LCTL get_param -n \
26820                      ldlm.namespaces.$imp_name.lru_size)
26821         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26822
26823         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26824
26825         # no lock cached, should use locked DIO append
26826         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26827                 conv=notrunc || error "DIO append failed"
26828         lock_count=$($LCTL get_param -n \
26829                      ldlm.namespaces.$imp_name.lru_size)
26830         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26831 }
26832 run_test 398a "direct IO should cancel lock otherwise lockless"
26833
26834 test_398b() { # LU-4198
26835         local before=$(date +%s)
26836         local njobs=4
26837         local size=48
26838
26839         which fio || skip_env "no fio installed"
26840         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26841         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26842
26843         # Single page, multiple pages, stripe size, 4*stripe size
26844         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26845                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26846                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26847                         --numjobs=$njobs --fallocate=none \
26848                         --iodepth=16 --allow_file_create=0 \
26849                         --size=$((size/njobs))M \
26850                         --filename=$DIR/$tfile &
26851                 bg_pid=$!
26852
26853                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26854                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26855                         --numjobs=$njobs --fallocate=none \
26856                         --iodepth=16 --allow_file_create=0 \
26857                         --size=$((size/njobs))M \
26858                         --filename=$DIR/$tfile || true
26859                 wait $bg_pid
26860         done
26861
26862         evict=$(do_facet client $LCTL get_param \
26863                 osc.$FSNAME-OST*-osc-*/state |
26864             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26865
26866         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26867                 (do_facet client $LCTL get_param \
26868                         osc.$FSNAME-OST*-osc-*/state;
26869                     error "eviction happened: $evict before:$before")
26870
26871         rm -f $DIR/$tfile
26872 }
26873 run_test 398b "DIO and buffer IO race"
26874
26875 test_398c() { # LU-4198
26876         local ost1_imp=$(get_osc_import_name client ost1)
26877         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26878                          cut -d'.' -f2)
26879
26880         which fio || skip_env "no fio installed"
26881
26882         saved_debug=$($LCTL get_param -n debug)
26883         $LCTL set_param debug=0
26884
26885         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26886         ((size /= 1024)) # by megabytes
26887         ((size /= 2)) # write half of the OST at most
26888         [ $size -gt 40 ] && size=40 #reduce test time anyway
26889
26890         $LFS setstripe -c 1 $DIR/$tfile
26891
26892         # it seems like ldiskfs reserves more space than necessary if the
26893         # writing blocks are not mapped, so it extends the file firstly
26894         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26895         cancel_lru_locks osc
26896
26897         # clear and verify rpc_stats later
26898         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26899
26900         local njobs=4
26901         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26902         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26903                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26904                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26905                 --filename=$DIR/$tfile
26906         [ $? -eq 0 ] || error "fio write error"
26907
26908         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26909                 error "Locks were requested while doing AIO"
26910
26911         # get the percentage of 1-page I/O
26912         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26913                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26914                 awk '{print $7}')
26915         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26916
26917         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26918         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26919                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26920                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26921                 --filename=$DIR/$tfile
26922         [ $? -eq 0 ] || error "fio mixed read write error"
26923
26924         echo "AIO with large block size ${size}M"
26925         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26926                 --numjobs=1 --fallocate=none --ioengine=libaio \
26927                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26928                 --filename=$DIR/$tfile
26929         [ $? -eq 0 ] || error "fio large block size failed"
26930
26931         rm -f $DIR/$tfile
26932         $LCTL set_param debug="$saved_debug"
26933 }
26934 run_test 398c "run fio to test AIO"
26935
26936 test_398d() { #  LU-13846
26937         which aiocp || skip_env "no aiocp installed"
26938         local aio_file=$DIR/$tfile.aio
26939
26940         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26941
26942         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26943         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26944         stack_trap "rm -f $DIR/$tfile $aio_file"
26945
26946         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26947
26948         # test memory unaligned aio
26949         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26950                 error "unaligned aio failed"
26951         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26952
26953         rm -f $DIR/$tfile $aio_file
26954 }
26955 run_test 398d "run aiocp to verify block size > stripe size"
26956
26957 test_398e() {
26958         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26959         touch $DIR/$tfile.new
26960         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26961 }
26962 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26963
26964 test_398f() { #  LU-14687
26965         which aiocp || skip_env "no aiocp installed"
26966         local aio_file=$DIR/$tfile.aio
26967
26968         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26969
26970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26971         stack_trap "rm -f $DIR/$tfile $aio_file"
26972
26973         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26974         $LCTL set_param fail_loc=0x1418
26975         # make sure we don't crash and fail properly
26976         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26977                 error "aio with page allocation failure succeeded"
26978         $LCTL set_param fail_loc=0
26979         diff $DIR/$tfile $aio_file
26980         [[ $? != 0 ]] || error "no diff after failed aiocp"
26981 }
26982 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26983
26984 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26985 # stripe and i/o size must be > stripe size
26986 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26987 # single RPC in flight.  This test shows async DIO submission is working by
26988 # showing multiple RPCs in flight.
26989 test_398g() { #  LU-13798
26990         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26991
26992         # We need to do some i/o first to acquire enough grant to put our RPCs
26993         # in flight; otherwise a new connection may not have enough grant
26994         # available
26995         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26996                 error "parallel dio failed"
26997         stack_trap "rm -f $DIR/$tfile"
26998
26999         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27000         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27001         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27002         stack_trap "$LCTL set_param -n $pages_per_rpc"
27003
27004         # Recreate file so it's empty
27005         rm -f $DIR/$tfile
27006         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27007         #Pause rpc completion to guarantee we see multiple rpcs in flight
27008         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27009         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27010         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27011
27012         # Clear rpc stats
27013         $LCTL set_param osc.*.rpc_stats=c
27014
27015         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27016                 error "parallel dio failed"
27017         stack_trap "rm -f $DIR/$tfile"
27018
27019         $LCTL get_param osc.*-OST0000-*.rpc_stats
27020         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27021                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27022                 grep "8:" | awk '{print $8}')
27023         # We look at the "8 rpcs in flight" field, and verify A) it is present
27024         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27025         # as expected for an 8M DIO to a file with 1M stripes.
27026         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
27027
27028         # Verify turning off parallel dio works as expected
27029         # Clear rpc stats
27030         $LCTL set_param osc.*.rpc_stats=c
27031         $LCTL set_param llite.*.parallel_dio=0
27032         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27033
27034         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27035                 error "dio with parallel dio disabled failed"
27036
27037         # Ideally, we would see only one RPC in flight here, but there is an
27038         # unavoidable race between i/o completion and RPC in flight counting,
27039         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27040         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27041         # So instead we just verify it's always < 8.
27042         $LCTL get_param osc.*-OST0000-*.rpc_stats
27043         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27044                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27045                 grep '^$' -B1 | grep . | awk '{print $1}')
27046         [ $ret != "8:" ] ||
27047                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27048 }
27049 run_test 398g "verify parallel dio async RPC submission"
27050
27051 test_398h() { #  LU-13798
27052         local dio_file=$DIR/$tfile.dio
27053
27054         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27055
27056         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27057         stack_trap "rm -f $DIR/$tfile $dio_file"
27058
27059         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27060                 error "parallel dio failed"
27061         diff $DIR/$tfile $dio_file
27062         [[ $? == 0 ]] || error "file diff after aiocp"
27063 }
27064 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27065
27066 test_398i() { #  LU-13798
27067         local dio_file=$DIR/$tfile.dio
27068
27069         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27070
27071         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27072         stack_trap "rm -f $DIR/$tfile $dio_file"
27073
27074         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27075         $LCTL set_param fail_loc=0x1418
27076         # make sure we don't crash and fail properly
27077         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27078                 error "parallel dio page allocation failure succeeded"
27079         diff $DIR/$tfile $dio_file
27080         [[ $? != 0 ]] || error "no diff after failed aiocp"
27081 }
27082 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27083
27084 test_398j() { #  LU-13798
27085         # Stripe size > RPC size but less than i/o size tests split across
27086         # stripes and RPCs for individual i/o op
27087         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27088
27089         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27090         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27091         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27092         stack_trap "$LCTL set_param -n $pages_per_rpc"
27093
27094         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27095                 error "parallel dio write failed"
27096         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27097
27098         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27099                 error "parallel dio read failed"
27100         diff $DIR/$tfile $DIR/$tfile.2
27101         [[ $? == 0 ]] || error "file diff after parallel dio read"
27102 }
27103 run_test 398j "test parallel dio where stripe size > rpc_size"
27104
27105 test_398k() { #  LU-13798
27106         wait_delete_completed
27107         wait_mds_ost_sync
27108
27109         # 4 stripe file; we will cause out of space on OST0
27110         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27111
27112         # Fill OST0 (if it's not too large)
27113         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27114                    head -n1)
27115         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27116                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27117         fi
27118         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27119         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27120                 error "dd should fill OST0"
27121         stack_trap "rm -f $DIR/$tfile.1"
27122
27123         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27124         err=$?
27125
27126         ls -la $DIR/$tfile
27127         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27128                 error "file is not 0 bytes in size"
27129
27130         # dd above should not succeed, but don't error until here so we can
27131         # get debug info above
27132         [[ $err != 0 ]] ||
27133                 error "parallel dio write with enospc succeeded"
27134         stack_trap "rm -f $DIR/$tfile"
27135 }
27136 run_test 398k "test enospc on first stripe"
27137
27138 test_398l() { #  LU-13798
27139         wait_delete_completed
27140         wait_mds_ost_sync
27141
27142         # 4 stripe file; we will cause out of space on OST0
27143         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27144         # happens on the second i/o chunk we issue
27145         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27146
27147         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27148         stack_trap "rm -f $DIR/$tfile"
27149
27150         # Fill OST0 (if it's not too large)
27151         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27152                    head -n1)
27153         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27154                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27155         fi
27156         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27157         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27158                 error "dd should fill OST0"
27159         stack_trap "rm -f $DIR/$tfile.1"
27160
27161         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27162         err=$?
27163         stack_trap "rm -f $DIR/$tfile.2"
27164
27165         # Check that short write completed as expected
27166         ls -la $DIR/$tfile.2
27167         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27168                 error "file is not 1M in size"
27169
27170         # dd above should not succeed, but don't error until here so we can
27171         # get debug info above
27172         [[ $err != 0 ]] ||
27173                 error "parallel dio write with enospc succeeded"
27174
27175         # Truncate source file to same length as output file and diff them
27176         $TRUNCATE $DIR/$tfile 1048576
27177         diff $DIR/$tfile $DIR/$tfile.2
27178         [[ $? == 0 ]] || error "data incorrect after short write"
27179 }
27180 run_test 398l "test enospc on intermediate stripe/RPC"
27181
27182 test_398m() { #  LU-13798
27183         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27184
27185         # Set up failure on OST0, the first stripe:
27186         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27187         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27188         # OST0 is on ost1, OST1 is on ost2.
27189         # So this fail_val specifies OST0
27190         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27191         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27192
27193         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27194                 error "parallel dio write with failure on first stripe succeeded"
27195         stack_trap "rm -f $DIR/$tfile"
27196         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27197
27198         # Place data in file for read
27199         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27200                 error "parallel dio write failed"
27201
27202         # Fail read on OST0, first stripe
27203         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27204         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27205         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27206                 error "parallel dio read with error on first stripe succeeded"
27207         rm -f $DIR/$tfile.2
27208         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27209
27210         # Switch to testing on OST1, second stripe
27211         # Clear file contents, maintain striping
27212         echo > $DIR/$tfile
27213         # Set up failure on OST1, second stripe:
27214         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27215         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27216
27217         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27218                 error "parallel dio write with failure on second stripe succeeded"
27219         stack_trap "rm -f $DIR/$tfile"
27220         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27221
27222         # Place data in file for read
27223         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27224                 error "parallel dio write failed"
27225
27226         # Fail read on OST1, second stripe
27227         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27228         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27229         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27230                 error "parallel dio read with error on second stripe succeeded"
27231         rm -f $DIR/$tfile.2
27232         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27233 }
27234 run_test 398m "test RPC failures with parallel dio"
27235
27236 # Parallel submission of DIO should not cause problems for append, but it's
27237 # important to verify.
27238 test_398n() { #  LU-13798
27239         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27240
27241         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27242                 error "dd to create source file failed"
27243         stack_trap "rm -f $DIR/$tfile"
27244
27245         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27246                 error "parallel dio write with failure on second stripe succeeded"
27247         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27248         diff $DIR/$tfile $DIR/$tfile.1
27249         [[ $? == 0 ]] || error "data incorrect after append"
27250
27251 }
27252 run_test 398n "test append with parallel DIO"
27253
27254 test_398o() {
27255         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27256 }
27257 run_test 398o "right kms with DIO"
27258
27259 test_398p()
27260 {
27261         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27262         which aiocp || skip_env "no aiocp installed"
27263
27264         local stripe_size=$((1024 * 1024)) #1 MiB
27265         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27266         local file_size=$((25 * stripe_size))
27267
27268         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27269         stack_trap "rm -f $DIR/$tfile*"
27270         # Just a bit bigger than the largest size in the test set below
27271         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27272                 error "buffered i/o to create file failed"
27273
27274         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27275                 $((stripe_size * 4)); do
27276
27277                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27278
27279                 echo "bs: $bs, file_size $file_size"
27280                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27281                         $DIR/$tfile.1 $DIR/$tfile.2 &
27282                 pid_dio1=$!
27283                 # Buffered I/O with similar but not the same block size
27284                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27285                         conv=notrunc &
27286                 pid_bio2=$!
27287                 wait $pid_dio1
27288                 rc1=$?
27289                 wait $pid_bio2
27290                 rc2=$?
27291                 if (( rc1 != 0 )); then
27292                         error "aio copy 1 w/bsize $bs failed: $rc1"
27293                 fi
27294                 if (( rc2 != 0 )); then
27295                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27296                 fi
27297
27298                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27299                         error "size incorrect"
27300                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27301                         error "files differ, bsize $bs"
27302                 rm -f $DIR/$tfile.2
27303         done
27304 }
27305 run_test 398p "race aio with buffered i/o"
27306
27307 test_398q()
27308 {
27309         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27310
27311         local stripe_size=$((1024 * 1024)) #1 MiB
27312         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27313         local file_size=$((25 * stripe_size))
27314
27315         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27316         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27317
27318         # Just a bit bigger than the largest size in the test set below
27319         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27320                 error "buffered i/o to create file failed"
27321
27322         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27323                 $((stripe_size * 4)); do
27324
27325                 echo "bs: $bs, file_size $file_size"
27326                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27327                         conv=notrunc oflag=direct iflag=direct &
27328                 pid_dio1=$!
27329                 # Buffered I/O with similar but not the same block size
27330                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27331                         conv=notrunc &
27332                 pid_bio2=$!
27333                 wait $pid_dio1
27334                 rc1=$?
27335                 wait $pid_bio2
27336                 rc2=$?
27337                 if (( rc1 != 0 )); then
27338                         error "dio copy 1 w/bsize $bs failed: $rc1"
27339                 fi
27340                 if (( rc2 != 0 )); then
27341                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27342                 fi
27343
27344                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27345                         error "size incorrect"
27346                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27347                         error "files differ, bsize $bs"
27348         done
27349
27350         rm -f $DIR/$tfile*
27351 }
27352 run_test 398q "race dio with buffered i/o"
27353
27354 test_fake_rw() {
27355         local read_write=$1
27356         if [ "$read_write" = "write" ]; then
27357                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27358         elif [ "$read_write" = "read" ]; then
27359                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27360         else
27361                 error "argument error"
27362         fi
27363
27364         # turn off debug for performance testing
27365         local saved_debug=$($LCTL get_param -n debug)
27366         $LCTL set_param debug=0
27367
27368         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27369
27370         # get ost1 size - $FSNAME-OST0000
27371         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27372         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27373         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27374
27375         if [ "$read_write" = "read" ]; then
27376                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27377         fi
27378
27379         local start_time=$(date +%s.%N)
27380         $dd_cmd bs=1M count=$blocks oflag=sync ||
27381                 error "real dd $read_write error"
27382         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27383
27384         if [ "$read_write" = "write" ]; then
27385                 rm -f $DIR/$tfile
27386         fi
27387
27388         # define OBD_FAIL_OST_FAKE_RW           0x238
27389         do_facet ost1 $LCTL set_param fail_loc=0x238
27390
27391         local start_time=$(date +%s.%N)
27392         $dd_cmd bs=1M count=$blocks oflag=sync ||
27393                 error "fake dd $read_write error"
27394         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27395
27396         if [ "$read_write" = "write" ]; then
27397                 # verify file size
27398                 cancel_lru_locks osc
27399                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27400                         error "$tfile size not $blocks MB"
27401         fi
27402         do_facet ost1 $LCTL set_param fail_loc=0
27403
27404         echo "fake $read_write $duration_fake vs. normal $read_write" \
27405                 "$duration in seconds"
27406         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27407                 error_not_in_vm "fake write is slower"
27408
27409         $LCTL set_param -n debug="$saved_debug"
27410         rm -f $DIR/$tfile
27411 }
27412 test_399a() { # LU-7655 for OST fake write
27413         remote_ost_nodsh && skip "remote OST with nodsh"
27414
27415         test_fake_rw write
27416 }
27417 run_test 399a "fake write should not be slower than normal write"
27418
27419 test_399b() { # LU-8726 for OST fake read
27420         remote_ost_nodsh && skip "remote OST with nodsh"
27421         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27422                 skip_env "ldiskfs only test"
27423         fi
27424
27425         test_fake_rw read
27426 }
27427 run_test 399b "fake read should not be slower than normal read"
27428
27429 test_400a() { # LU-1606, was conf-sanity test_74
27430         if ! which $CC > /dev/null 2>&1; then
27431                 skip_env "$CC is not installed"
27432         fi
27433
27434         local extra_flags=''
27435         local out=$TMP/$tfile
27436         local prefix=/usr/include/lustre
27437         local prog
27438
27439         # Oleg removes .c files in his test rig so test if any c files exist
27440         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27441                 skip_env "Needed .c test files are missing"
27442
27443         if ! [[ -d $prefix ]]; then
27444                 # Assume we're running in tree and fixup the include path.
27445                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27446                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27447                 extra_flags+=" -L$LUSTRE/utils/.libs"
27448         fi
27449
27450         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27451                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27452                         error "client api broken"
27453         done
27454         rm -f $out
27455 }
27456 run_test 400a "Lustre client api program can compile and link"
27457
27458 test_400b() { # LU-1606, LU-5011
27459         local header
27460         local out=$TMP/$tfile
27461         local prefix=/usr/include/linux/lustre
27462
27463         # We use a hard coded prefix so that this test will not fail
27464         # when run in tree. There are headers in lustre/include/lustre/
27465         # that are not packaged (like lustre_idl.h) and have more
27466         # complicated include dependencies (like config.h and lnet/types.h).
27467         # Since this test about correct packaging we just skip them when
27468         # they don't exist (see below) rather than try to fixup cppflags.
27469
27470         if ! which $CC > /dev/null 2>&1; then
27471                 skip_env "$CC is not installed"
27472         fi
27473
27474         for header in $prefix/*.h; do
27475                 if ! [[ -f "$header" ]]; then
27476                         continue
27477                 fi
27478
27479                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27480                         continue # lustre_ioctl.h is internal header
27481                 fi
27482
27483                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27484                         error "cannot compile '$header'"
27485         done
27486         rm -f $out
27487 }
27488 run_test 400b "packaged headers can be compiled"
27489
27490 test_401a() { #LU-7437
27491         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27492         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27493
27494         #count the number of parameters by "list_param -R"
27495         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27496         #count the number of parameters by listing proc files
27497         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27498         echo "proc_dirs='$proc_dirs'"
27499         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27500         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27501                       sort -u | wc -l)
27502
27503         [ $params -eq $procs ] ||
27504                 error "found $params parameters vs. $procs proc files"
27505
27506         # test the list_param -D option only returns directories
27507         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27508         #count the number of parameters by listing proc directories
27509         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27510                 sort -u | wc -l)
27511
27512         [ $params -eq $procs ] ||
27513                 error "found $params parameters vs. $procs proc files"
27514 }
27515 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27516
27517 test_401b() {
27518         # jobid_var may not allow arbitrary values, so use jobid_name
27519         # if available
27520         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27521                 local testname=jobid_name tmp='testing%p'
27522         else
27523                 local testname=jobid_var tmp=testing
27524         fi
27525
27526         local save=$($LCTL get_param -n $testname)
27527
27528         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27529                 error "no error returned when setting bad parameters"
27530
27531         local jobid_new=$($LCTL get_param -n foe $testname baz)
27532         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27533
27534         $LCTL set_param -n fog=bam $testname=$save bat=fog
27535         local jobid_old=$($LCTL get_param -n foe $testname bag)
27536         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27537 }
27538 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27539
27540 test_401c() {
27541         # jobid_var may not allow arbitrary values, so use jobid_name
27542         # if available
27543         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27544                 local testname=jobid_name
27545         else
27546                 local testname=jobid_var
27547         fi
27548
27549         local jobid_var_old=$($LCTL get_param -n $testname)
27550         local jobid_var_new
27551
27552         $LCTL set_param $testname= &&
27553                 error "no error returned for 'set_param a='"
27554
27555         jobid_var_new=$($LCTL get_param -n $testname)
27556         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27557                 error "$testname was changed by setting without value"
27558
27559         $LCTL set_param $testname &&
27560                 error "no error returned for 'set_param a'"
27561
27562         jobid_var_new=$($LCTL get_param -n $testname)
27563         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27564                 error "$testname was changed by setting without value"
27565 }
27566 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27567
27568 test_401d() {
27569         # jobid_var may not allow arbitrary values, so use jobid_name
27570         # if available
27571         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27572                 local testname=jobid_name new_value='foo=bar%p'
27573         else
27574                 local testname=jobid_var new_valuie=foo=bar
27575         fi
27576
27577         local jobid_var_old=$($LCTL get_param -n $testname)
27578         local jobid_var_new
27579
27580         $LCTL set_param $testname=$new_value ||
27581                 error "'set_param a=b' did not accept a value containing '='"
27582
27583         jobid_var_new=$($LCTL get_param -n $testname)
27584         [[ "$jobid_var_new" == "$new_value" ]] ||
27585                 error "'set_param a=b' failed on a value containing '='"
27586
27587         # Reset the $testname to test the other format
27588         $LCTL set_param $testname=$jobid_var_old
27589         jobid_var_new=$($LCTL get_param -n $testname)
27590         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27591                 error "failed to reset $testname"
27592
27593         $LCTL set_param $testname $new_value ||
27594                 error "'set_param a b' did not accept a value containing '='"
27595
27596         jobid_var_new=$($LCTL get_param -n $testname)
27597         [[ "$jobid_var_new" == "$new_value" ]] ||
27598                 error "'set_param a b' failed on a value containing '='"
27599
27600         $LCTL set_param $testname $jobid_var_old
27601         jobid_var_new=$($LCTL get_param -n $testname)
27602         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27603                 error "failed to reset $testname"
27604 }
27605 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27606
27607 test_401e() { # LU-14779
27608         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27609                 error "lctl list_param MGC* failed"
27610         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27611         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27612                 error "lctl get_param lru_size failed"
27613 }
27614 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27615
27616 test_402() {
27617         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27618         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27619                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27620         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27621                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27622                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27623         remote_mds_nodsh && skip "remote MDS with nodsh"
27624
27625         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27626 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27627         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27628         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27629                 echo "Touch failed - OK"
27630 }
27631 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27632
27633 test_403() {
27634         local file1=$DIR/$tfile.1
27635         local file2=$DIR/$tfile.2
27636         local tfile=$TMP/$tfile
27637
27638         rm -f $file1 $file2 $tfile
27639
27640         touch $file1
27641         ln $file1 $file2
27642
27643         # 30 sec OBD_TIMEOUT in ll_getattr()
27644         # right before populating st_nlink
27645         $LCTL set_param fail_loc=0x80001409
27646         stat -c %h $file1 > $tfile &
27647
27648         # create an alias, drop all locks and reclaim the dentry
27649         < $file2
27650         cancel_lru_locks mdc
27651         cancel_lru_locks osc
27652         sysctl -w vm.drop_caches=2
27653
27654         wait
27655
27656         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27657
27658         rm -f $tfile $file1 $file2
27659 }
27660 run_test 403 "i_nlink should not drop to zero due to aliasing"
27661
27662 test_404() { # LU-6601
27663         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27664                 skip "Need server version newer than 2.8.52"
27665         remote_mds_nodsh && skip "remote MDS with nodsh"
27666
27667         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27668                 awk '/osp .*-osc-MDT/ { print $4}')
27669
27670         local osp
27671         for osp in $mosps; do
27672                 echo "Deactivate: " $osp
27673                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27674                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27675                         awk -vp=$osp '$4 == p { print $2 }')
27676                 [ $stat = IN ] || {
27677                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27678                         error "deactivate error"
27679                 }
27680                 echo "Activate: " $osp
27681                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27682                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27683                         awk -vp=$osp '$4 == p { print $2 }')
27684                 [ $stat = UP ] || {
27685                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27686                         error "activate error"
27687                 }
27688         done
27689 }
27690 run_test 404 "validate manual {de}activated works properly for OSPs"
27691
27692 test_405() {
27693         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27694         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27695                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27696                         skip "Layout swap lock is not supported"
27697
27698         check_swap_layouts_support
27699         check_swap_layout_no_dom $DIR
27700
27701         test_mkdir $DIR/$tdir
27702         swap_lock_test -d $DIR/$tdir ||
27703                 error "One layout swap locked test failed"
27704 }
27705 run_test 405 "Various layout swap lock tests"
27706
27707 test_406() {
27708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27709         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27710         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27712         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27713                 skip "Need MDS version at least 2.8.50"
27714
27715         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27716         local test_pool=$TESTNAME
27717
27718         pool_add $test_pool || error "pool_add failed"
27719         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27720                 error "pool_add_targets failed"
27721
27722         save_layout_restore_at_exit $MOUNT
27723
27724         # parent set default stripe count only, child will stripe from both
27725         # parent and fs default
27726         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27727                 error "setstripe $MOUNT failed"
27728         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27729         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27730         for i in $(seq 10); do
27731                 local f=$DIR/$tdir/$tfile.$i
27732                 touch $f || error "touch failed"
27733                 local count=$($LFS getstripe -c $f)
27734                 [ $count -eq $OSTCOUNT ] ||
27735                         error "$f stripe count $count != $OSTCOUNT"
27736                 local offset=$($LFS getstripe -i $f)
27737                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27738                 local size=$($LFS getstripe -S $f)
27739                 [ $size -eq $((def_stripe_size * 2)) ] ||
27740                         error "$f stripe size $size != $((def_stripe_size * 2))"
27741                 local pool=$($LFS getstripe -p $f)
27742                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27743         done
27744
27745         # change fs default striping, delete parent default striping, now child
27746         # will stripe from new fs default striping only
27747         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27748                 error "change $MOUNT default stripe failed"
27749         $LFS setstripe -c 0 $DIR/$tdir ||
27750                 error "delete $tdir default stripe failed"
27751         for i in $(seq 11 20); do
27752                 local f=$DIR/$tdir/$tfile.$i
27753                 touch $f || error "touch $f failed"
27754                 local count=$($LFS getstripe -c $f)
27755                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27756                 local offset=$($LFS getstripe -i $f)
27757                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27758                 local size=$($LFS getstripe -S $f)
27759                 [ $size -eq $def_stripe_size ] ||
27760                         error "$f stripe size $size != $def_stripe_size"
27761                 local pool=$($LFS getstripe -p $f)
27762                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27763         done
27764
27765         unlinkmany $DIR/$tdir/$tfile. 1 20
27766
27767         local f=$DIR/$tdir/$tfile
27768         pool_remove_all_targets $test_pool $f
27769         pool_remove $test_pool $f
27770 }
27771 run_test 406 "DNE support fs default striping"
27772
27773 test_407() {
27774         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27775         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27776                 skip "Need MDS version at least 2.8.55"
27777         remote_mds_nodsh && skip "remote MDS with nodsh"
27778
27779         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27780                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27781         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27782                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27783         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27784
27785         #define OBD_FAIL_DT_TXN_STOP    0x2019
27786         for idx in $(seq $MDSCOUNT); do
27787                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27788         done
27789         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27790         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27791                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27792         true
27793 }
27794 run_test 407 "transaction fail should cause operation fail"
27795
27796 test_408() {
27797         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27798
27799         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27800         lctl set_param fail_loc=0x8000040a
27801         # let ll_prepare_partial_page() fail
27802         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27803
27804         rm -f $DIR/$tfile
27805
27806         # create at least 100 unused inodes so that
27807         # shrink_icache_memory(0) should not return 0
27808         touch $DIR/$tfile-{0..100}
27809         rm -f $DIR/$tfile-{0..100}
27810         sync
27811
27812         echo 2 > /proc/sys/vm/drop_caches
27813 }
27814 run_test 408 "drop_caches should not hang due to page leaks"
27815
27816 test_409()
27817 {
27818         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27819
27820         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27821         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27822         touch $DIR/$tdir/guard || error "(2) Fail to create"
27823
27824         local PREFIX=$(str_repeat 'A' 128)
27825         echo "Create 1K hard links start at $(date)"
27826         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27827                 error "(3) Fail to hard link"
27828
27829         echo "Links count should be right although linkEA overflow"
27830         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27831         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27832         [ $linkcount -eq 1001 ] ||
27833                 error "(5) Unexpected hard links count: $linkcount"
27834
27835         echo "List all links start at $(date)"
27836         ls -l $DIR/$tdir/foo > /dev/null ||
27837                 error "(6) Fail to list $DIR/$tdir/foo"
27838
27839         echo "Unlink hard links start at $(date)"
27840         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27841                 error "(7) Fail to unlink"
27842         echo "Unlink hard links finished at $(date)"
27843 }
27844 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27845
27846 test_410()
27847 {
27848         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27849                 skip "Need client version at least 2.9.59"
27850         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27851                 skip "Need MODULES build"
27852
27853         # Create a file, and stat it from the kernel
27854         local testfile=$DIR/$tfile
27855         touch $testfile
27856
27857         local run_id=$RANDOM
27858         local my_ino=$(stat --format "%i" $testfile)
27859
27860         # Try to insert the module. This will always fail as the
27861         # module is designed to not be inserted.
27862         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27863             &> /dev/null
27864
27865         # Anything but success is a test failure
27866         dmesg | grep -q \
27867             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27868             error "no inode match"
27869 }
27870 run_test 410 "Test inode number returned from kernel thread"
27871
27872 cleanup_test411_cgroup() {
27873         trap 0
27874         cat $1/memory.stat
27875         rmdir "$1"
27876 }
27877
27878 test_411a() {
27879         local cg_basedir=/sys/fs/cgroup/memory
27880         # LU-9966
27881         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27882                 skip "no setup for cgroup"
27883
27884         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27885                 error "test file creation failed"
27886         cancel_lru_locks osc
27887
27888         # Create a very small memory cgroup to force a slab allocation error
27889         local cgdir=$cg_basedir/osc_slab_alloc
27890         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27891         trap "cleanup_test411_cgroup $cgdir" EXIT
27892         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27893         echo 1M > $cgdir/memory.limit_in_bytes
27894
27895         # Should not LBUG, just be killed by oom-killer
27896         # dd will return 0 even allocation failure in some environment.
27897         # So don't check return value
27898         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27899         cleanup_test411_cgroup $cgdir
27900
27901         return 0
27902 }
27903 run_test 411a "Slab allocation error with cgroup does not LBUG"
27904
27905 test_411b() {
27906         local cg_basedir=/sys/fs/cgroup/memory
27907         # LU-9966
27908         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27909                 skip "no setup for cgroup"
27910         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27911         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27912         # limit, so we have 384M in cgroup
27913         # (arm) this seems to hit OOM more often than x86, so 1024M
27914         if [[ $(uname -m) = aarch64 ]]; then
27915                 local memlimit_mb=1024
27916         else
27917                 local memlimit_mb=384
27918         fi
27919
27920         # Create a cgroup and set memory limit
27921         # (tfile is used as an easy way to get a recognizable cgroup name)
27922         local cgdir=$cg_basedir/$tfile
27923         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27924         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27925         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27926
27927         echo "writing first file"
27928         # Write a file 4x the memory limit in size
27929         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27930                 error "(1) failed to write successfully"
27931
27932         sync
27933         cancel_lru_locks osc
27934
27935         rm -f $DIR/$tfile
27936         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27937
27938         # Try writing at a larger block size
27939         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27940         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27941         # need *some* memory to do IO in)
27942         echo "writing at larger block size"
27943         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27944                 error "(3) failed to write successfully"
27945
27946         sync
27947         cancel_lru_locks osc
27948         rm -f $DIR/$tfile
27949         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27950
27951         # Try writing multiple files at once
27952         echo "writing multiple files"
27953         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27954         local pid1=$!
27955         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27956         local pid2=$!
27957         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27958         local pid3=$!
27959         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27960         local pid4=$!
27961
27962         wait $pid1
27963         local rc1=$?
27964         wait $pid2
27965         local rc2=$?
27966         wait $pid3
27967         local rc3=$?
27968         wait $pid4
27969         local rc4=$?
27970         if (( rc1 != 0)); then
27971                 error "error $rc1 writing to file from $pid1"
27972         fi
27973         if (( rc2 != 0)); then
27974                 error "error $rc2 writing to file from $pid2"
27975         fi
27976         if (( rc3 != 0)); then
27977                 error "error $rc3 writing to file from $pid3"
27978         fi
27979         if (( rc4 != 0)); then
27980                 error "error $rc4 writing to file from $pid4"
27981         fi
27982
27983         sync
27984         cancel_lru_locks osc
27985
27986         # These files can be large-ish (~1 GiB total), so delete them rather
27987         # than leave for later cleanup
27988         rm -f $DIR/$tfile.*
27989         return 0
27990 }
27991 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27992
27993 test_412() {
27994         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27995         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27996                 skip "Need server version at least 2.10.55"
27997
27998         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27999                 error "mkdir failed"
28000         $LFS getdirstripe $DIR/$tdir
28001         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28002         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28003                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28004         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28005         [ $stripe_count -eq 2 ] ||
28006                 error "expect 2 get $stripe_count"
28007
28008         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28009
28010         local index
28011         local index2
28012
28013         # subdirs should be on the same MDT as parent
28014         for i in $(seq 0 $((MDSCOUNT - 1))); do
28015                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28016                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28017                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28018                 (( index == i )) || error "mdt$i/sub on MDT$index"
28019         done
28020
28021         # stripe offset -1, ditto
28022         for i in {1..10}; do
28023                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28024                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28025                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28026                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28027                 (( index == index2 )) ||
28028                         error "qos$i on MDT$index, sub on MDT$index2"
28029         done
28030
28031         local testdir=$DIR/$tdir/inherit
28032
28033         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28034         # inherit 2 levels
28035         for i in 1 2; do
28036                 testdir=$testdir/s$i
28037                 mkdir $testdir || error "mkdir $testdir failed"
28038                 index=$($LFS getstripe -m $testdir)
28039                 (( index == 1 )) ||
28040                         error "$testdir on MDT$index"
28041         done
28042
28043         # not inherit any more
28044         testdir=$testdir/s3
28045         mkdir $testdir || error "mkdir $testdir failed"
28046         getfattr -d -m dmv $testdir | grep dmv &&
28047                 error "default LMV set on $testdir" || true
28048 }
28049 run_test 412 "mkdir on specific MDTs"
28050
28051 TEST413_COUNT=${TEST413_COUNT:-200}
28052
28053 #
28054 # set_maxage() is used by test_413 only.
28055 # This is a helper function to set maxage. Does not return any value.
28056 # Input: maxage to set
28057 #
28058 set_maxage() {
28059         local lmv_qos_maxage
28060         local lod_qos_maxage
28061         local new_maxage=$1
28062
28063         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28064         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28065         stack_trap "$LCTL set_param \
28066                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28067         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28068                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28069         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28070                 lod.*.mdt_qos_maxage=$new_maxage
28071         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28072                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28073 }
28074
28075 generate_uneven_mdts() {
28076         local threshold=$1
28077         local ffree
28078         local bavail
28079         local max
28080         local min
28081         local max_index
28082         local min_index
28083         local tmp
28084         local i
28085
28086         echo
28087         echo "Check for uneven MDTs: "
28088
28089         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28090         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28091         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28092
28093         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28094         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28095         max_index=0
28096         min_index=0
28097         for ((i = 1; i < ${#ffree[@]}; i++)); do
28098                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28099                 if [ $tmp -gt $max ]; then
28100                         max=$tmp
28101                         max_index=$i
28102                 fi
28103                 if [ $tmp -lt $min ]; then
28104                         min=$tmp
28105                         min_index=$i
28106                 fi
28107         done
28108
28109         (( min > 0 )) || skip "low space on MDT$min_index"
28110         (( ${ffree[min_index]} > 0 )) ||
28111                 skip "no free files on MDT$min_index"
28112         (( ${ffree[min_index]} < 10000000 )) ||
28113                 skip "too many free files on MDT$min_index"
28114
28115         # Check if we need to generate uneven MDTs
28116         local diff=$(((max - min) * 100 / min))
28117         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28118         local testdir # individual folder within $testdirp
28119         local start
28120         local cmd
28121
28122         # fallocate is faster to consume space on MDT, if available
28123         if check_fallocate_supported mds$((min_index + 1)); then
28124                 cmd="fallocate -l 128K "
28125         else
28126                 cmd="dd if=/dev/zero bs=128K count=1 of="
28127         fi
28128
28129         echo "using cmd $cmd"
28130         for (( i = 0; diff < threshold; i++ )); do
28131                 testdir=${testdirp}/$i
28132                 [ -d $testdir ] && continue
28133
28134                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28135
28136                 mkdir -p $testdirp
28137                 # generate uneven MDTs, create till $threshold% diff
28138                 echo -n "weight diff=$diff% must be > $threshold% ..."
28139                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28140                 $LFS mkdir -i $min_index $testdir ||
28141                         error "mkdir $testdir failed"
28142                 $LFS setstripe -E 1M -L mdt $testdir ||
28143                         error "setstripe $testdir failed"
28144                 start=$SECONDS
28145                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28146                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28147                 done
28148                 sync; sleep 1; sync
28149
28150                 # wait for QOS to update
28151                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28152
28153                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28154                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28155                 max=$(((${ffree[max_index]} >> 8) *
28156                         (${bavail[max_index]} * bsize >> 16)))
28157                 min=$(((${ffree[min_index]} >> 8) *
28158                         (${bavail[min_index]} * bsize >> 16)))
28159                 (( min > 0 )) || skip "low space on MDT$min_index"
28160                 diff=$(((max - min) * 100 / min))
28161         done
28162
28163         echo "MDT filesfree available: ${ffree[*]}"
28164         echo "MDT blocks available: ${bavail[*]}"
28165         echo "weight diff=$diff%"
28166 }
28167
28168 test_qos_mkdir() {
28169         local mkdir_cmd=$1
28170         local stripe_count=$2
28171         local mdts=$(comma_list $(mdts_nodes))
28172
28173         local testdir
28174         local lmv_qos_prio_free
28175         local lmv_qos_threshold_rr
28176         local lod_qos_prio_free
28177         local lod_qos_threshold_rr
28178         local total
28179         local count
28180         local i
28181
28182         # @total is total directories created if it's testing plain
28183         # directories, otherwise it's total stripe object count for
28184         # striped directories test.
28185         # remote/striped directory unlinking is slow on zfs and may
28186         # timeout, test with fewer directories
28187         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28188
28189         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28190         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28191         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28192                 head -n1)
28193         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28194         stack_trap "$LCTL set_param \
28195                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28196         stack_trap "$LCTL set_param \
28197                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28198
28199         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28200                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28201         lod_qos_prio_free=${lod_qos_prio_free%%%}
28202         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28203                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28204         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28205         stack_trap "do_nodes $mdts $LCTL set_param \
28206                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28207         stack_trap "do_nodes $mdts $LCTL set_param \
28208                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28209
28210         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28211         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28212
28213         testdir=$DIR/$tdir-s$stripe_count/rr
28214
28215         local stripe_index=$($LFS getstripe -m $testdir)
28216         local test_mkdir_rr=true
28217
28218         getfattr -d -m dmv -e hex $testdir | grep dmv
28219         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28220                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28221                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28222                         test_mkdir_rr=false
28223         fi
28224
28225         echo
28226         $test_mkdir_rr &&
28227                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28228                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28229
28230         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28231         for (( i = 0; i < total / stripe_count; i++ )); do
28232                 eval $mkdir_cmd $testdir/subdir$i ||
28233                         error "$mkdir_cmd subdir$i failed"
28234         done
28235
28236         for (( i = 0; i < $MDSCOUNT; i++ )); do
28237                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28238                 echo "$count directories created on MDT$i"
28239                 if $test_mkdir_rr; then
28240                         (( count == total / stripe_count / MDSCOUNT )) ||
28241                                 error "subdirs are not evenly distributed"
28242                 elif (( i == stripe_index )); then
28243                         (( count == total / stripe_count )) ||
28244                                 error "$count subdirs created on MDT$i"
28245                 else
28246                         (( count == 0 )) ||
28247                                 error "$count subdirs created on MDT$i"
28248                 fi
28249
28250                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28251                         count=$($LFS getdirstripe $testdir/* |
28252                                 grep -c -P "^\s+$i\t")
28253                         echo "$count stripes created on MDT$i"
28254                         # deviation should < 5% of average
28255                         delta=$((count - total / MDSCOUNT))
28256                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28257                                 error "stripes are not evenly distributed"
28258                 fi
28259         done
28260
28261         echo
28262         echo "Check for uneven MDTs: "
28263
28264         local ffree
28265         local bavail
28266         local max
28267         local min
28268         local max_index
28269         local min_index
28270         local tmp
28271
28272         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28273         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28274         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28275
28276         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28277         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28278         max_index=0
28279         min_index=0
28280         for ((i = 1; i < ${#ffree[@]}; i++)); do
28281                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28282                 if [ $tmp -gt $max ]; then
28283                         max=$tmp
28284                         max_index=$i
28285                 fi
28286                 if [ $tmp -lt $min ]; then
28287                         min=$tmp
28288                         min_index=$i
28289                 fi
28290         done
28291         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28292
28293         (( min > 0 )) || skip "low space on MDT$min_index"
28294         (( ${ffree[min_index]} < 10000000 )) ||
28295                 skip "too many free files on MDT$min_index"
28296
28297         generate_uneven_mdts 120
28298
28299         echo "MDT filesfree available: ${ffree[*]}"
28300         echo "MDT blocks available: ${bavail[*]}"
28301         echo "weight diff=$(((max - min) * 100 / min))%"
28302         echo
28303         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28304
28305         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28306         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28307         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28308         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28309         # decrease statfs age, so that it can be updated in time
28310         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28311         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28312
28313         sleep 1
28314
28315         testdir=$DIR/$tdir-s$stripe_count/qos
28316
28317         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28318         for (( i = 0; i < total / stripe_count; i++ )); do
28319                 eval $mkdir_cmd $testdir/subdir$i ||
28320                         error "$mkdir_cmd subdir$i failed"
28321         done
28322
28323         max=0
28324         for (( i = 0; i < $MDSCOUNT; i++ )); do
28325                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28326                 (( count > max )) && max=$count
28327                 echo "$count directories created on MDT$i : curmax=$max"
28328         done
28329
28330         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28331
28332         # D-value should > 10% of average
28333         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28334                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28335
28336         # ditto for stripes
28337         if (( stripe_count > 1 )); then
28338                 max=0
28339                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28340                         count=$($LFS getdirstripe $testdir/* |
28341                                 grep -c -P "^\s+$i\t")
28342                         (( count > max )) && max=$count
28343                         echo "$count stripes created on MDT$i"
28344                 done
28345
28346                 min=$($LFS getdirstripe $testdir/* |
28347                         grep -c -P "^\s+$min_index\t")
28348                 (( max - min > total / MDSCOUNT / 10 )) ||
28349                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28350         fi
28351 }
28352
28353 most_full_mdt() {
28354         local ffree
28355         local bavail
28356         local bsize
28357         local min
28358         local min_index
28359         local tmp
28360
28361         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28362         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28363         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28364
28365         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28366         min_index=0
28367         for ((i = 1; i < ${#ffree[@]}; i++)); do
28368                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28369                 (( tmp < min )) && min=$tmp && min_index=$i
28370         done
28371
28372         echo -n $min_index
28373 }
28374
28375 test_413a() {
28376         [ $MDSCOUNT -lt 2 ] &&
28377                 skip "We need at least 2 MDTs for this test"
28378
28379         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28380                 skip "Need server version at least 2.12.52"
28381
28382         local stripe_max=$((MDSCOUNT - 1))
28383         local stripe_count
28384
28385         # let caller set maxage for latest result
28386         set_maxage 1
28387
28388         # fill MDT unevenly
28389         generate_uneven_mdts 120
28390
28391         # test 4-stripe directory at most, otherwise it's too slow
28392         # We are being very defensive. Although Autotest uses 4 MDTs.
28393         # We make sure stripe_max does not go over 4.
28394         (( stripe_max > 4 )) && stripe_max=4
28395         # unlinking striped directory is slow on zfs, and may timeout, only test
28396         # plain directory
28397         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28398         for stripe_count in $(seq 1 $stripe_max); do
28399                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28400                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28401                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28402                         error "mkdir failed"
28403                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28404         done
28405 }
28406 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28407
28408 test_413b() {
28409         [ $MDSCOUNT -lt 2 ] &&
28410                 skip "We need at least 2 MDTs for this test"
28411
28412         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28413                 skip "Need server version at least 2.12.52"
28414
28415         local stripe_max=$((MDSCOUNT - 1))
28416         local testdir
28417         local stripe_count
28418
28419         # let caller set maxage for latest result
28420         set_maxage 1
28421
28422         # fill MDT unevenly
28423         generate_uneven_mdts 120
28424
28425         # test 4-stripe directory at most, otherwise it's too slow
28426         # We are being very defensive. Although Autotest uses 4 MDTs.
28427         # We make sure stripe_max does not go over 4.
28428         (( stripe_max > 4 )) && stripe_max=4
28429         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28430         for stripe_count in $(seq 1 $stripe_max); do
28431                 testdir=$DIR/$tdir-s$stripe_count
28432                 mkdir $testdir || error "mkdir $testdir failed"
28433                 mkdir $testdir/rr || error "mkdir rr failed"
28434                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28435                         error "mkdir qos failed"
28436                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28437                         $testdir/rr || error "setdirstripe rr failed"
28438                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28439                         error "setdirstripe failed"
28440                 test_qos_mkdir "mkdir" $stripe_count
28441         done
28442 }
28443 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28444
28445 test_413c() {
28446         (( $MDSCOUNT >= 2 )) ||
28447                 skip "We need at least 2 MDTs for this test"
28448
28449         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28450                 skip "Need server version at least 2.14.51"
28451
28452         local testdir
28453         local inherit
28454         local inherit_rr
28455         local lmv_qos_maxage
28456         local lod_qos_maxage
28457
28458         # let caller set maxage for latest result
28459         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28460         $LCTL set_param lmv.*.qos_maxage=1
28461         stack_trap "$LCTL set_param \
28462                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28463         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28464                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28465         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28466                 lod.*.mdt_qos_maxage=1
28467         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28468                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28469
28470         # fill MDT unevenly
28471         generate_uneven_mdts 120
28472
28473         testdir=$DIR/${tdir}-s1
28474         mkdir $testdir || error "mkdir $testdir failed"
28475         mkdir $testdir/rr || error "mkdir rr failed"
28476         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28477         # default max_inherit is -1, default max_inherit_rr is 0
28478         $LFS setdirstripe -D -c 1 $testdir/rr ||
28479                 error "setdirstripe rr failed"
28480         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28481                 error "setdirstripe qos failed"
28482         test_qos_mkdir "mkdir" 1
28483
28484         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28485         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28486         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28487         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28488         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28489
28490         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28491         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28492         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28493         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28494         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28495         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28496         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28497                 error "level2 shouldn't have default LMV" || true
28498 }
28499 run_test 413c "mkdir with default LMV max inherit rr"
28500
28501 test_413d() {
28502         (( MDSCOUNT >= 2 )) ||
28503                 skip "We need at least 2 MDTs for this test"
28504
28505         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28506                 skip "Need server version at least 2.14.51"
28507
28508         local lmv_qos_threshold_rr
28509
28510         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28511                 head -n1)
28512         stack_trap "$LCTL set_param \
28513                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28514
28515         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28516         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28517         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28518                 error "$tdir shouldn't have default LMV"
28519         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28520                 error "mkdir sub failed"
28521
28522         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28523
28524         (( count == 100 )) || error "$count subdirs on MDT0"
28525 }
28526 run_test 413d "inherit ROOT default LMV"
28527
28528 test_413e() {
28529         (( MDSCOUNT >= 2 )) ||
28530                 skip "We need at least 2 MDTs for this test"
28531         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28532                 skip "Need server version at least 2.14.55"
28533
28534         local testdir=$DIR/$tdir
28535         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28536         local max_inherit
28537         local sub_max_inherit
28538
28539         mkdir -p $testdir || error "failed to create $testdir"
28540
28541         # set default max-inherit to -1 if stripe count is 0 or 1
28542         $LFS setdirstripe -D -c 1 $testdir ||
28543                 error "failed to set default LMV"
28544         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28545         (( max_inherit == -1 )) ||
28546                 error "wrong max_inherit value $max_inherit"
28547
28548         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28549         $LFS setdirstripe -D -c -1 $testdir ||
28550                 error "failed to set default LMV"
28551         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28552         (( max_inherit > 0 )) ||
28553                 error "wrong max_inherit value $max_inherit"
28554
28555         # and the subdir will decrease the max_inherit by 1
28556         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28557         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28558         (( sub_max_inherit == max_inherit - 1)) ||
28559                 error "wrong max-inherit of subdir $sub_max_inherit"
28560
28561         # check specified --max-inherit and warning message
28562         stack_trap "rm -f $tmpfile"
28563         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28564                 error "failed to set default LMV"
28565         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28566         (( max_inherit == -1 )) ||
28567                 error "wrong max_inherit value $max_inherit"
28568
28569         # check the warning messages
28570         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28571                 error "failed to detect warning string"
28572         fi
28573 }
28574 run_test 413e "check default max-inherit value"
28575
28576 test_fs_dmv_inherit()
28577 {
28578         local testdir=$DIR/$tdir
28579
28580         local count
28581         local inherit
28582         local inherit_rr
28583
28584         for i in 1 2; do
28585                 mkdir $testdir || error "mkdir $testdir failed"
28586                 count=$($LFS getdirstripe -D -c $testdir)
28587                 (( count == 1 )) ||
28588                         error "$testdir default LMV count mismatch $count != 1"
28589                 inherit=$($LFS getdirstripe -D -X $testdir)
28590                 (( inherit == 3 - i )) ||
28591                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28592                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28593                 (( inherit_rr == 3 - i )) ||
28594                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28595                 testdir=$testdir/sub
28596         done
28597
28598         mkdir $testdir || error "mkdir $testdir failed"
28599         count=$($LFS getdirstripe -D -c $testdir)
28600         (( count == 0 )) ||
28601                 error "$testdir default LMV count not zero: $count"
28602 }
28603
28604 test_413f() {
28605         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28606
28607         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28608                 skip "Need server version at least 2.14.55"
28609
28610         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28611                 error "dump $DIR default LMV failed"
28612         stack_trap "setfattr --restore=$TMP/dmv.ea"
28613
28614         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28615                 error "set $DIR default LMV failed"
28616
28617         test_fs_dmv_inherit
28618 }
28619 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28620
28621 test_413g() {
28622         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28623
28624         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28625         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28626                 error "dump $DIR default LMV failed"
28627         stack_trap "setfattr --restore=$TMP/dmv.ea"
28628
28629         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28630                 error "set $DIR default LMV failed"
28631
28632         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28633                 error "mount $MOUNT2 failed"
28634         stack_trap "umount_client $MOUNT2"
28635
28636         local saved_DIR=$DIR
28637
28638         export DIR=$MOUNT2
28639
28640         stack_trap "export DIR=$saved_DIR"
28641
28642         # first check filesystem-wide default LMV inheritance
28643         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28644
28645         # then check subdirs are spread to all MDTs
28646         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28647
28648         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28649
28650         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28651 }
28652 run_test 413g "enforce ROOT default LMV on subdir mount"
28653
28654 test_413h() {
28655         (( MDSCOUNT >= 2 )) ||
28656                 skip "We need at least 2 MDTs for this test"
28657
28658         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28659                 skip "Need server version at least 2.15.50.6"
28660
28661         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28662
28663         stack_trap "$LCTL set_param \
28664                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28665         $LCTL set_param lmv.*.qos_maxage=1
28666
28667         local depth=5
28668         local rr_depth=4
28669         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28670         local count=$((MDSCOUNT * 20))
28671
28672         generate_uneven_mdts 50
28673
28674         mkdir -p $dir || error "mkdir $dir failed"
28675         stack_trap "rm -rf $dir"
28676         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28677                 --max-inherit-rr=$rr_depth $dir
28678
28679         for ((d=0; d < depth + 2; d++)); do
28680                 log "dir=$dir:"
28681                 for ((sub=0; sub < count; sub++)); do
28682                         mkdir $dir/d$sub
28683                 done
28684                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28685                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28686                 # subdirs within $rr_depth should be created round-robin
28687                 if (( d < rr_depth )); then
28688                         (( ${num[0]} != count )) ||
28689                                 error "all objects created on MDT ${num[1]}"
28690                 fi
28691
28692                 dir=$dir/d0
28693         done
28694 }
28695 run_test 413h "don't stick to parent for round-robin dirs"
28696
28697 test_413i() {
28698         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28699
28700         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28701                 skip "Need server version at least 2.14.55"
28702
28703         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28704                 error "dump $DIR default LMV failed"
28705         stack_trap "setfattr --restore=$TMP/dmv.ea"
28706
28707         local testdir=$DIR/$tdir
28708         local def_max_rr=1
28709         local def_max=3
28710         local count
28711
28712         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28713                 --max-inherit-rr=$def_max_rr $DIR ||
28714                 error "set $DIR default LMV failed"
28715
28716         for i in $(seq 2 3); do
28717                 def_max=$((def_max - 1))
28718                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28719
28720                 mkdir $testdir
28721                 # RR is decremented and keeps zeroed once exhausted
28722                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28723                 (( count == def_max_rr )) ||
28724                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28725
28726                 # max-inherit is decremented
28727                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28728                 (( count == def_max )) ||
28729                         error_noexit "$testdir: max-inherit $count != $def_max"
28730
28731                 testdir=$testdir/d$i
28732         done
28733
28734         # d3 is the last inherited from ROOT, no inheritance anymore
28735         # i.e. no the default layout anymore
28736         mkdir -p $testdir/d4/d5
28737         count=$($LFS getdirstripe -D --max-inherit $testdir)
28738         (( count == -1 )) ||
28739                 error_noexit "$testdir: max-inherit $count != -1"
28740
28741         local p_count=$($LFS getdirstripe -i $testdir)
28742
28743         for i in $(seq 4 5); do
28744                 testdir=$testdir/d$i
28745
28746                 # the root default layout is not applied once exhausted
28747                 count=$($LFS getdirstripe -i $testdir)
28748                 (( count == p_count )) ||
28749                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28750         done
28751
28752         $LFS setdirstripe -i 0 $DIR/d2
28753         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28754         (( count == -1 )) ||
28755                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28756 }
28757 run_test 413i "check default layout inheritance"
28758
28759 test_413j()
28760 {
28761         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28762
28763         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28764         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
28765                 error "setdirstripe $tdir failed"
28766
28767         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
28768                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28769
28770         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
28771         # setfattr dmv calls setdirstripe -D
28772         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
28773                 error "setfattr sub failed"
28774         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
28775                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28776
28777         [ $value == $value2 ] || error "dmv mismatch"
28778
28779         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
28780
28781         # do not allow remove dmv by setfattr -x
28782         do_nodes $(comma_list $(mdts_nodes)) \
28783                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28784         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28785         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
28786
28787         # allow remove dmv by setfattr -x
28788         do_nodes $(comma_list $(mdts_nodes)) \
28789                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
28790         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28791         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
28792         do_nodes $(comma_list $(mdts_nodes)) \
28793                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28794 }
28795 run_test 413j "set default LMV by setxattr"
28796
28797 test_413z() {
28798         local pids=""
28799         local subdir
28800         local pid
28801
28802         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28803                 unlinkmany $subdir/f. $TEST413_COUNT &
28804                 pids="$pids $!"
28805         done
28806
28807         for pid in $pids; do
28808                 wait $pid
28809         done
28810
28811         true
28812 }
28813 run_test 413z "413 test cleanup"
28814
28815 test_414() {
28816 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28817         $LCTL set_param fail_loc=0x80000521
28818         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28819         rm -f $DIR/$tfile
28820 }
28821 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28822
28823 test_415() {
28824         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28825         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28826                 skip "Need server version at least 2.11.52"
28827
28828         # LU-11102
28829         local total=500
28830         local max=120
28831
28832         # this test may be slow on ZFS
28833         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28834
28835         # though this test is designed for striped directory, let's test normal
28836         # directory too since lock is always saved as CoS lock.
28837         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28838         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28839         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28840         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28841         wait_delete_completed_mds
28842
28843         # run a loop without concurrent touch to measure rename duration.
28844         # only for test debug/robustness, NOT part of COS functional test.
28845         local start_time=$SECONDS
28846         for ((i = 0; i < total; i++)); do
28847                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28848                         > /dev/null
28849         done
28850         local baseline=$((SECONDS - start_time))
28851         echo "rename $total files without 'touch' took $baseline sec"
28852
28853         (
28854                 while true; do
28855                         touch $DIR/$tdir
28856                 done
28857         ) &
28858         local setattr_pid=$!
28859
28860         # rename files back to original name so unlinkmany works
28861         start_time=$SECONDS
28862         for ((i = 0; i < total; i++)); do
28863                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28864                         > /dev/null
28865         done
28866         local duration=$((SECONDS - start_time))
28867
28868         kill -9 $setattr_pid
28869
28870         echo "rename $total files with 'touch' took $duration sec"
28871         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28872         (( duration <= max )) ||
28873                 error_not_in_vm "rename took $duration > $max sec"
28874 }
28875 run_test 415 "lock revoke is not missing"
28876
28877 test_416() {
28878         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28879                 skip "Need server version at least 2.11.55"
28880
28881         # define OBD_FAIL_OSD_TXN_START    0x19a
28882         do_facet mds1 lctl set_param fail_loc=0x19a
28883
28884         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28885
28886         true
28887 }
28888 run_test 416 "transaction start failure won't cause system hung"
28889
28890 cleanup_417() {
28891         trap 0
28892         do_nodes $(comma_list $(mdts_nodes)) \
28893                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28894         do_nodes $(comma_list $(mdts_nodes)) \
28895                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28896         do_nodes $(comma_list $(mdts_nodes)) \
28897                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28898 }
28899
28900 test_417() {
28901         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28902         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28903                 skip "Need MDS version at least 2.11.56"
28904
28905         trap cleanup_417 RETURN EXIT
28906
28907         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28908         do_nodes $(comma_list $(mdts_nodes)) \
28909                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28910         $LFS migrate -m 0 $DIR/$tdir.1 &&
28911                 error "migrate dir $tdir.1 should fail"
28912
28913         do_nodes $(comma_list $(mdts_nodes)) \
28914                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28915         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28916                 error "create remote dir $tdir.2 should fail"
28917
28918         do_nodes $(comma_list $(mdts_nodes)) \
28919                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28920         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28921                 error "create striped dir $tdir.3 should fail"
28922         true
28923 }
28924 run_test 417 "disable remote dir, striped dir and dir migration"
28925
28926 # Checks that the outputs of df [-i] and lfs df [-i] match
28927 #
28928 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28929 check_lfs_df() {
28930         local dir=$2
28931         local inodes
28932         local df_out
28933         local lfs_df_out
28934         local count
28935         local passed=false
28936
28937         # blocks or inodes
28938         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28939
28940         for count in {1..100}; do
28941                 do_nodes "$CLIENTS" \
28942                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28943                 sync; sleep 0.2
28944
28945                 # read the lines of interest
28946                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28947                         error "df $inodes $dir | tail -n +2 failed"
28948                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28949                         error "lfs df $inodes $dir | grep summary: failed"
28950
28951                 # skip first substrings of each output as they are different
28952                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28953                 # compare the two outputs
28954                 passed=true
28955                 #  skip "available" on MDT until LU-13997 is fixed.
28956                 #for i in {1..5}; do
28957                 for i in 1 2 4 5; do
28958                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28959                 done
28960                 $passed && break
28961         done
28962
28963         if ! $passed; then
28964                 df -P $inodes $dir
28965                 echo
28966                 lfs df $inodes $dir
28967                 error "df and lfs df $1 output mismatch: "      \
28968                       "df ${inodes}: ${df_out[*]}, "            \
28969                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28970         fi
28971 }
28972
28973 test_418() {
28974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28975
28976         local dir=$DIR/$tdir
28977         local numfiles=$((RANDOM % 4096 + 2))
28978         local numblocks=$((RANDOM % 256 + 1))
28979
28980         wait_delete_completed
28981         test_mkdir $dir
28982
28983         # check block output
28984         check_lfs_df blocks $dir
28985         # check inode output
28986         check_lfs_df inodes $dir
28987
28988         # create a single file and retest
28989         echo "Creating a single file and testing"
28990         createmany -o $dir/$tfile- 1 &>/dev/null ||
28991                 error "creating 1 file in $dir failed"
28992         check_lfs_df blocks $dir
28993         check_lfs_df inodes $dir
28994
28995         # create a random number of files
28996         echo "Creating $((numfiles - 1)) files and testing"
28997         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28998                 error "creating $((numfiles - 1)) files in $dir failed"
28999
29000         # write a random number of blocks to the first test file
29001         echo "Writing $numblocks 4K blocks and testing"
29002         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29003                 count=$numblocks &>/dev/null ||
29004                 error "dd to $dir/${tfile}-0 failed"
29005
29006         # retest
29007         check_lfs_df blocks $dir
29008         check_lfs_df inodes $dir
29009
29010         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29011                 error "unlinking $numfiles files in $dir failed"
29012 }
29013 run_test 418 "df and lfs df outputs match"
29014
29015 test_419()
29016 {
29017         local dir=$DIR/$tdir
29018
29019         mkdir -p $dir
29020         touch $dir/file
29021
29022         cancel_lru_locks mdc
29023
29024         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29025         $LCTL set_param fail_loc=0x1410
29026         cat $dir/file
29027         $LCTL set_param fail_loc=0
29028         rm -rf $dir
29029 }
29030 run_test 419 "Verify open file by name doesn't crash kernel"
29031
29032 test_420()
29033 {
29034         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29035                 skip "Need MDS version at least 2.12.53"
29036
29037         local SAVE_UMASK=$(umask)
29038         local dir=$DIR/$tdir
29039         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29040
29041         mkdir -p $dir
29042         umask 0000
29043         mkdir -m03777 $dir/testdir
29044         ls -dn $dir/testdir
29045         # Need to remove trailing '.' when SELinux is enabled
29046         local dirperms=$(ls -dn $dir/testdir |
29047                          awk '{ sub(/\.$/, "", $1); print $1}')
29048         [ $dirperms == "drwxrwsrwt" ] ||
29049                 error "incorrect perms on $dir/testdir"
29050
29051         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29052                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29053         ls -n $dir/testdir/testfile
29054         local fileperms=$(ls -n $dir/testdir/testfile |
29055                           awk '{ sub(/\.$/, "", $1); print $1}')
29056         [ $fileperms == "-rwxr-xr-x" ] ||
29057                 error "incorrect perms on $dir/testdir/testfile"
29058
29059         umask $SAVE_UMASK
29060 }
29061 run_test 420 "clear SGID bit on non-directories for non-members"
29062
29063 test_421a() {
29064         local cnt
29065         local fid1
29066         local fid2
29067
29068         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29069                 skip "Need MDS version at least 2.12.54"
29070
29071         test_mkdir $DIR/$tdir
29072         createmany -o $DIR/$tdir/f 3
29073         cnt=$(ls -1 $DIR/$tdir | wc -l)
29074         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29075
29076         fid1=$(lfs path2fid $DIR/$tdir/f1)
29077         fid2=$(lfs path2fid $DIR/$tdir/f2)
29078         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29079
29080         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29081         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29082
29083         cnt=$(ls -1 $DIR/$tdir | wc -l)
29084         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29085
29086         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29087         createmany -o $DIR/$tdir/f 3
29088         cnt=$(ls -1 $DIR/$tdir | wc -l)
29089         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29090
29091         fid1=$(lfs path2fid $DIR/$tdir/f1)
29092         fid2=$(lfs path2fid $DIR/$tdir/f2)
29093         echo "remove using fsname $FSNAME"
29094         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29095
29096         cnt=$(ls -1 $DIR/$tdir | wc -l)
29097         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29098 }
29099 run_test 421a "simple rm by fid"
29100
29101 test_421b() {
29102         local cnt
29103         local FID1
29104         local FID2
29105
29106         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29107                 skip "Need MDS version at least 2.12.54"
29108
29109         test_mkdir $DIR/$tdir
29110         createmany -o $DIR/$tdir/f 3
29111         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29112         MULTIPID=$!
29113
29114         FID1=$(lfs path2fid $DIR/$tdir/f1)
29115         FID2=$(lfs path2fid $DIR/$tdir/f2)
29116         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29117
29118         kill -USR1 $MULTIPID
29119         wait
29120
29121         cnt=$(ls $DIR/$tdir | wc -l)
29122         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29123 }
29124 run_test 421b "rm by fid on open file"
29125
29126 test_421c() {
29127         local cnt
29128         local FIDS
29129
29130         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29131                 skip "Need MDS version at least 2.12.54"
29132
29133         test_mkdir $DIR/$tdir
29134         createmany -o $DIR/$tdir/f 3
29135         touch $DIR/$tdir/$tfile
29136         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29137         cnt=$(ls -1 $DIR/$tdir | wc -l)
29138         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29139
29140         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29141         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29142
29143         cnt=$(ls $DIR/$tdir | wc -l)
29144         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29145 }
29146 run_test 421c "rm by fid against hardlinked files"
29147
29148 test_421d() {
29149         local cnt
29150         local FIDS
29151
29152         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29153                 skip "Need MDS version at least 2.12.54"
29154
29155         test_mkdir $DIR/$tdir
29156         createmany -o $DIR/$tdir/f 4097
29157         cnt=$(ls -1 $DIR/$tdir | wc -l)
29158         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29159
29160         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29161         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29162
29163         cnt=$(ls $DIR/$tdir | wc -l)
29164         rm -rf $DIR/$tdir
29165         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29166 }
29167 run_test 421d "rmfid en masse"
29168
29169 test_421e() {
29170         local cnt
29171         local FID
29172
29173         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29174         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29175                 skip "Need MDS version at least 2.12.54"
29176
29177         mkdir -p $DIR/$tdir
29178         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29179         createmany -o $DIR/$tdir/striped_dir/f 512
29180         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29181         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29182
29183         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29184                 sed "s/[/][^:]*://g")
29185         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29186
29187         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29188         rm -rf $DIR/$tdir
29189         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29190 }
29191 run_test 421e "rmfid in DNE"
29192
29193 test_421f() {
29194         local cnt
29195         local FID
29196
29197         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29198                 skip "Need MDS version at least 2.12.54"
29199
29200         test_mkdir $DIR/$tdir
29201         touch $DIR/$tdir/f
29202         cnt=$(ls -1 $DIR/$tdir | wc -l)
29203         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29204
29205         FID=$(lfs path2fid $DIR/$tdir/f)
29206         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29207         # rmfid should fail
29208         cnt=$(ls -1 $DIR/$tdir | wc -l)
29209         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29210
29211         chmod a+rw $DIR/$tdir
29212         ls -la $DIR/$tdir
29213         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29214         # rmfid should fail
29215         cnt=$(ls -1 $DIR/$tdir | wc -l)
29216         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29217
29218         rm -f $DIR/$tdir/f
29219         $RUNAS touch $DIR/$tdir/f
29220         FID=$(lfs path2fid $DIR/$tdir/f)
29221         echo "rmfid as root"
29222         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29223         cnt=$(ls -1 $DIR/$tdir | wc -l)
29224         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29225
29226         rm -f $DIR/$tdir/f
29227         $RUNAS touch $DIR/$tdir/f
29228         cnt=$(ls -1 $DIR/$tdir | wc -l)
29229         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29230         FID=$(lfs path2fid $DIR/$tdir/f)
29231         # rmfid w/o user_fid2path mount option should fail
29232         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29233         cnt=$(ls -1 $DIR/$tdir | wc -l)
29234         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29235
29236         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29237         stack_trap "rmdir $tmpdir"
29238         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29239                 error "failed to mount client'"
29240         stack_trap "umount_client $tmpdir"
29241
29242         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29243         # rmfid should succeed
29244         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29245         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29246
29247         # rmfid shouldn't allow to remove files due to dir's permission
29248         chmod a+rwx $tmpdir/$tdir
29249         touch $tmpdir/$tdir/f
29250         ls -la $tmpdir/$tdir
29251         FID=$(lfs path2fid $tmpdir/$tdir/f)
29252         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29253         return 0
29254 }
29255 run_test 421f "rmfid checks permissions"
29256
29257 test_421g() {
29258         local cnt
29259         local FIDS
29260
29261         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29262         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29263                 skip "Need MDS version at least 2.12.54"
29264
29265         mkdir -p $DIR/$tdir
29266         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29267         createmany -o $DIR/$tdir/striped_dir/f 512
29268         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29269         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29270
29271         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29272                 sed "s/[/][^:]*://g")
29273
29274         rm -f $DIR/$tdir/striped_dir/f1*
29275         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29276         removed=$((512 - cnt))
29277
29278         # few files have been just removed, so we expect
29279         # rmfid to fail on their fids
29280         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29281         [ $removed != $errors ] && error "$errors != $removed"
29282
29283         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29284         rm -rf $DIR/$tdir
29285         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29286 }
29287 run_test 421g "rmfid to return errors properly"
29288
29289 test_421h() {
29290         local mount_other
29291         local mount_ret
29292         local rmfid_ret
29293         local old_fid
29294         local fidA
29295         local fidB
29296         local fidC
29297         local fidD
29298
29299         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29300                 skip "Need MDS version at least 2.15.53"
29301
29302         test_mkdir $DIR/$tdir
29303         test_mkdir $DIR/$tdir/subdir
29304         touch $DIR/$tdir/subdir/file0
29305         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29306         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29307         rm -f $DIR/$tdir/subdir/file0
29308         touch $DIR/$tdir/subdir/fileA
29309         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29310         echo File $DIR/$tdir/subdir/fileA FID $fidA
29311         touch $DIR/$tdir/subdir/fileB
29312         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29313         echo File $DIR/$tdir/subdir/fileB FID $fidB
29314         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29315         touch $DIR/$tdir/subdir/fileC
29316         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29317         echo File $DIR/$tdir/subdir/fileC FID $fidC
29318         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29319         touch $DIR/$tdir/fileD
29320         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29321         echo File $DIR/$tdir/fileD FID $fidD
29322
29323         # mount another client mount point with subdirectory mount
29324         export FILESET=/$tdir/subdir
29325         mount_other=${MOUNT}_other
29326         mount_client $mount_other ${MOUNT_OPTS}
29327         mount_ret=$?
29328         export FILESET=""
29329         (( mount_ret == 0 )) || error "mount $mount_other failed"
29330
29331         echo Removing FIDs:
29332         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29333         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29334         rmfid_ret=$?
29335
29336         umount_client $mount_other || error "umount $mount_other failed"
29337
29338         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29339
29340         # fileA should have been deleted
29341         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29342
29343         # fileB should have been deleted
29344         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29345
29346         # fileC should not have been deleted, fid also exists outside of fileset
29347         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29348
29349         # fileD should not have been deleted, it exists outside of fileset
29350         stat $DIR/$tdir/fileD || error "fileD deleted"
29351 }
29352 run_test 421h "rmfid with fileset mount"
29353
29354 test_422() {
29355         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29356         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29357         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29358         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29359         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29360
29361         local amc=$(at_max_get client)
29362         local amo=$(at_max_get mds1)
29363         local timeout=`lctl get_param -n timeout`
29364
29365         at_max_set 0 client
29366         at_max_set 0 mds1
29367
29368 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29369         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29370                         fail_val=$(((2*timeout + 10)*1000))
29371         touch $DIR/$tdir/d3/file &
29372         sleep 2
29373 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29374         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29375                         fail_val=$((2*timeout + 5))
29376         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29377         local pid=$!
29378         sleep 1
29379         kill -9 $pid
29380         sleep $((2 * timeout))
29381         echo kill $pid
29382         kill -9 $pid
29383         lctl mark touch
29384         touch $DIR/$tdir/d2/file3
29385         touch $DIR/$tdir/d2/file4
29386         touch $DIR/$tdir/d2/file5
29387
29388         wait
29389         at_max_set $amc client
29390         at_max_set $amo mds1
29391
29392         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29393         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29394                 error "Watchdog is always throttled"
29395 }
29396 run_test 422 "kill a process with RPC in progress"
29397
29398 stat_test() {
29399     df -h $MOUNT &
29400     df -h $MOUNT &
29401     df -h $MOUNT &
29402     df -h $MOUNT &
29403     df -h $MOUNT &
29404     df -h $MOUNT &
29405 }
29406
29407 test_423() {
29408     local _stats
29409     # ensure statfs cache is expired
29410     sleep 2;
29411
29412     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29413     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29414
29415     return 0
29416 }
29417 run_test 423 "statfs should return a right data"
29418
29419 test_424() {
29420 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29421         $LCTL set_param fail_loc=0x80000522
29422         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29423         rm -f $DIR/$tfile
29424 }
29425 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29426
29427 test_425() {
29428         test_mkdir -c -1 $DIR/$tdir
29429         $LFS setstripe -c -1 $DIR/$tdir
29430
29431         lru_resize_disable "" 100
29432         stack_trap "lru_resize_enable" EXIT
29433
29434         sleep 5
29435
29436         for i in $(seq $((MDSCOUNT * 125))); do
29437                 local t=$DIR/$tdir/$tfile_$i
29438
29439                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29440                         error_noexit "Create file $t"
29441         done
29442         stack_trap "rm -rf $DIR/$tdir" EXIT
29443
29444         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29445                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29446                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29447
29448                 [ $lock_count -le $lru_size ] ||
29449                         error "osc lock count $lock_count > lru size $lru_size"
29450         done
29451
29452         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29453                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29454                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29455
29456                 [ $lock_count -le $lru_size ] ||
29457                         error "mdc lock count $lock_count > lru size $lru_size"
29458         done
29459 }
29460 run_test 425 "lock count should not exceed lru size"
29461
29462 test_426() {
29463         splice-test -r $DIR/$tfile
29464         splice-test -rd $DIR/$tfile
29465         splice-test $DIR/$tfile
29466         splice-test -d $DIR/$tfile
29467 }
29468 run_test 426 "splice test on Lustre"
29469
29470 test_427() {
29471         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29472         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29473                 skip "Need MDS version at least 2.12.4"
29474         local log
29475
29476         mkdir $DIR/$tdir
29477         mkdir $DIR/$tdir/1
29478         mkdir $DIR/$tdir/2
29479         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29480         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29481
29482         $LFS getdirstripe $DIR/$tdir/1/dir
29483
29484         #first setfattr for creating updatelog
29485         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29486
29487 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29488         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29489         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29490         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29491
29492         sleep 2
29493         fail mds2
29494         wait_recovery_complete mds2 $((2*TIMEOUT))
29495
29496         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29497         echo $log | grep "get update log failed" &&
29498                 error "update log corruption is detected" || true
29499 }
29500 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29501
29502 test_428() {
29503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29504         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29505                               awk '/^max_cached_mb/ { print $2 }')
29506         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29507
29508         $LCTL set_param -n llite.*.max_cached_mb=64
29509
29510         mkdir $DIR/$tdir
29511         $LFS setstripe -c 1 $DIR/$tdir
29512         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29513         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29514         #test write
29515         for f in $(seq 4); do
29516                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29517         done
29518         wait
29519
29520         cancel_lru_locks osc
29521         # Test read
29522         for f in $(seq 4); do
29523                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29524         done
29525         wait
29526 }
29527 run_test 428 "large block size IO should not hang"
29528
29529 test_429() { # LU-7915 / LU-10948
29530         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29531         local testfile=$DIR/$tfile
29532         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29533         local new_flag=1
29534         local first_rpc
29535         local second_rpc
29536         local third_rpc
29537
29538         $LCTL get_param $ll_opencache_threshold_count ||
29539                 skip "client does not have opencache parameter"
29540
29541         set_opencache $new_flag
29542         stack_trap "restore_opencache"
29543         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29544                 error "enable opencache failed"
29545         touch $testfile
29546         # drop MDC DLM locks
29547         cancel_lru_locks mdc
29548         # clear MDC RPC stats counters
29549         $LCTL set_param $mdc_rpcstats=clear
29550
29551         # According to the current implementation, we need to run 3 times
29552         # open & close file to verify if opencache is enabled correctly.
29553         # 1st, RPCs are sent for lookup/open and open handle is released on
29554         #      close finally.
29555         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29556         #      so open handle won't be released thereafter.
29557         # 3rd, No RPC is sent out.
29558         $MULTIOP $testfile oc || error "multiop failed"
29559         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29560         echo "1st: $first_rpc RPCs in flight"
29561
29562         $MULTIOP $testfile oc || error "multiop failed"
29563         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29564         echo "2nd: $second_rpc RPCs in flight"
29565
29566         $MULTIOP $testfile oc || error "multiop failed"
29567         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29568         echo "3rd: $third_rpc RPCs in flight"
29569
29570         #verify no MDC RPC is sent
29571         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29572 }
29573 run_test 429 "verify if opencache flag on client side does work"
29574
29575 lseek_test_430() {
29576         local offset
29577         local file=$1
29578
29579         # data at [200K, 400K)
29580         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29581                 error "256K->512K dd fails"
29582         # data at [2M, 3M)
29583         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29584                 error "2M->3M dd fails"
29585         # data at [4M, 5M)
29586         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29587                 error "4M->5M dd fails"
29588         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29589         # start at first component hole #1
29590         printf "Seeking hole from 1000 ... "
29591         offset=$(lseek_test -l 1000 $file)
29592         echo $offset
29593         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29594         printf "Seeking data from 1000 ... "
29595         offset=$(lseek_test -d 1000 $file)
29596         echo $offset
29597         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29598
29599         # start at first component data block
29600         printf "Seeking hole from 300000 ... "
29601         offset=$(lseek_test -l 300000 $file)
29602         echo $offset
29603         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29604         printf "Seeking data from 300000 ... "
29605         offset=$(lseek_test -d 300000 $file)
29606         echo $offset
29607         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29608
29609         # start at the first component but beyond end of object size
29610         printf "Seeking hole from 1000000 ... "
29611         offset=$(lseek_test -l 1000000 $file)
29612         echo $offset
29613         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29614         printf "Seeking data from 1000000 ... "
29615         offset=$(lseek_test -d 1000000 $file)
29616         echo $offset
29617         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29618
29619         # start at second component stripe 2 (empty file)
29620         printf "Seeking hole from 1500000 ... "
29621         offset=$(lseek_test -l 1500000 $file)
29622         echo $offset
29623         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29624         printf "Seeking data from 1500000 ... "
29625         offset=$(lseek_test -d 1500000 $file)
29626         echo $offset
29627         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29628
29629         # start at second component stripe 1 (all data)
29630         printf "Seeking hole from 3000000 ... "
29631         offset=$(lseek_test -l 3000000 $file)
29632         echo $offset
29633         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29634         printf "Seeking data from 3000000 ... "
29635         offset=$(lseek_test -d 3000000 $file)
29636         echo $offset
29637         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29638
29639         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29640                 error "2nd dd fails"
29641         echo "Add data block at 640K...1280K"
29642
29643         # start at before new data block, in hole
29644         printf "Seeking hole from 600000 ... "
29645         offset=$(lseek_test -l 600000 $file)
29646         echo $offset
29647         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29648         printf "Seeking data from 600000 ... "
29649         offset=$(lseek_test -d 600000 $file)
29650         echo $offset
29651         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29652
29653         # start at the first component new data block
29654         printf "Seeking hole from 1000000 ... "
29655         offset=$(lseek_test -l 1000000 $file)
29656         echo $offset
29657         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29658         printf "Seeking data from 1000000 ... "
29659         offset=$(lseek_test -d 1000000 $file)
29660         echo $offset
29661         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29662
29663         # start at second component stripe 2, new data
29664         printf "Seeking hole from 1200000 ... "
29665         offset=$(lseek_test -l 1200000 $file)
29666         echo $offset
29667         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29668         printf "Seeking data from 1200000 ... "
29669         offset=$(lseek_test -d 1200000 $file)
29670         echo $offset
29671         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29672
29673         # start beyond file end
29674         printf "Using offset > filesize ... "
29675         lseek_test -l 4000000 $file && error "lseek should fail"
29676         printf "Using offset > filesize ... "
29677         lseek_test -d 4000000 $file && error "lseek should fail"
29678
29679         printf "Done\n\n"
29680 }
29681
29682 test_430a() {
29683         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29684                 skip "MDT does not support SEEK_HOLE"
29685
29686         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29687                 skip "OST does not support SEEK_HOLE"
29688
29689         local file=$DIR/$tdir/$tfile
29690
29691         mkdir -p $DIR/$tdir
29692
29693         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29694         # OST stripe #1 will have continuous data at [1M, 3M)
29695         # OST stripe #2 is empty
29696         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29697         lseek_test_430 $file
29698         rm $file
29699         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29700         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29701         lseek_test_430 $file
29702         rm $file
29703         $LFS setstripe -c2 -S 512K $file
29704         echo "Two stripes, stripe size 512K"
29705         lseek_test_430 $file
29706         rm $file
29707         # FLR with stale mirror
29708         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29709                        -N -c2 -S 1M $file
29710         echo "Mirrored file:"
29711         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29712         echo "Plain 2 stripes 1M"
29713         lseek_test_430 $file
29714         rm $file
29715 }
29716 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29717
29718 test_430b() {
29719         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29720                 skip "OST does not support SEEK_HOLE"
29721
29722         local offset
29723         local file=$DIR/$tdir/$tfile
29724
29725         mkdir -p $DIR/$tdir
29726         # Empty layout lseek should fail
29727         $MCREATE $file
29728         # seek from 0
29729         printf "Seeking hole from 0 ... "
29730         lseek_test -l 0 $file && error "lseek should fail"
29731         printf "Seeking data from 0 ... "
29732         lseek_test -d 0 $file && error "lseek should fail"
29733         rm $file
29734
29735         # 1M-hole file
29736         $LFS setstripe -E 1M -c2 -E eof $file
29737         $TRUNCATE $file 1048576
29738         printf "Seeking hole from 1000000 ... "
29739         offset=$(lseek_test -l 1000000 $file)
29740         echo $offset
29741         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29742         printf "Seeking data from 1000000 ... "
29743         lseek_test -d 1000000 $file && error "lseek should fail"
29744         rm $file
29745
29746         # full component followed by non-inited one
29747         $LFS setstripe -E 1M -c2 -E eof $file
29748         dd if=/dev/urandom of=$file bs=1M count=1
29749         printf "Seeking hole from 1000000 ... "
29750         offset=$(lseek_test -l 1000000 $file)
29751         echo $offset
29752         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29753         printf "Seeking hole from 1048576 ... "
29754         lseek_test -l 1048576 $file && error "lseek should fail"
29755         # init second component and truncate back
29756         echo "123" >> $file
29757         $TRUNCATE $file 1048576
29758         printf "Seeking hole from 1000000 ... "
29759         offset=$(lseek_test -l 1000000 $file)
29760         echo $offset
29761         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29762         printf "Seeking hole from 1048576 ... "
29763         lseek_test -l 1048576 $file && error "lseek should fail"
29764         # boundary checks for big values
29765         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29766         offset=$(lseek_test -d 0 $file.10g)
29767         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29768         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29769         offset=$(lseek_test -d 0 $file.100g)
29770         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29771         return 0
29772 }
29773 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29774
29775 test_430c() {
29776         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29777                 skip "OST does not support SEEK_HOLE"
29778
29779         local file=$DIR/$tdir/$tfile
29780         local start
29781
29782         mkdir -p $DIR/$tdir
29783         stack_trap "rm -f $file $file.tmp"
29784         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29785
29786         # cp version 8.33+ prefers lseek over fiemap
29787         local ver=$(cp --version | awk '{ print $4; exit; }')
29788
29789         echo "cp $ver installed"
29790         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29791                 start=$SECONDS
29792                 time cp -v $file $file.tmp || error "cp $file failed"
29793                 (( SECONDS - start < 5 )) || {
29794                         strace cp $file $file.tmp |&
29795                                 grep -E "open|read|seek|FIEMAP" |
29796                                 grep -A 100 $file
29797                         error "cp: too long runtime $((SECONDS - start))"
29798                 }
29799         else
29800                 echo "cp test skipped due to $ver < 8.33"
29801         fi
29802
29803         # tar version 1.29+ supports SEEK_HOLE/DATA
29804         ver=$(tar --version | awk '{ print $4; exit; }')
29805         echo "tar $ver installed"
29806         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29807                 start=$SECONDS
29808                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29809                 (( SECONDS - start < 5 )) || {
29810                         strace tar cf $file.tmp --sparse $file |&
29811                                 grep -E "open|read|seek|FIEMAP" |
29812                                 grep -A 100 $file
29813                         error "tar: too long runtime $((SECONDS - start))"
29814                 }
29815         else
29816                 echo "tar test skipped due to $ver < 1.29"
29817         fi
29818 }
29819 run_test 430c "lseek: external tools check"
29820
29821 test_431() { # LU-14187
29822         local file=$DIR/$tdir/$tfile
29823
29824         mkdir -p $DIR/$tdir
29825         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29826         dd if=/dev/urandom of=$file bs=4k count=1
29827         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29828         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29829         #define OBD_FAIL_OST_RESTART_IO 0x251
29830         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29831         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29832         cp $file $file.0
29833         cancel_lru_locks
29834         sync_all_data
29835         echo 3 > /proc/sys/vm/drop_caches
29836         diff  $file $file.0 || error "data diff"
29837 }
29838 run_test 431 "Restart transaction for IO"
29839
29840 cleanup_test_432() {
29841         do_facet mgs $LCTL nodemap_activate 0
29842         wait_nm_sync active
29843 }
29844
29845 test_432() {
29846         local tmpdir=$TMP/dir432
29847
29848         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29849                 skip "Need MDS version at least 2.14.52"
29850
29851         stack_trap cleanup_test_432 EXIT
29852         mkdir $DIR/$tdir
29853         mkdir $tmpdir
29854
29855         do_facet mgs $LCTL nodemap_activate 1
29856         wait_nm_sync active
29857         do_facet mgs $LCTL nodemap_modify --name default \
29858                 --property admin --value 1
29859         do_facet mgs $LCTL nodemap_modify --name default \
29860                 --property trusted --value 1
29861         cancel_lru_locks mdc
29862         wait_nm_sync default admin_nodemap
29863         wait_nm_sync default trusted_nodemap
29864
29865         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29866                grep -ci "Operation not permitted") -ne 0 ]; then
29867                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29868         fi
29869 }
29870 run_test 432 "mv dir from outside Lustre"
29871
29872 test_433() {
29873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29874
29875         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29876                 skip "inode cache not supported"
29877
29878         $LCTL set_param llite.*.inode_cache=0
29879         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29880
29881         local count=256
29882         local before
29883         local after
29884
29885         cancel_lru_locks mdc
29886         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29887         createmany -m $DIR/$tdir/f $count
29888         createmany -d $DIR/$tdir/d $count
29889         ls -l $DIR/$tdir > /dev/null
29890         stack_trap "rm -rf $DIR/$tdir"
29891
29892         before=$(num_objects)
29893         cancel_lru_locks mdc
29894         after=$(num_objects)
29895
29896         # sometimes even @before is less than 2 * count
29897         while (( before - after < count )); do
29898                 sleep 1
29899                 after=$(num_objects)
29900                 wait=$((wait + 1))
29901                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29902                 if (( wait > 60 )); then
29903                         error "inode slab grew from $before to $after"
29904                 fi
29905         done
29906
29907         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29908 }
29909 run_test 433 "ldlm lock cancel releases dentries and inodes"
29910
29911 test_434() {
29912         local file
29913         local getxattr_count
29914         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29915         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29916
29917         [[ $(getenforce) == "Disabled" ]] ||
29918                 skip "lsm selinux module have to be disabled for this test"
29919
29920         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29921                 error "fail to create $DIR/$tdir/ on MDT0000"
29922
29923         touch $DIR/$tdir/$tfile-{001..100}
29924
29925         # disable the xattr cache
29926         save_lustre_params client "llite.*.xattr_cache" > $p
29927         lctl set_param llite.*.xattr_cache=0
29928         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29929
29930         # clear clients mdc stats
29931         clear_stats $mdc_stat_param ||
29932                 error "fail to clear stats on mdc MDT0000"
29933
29934         for file in $DIR/$tdir/$tfile-{001..100}; do
29935                 getfattr -n security.selinux $file |&
29936                         grep -q "Operation not supported" ||
29937                         error "getxattr on security.selinux should return EOPNOTSUPP"
29938         done
29939
29940         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29941         (( getxattr_count < 100 )) ||
29942                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29943 }
29944 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29945
29946 test_440() {
29947         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29948                 source $LUSTRE/scripts/bash-completion/lustre
29949         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29950                 source /usr/share/bash-completion/completions/lustre
29951         else
29952                 skip "bash completion scripts not found"
29953         fi
29954
29955         local lctl_completions
29956         local lfs_completions
29957
29958         lctl_completions=$(_lustre_cmds lctl)
29959         if [[ ! $lctl_completions =~ "get_param" ]]; then
29960                 error "lctl bash completion failed"
29961         fi
29962
29963         lfs_completions=$(_lustre_cmds lfs)
29964         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29965                 error "lfs bash completion failed"
29966         fi
29967 }
29968 run_test 440 "bash completion for lfs, lctl"
29969
29970 test_442() {
29971         local pid1
29972         local pid2
29973         mkdir -p $DIR/$tdir
29974         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
29975         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
29976         sleep 1
29977         touch $DIR/$tdir/$tfile.2
29978         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
29979         $LCTL set_param fail_loc=0x1430
29980         kill -USR1 $pid1
29981         sleep 1
29982         kill -USR1 $pid2
29983         wait
29984 }
29985 run_test 442 "truncate vs read/write should not panic"
29986
29987 prep_801() {
29988         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29989         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29990                 skip "Need server version at least 2.9.55"
29991
29992         start_full_debug_logging
29993 }
29994
29995 post_801() {
29996         stop_full_debug_logging
29997 }
29998
29999 barrier_stat() {
30000         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30001                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30002                            awk '/The barrier for/ { print $7 }')
30003                 echo $st
30004         else
30005                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30006                 echo \'$st\'
30007         fi
30008 }
30009
30010 barrier_expired() {
30011         local expired
30012
30013         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30014                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30015                           awk '/will be expired/ { print $7 }')
30016         else
30017                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30018         fi
30019
30020         echo $expired
30021 }
30022
30023 test_801a() {
30024         prep_801
30025
30026         echo "Start barrier_freeze at: $(date)"
30027         #define OBD_FAIL_BARRIER_DELAY          0x2202
30028         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30029         # Do not reduce barrier time - See LU-11873
30030         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30031
30032         sleep 2
30033         local b_status=$(barrier_stat)
30034         echo "Got barrier status at: $(date)"
30035         [ "$b_status" = "'freezing_p1'" ] ||
30036                 error "(1) unexpected barrier status $b_status"
30037
30038         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30039         wait
30040         b_status=$(barrier_stat)
30041         [ "$b_status" = "'frozen'" ] ||
30042                 error "(2) unexpected barrier status $b_status"
30043
30044         local expired=$(barrier_expired)
30045         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30046         sleep $((expired + 3))
30047
30048         b_status=$(barrier_stat)
30049         [ "$b_status" = "'expired'" ] ||
30050                 error "(3) unexpected barrier status $b_status"
30051
30052         # Do not reduce barrier time - See LU-11873
30053         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30054                 error "(4) fail to freeze barrier"
30055
30056         b_status=$(barrier_stat)
30057         [ "$b_status" = "'frozen'" ] ||
30058                 error "(5) unexpected barrier status $b_status"
30059
30060         echo "Start barrier_thaw at: $(date)"
30061         #define OBD_FAIL_BARRIER_DELAY          0x2202
30062         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30063         do_facet mgs $LCTL barrier_thaw $FSNAME &
30064
30065         sleep 2
30066         b_status=$(barrier_stat)
30067         echo "Got barrier status at: $(date)"
30068         [ "$b_status" = "'thawing'" ] ||
30069                 error "(6) unexpected barrier status $b_status"
30070
30071         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30072         wait
30073         b_status=$(barrier_stat)
30074         [ "$b_status" = "'thawed'" ] ||
30075                 error "(7) unexpected barrier status $b_status"
30076
30077         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30078         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30079         do_facet mgs $LCTL barrier_freeze $FSNAME
30080
30081         b_status=$(barrier_stat)
30082         [ "$b_status" = "'failed'" ] ||
30083                 error "(8) unexpected barrier status $b_status"
30084
30085         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30086         do_facet mgs $LCTL barrier_thaw $FSNAME
30087
30088         post_801
30089 }
30090 run_test 801a "write barrier user interfaces and stat machine"
30091
30092 test_801b() {
30093         prep_801
30094
30095         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30096         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30097         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30098         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30099         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30100
30101         cancel_lru_locks mdc
30102
30103         # 180 seconds should be long enough
30104         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30105
30106         local b_status=$(barrier_stat)
30107         [ "$b_status" = "'frozen'" ] ||
30108                 error "(6) unexpected barrier status $b_status"
30109
30110         mkdir $DIR/$tdir/d0/d10 &
30111         mkdir_pid=$!
30112
30113         touch $DIR/$tdir/d1/f13 &
30114         touch_pid=$!
30115
30116         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30117         ln_pid=$!
30118
30119         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30120         mv_pid=$!
30121
30122         rm -f $DIR/$tdir/d4/f12 &
30123         rm_pid=$!
30124
30125         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30126
30127         # To guarantee taht the 'stat' is not blocked
30128         b_status=$(barrier_stat)
30129         [ "$b_status" = "'frozen'" ] ||
30130                 error "(8) unexpected barrier status $b_status"
30131
30132         # let above commands to run at background
30133         sleep 5
30134
30135         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30136         ps -p $touch_pid || error "(10) touch should be blocked"
30137         ps -p $ln_pid || error "(11) link should be blocked"
30138         ps -p $mv_pid || error "(12) rename should be blocked"
30139         ps -p $rm_pid || error "(13) unlink should be blocked"
30140
30141         b_status=$(barrier_stat)
30142         [ "$b_status" = "'frozen'" ] ||
30143                 error "(14) unexpected barrier status $b_status"
30144
30145         do_facet mgs $LCTL barrier_thaw $FSNAME
30146         b_status=$(barrier_stat)
30147         [ "$b_status" = "'thawed'" ] ||
30148                 error "(15) unexpected barrier status $b_status"
30149
30150         wait $mkdir_pid || error "(16) mkdir should succeed"
30151         wait $touch_pid || error "(17) touch should succeed"
30152         wait $ln_pid || error "(18) link should succeed"
30153         wait $mv_pid || error "(19) rename should succeed"
30154         wait $rm_pid || error "(20) unlink should succeed"
30155
30156         post_801
30157 }
30158 run_test 801b "modification will be blocked by write barrier"
30159
30160 test_801c() {
30161         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30162
30163         prep_801
30164
30165         stop mds2 || error "(1) Fail to stop mds2"
30166
30167         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30168
30169         local b_status=$(barrier_stat)
30170         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30171                 do_facet mgs $LCTL barrier_thaw $FSNAME
30172                 error "(2) unexpected barrier status $b_status"
30173         }
30174
30175         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30176                 error "(3) Fail to rescan barrier bitmap"
30177
30178         # Do not reduce barrier time - See LU-11873
30179         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30180
30181         b_status=$(barrier_stat)
30182         [ "$b_status" = "'frozen'" ] ||
30183                 error "(4) unexpected barrier status $b_status"
30184
30185         do_facet mgs $LCTL barrier_thaw $FSNAME
30186         b_status=$(barrier_stat)
30187         [ "$b_status" = "'thawed'" ] ||
30188                 error "(5) unexpected barrier status $b_status"
30189
30190         local devname=$(mdsdevname 2)
30191
30192         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30193
30194         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30195                 error "(7) Fail to rescan barrier bitmap"
30196
30197         post_801
30198 }
30199 run_test 801c "rescan barrier bitmap"
30200
30201 test_802b() {
30202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30203         remote_mds_nodsh && skip "remote MDS with nodsh"
30204
30205         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30206                 skip "readonly option not available"
30207
30208         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30209
30210         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30211                 error "(2) Fail to copy"
30212
30213         # write back all cached data before setting MDT to readonly
30214         cancel_lru_locks
30215         sync_all_data
30216
30217         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30218         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30219
30220         echo "Modify should be refused"
30221         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30222
30223         echo "Read should be allowed"
30224         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30225                 error "(7) Read should succeed under ro mode"
30226
30227         # disable readonly
30228         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30229 }
30230 run_test 802b "be able to set MDTs to readonly"
30231
30232 test_803a() {
30233         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30234         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30235                 skip "MDS needs to be newer than 2.10.54"
30236
30237         mkdir_on_mdt0 $DIR/$tdir
30238         # Create some objects on all MDTs to trigger related logs objects
30239         for idx in $(seq $MDSCOUNT); do
30240                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30241                         $DIR/$tdir/dir${idx} ||
30242                         error "Fail to create $DIR/$tdir/dir${idx}"
30243         done
30244
30245         wait_delete_completed # ensure old test cleanups are finished
30246         sleep 3
30247         echo "before create:"
30248         $LFS df -i $MOUNT
30249         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30250
30251         for i in {1..10}; do
30252                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30253                         error "Fail to create $DIR/$tdir/foo$i"
30254         done
30255
30256         # sync ZFS-on-MDS to refresh statfs data
30257         wait_zfs_commit mds1
30258         sleep 3
30259         echo "after create:"
30260         $LFS df -i $MOUNT
30261         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30262
30263         # allow for an llog to be cleaned up during the test
30264         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30265                 error "before ($before_used) + 10 > after ($after_used)"
30266
30267         for i in {1..10}; do
30268                 rm -rf $DIR/$tdir/foo$i ||
30269                         error "Fail to remove $DIR/$tdir/foo$i"
30270         done
30271
30272         # sync ZFS-on-MDS to refresh statfs data
30273         wait_zfs_commit mds1
30274         wait_delete_completed
30275         sleep 3 # avoid MDT return cached statfs
30276         echo "after unlink:"
30277         $LFS df -i $MOUNT
30278         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30279
30280         # allow for an llog to be created during the test
30281         [ $after_used -le $((before_used + 1)) ] ||
30282                 error "after ($after_used) > before ($before_used) + 1"
30283 }
30284 run_test 803a "verify agent object for remote object"
30285
30286 test_803b() {
30287         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30288         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30289                 skip "MDS needs to be newer than 2.13.56"
30290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30291
30292         for i in $(seq 0 $((MDSCOUNT - 1))); do
30293                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30294         done
30295
30296         local before=0
30297         local after=0
30298
30299         local tmp
30300
30301         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30302         for i in $(seq 0 $((MDSCOUNT - 1))); do
30303                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30304                         awk '/getattr/ { print $2 }')
30305                 before=$((before + tmp))
30306         done
30307         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30308         for i in $(seq 0 $((MDSCOUNT - 1))); do
30309                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30310                         awk '/getattr/ { print $2 }')
30311                 after=$((after + tmp))
30312         done
30313
30314         [ $before -eq $after ] || error "getattr count $before != $after"
30315 }
30316 run_test 803b "remote object can getattr from cache"
30317
30318 test_804() {
30319         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30320         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30321                 skip "MDS needs to be newer than 2.10.54"
30322         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30323
30324         mkdir -p $DIR/$tdir
30325         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30326                 error "Fail to create $DIR/$tdir/dir0"
30327
30328         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30329         local dev=$(mdsdevname 2)
30330
30331         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30332                 grep ${fid} || error "NOT found agent entry for dir0"
30333
30334         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30335                 error "Fail to create $DIR/$tdir/dir1"
30336
30337         touch $DIR/$tdir/dir1/foo0 ||
30338                 error "Fail to create $DIR/$tdir/dir1/foo0"
30339         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30340         local rc=0
30341
30342         for idx in $(seq $MDSCOUNT); do
30343                 dev=$(mdsdevname $idx)
30344                 do_facet mds${idx} \
30345                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30346                         grep ${fid} && rc=$idx
30347         done
30348
30349         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30350                 error "Fail to rename foo0 to foo1"
30351         if [ $rc -eq 0 ]; then
30352                 for idx in $(seq $MDSCOUNT); do
30353                         dev=$(mdsdevname $idx)
30354                         do_facet mds${idx} \
30355                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30356                         grep ${fid} && rc=$idx
30357                 done
30358         fi
30359
30360         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30361                 error "Fail to rename foo1 to foo2"
30362         if [ $rc -eq 0 ]; then
30363                 for idx in $(seq $MDSCOUNT); do
30364                         dev=$(mdsdevname $idx)
30365                         do_facet mds${idx} \
30366                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30367                         grep ${fid} && rc=$idx
30368                 done
30369         fi
30370
30371         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30372
30373         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30374                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30375         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30376                 error "Fail to rename foo2 to foo0"
30377         unlink $DIR/$tdir/dir1/foo0 ||
30378                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30379         rm -rf $DIR/$tdir/dir0 ||
30380                 error "Fail to rm $DIR/$tdir/dir0"
30381
30382         for idx in $(seq $MDSCOUNT); do
30383                 rc=0
30384
30385                 stop mds${idx}
30386                 dev=$(mdsdevname $idx)
30387                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30388                         rc=$?
30389                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30390                         error "mount mds$idx failed"
30391                 df $MOUNT > /dev/null 2>&1
30392
30393                 # e2fsck should not return error
30394                 [ $rc -eq 0 ] ||
30395                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30396         done
30397 }
30398 run_test 804 "verify agent entry for remote entry"
30399
30400 cleanup_805() {
30401         do_facet $SINGLEMDS zfs set quota=$old $fsset
30402         unlinkmany $DIR/$tdir/f- 1000000
30403         trap 0
30404 }
30405
30406 test_805() {
30407         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30408         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30409         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30410                 skip "netfree not implemented before 0.7"
30411         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30412                 skip "Need MDS version at least 2.10.57"
30413
30414         local fsset
30415         local freekb
30416         local usedkb
30417         local old
30418         local quota
30419         local pref="osd-zfs.$FSNAME-MDT0000."
30420
30421         # limit available space on MDS dataset to meet nospace issue
30422         # quickly. then ZFS 0.7.2 can use reserved space if asked
30423         # properly (using netfree flag in osd_declare_destroy()
30424         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30425         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30426                 gawk '{print $3}')
30427         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30428         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30429         let "usedkb=usedkb-freekb"
30430         let "freekb=freekb/2"
30431         if let "freekb > 5000"; then
30432                 let "freekb=5000"
30433         fi
30434         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30435         trap cleanup_805 EXIT
30436         mkdir_on_mdt0 $DIR/$tdir
30437         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30438                 error "Can't set PFL layout"
30439         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30440         rm -rf $DIR/$tdir || error "not able to remove"
30441         do_facet $SINGLEMDS zfs set quota=$old $fsset
30442         trap 0
30443 }
30444 run_test 805 "ZFS can remove from full fs"
30445
30446 # Size-on-MDS test
30447 check_lsom_data()
30448 {
30449         local file=$1
30450         local expect=$(stat -c %s $file)
30451
30452         check_lsom_size $1 $expect
30453
30454         local blocks=$($LFS getsom -b $file)
30455         expect=$(stat -c %b $file)
30456         [[ $blocks == $expect ]] ||
30457                 error "$file expected blocks: $expect, got: $blocks"
30458 }
30459
30460 check_lsom_size()
30461 {
30462         local size
30463         local expect=$2
30464
30465         cancel_lru_locks mdc
30466
30467         size=$($LFS getsom -s $1)
30468         [[ $size == $expect ]] ||
30469                 error "$file expected size: $expect, got: $size"
30470 }
30471
30472 test_806() {
30473         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30474                 skip "Need MDS version at least 2.11.52"
30475
30476         local bs=1048576
30477
30478         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30479
30480         disable_opencache
30481         stack_trap "restore_opencache"
30482
30483         # single-threaded write
30484         echo "Test SOM for single-threaded write"
30485         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30486                 error "write $tfile failed"
30487         check_lsom_size $DIR/$tfile $bs
30488
30489         local num=32
30490         local size=$(($num * $bs))
30491         local offset=0
30492         local i
30493
30494         echo "Test SOM for single client multi-threaded($num) write"
30495         $TRUNCATE $DIR/$tfile 0
30496         for ((i = 0; i < $num; i++)); do
30497                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30498                 local pids[$i]=$!
30499                 offset=$((offset + $bs))
30500         done
30501         for (( i=0; i < $num; i++ )); do
30502                 wait ${pids[$i]}
30503         done
30504         check_lsom_size $DIR/$tfile $size
30505
30506         $TRUNCATE $DIR/$tfile 0
30507         for ((i = 0; i < $num; i++)); do
30508                 offset=$((offset - $bs))
30509                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30510                 local pids[$i]=$!
30511         done
30512         for (( i=0; i < $num; i++ )); do
30513                 wait ${pids[$i]}
30514         done
30515         check_lsom_size $DIR/$tfile $size
30516
30517         # multi-client writes
30518         num=$(get_node_count ${CLIENTS//,/ })
30519         size=$(($num * $bs))
30520         offset=0
30521         i=0
30522
30523         echo "Test SOM for multi-client ($num) writes"
30524         $TRUNCATE $DIR/$tfile 0
30525         for client in ${CLIENTS//,/ }; do
30526                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30527                 local pids[$i]=$!
30528                 i=$((i + 1))
30529                 offset=$((offset + $bs))
30530         done
30531         for (( i=0; i < $num; i++ )); do
30532                 wait ${pids[$i]}
30533         done
30534         check_lsom_size $DIR/$tfile $offset
30535
30536         i=0
30537         $TRUNCATE $DIR/$tfile 0
30538         for client in ${CLIENTS//,/ }; do
30539                 offset=$((offset - $bs))
30540                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30541                 local pids[$i]=$!
30542                 i=$((i + 1))
30543         done
30544         for (( i=0; i < $num; i++ )); do
30545                 wait ${pids[$i]}
30546         done
30547         check_lsom_size $DIR/$tfile $size
30548
30549         # verify SOM blocks count
30550         echo "Verify SOM block count"
30551         $TRUNCATE $DIR/$tfile 0
30552         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30553                 error "failed to write file $tfile with fdatasync and fstat"
30554         check_lsom_data $DIR/$tfile
30555
30556         $TRUNCATE $DIR/$tfile 0
30557         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30558                 error "failed to write file $tfile with fdatasync"
30559         check_lsom_data $DIR/$tfile
30560
30561         $TRUNCATE $DIR/$tfile 0
30562         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30563                 error "failed to write file $tfile with sync IO"
30564         check_lsom_data $DIR/$tfile
30565
30566         # verify truncate
30567         echo "Test SOM for truncate"
30568         # use ftruncate to sync blocks on close request
30569         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30570         check_lsom_size $DIR/$tfile 16384
30571         check_lsom_data $DIR/$tfile
30572
30573         $TRUNCATE $DIR/$tfile 1234
30574         check_lsom_size $DIR/$tfile 1234
30575         # sync blocks on the MDT
30576         $MULTIOP $DIR/$tfile oc
30577         check_lsom_data $DIR/$tfile
30578 }
30579 run_test 806 "Verify Lazy Size on MDS"
30580
30581 test_807() {
30582         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30583         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30584                 skip "Need MDS version at least 2.11.52"
30585
30586         # Registration step
30587         changelog_register || error "changelog_register failed"
30588         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30589         changelog_users $SINGLEMDS | grep -q $cl_user ||
30590                 error "User $cl_user not found in changelog_users"
30591
30592         rm -rf $DIR/$tdir || error "rm $tdir failed"
30593         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30594         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30595         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30596         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30597                 error "truncate $tdir/trunc failed"
30598
30599         local bs=1048576
30600         echo "Test SOM for single-threaded write with fsync"
30601         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30602                 error "write $tfile failed"
30603         sync;sync;sync
30604
30605         # multi-client wirtes
30606         local num=$(get_node_count ${CLIENTS//,/ })
30607         local offset=0
30608         local i=0
30609
30610         echo "Test SOM for multi-client ($num) writes"
30611         touch $DIR/$tfile || error "touch $tfile failed"
30612         $TRUNCATE $DIR/$tfile 0
30613         for client in ${CLIENTS//,/ }; do
30614                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30615                 local pids[$i]=$!
30616                 i=$((i + 1))
30617                 offset=$((offset + $bs))
30618         done
30619         for (( i=0; i < $num; i++ )); do
30620                 wait ${pids[$i]}
30621         done
30622
30623         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30624         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30625         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30626         check_lsom_data $DIR/$tdir/trunc
30627         check_lsom_data $DIR/$tdir/single_dd
30628         check_lsom_data $DIR/$tfile
30629
30630         rm -rf $DIR/$tdir
30631         # Deregistration step
30632         changelog_deregister || error "changelog_deregister failed"
30633 }
30634 run_test 807 "verify LSOM syncing tool"
30635
30636 check_som_nologged()
30637 {
30638         local lines=$($LFS changelog $FSNAME-MDT0000 |
30639                 grep 'x=trusted.som' | wc -l)
30640         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30641 }
30642
30643 test_808() {
30644         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30645                 skip "Need MDS version at least 2.11.55"
30646
30647         # Registration step
30648         changelog_register || error "changelog_register failed"
30649
30650         touch $DIR/$tfile || error "touch $tfile failed"
30651         check_som_nologged
30652
30653         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30654                 error "write $tfile failed"
30655         check_som_nologged
30656
30657         $TRUNCATE $DIR/$tfile 1234
30658         check_som_nologged
30659
30660         $TRUNCATE $DIR/$tfile 1048576
30661         check_som_nologged
30662
30663         # Deregistration step
30664         changelog_deregister || error "changelog_deregister failed"
30665 }
30666 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30667
30668 check_som_nodata()
30669 {
30670         $LFS getsom $1
30671         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30672 }
30673
30674 test_809() {
30675         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30676                 skip "Need MDS version at least 2.11.56"
30677
30678         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30679                 error "failed to create DoM-only file $DIR/$tfile"
30680         touch $DIR/$tfile || error "touch $tfile failed"
30681         check_som_nodata $DIR/$tfile
30682
30683         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30684                 error "write $tfile failed"
30685         check_som_nodata $DIR/$tfile
30686
30687         $TRUNCATE $DIR/$tfile 1234
30688         check_som_nodata $DIR/$tfile
30689
30690         $TRUNCATE $DIR/$tfile 4097
30691         check_som_nodata $DIR/$file
30692 }
30693 run_test 809 "Verify no SOM xattr store for DoM-only files"
30694
30695 test_810() {
30696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30697         $GSS && skip_env "could not run with gss"
30698         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30699                 skip "OST < 2.12.58 doesn't align checksum"
30700
30701         set_checksums 1
30702         stack_trap "set_checksums $ORIG_CSUM" EXIT
30703         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30704
30705         local csum
30706         local before
30707         local after
30708         for csum in $CKSUM_TYPES; do
30709                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30710                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30711                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30712                         eval set -- $i
30713                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30714                         before=$(md5sum $DIR/$tfile)
30715                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30716                         after=$(md5sum $DIR/$tfile)
30717                         [ "$before" == "$after" ] ||
30718                                 error "$csum: $before != $after bs=$1 seek=$2"
30719                 done
30720         done
30721 }
30722 run_test 810 "partial page writes on ZFS (LU-11663)"
30723
30724 test_812a() {
30725         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30726                 skip "OST < 2.12.51 doesn't support this fail_loc"
30727
30728         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30729         # ensure ost1 is connected
30730         stat $DIR/$tfile >/dev/null || error "can't stat"
30731         wait_osc_import_state client ost1 FULL
30732         # no locks, no reqs to let the connection idle
30733         cancel_lru_locks osc
30734
30735         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30736 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30737         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30738         wait_osc_import_state client ost1 CONNECTING
30739         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30740
30741         stat $DIR/$tfile >/dev/null || error "can't stat file"
30742 }
30743 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30744
30745 test_812b() { # LU-12378
30746         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30747                 skip "OST < 2.12.51 doesn't support this fail_loc"
30748
30749         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30750         # ensure ost1 is connected
30751         stat $DIR/$tfile >/dev/null || error "can't stat"
30752         wait_osc_import_state client ost1 FULL
30753         # no locks, no reqs to let the connection idle
30754         cancel_lru_locks osc
30755
30756         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30757 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30758         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30759         wait_osc_import_state client ost1 CONNECTING
30760         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30761
30762         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30763         wait_osc_import_state client ost1 IDLE
30764 }
30765 run_test 812b "do not drop no resend request for idle connect"
30766
30767 test_812c() {
30768         local old
30769
30770         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30771
30772         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30773         $LFS getstripe $DIR/$tfile
30774         $LCTL set_param osc.*.idle_timeout=10
30775         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30776         # ensure ost1 is connected
30777         stat $DIR/$tfile >/dev/null || error "can't stat"
30778         wait_osc_import_state client ost1 FULL
30779         # no locks, no reqs to let the connection idle
30780         cancel_lru_locks osc
30781
30782 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30783         $LCTL set_param fail_loc=0x80000533
30784         sleep 15
30785         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30786 }
30787 run_test 812c "idle import vs lock enqueue race"
30788
30789 test_813() {
30790         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30791         [ -z "$file_heat_sav" ] && skip "no file heat support"
30792
30793         local readsample
30794         local writesample
30795         local readbyte
30796         local writebyte
30797         local readsample1
30798         local writesample1
30799         local readbyte1
30800         local writebyte1
30801
30802         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30803         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30804
30805         $LCTL set_param -n llite.*.file_heat=1
30806         echo "Turn on file heat"
30807         echo "Period second: $period_second, Decay percentage: $decay_pct"
30808
30809         echo "QQQQ" > $DIR/$tfile
30810         echo "QQQQ" > $DIR/$tfile
30811         echo "QQQQ" > $DIR/$tfile
30812         cat $DIR/$tfile > /dev/null
30813         cat $DIR/$tfile > /dev/null
30814         cat $DIR/$tfile > /dev/null
30815         cat $DIR/$tfile > /dev/null
30816
30817         local out=$($LFS heat_get $DIR/$tfile)
30818
30819         $LFS heat_get $DIR/$tfile
30820         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30821         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30822         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30823         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30824
30825         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30826         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30827         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30828         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30829
30830         sleep $((period_second + 3))
30831         echo "Sleep $((period_second + 3)) seconds..."
30832         # The recursion formula to calculate the heat of the file f is as
30833         # follow:
30834         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30835         # Where Hi is the heat value in the period between time points i*I and
30836         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30837         # to the weight of Ci.
30838         out=$($LFS heat_get $DIR/$tfile)
30839         $LFS heat_get $DIR/$tfile
30840         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30841         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30842         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30843         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30844
30845         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30846                 error "read sample ($readsample) is wrong"
30847         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30848                 error "write sample ($writesample) is wrong"
30849         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30850                 error "read bytes ($readbyte) is wrong"
30851         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30852                 error "write bytes ($writebyte) is wrong"
30853
30854         echo "QQQQ" > $DIR/$tfile
30855         echo "QQQQ" > $DIR/$tfile
30856         echo "QQQQ" > $DIR/$tfile
30857         cat $DIR/$tfile > /dev/null
30858         cat $DIR/$tfile > /dev/null
30859         cat $DIR/$tfile > /dev/null
30860         cat $DIR/$tfile > /dev/null
30861
30862         sleep $((period_second + 3))
30863         echo "Sleep $((period_second + 3)) seconds..."
30864
30865         out=$($LFS heat_get $DIR/$tfile)
30866         $LFS heat_get $DIR/$tfile
30867         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30868         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30869         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30870         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30871
30872         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30873                 4 * $decay_pct) / 100") -eq 1 ] ||
30874                 error "read sample ($readsample1) is wrong"
30875         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30876                 3 * $decay_pct) / 100") -eq 1 ] ||
30877                 error "write sample ($writesample1) is wrong"
30878         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30879                 20 * $decay_pct) / 100") -eq 1 ] ||
30880                 error "read bytes ($readbyte1) is wrong"
30881         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30882                 15 * $decay_pct) / 100") -eq 1 ] ||
30883                 error "write bytes ($writebyte1) is wrong"
30884
30885         echo "Turn off file heat for the file $DIR/$tfile"
30886         $LFS heat_set -o $DIR/$tfile
30887
30888         echo "QQQQ" > $DIR/$tfile
30889         echo "QQQQ" > $DIR/$tfile
30890         echo "QQQQ" > $DIR/$tfile
30891         cat $DIR/$tfile > /dev/null
30892         cat $DIR/$tfile > /dev/null
30893         cat $DIR/$tfile > /dev/null
30894         cat $DIR/$tfile > /dev/null
30895
30896         out=$($LFS heat_get $DIR/$tfile)
30897         $LFS heat_get $DIR/$tfile
30898         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30899         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30900         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30901         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30902
30903         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30904         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30905         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30906         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30907
30908         echo "Trun on file heat for the file $DIR/$tfile"
30909         $LFS heat_set -O $DIR/$tfile
30910
30911         echo "QQQQ" > $DIR/$tfile
30912         echo "QQQQ" > $DIR/$tfile
30913         echo "QQQQ" > $DIR/$tfile
30914         cat $DIR/$tfile > /dev/null
30915         cat $DIR/$tfile > /dev/null
30916         cat $DIR/$tfile > /dev/null
30917         cat $DIR/$tfile > /dev/null
30918
30919         out=$($LFS heat_get $DIR/$tfile)
30920         $LFS heat_get $DIR/$tfile
30921         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30922         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30923         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30924         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30925
30926         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30927         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30928         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30929         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30930
30931         $LFS heat_set -c $DIR/$tfile
30932         $LCTL set_param -n llite.*.file_heat=0
30933         echo "Turn off file heat support for the Lustre filesystem"
30934
30935         echo "QQQQ" > $DIR/$tfile
30936         echo "QQQQ" > $DIR/$tfile
30937         echo "QQQQ" > $DIR/$tfile
30938         cat $DIR/$tfile > /dev/null
30939         cat $DIR/$tfile > /dev/null
30940         cat $DIR/$tfile > /dev/null
30941         cat $DIR/$tfile > /dev/null
30942
30943         out=$($LFS heat_get $DIR/$tfile)
30944         $LFS heat_get $DIR/$tfile
30945         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30946         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30947         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30948         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30949
30950         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30951         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30952         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30953         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30954
30955         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30956         rm -f $DIR/$tfile
30957 }
30958 run_test 813 "File heat verfication"
30959
30960 test_814()
30961 {
30962         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30963         echo -n y >> $DIR/$tfile
30964         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30965         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30966 }
30967 run_test 814 "sparse cp works as expected (LU-12361)"
30968
30969 test_815()
30970 {
30971         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30972         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30973 }
30974 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30975
30976 test_816() {
30977         local ost1_imp=$(get_osc_import_name client ost1)
30978         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30979                          cut -d'.' -f2)
30980
30981         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30982         # ensure ost1 is connected
30983
30984         stat $DIR/$tfile >/dev/null || error "can't stat"
30985         wait_osc_import_state client ost1 FULL
30986         # no locks, no reqs to let the connection idle
30987         cancel_lru_locks osc
30988         lru_resize_disable osc
30989         local before
30990         local now
30991         before=$($LCTL get_param -n \
30992                  ldlm.namespaces.$imp_name.lru_size)
30993
30994         wait_osc_import_state client ost1 IDLE
30995         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30996         now=$($LCTL get_param -n \
30997               ldlm.namespaces.$imp_name.lru_size)
30998         [ $before == $now ] || error "lru_size changed $before != $now"
30999 }
31000 run_test 816 "do not reset lru_resize on idle reconnect"
31001
31002 cleanup_817() {
31003         umount $tmpdir
31004         exportfs -u localhost:$DIR/nfsexp
31005         rm -rf $DIR/nfsexp
31006 }
31007
31008 test_817() {
31009         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31010
31011         mkdir -p $DIR/nfsexp
31012         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31013                 error "failed to export nfs"
31014
31015         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31016         stack_trap cleanup_817 EXIT
31017
31018         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31019                 error "failed to mount nfs to $tmpdir"
31020
31021         cp /bin/true $tmpdir
31022         $DIR/nfsexp/true || error "failed to execute 'true' command"
31023 }
31024 run_test 817 "nfsd won't cache write lock for exec file"
31025
31026 test_818() {
31027         test_mkdir -i0 -c1 $DIR/$tdir
31028         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31029         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31030         stop $SINGLEMDS
31031
31032         # restore osp-syn threads
31033         stack_trap "fail $SINGLEMDS"
31034
31035         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31036         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31037         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31038                 error "start $SINGLEMDS failed"
31039         rm -rf $DIR/$tdir
31040
31041         local testid=$(echo $TESTNAME | tr '_' ' ')
31042
31043         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31044                 grep "run LFSCK" || error "run LFSCK is not suggested"
31045 }
31046 run_test 818 "unlink with failed llog"
31047
31048 test_819a() {
31049         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31050         cancel_lru_locks osc
31051         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31052         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31053         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31054         rm -f $TDIR/$tfile
31055 }
31056 run_test 819a "too big niobuf in read"
31057
31058 test_819b() {
31059         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31060         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31062         cancel_lru_locks osc
31063         sleep 1
31064         rm -f $TDIR/$tfile
31065 }
31066 run_test 819b "too big niobuf in write"
31067
31068
31069 function test_820_start_ost() {
31070         sleep 5
31071
31072         for num in $(seq $OSTCOUNT); do
31073                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31074         done
31075 }
31076
31077 test_820() {
31078         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31079
31080         mkdir $DIR/$tdir
31081         umount_client $MOUNT || error "umount failed"
31082         for num in $(seq $OSTCOUNT); do
31083                 stop ost$num
31084         done
31085
31086         # mount client with no active OSTs
31087         # so that the client can't initialize max LOV EA size
31088         # from OSC notifications
31089         mount_client $MOUNT || error "mount failed"
31090         # delay OST starting to keep this 0 max EA size for a while
31091         test_820_start_ost &
31092
31093         # create a directory on MDS2
31094         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31095                 error "Failed to create directory"
31096         # open intent should update default EA size
31097         # see mdc_update_max_ea_from_body()
31098         # notice this is the very first RPC to MDS2
31099         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31100         ret=$?
31101         echo $out
31102         # With SSK, this situation can lead to -EPERM being returned.
31103         # In that case, simply retry.
31104         if [ $ret -ne 0 ] && $SHARED_KEY; then
31105                 if echo "$out" | grep -q "not permitted"; then
31106                         cp /etc/services $DIR/$tdir/mds2
31107                         ret=$?
31108                 fi
31109         fi
31110         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31111 }
31112 run_test 820 "update max EA from open intent"
31113
31114 test_823() {
31115         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31116         local OST_MAX_PRECREATE=20000
31117
31118         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31119                 skip "Need MDS version at least 2.14.56"
31120
31121         save_lustre_params mds1 \
31122                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31123         do_facet $SINGLEMDS "$LCTL set_param -n \
31124                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31125         do_facet $SINGLEMDS "$LCTL set_param -n \
31126                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31127
31128         stack_trap "restore_lustre_params < $p; rm $p"
31129
31130         do_facet $SINGLEMDS "$LCTL set_param -n \
31131                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31132
31133         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31134                       osp.$FSNAME-OST0000*MDT0000.create_count")
31135         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31136                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31137         local expect_count=$(((($max/2)/256) * 256))
31138
31139         log "setting create_count to 100200:"
31140         log " -result- count: $count with max: $max, expecting: $expect_count"
31141
31142         [[ $count -eq expect_count ]] ||
31143                 error "Create count not set to max precreate."
31144 }
31145 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31146
31147 test_831() {
31148         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31149                 skip "Need MDS version 2.14.56"
31150
31151         local sync_changes=$(do_facet $SINGLEMDS \
31152                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31153
31154         [ "$sync_changes" -gt 100 ] &&
31155                 skip "Sync changes $sync_changes > 100 already"
31156
31157         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31158
31159         $LFS mkdir -i 0 $DIR/$tdir
31160         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31161
31162         save_lustre_params mds1 \
31163                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31164         save_lustre_params mds1 \
31165                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31166
31167         do_facet mds1 "$LCTL set_param -n \
31168                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31169                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31170         stack_trap "restore_lustre_params < $p" EXIT
31171
31172         createmany -o $DIR/$tdir/f- 1000
31173         unlinkmany $DIR/$tdir/f- 1000 &
31174         local UNLINK_PID=$!
31175
31176         while sleep 1; do
31177                 sync_changes=$(do_facet mds1 \
31178                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31179                 # the check in the code is racy, fail the test
31180                 # if the value above the limit by 10.
31181                 [ $sync_changes -gt 110 ] && {
31182                         kill -2 $UNLINK_PID
31183                         wait
31184                         error "osp changes throttling failed, $sync_changes>110"
31185                 }
31186                 kill -0 $UNLINK_PID 2> /dev/null || break
31187         done
31188         wait
31189 }
31190 run_test 831 "throttling unlink/setattr queuing on OSP"
31191
31192 test_832() {
31193         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31194         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31195                 skip "Need MDS version 2.15.52+"
31196         is_rmentry_supported || skip "rm_entry not supported"
31197
31198         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31199         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31200         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31201                 error "mkdir remote_dir failed"
31202         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31203                 error "mkdir striped_dir failed"
31204         touch $DIR/$tdir/file || error "touch file failed"
31205         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31206         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31207 }
31208 run_test 832 "lfs rm_entry"
31209
31210 test_833() {
31211         local file=$DIR/$tfile
31212
31213         stack_trap "rm -f $file" EXIT
31214         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31215
31216         local wpid
31217         local rpid
31218         local rpid2
31219
31220         # Buffered I/O write
31221         (
31222                 while [ ! -e $DIR/sanity.833.lck ]; do
31223                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31224                                 error "failed to write $file"
31225                         sleep 0.$((RANDOM % 4 + 1))
31226                 done
31227         )&
31228         wpid=$!
31229
31230         # Buffered I/O read
31231         (
31232                 while [ ! -e $DIR/sanity.833.lck ]; do
31233                         dd if=$file of=/dev/null bs=1M count=50 ||
31234                                 error "failed to read $file"
31235                         sleep 0.$((RANDOM % 4 + 1))
31236                 done
31237         )&
31238         rpid=$!
31239
31240         # Direct I/O read
31241         (
31242                 while [ ! -e $DIR/sanity.833.lck ]; do
31243                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31244                                 error "failed to read $file in direct I/O mode"
31245                         sleep 0.$((RANDOM % 4 + 1))
31246                 done
31247         )&
31248         rpid2=$!
31249
31250         sleep 30
31251         touch $DIR/sanity.833.lck
31252         wait $wpid || error "$?: buffered write failed"
31253         wait $rpid || error "$?: buffered read failed"
31254         wait $rpid2 || error "$?: direct read failed"
31255 }
31256 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31257
31258 test_850() {
31259         local dir=$DIR/$tdir
31260         local file=$dir/$tfile
31261         local statsfile=$dir/all_job_stats.txt
31262
31263         test_mkdir -p $dir || error "failed to create dir $dir"
31264         echo "abcdefg" > $file || error "failed to create file $file"
31265
31266         # read job_stats in the living system
31267         lljobstat -n 1 ||
31268                 error "failed to run lljobstat on living system"
31269
31270         $LCTL get_param *.*.job_stats > $statsfile
31271         lljobstat --statsfile=$statsfile ||
31272                 error "failed to run lljobstat on file $statsfile"
31273 }
31274 run_test 850 "lljobstat can parse living and aggregated job_stats"
31275
31276 #
31277 # tests that do cleanup/setup should be run at the end
31278 #
31279
31280 test_900() {
31281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31282         local ls
31283
31284         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31285         $LCTL set_param fail_loc=0x903
31286
31287         cancel_lru_locks MGC
31288
31289         FAIL_ON_ERROR=true cleanup
31290         FAIL_ON_ERROR=true setup
31291 }
31292 run_test 900 "umount should not race with any mgc requeue thread"
31293
31294 # LUS-6253/LU-11185
31295 test_901() {
31296         local old
31297         local count
31298         local oldc
31299         local newc
31300         local olds
31301         local news
31302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31303
31304         # some get_param have a bug to handle dot in param name
31305         cancel_lru_locks MGC
31306         old=$(mount -t lustre | wc -l)
31307         # 1 config+sptlrpc
31308         # 2 params
31309         # 3 nodemap
31310         # 4 IR
31311         old=$((old * 4))
31312         oldc=0
31313         count=0
31314         while [ $old -ne $oldc ]; do
31315                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31316                 sleep 1
31317                 ((count++))
31318                 if [ $count -ge $TIMEOUT ]; then
31319                         error "too large timeout"
31320                 fi
31321         done
31322         umount_client $MOUNT || error "umount failed"
31323         mount_client $MOUNT || error "mount failed"
31324         cancel_lru_locks MGC
31325         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31326
31327         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31328
31329         return 0
31330 }
31331 run_test 901 "don't leak a mgc lock on client umount"
31332
31333 # LU-13377
31334 test_902() {
31335         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31336                 skip "client does not have LU-13377 fix"
31337         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31338         $LCTL set_param fail_loc=0x1415
31339         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31340         cancel_lru_locks osc
31341         rm -f $DIR/$tfile
31342 }
31343 run_test 902 "test short write doesn't hang lustre"
31344
31345 # LU-14711
31346 test_903() {
31347         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31348         echo "blah" > $DIR/${tfile}-2
31349         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31350         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31351         $LCTL set_param fail_loc=0x417 fail_val=20
31352
31353         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31354         sleep 1 # To start the destroy
31355         wait_destroy_complete 150 || error "Destroy taking too long"
31356         cat $DIR/$tfile > /dev/null || error "Evicted"
31357 }
31358 run_test 903 "Test long page discard does not cause evictions"
31359
31360 test_904() {
31361         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31362         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31363                 grep -q project || skip "skip project quota not supported"
31364
31365         local testfile="$DIR/$tdir/$tfile"
31366         local xattr="trusted.projid"
31367         local projid
31368         local mdts=$(comma_list $(mdts_nodes))
31369         local saved=$(do_facet mds1 $LCTL get_param -n \
31370                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31371
31372         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31373         stack_trap "do_nodes $mdts $LCTL set_param \
31374                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31375
31376         mkdir -p $DIR/$tdir
31377         touch $testfile
31378         #hide projid xattr on server
31379         $LFS project -p 1 $testfile ||
31380                 error "set $testfile project id failed"
31381         getfattr -m - $testfile | grep $xattr &&
31382                 error "do not show trusted.projid when disabled on server"
31383         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31384         #should be hidden when projid is 0
31385         $LFS project -p 0 $testfile ||
31386                 error "set $testfile project id failed"
31387         getfattr -m - $testfile | grep $xattr &&
31388                 error "do not show trusted.projid with project ID 0"
31389
31390         #still can getxattr explicitly
31391         projid=$(getfattr -n $xattr $testfile |
31392                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31393         [ $projid == "0" ] ||
31394                 error "projid expected 0 not $projid"
31395
31396         #set the projid via setxattr
31397         setfattr -n $xattr -v "1000" $testfile ||
31398                 error "setattr failed with $?"
31399         projid=($($LFS project $testfile))
31400         [ ${projid[0]} == "1000" ] ||
31401                 error "projid expected 1000 not $projid"
31402
31403         #check the new projid via getxattr
31404         $LFS project -p 1001 $testfile ||
31405                 error "set $testfile project id failed"
31406         getfattr -m - $testfile | grep $xattr ||
31407                 error "should show trusted.projid when project ID != 0"
31408         projid=$(getfattr -n $xattr $testfile |
31409                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31410         [ $projid == "1001" ] ||
31411                 error "projid expected 1001 not $projid"
31412
31413         #try to set invalid projid
31414         setfattr -n $xattr -v "4294967295" $testfile &&
31415                 error "set invalid projid should fail"
31416
31417         #remove the xattr means setting projid to 0
31418         setfattr -x $xattr $testfile ||
31419                 error "setfattr failed with $?"
31420         projid=($($LFS project $testfile))
31421         [ ${projid[0]} == "0" ] ||
31422                 error "projid expected 0 not $projid"
31423
31424         #should be hidden when parent has inherit flag and same projid
31425         $LFS project -srp 1002 $DIR/$tdir ||
31426                 error "set $tdir project id failed"
31427         getfattr -m - $testfile | grep $xattr &&
31428                 error "do not show trusted.projid with inherit flag"
31429
31430         #still can getxattr explicitly
31431         projid=$(getfattr -n $xattr $testfile |
31432                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31433         [ $projid == "1002" ] ||
31434                 error "projid expected 1002 not $projid"
31435 }
31436 run_test 904 "virtual project ID xattr"
31437
31438 # LU-8582
31439 test_905() {
31440         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31441                 skip "need OST version >= 2.15.50.220 for fail_loc"
31442
31443         remote_ost_nodsh && skip "remote OST with nodsh"
31444         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31445
31446         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31447
31448         #define OBD_FAIL_OST_OPCODE 0x253
31449         # OST_LADVISE = 21
31450         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31451         $LFS ladvise -a willread $DIR/$tfile &&
31452                 error "unexpected success of ladvise with fault injection"
31453         $LFS ladvise -a willread $DIR/$tfile |&
31454                 grep -q "Operation not supported"
31455         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31456 }
31457 run_test 905 "bad or new opcode should not stuck client"
31458
31459 test_906() {
31460         grep -q io_uring_setup /proc/kallsyms ||
31461                 skip "Client OS does not support io_uring I/O engine"
31462         io_uring_probe || skip "kernel does not support io_uring fully"
31463         which fio || skip_env "no fio installed"
31464         fio --enghelp | grep -q io_uring ||
31465                 skip_env "fio does not support io_uring I/O engine"
31466
31467         local file=$DIR/$tfile
31468         local ioengine="io_uring"
31469         local numjobs=2
31470         local size=50M
31471
31472         fio --name=seqwrite --ioengine=$ioengine        \
31473                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31474                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31475                 error "fio seqwrite $file failed"
31476
31477         fio --name=seqread --ioengine=$ioengine \
31478                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31479                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31480                 error "fio seqread $file failed"
31481
31482         rm -f $file || error "rm -f $file failed"
31483 }
31484 run_test 906 "Simple test for io_uring I/O engine via fio"
31485
31486 test_907() {
31487         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31488
31489         # set stripe size to max rpc size
31490         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31491         $LFS getstripe $DIR/$tfile
31492 #define OBD_FAIL_OST_EROFS               0x216
31493         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31494
31495         local bs=$((max_pages * PAGE_SIZE / 16))
31496
31497         # write full one stripe and one block
31498         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31499
31500         rm $DIR/$tfile || error "rm failed"
31501 }
31502 run_test 907 "write rpc error during unlink"
31503
31504
31505 complete_test $SECONDS
31506 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31507 check_and_cleanup_lustre
31508 if [ "$I_MOUNTED" != "yes" ]; then
31509         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31510 fi
31511 exit_status