Whamcloud - gitweb
LU-16194 lod: define negative extent offset as invalid
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47 fi
48
49 # skip the grant tests for ARM until they are fixed
50 if [[ $(uname -m) = aarch64 ]]; then
51         always_except LU-11671 45
52 fi
53
54 # skip nfs tests on kernels >= 4.12.0 until they are fixed
55 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
56         always_except LU-12661 817
57 fi
58 # skip cgroup tests on RHEL8.1 kernels until they are fixed
59 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
60       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
61         always_except LU-13063 411
62 fi
63
64 #                                  5              12     8   12  15   (min)"
65 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
66
67 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
68         #                                               13    (min)"
69         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
70 fi
71
72 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
73         always_except LU-1941 130b 130c 130d 130e 130f 130g
74         always_except LU-9054 312
75 fi
76
77 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
78
79 # Get the SLES distro version
80 #
81 # Returns a version string that should only be used in comparing
82 # strings returned by version_code()
83 sles_version_code()
84 {
85         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
86
87         # All SuSE Linux versions have one decimal. version_code expects two
88         local sles_version=$version.0
89         version_code $sles_version
90 }
91
92 # Check if we are running on Ubuntu or SLES so we can make decisions on
93 # what tests to run
94 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
95         sles_version=$(sles_version_code)
96         [ $sles_version -lt $(version_code 11.4.0) ] &&
97                 always_except LU-4341 170
98
99         [ $sles_version -lt $(version_code 12.0.0) ] &&
100                 always_except LU-3703 234
101 elif [ -r /etc/os-release ]; then
102         if grep -qi ubuntu /etc/os-release; then
103                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
104                                                 -e 's/^VERSION=//p' \
105                                                 /etc/os-release |
106                                                 awk '{ print $1 }'))
107
108                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
109                         always_except LU-10366 410
110                 fi
111         fi
112 fi
113
114 build_test_filter
115 FAIL_ON_ERROR=false
116
117 cleanup() {
118         echo -n "cln.."
119         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
120         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
121 }
122 setup() {
123         echo -n "mnt.."
124         load_modules
125         setupall || exit 10
126         echo "done"
127 }
128
129 check_swap_layouts_support()
130 {
131         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
132                 skip "Does not support layout lock."
133 }
134
135 check_swap_layout_no_dom()
136 {
137         local FOLDER=$1
138         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
139         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
140 }
141
142 check_and_setup_lustre
143 DIR=${DIR:-$MOUNT}
144 assert_DIR
145
146 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
147
148 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
149 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
150 rm -rf $DIR/[Rdfs][0-9]*
151
152 # $RUNAS_ID may get set incorrectly somewhere else
153 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
154         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
155
156 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
157
158 if [ "${ONLY}" = "MOUNT" ] ; then
159         echo "Lustre is up, please go on"
160         exit
161 fi
162
163 echo "preparing for tests involving mounts"
164 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
165 touch $EXT2_DEV
166 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
167 echo # add a newline after mke2fs.
168
169 umask 077
170
171 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
172
173 # ensure all internal functions know we want full debug
174 export PTLDEBUG=all
175 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
176
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare client versions.  Only compare top-3 fields for compatibility
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
232         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "exp version '$exp_client_version'($exp_val) != " \
235                         "'$(lustre_build_version client)'($imp_val)"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_0e() { # LU-13417
240         (( $MDSCOUNT > 1 )) ||
241                 skip "We need at least 2 MDTs for this test"
242
243         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
244                 skip "Need server version at least 2.14.51"
245
246         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
247         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
248
249         [ $default_lmv_count -eq 1 ] ||
250                 error "$MOUNT default stripe count $default_lmv_count"
251
252         [ $default_lmv_index -eq -1 ] ||
253                 error "$MOUNT default stripe index $default_lmv_index"
254
255         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
256         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
257
258         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
259         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
260
261         [ $mdt_index1 -eq $mdt_index2 ] &&
262                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
263
264         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
265 }
266 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
267
268 test_1() {
269         test_mkdir $DIR/$tdir
270         test_mkdir $DIR/$tdir/d2
271         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
273         rmdir $DIR/$tdir/d2
274         rmdir $DIR/$tdir
275         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
276 }
277 run_test 1 "mkdir; remkdir; rmdir"
278
279 test_2() {
280         test_mkdir $DIR/$tdir
281         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
282         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
283         rm -r $DIR/$tdir
284         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
285 }
286 run_test 2 "mkdir; touch; rmdir; check file"
287
288 test_3() {
289         test_mkdir $DIR/$tdir
290         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
291         touch $DIR/$tdir/$tfile
292         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
293         rm -r $DIR/$tdir
294         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
295 }
296 run_test 3 "mkdir; touch; rmdir; check dir"
297
298 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
299 test_4() {
300         test_mkdir -i 1 $DIR/$tdir
301
302         touch $DIR/$tdir/$tfile ||
303                 error "Create file under remote directory failed"
304
305         rmdir $DIR/$tdir &&
306                 error "Expect error removing in-use dir $DIR/$tdir"
307
308         test -d $DIR/$tdir || error "Remote directory disappeared"
309
310         rm -rf $DIR/$tdir || error "remove remote dir error"
311 }
312 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
313
314 test_5() {
315         test_mkdir $DIR/$tdir
316         test_mkdir $DIR/$tdir/d2
317         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
318         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
319         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
320 }
321 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
322
323 test_6a() {
324         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
325         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile does not have perm 0666 or UID $UID"
328         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile should be 0666 and owned by UID $UID"
331 }
332 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
333
334 test_6c() {
335         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
336
337         touch $DIR/$tfile
338         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344 }
345 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
346
347 test_6e() {
348         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
349
350         touch $DIR/$tfile
351         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by GID $UID"
354         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
357 }
358 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
359
360 test_6g() {
361         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
362
363         test_mkdir $DIR/$tdir
364         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
365         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
366         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
367         test_mkdir $DIR/$tdir/d/subdir
368         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
369                 error "$tdir/d/subdir should be GID $RUNAS_GID"
370         if [[ $MDSCOUNT -gt 1 ]]; then
371                 # check remote dir sgid inherite
372                 $LFS mkdir -i 0 $DIR/$tdir.local ||
373                         error "mkdir $tdir.local failed"
374                 chmod g+s $DIR/$tdir.local ||
375                         error "chmod $tdir.local failed"
376                 chgrp $RUNAS_GID $DIR/$tdir.local ||
377                         error "chgrp $tdir.local failed"
378                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
379                         error "mkdir $tdir.remote failed"
380                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
381                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
382                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
383                         error "$tdir.remote should be mode 02755"
384         fi
385 }
386 run_test 6g "verify new dir in sgid dir inherits group"
387
388 test_6h() { # bug 7331
389         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
390
391         touch $DIR/$tfile || error "touch failed"
392         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
393         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
394                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
395         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
396                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
397 }
398 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
399
400 test_7a() {
401         test_mkdir $DIR/$tdir
402         $MCREATE $DIR/$tdir/$tfile
403         chmod 0666 $DIR/$tdir/$tfile
404         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
405                 error "$tdir/$tfile should be mode 0666"
406 }
407 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
408
409 test_7b() {
410         if [ ! -d $DIR/$tdir ]; then
411                 test_mkdir $DIR/$tdir
412         fi
413         $MCREATE $DIR/$tdir/$tfile
414         echo -n foo > $DIR/$tdir/$tfile
415         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
416         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
417 }
418 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
419
420 test_8() {
421         test_mkdir $DIR/$tdir
422         touch $DIR/$tdir/$tfile
423         chmod 0666 $DIR/$tdir/$tfile
424         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
425                 error "$tfile mode not 0666"
426 }
427 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
428
429 test_9() {
430         test_mkdir $DIR/$tdir
431         test_mkdir $DIR/$tdir/d2
432         test_mkdir $DIR/$tdir/d2/d3
433         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
434 }
435 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
436
437 test_10() {
438         test_mkdir $DIR/$tdir
439         test_mkdir $DIR/$tdir/d2
440         touch $DIR/$tdir/d2/$tfile
441         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
442                 error "$tdir/d2/$tfile not a file"
443 }
444 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
445
446 test_11() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         chmod 0666 $DIR/$tdir/d2
450         chmod 0705 $DIR/$tdir/d2
451         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
452                 error "$tdir/d2 mode not 0705"
453 }
454 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
455
456 test_12() {
457         test_mkdir $DIR/$tdir
458         touch $DIR/$tdir/$tfile
459         chmod 0666 $DIR/$tdir/$tfile
460         chmod 0654 $DIR/$tdir/$tfile
461         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
462                 error "$tdir/d2 mode not 0654"
463 }
464 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
465
466 test_13() {
467         test_mkdir $DIR/$tdir
468         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
469         >  $DIR/$tdir/$tfile
470         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
471                 error "$tdir/$tfile size not 0 after truncate"
472 }
473 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
474
475 test_14() {
476         test_mkdir $DIR/$tdir
477         touch $DIR/$tdir/$tfile
478         rm $DIR/$tdir/$tfile
479         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
480 }
481 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
482
483 test_15() {
484         test_mkdir $DIR/$tdir
485         touch $DIR/$tdir/$tfile
486         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
487         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
488                 error "$tdir/${tfile_2} not a file after rename"
489         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
490 }
491 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
492
493 test_16() {
494         test_mkdir $DIR/$tdir
495         touch $DIR/$tdir/$tfile
496         rm -rf $DIR/$tdir/$tfile
497         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
498 }
499 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
500
501 test_17a() {
502         test_mkdir $DIR/$tdir
503         touch $DIR/$tdir/$tfile
504         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
505         ls -l $DIR/$tdir
506         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
507                 error "$tdir/l-exist not a symlink"
508         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
509                 error "$tdir/l-exist not referencing a file"
510         rm -f $DIR/$tdir/l-exist
511         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
512 }
513 run_test 17a "symlinks: create, remove (real)"
514
515 test_17b() {
516         test_mkdir $DIR/$tdir
517         ln -s no-such-file $DIR/$tdir/l-dangle
518         ls -l $DIR/$tdir
519         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
520                 error "$tdir/l-dangle not referencing no-such-file"
521         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
522                 error "$tdir/l-dangle not referencing non-existent file"
523         rm -f $DIR/$tdir/l-dangle
524         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
525 }
526 run_test 17b "symlinks: create, remove (dangling)"
527
528 test_17c() { # bug 3440 - don't save failed open RPC for replay
529         test_mkdir $DIR/$tdir
530         ln -s foo $DIR/$tdir/$tfile
531         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
532 }
533 run_test 17c "symlinks: open dangling (should return error)"
534
535 test_17d() {
536         test_mkdir $DIR/$tdir
537         ln -s foo $DIR/$tdir/$tfile
538         touch $DIR/$tdir/$tfile || error "creating to new symlink"
539 }
540 run_test 17d "symlinks: create dangling"
541
542 test_17e() {
543         test_mkdir $DIR/$tdir
544         local foo=$DIR/$tdir/$tfile
545         ln -s $foo $foo || error "create symlink failed"
546         ls -l $foo || error "ls -l failed"
547         ls $foo && error "ls not failed" || true
548 }
549 run_test 17e "symlinks: create recursive symlink (should return error)"
550
551 test_17f() {
552         test_mkdir $DIR/$tdir
553         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
556         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
559         ls -l  $DIR/$tdir
560 }
561 run_test 17f "symlinks: long and very long symlink name"
562
563 # str_repeat(S, N) generate a string that is string S repeated N times
564 str_repeat() {
565         local s=$1
566         local n=$2
567         local ret=''
568         while [ $((n -= 1)) -ge 0 ]; do
569                 ret=$ret$s
570         done
571         echo $ret
572 }
573
574 # Long symlinks and LU-2241
575 test_17g() {
576         test_mkdir $DIR/$tdir
577         local TESTS="59 60 61 4094 4095"
578
579         # Fix for inode size boundary in 2.1.4
580         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
581                 TESTS="4094 4095"
582
583         # Patch not applied to 2.2 or 2.3 branches
584         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
585         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
586                 TESTS="4094 4095"
587
588         for i in $TESTS; do
589                 local SYMNAME=$(str_repeat 'x' $i)
590                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
591                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
592         done
593 }
594 run_test 17g "symlinks: really long symlink name and inode boundaries"
595
596 test_17h() { #bug 17378
597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
598         remote_mds_nodsh && skip "remote MDS with nodsh"
599
600         local mdt_idx
601
602         test_mkdir $DIR/$tdir
603         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
604         $LFS setstripe -c -1 $DIR/$tdir
605         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
606         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
607         touch $DIR/$tdir/$tfile || true
608 }
609 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
610
611 test_17i() { #bug 20018
612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
613         remote_mds_nodsh && skip "remote MDS with nodsh"
614
615         local foo=$DIR/$tdir/$tfile
616         local mdt_idx
617
618         test_mkdir -c1 $DIR/$tdir
619         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
620         ln -s $foo $foo || error "create symlink failed"
621 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
622         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
623         ls -l $foo && error "error not detected"
624         return 0
625 }
626 run_test 17i "don't panic on short symlink (should return error)"
627
628 test_17k() { #bug 22301
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         [[ -z "$(which rsync 2>/dev/null)" ]] &&
631                 skip "no rsync command"
632         rsync --help | grep -q xattr ||
633                 skip_env "$(rsync --version | head -n1) does not support xattrs"
634         test_mkdir $DIR/$tdir
635         test_mkdir $DIR/$tdir.new
636         touch $DIR/$tdir/$tfile
637         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
638         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
639                 error "rsync failed with xattrs enabled"
640 }
641 run_test 17k "symlinks: rsync with xattrs enabled"
642
643 test_17l() { # LU-279
644         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
645                 skip "no getfattr command"
646
647         test_mkdir $DIR/$tdir
648         touch $DIR/$tdir/$tfile
649         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
650         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
651                 # -h to not follow symlinks. -m '' to list all the xattrs.
652                 # grep to remove first line: '# file: $path'.
653                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
654                 do
655                         lgetxattr_size_check $path $xattr ||
656                                 error "lgetxattr_size_check $path $xattr failed"
657                 done
658         done
659 }
660 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
661
662 # LU-1540
663 test_17m() {
664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
665         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
666         remote_mds_nodsh && skip "remote MDS with nodsh"
667         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
668         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
669                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
670
671         local short_sym="0123456789"
672         local wdir=$DIR/$tdir
673         local i
674
675         test_mkdir $wdir
676         long_sym=$short_sym
677         # create a long symlink file
678         for ((i = 0; i < 4; ++i)); do
679                 long_sym=${long_sym}${long_sym}
680         done
681
682         echo "create 512 short and long symlink files under $wdir"
683         for ((i = 0; i < 256; ++i)); do
684                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
685                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
686         done
687
688         echo "erase them"
689         rm -f $wdir/*
690         sync
691         wait_delete_completed
692
693         echo "recreate the 512 symlink files with a shorter string"
694         for ((i = 0; i < 512; ++i)); do
695                 # rewrite the symlink file with a shorter string
696                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
697                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
698         done
699
700         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
701
702         echo "stop and checking mds${mds_index}:"
703         # e2fsck should not return error
704         stop mds${mds_index}
705         local devname=$(mdsdevname $mds_index)
706         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
707         rc=$?
708
709         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
710                 error "start mds${mds_index} failed"
711         df $MOUNT > /dev/null 2>&1
712         [ $rc -eq 0 ] ||
713                 error "e2fsck detected error for short/long symlink: rc=$rc"
714         rm -f $wdir/*
715 }
716 run_test 17m "run e2fsck against MDT which contains short/long symlink"
717
718 check_fs_consistency_17n() {
719         local mdt_index
720         local rc=0
721
722         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
723         # so it only check MDT1/MDT2 instead of all of MDTs.
724         for mdt_index in 1 2; do
725                 # e2fsck should not return error
726                 stop mds${mdt_index}
727                 local devname=$(mdsdevname $mdt_index)
728                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
729                         rc=$((rc + $?))
730
731                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
732                         error "mount mds$mdt_index failed"
733                 df $MOUNT > /dev/null 2>&1
734         done
735         return $rc
736 }
737
738 test_17n() {
739         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
741         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
742         remote_mds_nodsh && skip "remote MDS with nodsh"
743         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
744         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
745                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
746
747         local i
748
749         test_mkdir $DIR/$tdir
750         for ((i=0; i<10; i++)); do
751                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
752                         error "create remote dir error $i"
753                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
754                         error "create files under remote dir failed $i"
755         done
756
757         check_fs_consistency_17n ||
758                 error "e2fsck report error after create files under remote dir"
759
760         for ((i = 0; i < 10; i++)); do
761                 rm -rf $DIR/$tdir/remote_dir_${i} ||
762                         error "destroy remote dir error $i"
763         done
764
765         check_fs_consistency_17n ||
766                 error "e2fsck report error after unlink files under remote dir"
767
768         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
769                 skip "lustre < 2.4.50 does not support migrate mv"
770
771         for ((i = 0; i < 10; i++)); do
772                 mkdir -p $DIR/$tdir/remote_dir_${i}
773                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
774                         error "create files under remote dir failed $i"
775                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
776                         error "migrate remote dir error $i"
777         done
778         check_fs_consistency_17n || error "e2fsck report error after migration"
779
780         for ((i = 0; i < 10; i++)); do
781                 rm -rf $DIR/$tdir/remote_dir_${i} ||
782                         error "destroy remote dir error $i"
783         done
784
785         check_fs_consistency_17n || error "e2fsck report error after unlink"
786 }
787 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
788
789 test_17o() {
790         remote_mds_nodsh && skip "remote MDS with nodsh"
791         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
792                 skip "Need MDS version at least 2.3.64"
793
794         local wdir=$DIR/${tdir}o
795         local mdt_index
796         local rc=0
797
798         test_mkdir $wdir
799         touch $wdir/$tfile
800         mdt_index=$($LFS getstripe -m $wdir/$tfile)
801         mdt_index=$((mdt_index + 1))
802
803         cancel_lru_locks mdc
804         #fail mds will wait the failover finish then set
805         #following fail_loc to avoid interfer the recovery process.
806         fail mds${mdt_index}
807
808         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
809         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
810         ls -l $wdir/$tfile && rc=1
811         do_facet mds${mdt_index} lctl set_param fail_loc=0
812         [[ $rc -eq 0 ]] || error "stat file should fail"
813 }
814 run_test 17o "stat file with incompat LMA feature"
815
816 test_18() {
817         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
818         ls $DIR || error "Failed to ls $DIR: $?"
819 }
820 run_test 18 "touch .../f ; ls ... =============================="
821
822 test_19a() {
823         touch $DIR/$tfile
824         ls -l $DIR
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
829
830 test_19b() {
831         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
832 }
833 run_test 19b "ls -l .../f19 (should return error) =============="
834
835 test_19c() {
836         [ $RUNAS_ID -eq $UID ] &&
837                 skip_env "RUNAS_ID = UID = $UID -- skipping"
838
839         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
840 }
841 run_test 19c "$RUNAS touch .../f19 (should return error) =="
842
843 test_19d() {
844         cat $DIR/f19 && error || true
845 }
846 run_test 19d "cat .../f19 (should return error) =============="
847
848 test_20() {
849         touch $DIR/$tfile
850         rm $DIR/$tfile
851         touch $DIR/$tfile
852         rm $DIR/$tfile
853         touch $DIR/$tfile
854         rm $DIR/$tfile
855         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
856 }
857 run_test 20 "touch .../f ; ls -l ..."
858
859 test_21() {
860         test_mkdir $DIR/$tdir
861         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
862         ln -s dangle $DIR/$tdir/link
863         echo foo >> $DIR/$tdir/link
864         cat $DIR/$tdir/dangle
865         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
866         $CHECKSTAT -f -t file $DIR/$tdir/link ||
867                 error "$tdir/link not linked to a file"
868 }
869 run_test 21 "write to dangling link"
870
871 test_22() {
872         local wdir=$DIR/$tdir
873         test_mkdir $wdir
874         chown $RUNAS_ID:$RUNAS_GID $wdir
875         (cd $wdir || error "cd $wdir failed";
876                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
877                 $RUNAS tar xf -)
878         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
879         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
880         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
881                 error "checkstat -u failed"
882 }
883 run_test 22 "unpack tar archive as non-root user"
884
885 # was test_23
886 test_23a() {
887         test_mkdir $DIR/$tdir
888         local file=$DIR/$tdir/$tfile
889
890         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
891         openfile -f O_CREAT:O_EXCL $file &&
892                 error "$file recreate succeeded" || true
893 }
894 run_test 23a "O_CREAT|O_EXCL in subdir"
895
896 test_23b() { # bug 18988
897         test_mkdir $DIR/$tdir
898         local file=$DIR/$tdir/$tfile
899
900         rm -f $file
901         echo foo > $file || error "write filed"
902         echo bar >> $file || error "append filed"
903         $CHECKSTAT -s 8 $file || error "wrong size"
904         rm $file
905 }
906 run_test 23b "O_APPEND check"
907
908 # LU-9409, size with O_APPEND and tiny writes
909 test_23c() {
910         local file=$DIR/$tfile
911
912         # single dd
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
914         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
915         rm -f $file
916
917         # racing tiny writes
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
920         wait
921         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
922         rm -f $file
923
924         #racing tiny & normal writes
925         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
926         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
927         wait
928         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
929         rm -f $file
930
931         #racing tiny & normal writes 2, ugly numbers
932         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
934         wait
935         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
936         rm -f $file
937 }
938 run_test 23c "O_APPEND size checks for tiny writes"
939
940 # LU-11069 file offset is correct after appending writes
941 test_23d() {
942         local file=$DIR/$tfile
943         local offset
944
945         echo CentaurHauls > $file
946         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
947         if ((offset != 26)); then
948                 error "wrong offset, expected 26, got '$offset'"
949         fi
950 }
951 run_test 23d "file offset is correct after appending writes"
952
953 # rename sanity
954 test_24a() {
955         echo '-- same directory rename'
956         test_mkdir $DIR/$tdir
957         touch $DIR/$tdir/$tfile.1
958         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
959         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
960 }
961 run_test 24a "rename file to non-existent target"
962
963 test_24b() {
964         test_mkdir $DIR/$tdir
965         touch $DIR/$tdir/$tfile.{1,2}
966         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
967         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
968         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
969 }
970 run_test 24b "rename file to existing target"
971
972 test_24c() {
973         test_mkdir $DIR/$tdir
974         test_mkdir $DIR/$tdir/d$testnum.1
975         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
976         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
977         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
978 }
979 run_test 24c "rename directory to non-existent target"
980
981 test_24d() {
982         test_mkdir -c1 $DIR/$tdir
983         test_mkdir -c1 $DIR/$tdir/d$testnum.1
984         test_mkdir -c1 $DIR/$tdir/d$testnum.2
985         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
986         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
987         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
988 }
989 run_test 24d "rename directory to existing target"
990
991 test_24e() {
992         echo '-- cross directory renames --'
993         test_mkdir $DIR/R5a
994         test_mkdir $DIR/R5b
995         touch $DIR/R5a/f
996         mv $DIR/R5a/f $DIR/R5b/g
997         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
998         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
999 }
1000 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1001
1002 test_24f() {
1003         test_mkdir $DIR/R6a
1004         test_mkdir $DIR/R6b
1005         touch $DIR/R6a/f $DIR/R6b/g
1006         mv $DIR/R6a/f $DIR/R6b/g
1007         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1008         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1009 }
1010 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1011
1012 test_24g() {
1013         test_mkdir $DIR/R7a
1014         test_mkdir $DIR/R7b
1015         test_mkdir $DIR/R7a/d
1016         mv $DIR/R7a/d $DIR/R7b/e
1017         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1018         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1019 }
1020 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1021
1022 test_24h() {
1023         test_mkdir -c1 $DIR/R8a
1024         test_mkdir -c1 $DIR/R8b
1025         test_mkdir -c1 $DIR/R8a/d
1026         test_mkdir -c1 $DIR/R8b/e
1027         mrename $DIR/R8a/d $DIR/R8b/e
1028         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1029         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1030 }
1031 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1032
1033 test_24i() {
1034         echo "-- rename error cases"
1035         test_mkdir $DIR/R9
1036         test_mkdir $DIR/R9/a
1037         touch $DIR/R9/f
1038         mrename $DIR/R9/f $DIR/R9/a
1039         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1040         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1041         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1042 }
1043 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1044
1045 test_24j() {
1046         test_mkdir $DIR/R10
1047         mrename $DIR/R10/f $DIR/R10/g
1048         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1049         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1050         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1051 }
1052 run_test 24j "source does not exist ============================"
1053
1054 test_24k() {
1055         test_mkdir $DIR/R11a
1056         test_mkdir $DIR/R11a/d
1057         touch $DIR/R11a/f
1058         mv $DIR/R11a/f $DIR/R11a/d
1059         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1060         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1061 }
1062 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1063
1064 # bug 2429 - rename foo foo foo creates invalid file
1065 test_24l() {
1066         f="$DIR/f24l"
1067         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1068 }
1069 run_test 24l "Renaming a file to itself ========================"
1070
1071 test_24m() {
1072         f="$DIR/f24m"
1073         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1074         # on ext3 this does not remove either the source or target files
1075         # though the "expected" operation would be to remove the source
1076         $CHECKSTAT -t file ${f} || error "${f} missing"
1077         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1078 }
1079 run_test 24m "Renaming a file to a hard link to itself ========="
1080
1081 test_24n() {
1082     f="$DIR/f24n"
1083     # this stats the old file after it was renamed, so it should fail
1084     touch ${f}
1085     $CHECKSTAT ${f} || error "${f} missing"
1086     mv ${f} ${f}.rename
1087     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1088     $CHECKSTAT -a ${f} || error "${f} exists"
1089 }
1090 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1091
1092 test_24o() {
1093         test_mkdir $DIR/$tdir
1094         rename_many -s random -v -n 10 $DIR/$tdir
1095 }
1096 run_test 24o "rename of files during htree split"
1097
1098 test_24p() {
1099         test_mkdir $DIR/R12a
1100         test_mkdir $DIR/R12b
1101         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1102         mrename $DIR/R12a $DIR/R12b
1103         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1104         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1105         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1106         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1107 }
1108 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1109
1110 cleanup_multiop_pause() {
1111         trap 0
1112         kill -USR1 $MULTIPID
1113 }
1114
1115 test_24q() {
1116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1117
1118         test_mkdir $DIR/R13a
1119         test_mkdir $DIR/R13b
1120         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1121         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1122         MULTIPID=$!
1123
1124         trap cleanup_multiop_pause EXIT
1125         mrename $DIR/R13a $DIR/R13b
1126         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1127         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1128         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1129         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1130         cleanup_multiop_pause
1131         wait $MULTIPID || error "multiop close failed"
1132 }
1133 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1134
1135 test_24r() { #bug 3789
1136         test_mkdir $DIR/R14a
1137         test_mkdir $DIR/R14a/b
1138         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1139         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1140         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1141 }
1142 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1143
1144 test_24s() {
1145         test_mkdir $DIR/R15a
1146         test_mkdir $DIR/R15a/b
1147         test_mkdir $DIR/R15a/b/c
1148         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1149         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1150         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1151 }
1152 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1153
1154 test_24t() {
1155         test_mkdir $DIR/R16a
1156         test_mkdir $DIR/R16a/b
1157         test_mkdir $DIR/R16a/b/c
1158         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1159         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1160         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1161 }
1162 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1163
1164 test_24u() { # bug12192
1165         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1166         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1167 }
1168 run_test 24u "create stripe file"
1169
1170 simple_cleanup_common() {
1171         local createmany=$1
1172         local rc=0
1173
1174         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1175
1176         local start=$SECONDS
1177
1178         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1179         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1180         rc=$?
1181         wait_delete_completed
1182         echo "cleanup time $((SECONDS - start))"
1183         return $rc
1184 }
1185
1186 max_pages_per_rpc() {
1187         local mdtname="$(printf "MDT%04x" ${1:-0})"
1188         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1189 }
1190
1191 test_24v() {
1192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1193
1194         local nrfiles=${COUNT:-100000}
1195         local fname="$DIR/$tdir/$tfile"
1196
1197         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1198         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1199
1200         test_mkdir "$(dirname $fname)"
1201         # assume MDT0000 has the fewest inodes
1202         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1203         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1204         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1205
1206         stack_trap "simple_cleanup_common $nrfiles"
1207
1208         createmany -m "$fname" $nrfiles
1209
1210         cancel_lru_locks mdc
1211         lctl set_param mdc.*.stats clear
1212
1213         # was previously test_24D: LU-6101
1214         # readdir() returns correct number of entries after cursor reload
1215         local num_ls=$(ls $DIR/$tdir | wc -l)
1216         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1217         local num_all=$(ls -a $DIR/$tdir | wc -l)
1218         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1219                 [ $num_all -ne $((nrfiles + 2)) ]; then
1220                         error "Expected $nrfiles files, got $num_ls " \
1221                                 "($num_uniq unique $num_all .&..)"
1222         fi
1223         # LU-5 large readdir
1224         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1225         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1226         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1227         # take into account of overhead in lu_dirpage header and end mark in
1228         # each page, plus one in rpc_num calculation.
1229         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1230         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1231         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1232         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1233         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1234         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1235         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1236         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1237                 error "large readdir doesn't take effect: " \
1238                       "$mds_readpage should be about $rpc_max"
1239 }
1240 run_test 24v "list large directory (test hash collision, b=17560)"
1241
1242 test_24w() { # bug21506
1243         SZ1=234852
1244         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1245         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1246         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1247         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1248         [[ "$SZ1" -eq "$SZ2" ]] ||
1249                 error "Error reading at the end of the file $tfile"
1250 }
1251 run_test 24w "Reading a file larger than 4Gb"
1252
1253 test_24x() {
1254         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1256         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1257                 skip "Need MDS version at least 2.7.56"
1258
1259         local MDTIDX=1
1260         local remote_dir=$DIR/$tdir/remote_dir
1261
1262         test_mkdir $DIR/$tdir
1263         $LFS mkdir -i $MDTIDX $remote_dir ||
1264                 error "create remote directory failed"
1265
1266         test_mkdir $DIR/$tdir/src_dir
1267         touch $DIR/$tdir/src_file
1268         test_mkdir $remote_dir/tgt_dir
1269         touch $remote_dir/tgt_file
1270
1271         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1272                 error "rename dir cross MDT failed!"
1273
1274         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1275                 error "rename file cross MDT failed!"
1276
1277         touch $DIR/$tdir/ln_file
1278         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1279                 error "ln file cross MDT failed"
1280
1281         rm -rf $DIR/$tdir || error "Can not delete directories"
1282 }
1283 run_test 24x "cross MDT rename/link"
1284
1285 test_24y() {
1286         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1288
1289         local remote_dir=$DIR/$tdir/remote_dir
1290         local mdtidx=1
1291
1292         test_mkdir $DIR/$tdir
1293         $LFS mkdir -i $mdtidx $remote_dir ||
1294                 error "create remote directory failed"
1295
1296         test_mkdir $remote_dir/src_dir
1297         touch $remote_dir/src_file
1298         test_mkdir $remote_dir/tgt_dir
1299         touch $remote_dir/tgt_file
1300
1301         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1302                 error "rename subdir in the same remote dir failed!"
1303
1304         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1305                 error "rename files in the same remote dir failed!"
1306
1307         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1308                 error "link files in the same remote dir failed!"
1309
1310         rm -rf $DIR/$tdir || error "Can not delete directories"
1311 }
1312 run_test 24y "rename/link on the same dir should succeed"
1313
1314 test_24z() {
1315         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1316         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1317                 skip "Need MDS version at least 2.12.51"
1318
1319         local index
1320
1321         for index in 0 1; do
1322                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1323                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1324         done
1325
1326         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1327
1328         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1329         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1330
1331         local mdts=$(comma_list $(mdts_nodes))
1332
1333         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1334         stack_trap "do_nodes $mdts $LCTL \
1335                 set_param mdt.*.enable_remote_rename=1" EXIT
1336
1337         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1338
1339         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1340         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1341 }
1342 run_test 24z "cross-MDT rename is done as cp"
1343
1344 test_24A() { # LU-3182
1345         local NFILES=5000
1346
1347         test_mkdir $DIR/$tdir
1348         stack_trap "simple_cleanup_common $NFILES"
1349         createmany -m $DIR/$tdir/$tfile $NFILES
1350         local t=$(ls $DIR/$tdir | wc -l)
1351         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1352         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1353
1354         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1355                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1356 }
1357 run_test 24A "readdir() returns correct number of entries."
1358
1359 test_24B() { # LU-4805
1360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1361
1362         local count
1363
1364         test_mkdir $DIR/$tdir
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1366                 error "create striped dir failed"
1367
1368         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1369         [ $count -eq 2 ] || error "Expected 2, got $count"
1370
1371         touch $DIR/$tdir/striped_dir/a
1372
1373         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1374         [ $count -eq 3 ] || error "Expected 3, got $count"
1375
1376         touch $DIR/$tdir/striped_dir/.f
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 4 ] || error "Expected 4, got $count"
1380
1381         rm -rf $DIR/$tdir || error "Can not delete directories"
1382 }
1383 run_test 24B "readdir for striped dir return correct number of entries"
1384
1385 test_24C() {
1386         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1387
1388         mkdir $DIR/$tdir
1389         mkdir $DIR/$tdir/d0
1390         mkdir $DIR/$tdir/d1
1391
1392         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1393                 error "create striped dir failed"
1394
1395         cd $DIR/$tdir/d0/striped_dir
1396
1397         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1398         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1399         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1400
1401         [ "$d0_ino" = "$parent_ino" ] ||
1402                 error ".. wrong, expect $d0_ino, get $parent_ino"
1403
1404         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1405                 error "mv striped dir failed"
1406
1407         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1408
1409         [ "$d1_ino" = "$parent_ino" ] ||
1410                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1411 }
1412 run_test 24C "check .. in striped dir"
1413
1414 test_24E() {
1415         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1417
1418         mkdir -p $DIR/$tdir
1419         mkdir $DIR/$tdir/src_dir
1420         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1421                 error "create remote source failed"
1422
1423         touch $DIR/$tdir/src_dir/src_child/a
1424
1425         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1426                 error "create remote target dir failed"
1427
1428         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "create remote target child failed"
1430
1431         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1432                 error "rename dir cross MDT failed!"
1433
1434         find $DIR/$tdir
1435
1436         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1437                 error "src_child still exists after rename"
1438
1439         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1440                 error "missing file(a) after rename"
1441
1442         rm -rf $DIR/$tdir || error "Can not delete directories"
1443 }
1444 run_test 24E "cross MDT rename/link"
1445
1446 test_24F () {
1447         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1448
1449         local repeats=1000
1450         [ "$SLOW" = "no" ] && repeats=100
1451
1452         mkdir -p $DIR/$tdir
1453
1454         echo "$repeats repeats"
1455         for ((i = 0; i < repeats; i++)); do
1456                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1457                 touch $DIR/$tdir/test/a || error "touch fails"
1458                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1459                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1460         done
1461
1462         true
1463 }
1464 run_test 24F "hash order vs readdir (LU-11330)"
1465
1466 test_24G () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1468
1469         local ino1
1470         local ino2
1471
1472         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1473         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1474         touch $DIR/$tdir-0/f1 || error "touch f1"
1475         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1476         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1477         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1478         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1479         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1480 }
1481 run_test 24G "migrate symlink in rename"
1482
1483 test_24H() {
1484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1485         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1486                 skip "MDT1 should be on another node"
1487
1488         test_mkdir -i 1 -c 1 $DIR/$tdir
1489 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1490         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1491         touch $DIR/$tdir/$tfile || error "touch failed"
1492 }
1493 run_test 24H "repeat FLD_QUERY rpc"
1494
1495 test_25a() {
1496         echo '== symlink sanity ============================================='
1497
1498         test_mkdir $DIR/d25
1499         ln -s d25 $DIR/s25
1500         touch $DIR/s25/foo ||
1501                 error "File creation in symlinked directory failed"
1502 }
1503 run_test 25a "create file in symlinked directory ==============="
1504
1505 test_25b() {
1506         [ ! -d $DIR/d25 ] && test_25a
1507         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1508 }
1509 run_test 25b "lookup file in symlinked directory ==============="
1510
1511 test_26a() {
1512         test_mkdir $DIR/d26
1513         test_mkdir $DIR/d26/d26-2
1514         ln -s d26/d26-2 $DIR/s26
1515         touch $DIR/s26/foo || error "File creation failed"
1516 }
1517 run_test 26a "multiple component symlink ======================="
1518
1519 test_26b() {
1520         test_mkdir -p $DIR/$tdir/d26-2
1521         ln -s $tdir/d26-2/foo $DIR/s26-2
1522         touch $DIR/s26-2 || error "File creation failed"
1523 }
1524 run_test 26b "multiple component symlink at end of lookup ======"
1525
1526 test_26c() {
1527         test_mkdir $DIR/d26.2
1528         touch $DIR/d26.2/foo
1529         ln -s d26.2 $DIR/s26.2-1
1530         ln -s s26.2-1 $DIR/s26.2-2
1531         ln -s s26.2-2 $DIR/s26.2-3
1532         chmod 0666 $DIR/s26.2-3/foo
1533 }
1534 run_test 26c "chain of symlinks"
1535
1536 # recursive symlinks (bug 439)
1537 test_26d() {
1538         ln -s d26-3/foo $DIR/d26-3
1539 }
1540 run_test 26d "create multiple component recursive symlink"
1541
1542 test_26e() {
1543         [ ! -h $DIR/d26-3 ] && test_26d
1544         rm $DIR/d26-3
1545 }
1546 run_test 26e "unlink multiple component recursive symlink"
1547
1548 # recursive symlinks (bug 7022)
1549 test_26f() {
1550         test_mkdir $DIR/$tdir
1551         test_mkdir $DIR/$tdir/$tfile
1552         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1553         test_mkdir -p lndir/bar1
1554         test_mkdir $DIR/$tdir/$tfile/$tfile
1555         cd $tfile                || error "cd $tfile failed"
1556         ln -s .. dotdot          || error "ln dotdot failed"
1557         ln -s dotdot/lndir lndir || error "ln lndir failed"
1558         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1559         output=`ls $tfile/$tfile/lndir/bar1`
1560         [ "$output" = bar1 ] && error "unexpected output"
1561         rm -r $tfile             || error "rm $tfile failed"
1562         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1563 }
1564 run_test 26f "rm -r of a directory which has recursive symlink"
1565
1566 test_27a() {
1567         test_mkdir $DIR/$tdir
1568         $LFS getstripe $DIR/$tdir
1569         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1570         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1571         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1572 }
1573 run_test 27a "one stripe file"
1574
1575 test_27b() {
1576         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1577
1578         test_mkdir $DIR/$tdir
1579         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1580         $LFS getstripe -c $DIR/$tdir/$tfile
1581         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1582                 error "two-stripe file doesn't have two stripes"
1583
1584         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1585 }
1586 run_test 27b "create and write to two stripe file"
1587
1588 # 27c family tests specific striping, setstripe -o
1589 test_27ca() {
1590         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1591         test_mkdir -p $DIR/$tdir
1592         local osts="1"
1593
1594         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1595         $LFS getstripe -i $DIR/$tdir/$tfile
1596         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1597                 error "stripe not on specified OST"
1598
1599         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1600 }
1601 run_test 27ca "one stripe on specified OST"
1602
1603 test_27cb() {
1604         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1605         test_mkdir -p $DIR/$tdir
1606         local osts="1,0"
1607         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1608         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1609         echo "$getstripe"
1610
1611         # Strip getstripe output to a space separated list of OSTs
1612         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1613                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1614         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1615                 error "stripes not on specified OSTs"
1616
1617         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1618 }
1619 run_test 27cb "two stripes on specified OSTs"
1620
1621 test_27cc() {
1622         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1623         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1624                 skip "server does not support overstriping"
1625
1626         test_mkdir -p $DIR/$tdir
1627         local osts="0,0"
1628         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1629         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1630         echo "$getstripe"
1631
1632         # Strip getstripe output to a space separated list of OSTs
1633         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1634                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1635         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1636                 error "stripes not on specified OSTs"
1637
1638         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1639 }
1640 run_test 27cc "two stripes on the same OST"
1641
1642 test_27cd() {
1643         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1644         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1645                 skip "server does not support overstriping"
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,1,1,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cd "four stripes on two OSTs"
1661
1662 test_27ce() {
1663         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1664                 skip_env "too many osts, skipping"
1665         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1666                 skip "server does not support overstriping"
1667         # We do one more stripe than we have OSTs
1668         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1669                 skip_env "ea_inode feature disabled"
1670
1671         test_mkdir -p $DIR/$tdir
1672         local osts=""
1673         for i in $(seq 0 $OSTCOUNT);
1674         do
1675                 osts=$osts"0"
1676                 if [ $i -ne $OSTCOUNT ]; then
1677                         osts=$osts","
1678                 fi
1679         done
1680         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1681         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1682         echo "$getstripe"
1683
1684         # Strip getstripe output to a space separated list of OSTs
1685         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1686                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1687         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1688                 error "stripes not on specified OSTs"
1689
1690         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1691 }
1692 run_test 27ce "more stripes than OSTs with -o"
1693
1694 test_27cf() {
1695         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1696         local pid=0
1697
1698         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1699         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1700         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1701         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1702                 error "failed to set $osp_proc=0"
1703
1704         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1705         pid=$!
1706         sleep 1
1707         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1709                 error "failed to set $osp_proc=1"
1710         wait $pid
1711         [[ $pid -ne 0 ]] ||
1712                 error "should return error due to $osp_proc=0"
1713 }
1714 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1715
1716 test_27cg() {
1717         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1718                 skip "server does not support overstriping"
1719         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1720         large_xattr_enabled || skip_env "ea_inode feature disabled"
1721
1722         local osts="0"
1723
1724         for ((i=1;i<1000;i++)); do
1725                 osts+=",$((i % OSTCOUNT))"
1726         done
1727
1728         local mdts=$(comma_list $(mdts_nodes))
1729         local before=$(do_nodes $mdts \
1730                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1731                 awk '/many credits/{print $3}' |
1732                 calc_sum)
1733
1734         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1735         $LFS getstripe $DIR/$tfile | grep stripe
1736
1737         rm -f $DIR/$tfile || error "can't unlink"
1738
1739         after=$(do_nodes $mdts \
1740                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1741                 awk '/many credits/{print $3}' |
1742                 calc_sum)
1743
1744         (( before == after )) ||
1745                 error "too many credits happened: $after > $before"
1746 }
1747 run_test 27cg "1000 shouldn't cause too many credits"
1748
1749 test_27d() {
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1752                 error "setstripe failed"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1755 }
1756 run_test 27d "create file with default settings"
1757
1758 test_27e() {
1759         # LU-5839 adds check for existed layout before setting it
1760         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1761                 skip "Need MDS version at least 2.7.56"
1762
1763         test_mkdir $DIR/$tdir
1764         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1765         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1766         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1767 }
1768 run_test 27e "setstripe existing file (should return error)"
1769
1770 test_27f() {
1771         test_mkdir $DIR/$tdir
1772         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1773                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1774         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1775                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1776         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1777         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1778 }
1779 run_test 27f "setstripe with bad stripe size (should return error)"
1780
1781 test_27g() {
1782         test_mkdir $DIR/$tdir
1783         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1784         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1785                 error "$DIR/$tdir/$tfile has object"
1786 }
1787 run_test 27g "$LFS getstripe with no objects"
1788
1789 test_27ga() {
1790         test_mkdir $DIR/$tdir
1791         touch $DIR/$tdir/$tfile || error "touch failed"
1792         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1793         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1794         local rc=$?
1795         (( rc == 2 )) || error "getstripe did not return ENOENT"
1796 }
1797 run_test 27ga "$LFS getstripe with missing file (should return error)"
1798
1799 test_27i() {
1800         test_mkdir $DIR/$tdir
1801         touch $DIR/$tdir/$tfile || error "touch failed"
1802         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1803                 error "missing objects"
1804 }
1805 run_test 27i "$LFS getstripe with some objects"
1806
1807 test_27j() {
1808         test_mkdir $DIR/$tdir
1809         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1810                 error "setstripe failed" || true
1811 }
1812 run_test 27j "setstripe with bad stripe offset (should return error)"
1813
1814 test_27k() { # bug 2844
1815         test_mkdir $DIR/$tdir
1816         local file=$DIR/$tdir/$tfile
1817         local ll_max_blksize=$((4 * 1024 * 1024))
1818         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1819         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1820         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1821         dd if=/dev/zero of=$file bs=4k count=1
1822         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1823         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1824 }
1825 run_test 27k "limit i_blksize for broken user apps"
1826
1827 test_27l() {
1828         mcreate $DIR/$tfile || error "creating file"
1829         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1830                 error "setstripe should have failed" || true
1831 }
1832 run_test 27l "check setstripe permissions (should return error)"
1833
1834 test_27m() {
1835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1836
1837         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1838                 skip_env "multiple clients -- skipping"
1839
1840         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1841                    head -n1)
1842         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1843                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1844         fi
1845         stack_trap simple_cleanup_common
1846         test_mkdir $DIR/$tdir
1847         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1848         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1849                 error "dd should fill OST0"
1850         i=2
1851         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1852                 i=$((i + 1))
1853                 [ $i -gt 256 ] && break
1854         done
1855         i=$((i + 1))
1856         touch $DIR/$tdir/$tfile.$i
1857         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1858             awk '{print $1}'| grep -w "0") ] &&
1859                 error "OST0 was full but new created file still use it"
1860         i=$((i + 1))
1861         touch $DIR/$tdir/$tfile.$i
1862         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1863             awk '{print $1}'| grep -w "0") ] &&
1864                 error "OST0 was full but new created file still use it" || true
1865 }
1866 run_test 27m "create file while OST0 was full"
1867
1868 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1869 # if the OST isn't full anymore.
1870 reset_enospc() {
1871         local ostidx=${1:-""}
1872         local delay
1873         local ready
1874         local get_prealloc
1875
1876         local list=$(comma_list $(osts_nodes))
1877         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1878
1879         do_nodes $list lctl set_param fail_loc=0
1880         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1881         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1882                 awk '{print $1 * 2;exit;}')
1883         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1884                         grep -v \"^0$\""
1885         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1886 }
1887
1888 test_27n() {
1889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1891         remote_mds_nodsh && skip "remote MDS with nodsh"
1892         remote_ost_nodsh && skip "remote OST with nodsh"
1893
1894         reset_enospc
1895         rm -f $DIR/$tdir/$tfile
1896         exhaust_precreations 0 0x80000215
1897         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1898         touch $DIR/$tdir/$tfile || error "touch failed"
1899         $LFS getstripe $DIR/$tdir/$tfile
1900         reset_enospc
1901 }
1902 run_test 27n "create file with some full OSTs"
1903
1904 test_27o() {
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907         remote_mds_nodsh && skip "remote MDS with nodsh"
1908         remote_ost_nodsh && skip "remote OST with nodsh"
1909
1910         reset_enospc
1911         rm -f $DIR/$tdir/$tfile
1912         exhaust_all_precreations 0x215
1913
1914         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1915
1916         reset_enospc
1917         rm -rf $DIR/$tdir/*
1918 }
1919 run_test 27o "create file with all full OSTs (should error)"
1920
1921 function create_and_checktime() {
1922         local fname=$1
1923         local loops=$2
1924         local i
1925
1926         for ((i=0; i < $loops; i++)); do
1927                 local start=$SECONDS
1928                 multiop $fname-$i Oc
1929                 ((SECONDS-start < TIMEOUT)) ||
1930                         error "creation took " $((SECONDS-$start)) && return 1
1931         done
1932 }
1933
1934 test_27oo() {
1935         local mdts=$(comma_list $(mdts_nodes))
1936
1937         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1938                 skip "Need MDS version at least 2.13.57"
1939
1940         local f0=$DIR/${tfile}-0
1941         local f1=$DIR/${tfile}-1
1942
1943         wait_delete_completed
1944
1945         # refill precreated objects
1946         $LFS setstripe -i0 -c1 $f0
1947
1948         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1949         # force QoS allocation policy
1950         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1951         stack_trap "do_nodes $mdts $LCTL set_param \
1952                 lov.*.qos_threshold_rr=$saved" EXIT
1953         sleep_maxage
1954
1955         # one OST is unavailable, but still have few objects preallocated
1956         stop ost1
1957         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1958                 rm -rf $f1 $DIR/$tdir*" EXIT
1959
1960         for ((i=0; i < 7; i++)); do
1961                 mkdir $DIR/$tdir$i || error "can't create dir"
1962                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1963                         error "can't set striping"
1964         done
1965         for ((i=0; i < 7; i++)); do
1966                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1967         done
1968         wait
1969 }
1970 run_test 27oo "don't let few threads to reserve too many objects"
1971
1972 test_27p() {
1973         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1975         remote_mds_nodsh && skip "remote MDS with nodsh"
1976         remote_ost_nodsh && skip "remote OST with nodsh"
1977
1978         reset_enospc
1979         rm -f $DIR/$tdir/$tfile
1980         test_mkdir $DIR/$tdir
1981
1982         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1983         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1984         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1985
1986         exhaust_precreations 0 0x80000215
1987         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1988         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1989         $LFS getstripe $DIR/$tdir/$tfile
1990
1991         reset_enospc
1992 }
1993 run_test 27p "append to a truncated file with some full OSTs"
1994
1995 test_27q() {
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         reset_enospc
2002         rm -f $DIR/$tdir/$tfile
2003
2004         mkdir_on_mdt0 $DIR/$tdir
2005         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2006         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2007                 error "truncate $DIR/$tdir/$tfile failed"
2008         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2009
2010         exhaust_all_precreations 0x215
2011
2012         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2013         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2014
2015         reset_enospc
2016 }
2017 run_test 27q "append to truncated file with all OSTs full (should error)"
2018
2019 test_27r() {
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023         remote_ost_nodsh && skip "remote OST with nodsh"
2024
2025         reset_enospc
2026         rm -f $DIR/$tdir/$tfile
2027         exhaust_precreations 0 0x80000215
2028
2029         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2030
2031         reset_enospc
2032 }
2033 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2034
2035 test_27s() { # bug 10725
2036         test_mkdir $DIR/$tdir
2037         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2038         local stripe_count=0
2039         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2040         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2041                 error "stripe width >= 2^32 succeeded" || true
2042
2043 }
2044 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2045
2046 test_27t() { # bug 10864
2047         WDIR=$(pwd)
2048         WLFS=$(which lfs)
2049         cd $DIR
2050         touch $tfile
2051         $WLFS getstripe $tfile
2052         cd $WDIR
2053 }
2054 run_test 27t "check that utils parse path correctly"
2055
2056 test_27u() { # bug 4900
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         remote_mds_nodsh && skip "remote MDS with nodsh"
2059
2060         local index
2061         local list=$(comma_list $(mdts_nodes))
2062
2063 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2064         do_nodes $list $LCTL set_param fail_loc=0x139
2065         test_mkdir -p $DIR/$tdir
2066         stack_trap "simple_cleanup_common 1000"
2067         createmany -o $DIR/$tdir/$tfile 1000
2068         do_nodes $list $LCTL set_param fail_loc=0
2069
2070         TLOG=$TMP/$tfile.getstripe
2071         $LFS getstripe $DIR/$tdir > $TLOG
2072         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2073         [[ $OBJS -gt 0 ]] &&
2074                 error "$OBJS objects created on OST-0. See $TLOG" ||
2075                 rm -f $TLOG
2076 }
2077 run_test 27u "skip object creation on OSC w/o objects"
2078
2079 test_27v() { # bug 4900
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082         remote_mds_nodsh && skip "remote MDS with nodsh"
2083         remote_ost_nodsh && skip "remote OST with nodsh"
2084
2085         exhaust_all_precreations 0x215
2086         reset_enospc
2087
2088         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2089
2090         touch $DIR/$tdir/$tfile
2091         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2092         # all except ost1
2093         for (( i=1; i < OSTCOUNT; i++ )); do
2094                 do_facet ost$i lctl set_param fail_loc=0x705
2095         done
2096         local START=`date +%s`
2097         createmany -o $DIR/$tdir/$tfile 32
2098
2099         local FINISH=`date +%s`
2100         local TIMEOUT=`lctl get_param -n timeout`
2101         local PROCESS=$((FINISH - START))
2102         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2103                error "$FINISH - $START >= $TIMEOUT / 2"
2104         sleep $((TIMEOUT / 2 - PROCESS))
2105         reset_enospc
2106 }
2107 run_test 27v "skip object creation on slow OST"
2108
2109 test_27w() { # bug 10997
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2112         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2113                 error "stripe size $size != 65536" || true
2114         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2115                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2116 }
2117 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2118
2119 test_27wa() {
2120         [[ $OSTCOUNT -lt 2 ]] &&
2121                 skip_env "skipping multiple stripe count/offset test"
2122
2123         test_mkdir $DIR/$tdir
2124         for i in $(seq 1 $OSTCOUNT); do
2125                 offset=$((i - 1))
2126                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2127                         error "setstripe -c $i -i $offset failed"
2128                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2129                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2130                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2131                 [ $index -ne $offset ] &&
2132                         error "stripe offset $index != $offset" || true
2133         done
2134 }
2135 run_test 27wa "check $LFS setstripe -c -i options"
2136
2137 test_27x() {
2138         remote_ost_nodsh && skip "remote OST with nodsh"
2139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2141
2142         OFFSET=$(($OSTCOUNT - 1))
2143         OSTIDX=0
2144         local OST=$(ostname_from_index $OSTIDX)
2145
2146         test_mkdir $DIR/$tdir
2147         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2151         for i in $(seq 0 $OFFSET); do
2152                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2153                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2154                 error "OST0 was degraded but new created file still use it"
2155         done
2156         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2157 }
2158 run_test 27x "create files while OST0 is degraded"
2159
2160 test_27y() {
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         remote_mds_nodsh && skip "remote MDS with nodsh"
2163         remote_ost_nodsh && skip "remote OST with nodsh"
2164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2165
2166         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2167         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2168                 osp.$mdtosc.prealloc_last_id)
2169         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2170                 osp.$mdtosc.prealloc_next_id)
2171         local fcount=$((last_id - next_id))
2172         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2173         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2174
2175         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2176                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2177         local OST_DEACTIVE_IDX=-1
2178         local OSC
2179         local OSTIDX
2180         local OST
2181
2182         for OSC in $MDS_OSCS; do
2183                 OST=$(osc_to_ost $OSC)
2184                 OSTIDX=$(index_from_ostuuid $OST)
2185                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2186                         OST_DEACTIVE_IDX=$OSTIDX
2187                 fi
2188                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2189                         echo $OSC "is Deactivated:"
2190                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2191                 fi
2192         done
2193
2194         OSTIDX=$(index_from_ostuuid $OST)
2195         test_mkdir $DIR/$tdir
2196         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=1
2205                 fi
2206         done
2207
2208         sleep_maxage
2209         createmany -o $DIR/$tdir/$tfile $fcount
2210
2211         for OSC in $MDS_OSCS; do
2212                 OST=$(osc_to_ost $OSC)
2213                 OSTIDX=$(index_from_ostuuid $OST)
2214                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2215                         echo $OST "is recovered from degraded:"
2216                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2217                                                 obdfilter.$OST.degraded=0
2218                 else
2219                         do_facet $SINGLEMDS lctl --device %$OSC activate
2220                 fi
2221         done
2222
2223         # all osp devices get activated, hence -1 stripe count restored
2224         local stripe_count=0
2225
2226         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2227         # devices get activated.
2228         sleep_maxage
2229         $LFS setstripe -c -1 $DIR/$tfile
2230         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2231         rm -f $DIR/$tfile
2232         [ $stripe_count -ne $OSTCOUNT ] &&
2233                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2234         return 0
2235 }
2236 run_test 27y "create files while OST0 is degraded and the rest inactive"
2237
2238 check_seq_oid()
2239 {
2240         log "check file $1"
2241
2242         lmm_count=$($LFS getstripe -c $1)
2243         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2244         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2245
2246         local old_ifs="$IFS"
2247         IFS=$'[:]'
2248         fid=($($LFS path2fid $1))
2249         IFS="$old_ifs"
2250
2251         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2252         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2253
2254         # compare lmm_seq and lu_fid->f_seq
2255         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2256         # compare lmm_object_id and lu_fid->oid
2257         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2258
2259         # check the trusted.fid attribute of the OST objects of the file
2260         local have_obdidx=false
2261         local stripe_nr=0
2262         $LFS getstripe $1 | while read obdidx oid hex seq; do
2263                 # skip lines up to and including "obdidx"
2264                 [ -z "$obdidx" ] && break
2265                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2266                 $have_obdidx || continue
2267
2268                 local ost=$((obdidx + 1))
2269                 local dev=$(ostdevname $ost)
2270                 local oid_hex
2271
2272                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2273
2274                 seq=$(echo $seq | sed -e "s/^0x//g")
2275                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2276                         oid_hex=$(echo $oid)
2277                 else
2278                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2279                 fi
2280                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2281
2282                 local ff=""
2283                 #
2284                 # Don't unmount/remount the OSTs if we don't need to do that.
2285                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2286                 # update too, until that use mount/ll_decode_filter_fid/mount.
2287                 # Re-enable when debugfs will understand new filter_fid.
2288                 #
2289                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2290                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2291                                 $dev 2>/dev/null" | grep "parent=")
2292                 fi
2293                 if [ -z "$ff" ]; then
2294                         stop ost$ost
2295                         mount_fstype ost$ost
2296                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2297                                 $(facet_mntpt ost$ost)/$obj_file)
2298                         unmount_fstype ost$ost
2299                         start ost$ost $dev $OST_MOUNT_OPTS
2300                         clients_up
2301                 fi
2302
2303                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2304
2305                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2306
2307                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2308                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2309                 #
2310                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2311                 #       stripe_size=1048576 component_id=1 component_start=0 \
2312                 #       component_end=33554432
2313                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2314                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2315                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2316                 local ff_pstripe
2317                 if grep -q 'stripe=' <<<$ff; then
2318                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2319                 else
2320                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2321                         # into f_ver in this case.  See comment on ff_parent.
2322                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2323                 fi
2324
2325                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2326                 [ $ff_pseq = $lmm_seq ] ||
2327                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2328                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2329                 [ $ff_poid = $lmm_oid ] ||
2330                         error "FF parent OID $ff_poid != $lmm_oid"
2331                 (($ff_pstripe == $stripe_nr)) ||
2332                         error "FF stripe $ff_pstripe != $stripe_nr"
2333
2334                 stripe_nr=$((stripe_nr + 1))
2335                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2336                         continue
2337                 if grep -q 'stripe_count=' <<<$ff; then
2338                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2339                                             -e 's/ .*//' <<<$ff)
2340                         [ $lmm_count = $ff_scnt ] ||
2341                                 error "FF stripe count $lmm_count != $ff_scnt"
2342                 fi
2343         done
2344 }
2345
2346 test_27z() {
2347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2348         remote_ost_nodsh && skip "remote OST with nodsh"
2349
2350         test_mkdir $DIR/$tdir
2351         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2352                 { error "setstripe -c -1 failed"; return 1; }
2353         # We need to send a write to every object to get parent FID info set.
2354         # This _should_ also work for setattr, but does not currently.
2355         # touch $DIR/$tdir/$tfile-1 ||
2356         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2357                 { error "dd $tfile-1 failed"; return 2; }
2358         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2359                 { error "setstripe -c -1 failed"; return 3; }
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2361                 { error "dd $tfile-2 failed"; return 4; }
2362
2363         # make sure write RPCs have been sent to OSTs
2364         sync; sleep 5; sync
2365
2366         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2367         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2368 }
2369 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2370
2371 test_27A() { # b=19102
2372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2373
2374         save_layout_restore_at_exit $MOUNT
2375         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2376         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2377                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2378         local default_size=$($LFS getstripe -S $MOUNT)
2379         local default_offset=$($LFS getstripe -i $MOUNT)
2380         local dsize=$(do_facet $SINGLEMDS \
2381                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2382         [ $default_size -eq $dsize ] ||
2383                 error "stripe size $default_size != $dsize"
2384         [ $default_offset -eq -1 ] ||
2385                 error "stripe offset $default_offset != -1"
2386 }
2387 run_test 27A "check filesystem-wide default LOV EA values"
2388
2389 test_27B() { # LU-2523
2390         test_mkdir $DIR/$tdir
2391         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2392         touch $DIR/$tdir/f0
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # rename f0 onto f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2398                 $DIR/$tdir/f0
2399
2400         rm -f $DIR/$tdir/f1
2401         # open f1 with O_LOV_DELAY_CREATE
2402         # unlink f1
2403         # call setstripe ioctl on open file descriptor for f1
2404         # close
2405         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2406
2407         # Allow multiop to fail in imitation of NFS's busted semantics.
2408         true
2409 }
2410 run_test 27B "call setstripe on open unlinked file/rename victim"
2411
2412 # 27C family tests full striping and overstriping
2413 test_27Ca() { #LU-2871
2414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2415
2416         declare -a ost_idx
2417         local index
2418         local found
2419         local i
2420         local j
2421
2422         test_mkdir $DIR/$tdir
2423         cd $DIR/$tdir
2424         for i in $(seq 0 $((OSTCOUNT - 1))); do
2425                 # set stripe across all OSTs starting from OST$i
2426                 $LFS setstripe -i $i -c -1 $tfile$i
2427                 # get striping information
2428                 ost_idx=($($LFS getstripe $tfile$i |
2429                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2430                 echo "OST Index: ${ost_idx[*]}"
2431
2432                 # check the layout
2433                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2434                         error "${#ost_idx[@]} != $OSTCOUNT"
2435
2436                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2437                         found=0
2438                         for j in "${ost_idx[@]}"; do
2439                                 if [ $index -eq $j ]; then
2440                                         found=1
2441                                         break
2442                                 fi
2443                         done
2444                         [ $found = 1 ] ||
2445                                 error "Can not find $index in ${ost_idx[*]}"
2446                 done
2447         done
2448 }
2449 run_test 27Ca "check full striping across all OSTs"
2450
2451 test_27Cb() {
2452         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2453                 skip "server does not support overstriping"
2454         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2455                 skip_env "too many osts, skipping"
2456
2457         test_mkdir -p $DIR/$tdir
2458         local setcount=$(($OSTCOUNT * 2))
2459         [ $setcount -lt 160 ] || large_xattr_enabled ||
2460                 skip_env "ea_inode feature disabled"
2461
2462         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2463                 error "setstripe failed"
2464
2465         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2466         [ $count -eq $setcount ] ||
2467                 error "stripe count $count, should be $setcount"
2468
2469         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2470                 error "overstriped should be set in pattern"
2471
2472         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2473                 error "dd failed"
2474 }
2475 run_test 27Cb "more stripes than OSTs with -C"
2476
2477 test_27Cc() {
2478         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2479                 skip "server does not support overstriping"
2480         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2481
2482         test_mkdir -p $DIR/$tdir
2483         local setcount=$(($OSTCOUNT - 1))
2484
2485         [ $setcount -lt 160 ] || large_xattr_enabled ||
2486                 skip_env "ea_inode feature disabled"
2487
2488         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2489                 error "setstripe failed"
2490
2491         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2492         [ $count -eq $setcount ] ||
2493                 error "stripe count $count, should be $setcount"
2494
2495         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2496                 error "overstriped should not be set in pattern"
2497
2498         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2499                 error "dd failed"
2500 }
2501 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2502
2503 test_27Cd() {
2504         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2505                 skip "server does not support overstriping"
2506         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2507         large_xattr_enabled || skip_env "ea_inode feature disabled"
2508
2509         force_new_seq_all
2510
2511         test_mkdir -p $DIR/$tdir
2512         local setcount=$LOV_MAX_STRIPE_COUNT
2513
2514         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2515                 error "setstripe failed"
2516
2517         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2518         [ $count -eq $setcount ] ||
2519                 error "stripe count $count, should be $setcount"
2520
2521         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2522                 error "overstriped should be set in pattern"
2523
2524         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2525                 error "dd failed"
2526
2527         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2528 }
2529 run_test 27Cd "test maximum stripe count"
2530
2531 test_27Ce() {
2532         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2533                 skip "server does not support overstriping"
2534         test_mkdir -p $DIR/$tdir
2535
2536         pool_add $TESTNAME || error "Pool creation failed"
2537         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2538
2539         local setcount=8
2540
2541         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2542                 error "setstripe failed"
2543
2544         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2545         [ $count -eq $setcount ] ||
2546                 error "stripe count $count, should be $setcount"
2547
2548         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2549                 error "overstriped should be set in pattern"
2550
2551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2552                 error "dd failed"
2553
2554         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2555 }
2556 run_test 27Ce "test pool with overstriping"
2557
2558 test_27Cf() {
2559         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2560                 skip "server does not support overstriping"
2561         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2562                 skip_env "too many osts, skipping"
2563
2564         test_mkdir -p $DIR/$tdir
2565
2566         local setcount=$(($OSTCOUNT * 2))
2567         [ $setcount -lt 160 ] || large_xattr_enabled ||
2568                 skip_env "ea_inode feature disabled"
2569
2570         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2571                 error "setstripe failed"
2572
2573         echo 1 > $DIR/$tdir/$tfile
2574
2575         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2576         [ $count -eq $setcount ] ||
2577                 error "stripe count $count, should be $setcount"
2578
2579         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2580                 error "overstriped should be set in pattern"
2581
2582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2583                 error "dd failed"
2584
2585         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2586 }
2587 run_test 27Cf "test default inheritance with overstriping"
2588
2589 test_27Cg() {
2590         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2591                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2592
2593         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2594         (( $? != 0 )) || error "must be an error for not existent OST#"
2595 }
2596 run_test 27Cg "test setstripe with wrong OST idx"
2597
2598 test_27D() {
2599         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2600         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2601         remote_mds_nodsh && skip "remote MDS with nodsh"
2602
2603         local POOL=${POOL:-testpool}
2604         local first_ost=0
2605         local last_ost=$(($OSTCOUNT - 1))
2606         local ost_step=1
2607         local ost_list=$(seq $first_ost $ost_step $last_ost)
2608         local ost_range="$first_ost $last_ost $ost_step"
2609
2610         test_mkdir $DIR/$tdir
2611         pool_add $POOL || error "pool_add failed"
2612         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2613
2614         local skip27D
2615         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2616                 skip27D+="-s 29"
2617         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2618                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2619                         skip27D+=" -s 30,31"
2620         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2621           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2622                 skip27D+=" -s 32,33"
2623         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2624                 skip27D+=" -s 34"
2625         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2626                 error "llapi_layout_test failed"
2627
2628         destroy_test_pools || error "destroy test pools failed"
2629 }
2630 run_test 27D "validate llapi_layout API"
2631
2632 # Verify that default_easize is increased from its initial value after
2633 # accessing a widely striped file.
2634 test_27E() {
2635         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2636         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2637                 skip "client does not have LU-3338 fix"
2638
2639         # 72 bytes is the minimum space required to store striping
2640         # information for a file striped across one OST:
2641         # (sizeof(struct lov_user_md_v3) +
2642         #  sizeof(struct lov_user_ost_data_v1))
2643         local min_easize=72
2644         $LCTL set_param -n llite.*.default_easize $min_easize ||
2645                 error "lctl set_param failed"
2646         local easize=$($LCTL get_param -n llite.*.default_easize)
2647
2648         [ $easize -eq $min_easize ] ||
2649                 error "failed to set default_easize"
2650
2651         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2652                 error "setstripe failed"
2653         # In order to ensure stat() call actually talks to MDS we need to
2654         # do something drastic to this file to shake off all lock, e.g.
2655         # rename it (kills lookup lock forcing cache cleaning)
2656         mv $DIR/$tfile $DIR/${tfile}-1
2657         ls -l $DIR/${tfile}-1
2658         rm $DIR/${tfile}-1
2659
2660         easize=$($LCTL get_param -n llite.*.default_easize)
2661
2662         [ $easize -gt $min_easize ] ||
2663                 error "default_easize not updated"
2664 }
2665 run_test 27E "check that default extended attribute size properly increases"
2666
2667 test_27F() { # LU-5346/LU-7975
2668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2669         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2670         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2671                 skip "Need MDS version at least 2.8.51"
2672         remote_ost_nodsh && skip "remote OST with nodsh"
2673
2674         test_mkdir $DIR/$tdir
2675         rm -f $DIR/$tdir/f0
2676         $LFS setstripe -c 2 $DIR/$tdir
2677
2678         # stop all OSTs to reproduce situation for LU-7975 ticket
2679         for num in $(seq $OSTCOUNT); do
2680                 stop ost$num
2681         done
2682
2683         # open/create f0 with O_LOV_DELAY_CREATE
2684         # truncate f0 to a non-0 size
2685         # close
2686         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2687
2688         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2689         # open/write it again to force delayed layout creation
2690         cat /etc/hosts > $DIR/$tdir/f0 &
2691         catpid=$!
2692
2693         # restart OSTs
2694         for num in $(seq $OSTCOUNT); do
2695                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2696                         error "ost$num failed to start"
2697         done
2698
2699         wait $catpid || error "cat failed"
2700
2701         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2702         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2703                 error "wrong stripecount"
2704
2705 }
2706 run_test 27F "Client resend delayed layout creation with non-zero size"
2707
2708 test_27G() { #LU-10629
2709         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2710                 skip "Need MDS version at least 2.11.51"
2711         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2712         remote_mds_nodsh && skip "remote MDS with nodsh"
2713         local POOL=${POOL:-testpool}
2714         local ostrange="0 0 1"
2715
2716         test_mkdir $DIR/$tdir
2717         touch $DIR/$tdir/$tfile.nopool
2718         pool_add $POOL || error "pool_add failed"
2719         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2720         $LFS setstripe -p $POOL $DIR/$tdir
2721
2722         local pool=$($LFS getstripe -p $DIR/$tdir)
2723
2724         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2725         touch $DIR/$tdir/$tfile.default
2726         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2727         $LFS find $DIR/$tdir -type f --pool $POOL
2728         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2729         [[ "$found" == "2" ]] ||
2730                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2731
2732         $LFS setstripe -d $DIR/$tdir
2733
2734         pool=$($LFS getstripe -p -d $DIR/$tdir)
2735
2736         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2737 }
2738 run_test 27G "Clear OST pool from stripe"
2739
2740 test_27H() {
2741         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2742                 skip "Need MDS version newer than 2.11.54"
2743         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2744         test_mkdir $DIR/$tdir
2745         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2746         touch $DIR/$tdir/$tfile
2747         $LFS getstripe -c $DIR/$tdir/$tfile
2748         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2749                 error "two-stripe file doesn't have two stripes"
2750
2751         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2752         $LFS getstripe -y $DIR/$tdir/$tfile
2753         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2754              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2755                 error "expected l_ost_idx: [02]$ not matched"
2756
2757         # make sure ost list has been cleared
2758         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2759         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2760                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2761         touch $DIR/$tdir/f3
2762         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2763 }
2764 run_test 27H "Set specific OSTs stripe"
2765
2766 test_27I() {
2767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2768         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2769         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2770                 skip "Need MDS version newer than 2.12.52"
2771         local pool=$TESTNAME
2772         local ostrange="1 1 1"
2773
2774         save_layout_restore_at_exit $MOUNT
2775         $LFS setstripe -c 2 -i 0 $MOUNT
2776         pool_add $pool || error "pool_add failed"
2777         pool_add_targets $pool $ostrange ||
2778                 error "pool_add_targets failed"
2779         test_mkdir $DIR/$tdir
2780         $LFS setstripe -p $pool $DIR/$tdir
2781         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2782         $LFS getstripe $DIR/$tdir/$tfile
2783 }
2784 run_test 27I "check that root dir striping does not break parent dir one"
2785
2786 test_27J() {
2787         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2788                 skip "Need MDS version newer than 2.12.51"
2789
2790         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2791         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2792         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2793            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2794                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2795
2796         test_mkdir $DIR/$tdir
2797         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2798         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2799
2800         # create foreign file (raw way)
2801         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2802                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2803
2804         ! $LFS setstripe --foreign --flags foo \
2805                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2806                         error "creating $tfile with '--flags foo' should fail"
2807
2808         ! $LFS setstripe --foreign --flags 0xffffffff \
2809                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2810                         error "creating $tfile w/ 0xffffffff flags should fail"
2811
2812         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2813                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2814
2815         # verify foreign file (raw way)
2816         parse_foreign_file -f $DIR/$tdir/$tfile |
2817                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2818                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2819         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2820                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2821         parse_foreign_file -f $DIR/$tdir/$tfile |
2822                 grep "lov_foreign_size: 73" ||
2823                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2824         parse_foreign_file -f $DIR/$tdir/$tfile |
2825                 grep "lov_foreign_type: 1" ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_flags: 0x0000DA08" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2830         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2831                 grep "lov_foreign_value: 0x" |
2832                 sed -e 's/lov_foreign_value: 0x//')
2833         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2834         [[ $lov = ${lov2// /} ]] ||
2835                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2836
2837         # create foreign file (lfs + API)
2838         $LFS setstripe --foreign=none --flags 0xda08 \
2839                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2840                 error "$DIR/$tdir/${tfile}2: create failed"
2841
2842         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2843                 grep "lfm_magic:.*0x0BD70BD0" ||
2844                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2845         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2846         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2847                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2849                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2850         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2851                 grep "lfm_flags:.*0x0000DA08" ||
2852                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2853         $LFS getstripe $DIR/$tdir/${tfile}2 |
2854                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2856
2857         # modify striping should fail
2858         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2859                 error "$DIR/$tdir/$tfile: setstripe should fail"
2860         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2861                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2862
2863         # R/W should fail
2864         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2865         cat $DIR/$tdir/${tfile}2 &&
2866                 error "$DIR/$tdir/${tfile}2: read should fail"
2867         cat /etc/passwd > $DIR/$tdir/$tfile &&
2868                 error "$DIR/$tdir/$tfile: write should fail"
2869         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2870                 error "$DIR/$tdir/${tfile}2: write should fail"
2871
2872         # chmod should work
2873         chmod 222 $DIR/$tdir/$tfile ||
2874                 error "$DIR/$tdir/$tfile: chmod failed"
2875         chmod 222 $DIR/$tdir/${tfile}2 ||
2876                 error "$DIR/$tdir/${tfile}2: chmod failed"
2877
2878         # chown should work
2879         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2880                 error "$DIR/$tdir/$tfile: chown failed"
2881         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2882                 error "$DIR/$tdir/${tfile}2: chown failed"
2883
2884         # rename should work
2885         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2886                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2887         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2888                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2889
2890         #remove foreign file
2891         rm $DIR/$tdir/${tfile}.new ||
2892                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2893         rm $DIR/$tdir/${tfile}2.new ||
2894                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2895 }
2896 run_test 27J "basic ops on file with foreign LOV"
2897
2898 test_27K() {
2899         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2900                 skip "Need MDS version newer than 2.12.49"
2901
2902         test_mkdir $DIR/$tdir
2903         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2904         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2905
2906         # create foreign dir (raw way)
2907         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2908                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2909
2910         ! $LFS setdirstripe --foreign --flags foo \
2911                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2912                         error "creating $tdir with '--flags foo' should fail"
2913
2914         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2915                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2916                         error "creating $tdir w/ 0xffffffff flags should fail"
2917
2918         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2919                 error "create_foreign_dir FAILED"
2920
2921         # verify foreign dir (raw way)
2922         parse_foreign_dir -d $DIR/$tdir/$tdir |
2923                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2924                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2925         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2926                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2927         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2928                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2929         parse_foreign_dir -d $DIR/$tdir/$tdir |
2930                 grep "lmv_foreign_flags: 55813$" ||
2931                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2932         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2933                 grep "lmv_foreign_value: 0x" |
2934                 sed 's/lmv_foreign_value: 0x//')
2935         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2936                 sed 's/ //g')
2937         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2938
2939         # create foreign dir (lfs + API)
2940         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2941                 $DIR/$tdir/${tdir}2 ||
2942                 error "$DIR/$tdir/${tdir}2: create failed"
2943
2944         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2945
2946         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2947                 grep "lfm_magic:.*0x0CD50CD0" ||
2948                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2949         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2950         # - sizeof(lfm_type) - sizeof(lfm_flags)
2951         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2953         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2954                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2956                 grep "lfm_flags:.*0x0000DA05" ||
2957                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2958         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2959                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2960                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2961
2962         # file create in dir should fail
2963         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2964         touch $DIR/$tdir/${tdir}2/$tfile &&
2965                 error "$DIR/${tdir}2: file create should fail"
2966
2967         # chmod should work
2968         chmod 777 $DIR/$tdir/$tdir ||
2969                 error "$DIR/$tdir: chmod failed"
2970         chmod 777 $DIR/$tdir/${tdir}2 ||
2971                 error "$DIR/${tdir}2: chmod failed"
2972
2973         # chown should work
2974         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2975                 error "$DIR/$tdir: chown failed"
2976         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2977                 error "$DIR/${tdir}2: chown failed"
2978
2979         # rename should work
2980         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2981                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2982         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2983                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2984
2985         #remove foreign dir
2986         rmdir $DIR/$tdir/${tdir}.new ||
2987                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2988         rmdir $DIR/$tdir/${tdir}2.new ||
2989                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2990 }
2991 run_test 27K "basic ops on dir with foreign LMV"
2992
2993 test_27L() {
2994         remote_mds_nodsh && skip "remote MDS with nodsh"
2995
2996         local POOL=${POOL:-$TESTNAME}
2997
2998         pool_add $POOL || error "pool_add failed"
2999
3000         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3001                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3002                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3003 }
3004 run_test 27L "lfs pool_list gives correct pool name"
3005
3006 test_27M() {
3007         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3008                 skip "Need MDS version >= than 2.12.57"
3009         remote_mds_nodsh && skip "remote MDS with nodsh"
3010         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3011
3012         # Set default striping on directory
3013         local setcount=4
3014         local stripe_opt
3015         local mdts=$(comma_list $(mdts_nodes))
3016
3017         # if we run against a 2.12 server which lacks overstring support
3018         # then the connect_flag will not report overstriping, even if client
3019         # is 2.14+
3020         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3021                 stripe_opt="-C $setcount"
3022         elif (( $OSTCOUNT >= $setcount )); then
3023                 stripe_opt="-c $setcount"
3024         else
3025                 skip "server does not support overstriping"
3026         fi
3027
3028         test_mkdir $DIR/$tdir
3029
3030         # Validate existing append_* params and ensure restore
3031         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3032         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3033         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3034
3035         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3036         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3037         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3038
3039         $LFS setstripe $stripe_opt $DIR/$tdir
3040
3041         echo 1 > $DIR/$tdir/${tfile}.1
3042         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3043         (( $count == $setcount )) ||
3044                 error "(1) stripe count $count, should be $setcount"
3045
3046         local appendcount=$orig_count
3047         echo 1 >> $DIR/$tdir/${tfile}.2_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3049         (( $count == $appendcount )) ||
3050                 error "(2)stripe count $count, should be $appendcount for append"
3051
3052         # Disable O_APPEND striping, verify it works
3053         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3054
3055         # Should now get the default striping, which is 4
3056         setcount=4
3057         echo 1 >> $DIR/$tdir/${tfile}.3_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3059         (( $count == $setcount )) ||
3060                 error "(3) stripe count $count, should be $setcount"
3061
3062         # Try changing the stripe count for append files
3063         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3064
3065         # Append striping is now 2 (directory default is still 4)
3066         appendcount=2
3067         echo 1 >> $DIR/$tdir/${tfile}.4_append
3068         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3069         (( $count == $appendcount )) ||
3070                 error "(4) stripe count $count, should be $appendcount for append"
3071
3072         # Test append stripe count of -1
3073         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3074         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3075                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3076                 touch $DIR/$tdir/$tfile.specific.{1..128}
3077         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3078
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3080         appendcount=$OSTCOUNT
3081         echo 1 >> $DIR/$tdir/${tfile}.5
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3083         (( $count == $appendcount )) ||
3084                 error "(5) stripe count $count, should be $appendcount for append"
3085
3086         # Set append striping back to default of 1
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3088
3089         # Try a new default striping, PFL + DOM
3090         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3091
3092         # Create normal DOM file, DOM returns stripe count == 0
3093         setcount=0
3094         touch $DIR/$tdir/${tfile}.6
3095         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3096         (( $count == $setcount )) ||
3097                 error "(6) stripe count $count, should be $setcount"
3098
3099         # Show
3100         appendcount=1
3101         echo 1 >> $DIR/$tdir/${tfile}.7_append
3102         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3103         (( $count == $appendcount )) ||
3104                 error "(7) stripe count $count, should be $appendcount for append"
3105
3106         # Clean up DOM layout
3107         $LFS setstripe -d $DIR/$tdir
3108
3109         save_layout_restore_at_exit $MOUNT
3110         # Now test that append striping works when layout is from root
3111         $LFS setstripe -c 2 $MOUNT
3112         # Make a special directory for this
3113         mkdir $DIR/${tdir}/${tdir}.2
3114
3115         # Verify for normal file
3116         setcount=2
3117         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3118         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3119         (( $count == $setcount )) ||
3120                 error "(8) stripe count $count, should be $setcount"
3121
3122         appendcount=1
3123         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3124         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3125         (( $count == $appendcount )) ||
3126                 error "(9) stripe count $count, should be $appendcount for append"
3127
3128         # Now test O_APPEND striping with pools
3129         pool_add $TESTNAME || error "pool creation failed"
3130         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3131         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3132
3133         echo 1 >> $DIR/$tdir/${tfile}.10_append
3134
3135         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3136         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3137
3138         # Check that count is still correct
3139         appendcount=1
3140         echo 1 >> $DIR/$tdir/${tfile}.11_append
3141         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3142         (( $count == $appendcount )) ||
3143                 error "(11) stripe count $count, should be $appendcount for append"
3144
3145         # Disable O_APPEND stripe count, verify pool works separately
3146         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3147
3148         echo 1 >> $DIR/$tdir/${tfile}.12_append
3149
3150         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3151         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3152
3153         # Remove pool setting, verify it's not applied
3154         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3155
3156         echo 1 >> $DIR/$tdir/${tfile}.13_append
3157
3158         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3159         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3160 }
3161 run_test 27M "test O_APPEND striping"
3162
3163 test_27N() {
3164         combined_mgs_mds && skip "needs separate MGS/MDT"
3165
3166         pool_add $TESTNAME || error "pool_add failed"
3167         do_facet mgs "$LCTL pool_list $FSNAME" |
3168                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3169                 error "lctl pool_list on MGS failed"
3170 }
3171 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3172
3173 clean_foreign_symlink() {
3174         trap 0
3175         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3176         for i in $DIR/$tdir/* ; do
3177                 $LFS unlink_foreign $i || true
3178         done
3179 }
3180
3181 test_27O() {
3182         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3183                 skip "Need MDS version newer than 2.12.51"
3184
3185         test_mkdir $DIR/$tdir
3186         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3187         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3188
3189         trap clean_foreign_symlink EXIT
3190
3191         # enable foreign_symlink behaviour
3192         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3193
3194         # foreign symlink LOV format is a partial path by default
3195
3196         # create foreign file (lfs + API)
3197         $LFS setstripe --foreign=symlink --flags 0xda05 \
3198                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3199                 error "$DIR/$tdir/${tfile}: create failed"
3200
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_magic:.*0x0BD70BD0" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3204         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3205                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3206         $LFS getstripe -v $DIR/$tdir/${tfile} |
3207                 grep "lfm_flags:.*0x0000DA05" ||
3208                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3209         $LFS getstripe $DIR/$tdir/${tfile} |
3210                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3211                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3212
3213         # modify striping should fail
3214         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: setstripe should fail"
3216
3217         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3218         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3219         cat /etc/passwd > $DIR/$tdir/$tfile &&
3220                 error "$DIR/$tdir/$tfile: write should fail"
3221
3222         # rename should succeed
3223         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3224                 error "$DIR/$tdir/$tfile: rename has failed"
3225
3226         #remove foreign_symlink file should fail
3227         rm $DIR/$tdir/${tfile}.new &&
3228                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3229
3230         #test fake symlink
3231         mkdir /tmp/${uuid1} ||
3232                 error "/tmp/${uuid1}: mkdir has failed"
3233         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3234                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3235         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3236         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3237                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3238         #read should succeed now
3239         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3240                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3241         #write should succeed now
3242         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3243                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3244         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3245                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3246         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3247                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3248
3249         #check that getstripe still works
3250         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3251                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3252
3253         # chmod should still succeed
3254         chmod 644 $DIR/$tdir/${tfile}.new ||
3255                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3256
3257         # chown should still succeed
3258         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3259                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3260
3261         # rename should still succeed
3262         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3263                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3264
3265         #remove foreign_symlink file should still fail
3266         rm $DIR/$tdir/${tfile} &&
3267                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3268
3269         #use special ioctl() to unlink foreign_symlink file
3270         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3271                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3272
3273 }
3274 run_test 27O "basic ops on foreign file of symlink type"
3275
3276 test_27P() {
3277         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3278                 skip "Need MDS version newer than 2.12.49"
3279
3280         test_mkdir $DIR/$tdir
3281         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3282         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3283
3284         trap clean_foreign_symlink EXIT
3285
3286         # enable foreign_symlink behaviour
3287         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3288
3289         # foreign symlink LMV format is a partial path by default
3290
3291         # create foreign dir (lfs + API)
3292         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3293                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3294                 error "$DIR/$tdir/${tdir}: create failed"
3295
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3297
3298         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3299                 grep "lfm_magic:.*0x0CD50CD0" ||
3300                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3301         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3302                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3303         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3304                 grep "lfm_flags:.*0x0000DA05" ||
3305                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3306         $LFS getdirstripe $DIR/$tdir/${tdir} |
3307                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3308                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3309
3310         # file create in dir should fail
3311         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3312         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3313
3314         # rename should succeed
3315         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3316                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3317
3318         #remove foreign_symlink dir should fail
3319         rmdir $DIR/$tdir/${tdir}.new &&
3320                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3321
3322         #test fake symlink
3323         mkdir -p /tmp/${uuid1}/${uuid2} ||
3324                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3325         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3326                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3327         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3328         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3329                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3330         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3331                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3332
3333         #check that getstripe fails now that foreign_symlink enabled
3334         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3335                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3336
3337         # file create in dir should work now
3338         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3339                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3340         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3341                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3342         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3343                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3344
3345         # chmod should still succeed
3346         chmod 755 $DIR/$tdir/${tdir}.new ||
3347                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3348
3349         # chown should still succeed
3350         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3351                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3352
3353         # rename should still succeed
3354         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3355                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3356
3357         #remove foreign_symlink dir should still fail
3358         rmdir $DIR/$tdir/${tdir} &&
3359                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3360
3361         #use special ioctl() to unlink foreign_symlink file
3362         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3363                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3364
3365         #created file should still exist
3366         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3367                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3368         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3369                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3370 }
3371 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3372
3373 test_27Q() {
3374         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3375         stack_trap "rm -f $TMP/$tfile*"
3376
3377         test_mkdir $DIR/$tdir-1
3378         test_mkdir $DIR/$tdir-2
3379
3380         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3381         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3382
3383         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3384         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3385
3386         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3387         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3388
3389         # Create some bad symlinks and ensure that we don't loop
3390         # forever or something. These should return ELOOP (40) and
3391         # ENOENT (2) but I don't want to test for that because there's
3392         # always some weirdo architecture that needs to ruin
3393         # everything by defining these error numbers differently.
3394
3395         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3396         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3397
3398         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3399         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3400
3401         return 0
3402 }
3403 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3404
3405 test_27R() {
3406         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3407                 skip "need MDS 2.14.55 or later"
3408         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3409
3410         local testdir="$DIR/$tdir"
3411         test_mkdir -p $testdir
3412         stack_trap "rm -rf $testdir"
3413         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3414
3415         local f1="$testdir/f1"
3416         touch $f1 || error "failed to touch $f1"
3417         local count=$($LFS getstripe -c $f1)
3418         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3419
3420         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3421         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3422
3423         local maxcount=$(($OSTCOUNT - 1))
3424         local mdts=$(comma_list $(mdts_nodes))
3425         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3426         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3427
3428         local f2="$testdir/f2"
3429         touch $f2 || error "failed to touch $f2"
3430         local count=$($LFS getstripe -c $f2)
3431         (( $count == $maxcount )) || error "wrong stripe count"
3432 }
3433 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3434
3435 test_27T() {
3436         [ $(facet_host client) == $(facet_host ost1) ] &&
3437                 skip "need ost1 and client on different nodes"
3438
3439 #define OBD_FAIL_OSC_NO_GRANT            0x411
3440         $LCTL set_param fail_loc=0x20000411 fail_val=1
3441 #define OBD_FAIL_OST_ENOSPC              0x215
3442         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3443         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3444         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3445                 error "multiop failed"
3446 }
3447 run_test 27T "no eio on close on partial write due to enosp"
3448
3449 test_27U() {
3450         local dir=$DIR/$tdir
3451         local file=$dir/$tfile
3452         local append_pool=${TESTNAME}-append
3453         local normal_pool=${TESTNAME}-normal
3454         local pool
3455         local stripe_count
3456         local stripe_count2
3457         local mdts=$(comma_list $(mdts_nodes))
3458
3459         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3460                 skip "Need MDS version at least 2.15.51 for append pool feature"
3461
3462         # Validate existing append_* params and ensure restore
3463         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3464         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3465         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3466
3467         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3468         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3469         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3470
3471         pool_add $append_pool || error "pool creation failed"
3472         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3473
3474         pool_add $normal_pool || error "pool creation failed"
3475         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3476
3477         test_mkdir $dir
3478         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3479
3480         echo XXX >> $file.1
3481         $LFS getstripe $file.1
3482
3483         pool=$($LFS getstripe -p $file.1)
3484         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3485
3486         stripe_count2=$($LFS getstripe -c $file.1)
3487         ((stripe_count2 == stripe_count)) ||
3488                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3489
3490         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3491
3492         echo XXX >> $file.2
3493         $LFS getstripe $file.2
3494
3495         pool=$($LFS getstripe -p $file.2)
3496         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3497
3498         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3499
3500         echo XXX >> $file.3
3501         $LFS getstripe $file.3
3502
3503         stripe_count2=$($LFS getstripe -c $file.3)
3504         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3505 }
3506 run_test 27U "append pool and stripe count work with composite default layout"
3507
3508 # createtest also checks that device nodes are created and
3509 # then visible correctly (#2091)
3510 test_28() { # bug 2091
3511         test_mkdir $DIR/d28
3512         $CREATETEST $DIR/d28/ct || error "createtest failed"
3513 }
3514 run_test 28 "create/mknod/mkdir with bad file types ============"
3515
3516 test_29() {
3517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3518
3519         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3520                 disable_opencache
3521                 stack_trap "restore_opencache"
3522         }
3523
3524         sync; sleep 1; sync # flush out any dirty pages from previous tests
3525         cancel_lru_locks
3526         test_mkdir $DIR/d29
3527         touch $DIR/d29/foo
3528         log 'first d29'
3529         ls -l $DIR/d29
3530
3531         declare -i LOCKCOUNTORIG=0
3532         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3533                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3534         done
3535         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3536
3537         declare -i LOCKUNUSEDCOUNTORIG=0
3538         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3539                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3540         done
3541
3542         log 'second d29'
3543         ls -l $DIR/d29
3544         log 'done'
3545
3546         declare -i LOCKCOUNTCURRENT=0
3547         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3548                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3549         done
3550
3551         declare -i LOCKUNUSEDCOUNTCURRENT=0
3552         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3553                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3554         done
3555
3556         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3557                 $LCTL set_param -n ldlm.dump_namespaces ""
3558                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3559                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3560                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3561                 return 2
3562         fi
3563         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3564                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3565                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3566                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3567                 return 3
3568         fi
3569 }
3570 run_test 29 "IT_GETATTR regression  ============================"
3571
3572 test_30a() { # was test_30
3573         cp $(which ls) $DIR || cp /bin/ls $DIR
3574         $DIR/ls / || error "Can't execute binary from lustre"
3575         rm $DIR/ls
3576 }
3577 run_test 30a "execute binary from Lustre (execve) =============="
3578
3579 test_30b() {
3580         cp `which ls` $DIR || cp /bin/ls $DIR
3581         chmod go+rx $DIR/ls
3582         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3583         rm $DIR/ls
3584 }
3585 run_test 30b "execute binary from Lustre as non-root ==========="
3586
3587 test_30c() { # b=22376
3588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3589
3590         cp $(which ls) $DIR || cp /bin/ls $DIR
3591         chmod a-rw $DIR/ls
3592         cancel_lru_locks mdc
3593         cancel_lru_locks osc
3594         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3595         rm -f $DIR/ls
3596 }
3597 run_test 30c "execute binary from Lustre without read perms ===="
3598
3599 test_30d() {
3600         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3601
3602         for i in {1..10}; do
3603                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3604                 local PID=$!
3605                 sleep 1
3606                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3607                 wait $PID || error "executing dd from Lustre failed"
3608                 rm -f $DIR/$tfile
3609         done
3610
3611         rm -f $DIR/dd
3612 }
3613 run_test 30d "execute binary from Lustre while clear locks"
3614
3615 test_31a() {
3616         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3617         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3618 }
3619 run_test 31a "open-unlink file =================================="
3620
3621 test_31b() {
3622         touch $DIR/f31 || error "touch $DIR/f31 failed"
3623         ln $DIR/f31 $DIR/f31b || error "ln failed"
3624         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3625         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3626 }
3627 run_test 31b "unlink file with multiple links while open ======="
3628
3629 test_31c() {
3630         touch $DIR/f31 || error "touch $DIR/f31 failed"
3631         ln $DIR/f31 $DIR/f31c || error "ln failed"
3632         multiop_bg_pause $DIR/f31 O_uc ||
3633                 error "multiop_bg_pause for $DIR/f31 failed"
3634         MULTIPID=$!
3635         $MULTIOP $DIR/f31c Ouc
3636         kill -USR1 $MULTIPID
3637         wait $MULTIPID
3638 }
3639 run_test 31c "open-unlink file with multiple links ============="
3640
3641 test_31d() {
3642         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3643         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3644 }
3645 run_test 31d "remove of open directory ========================="
3646
3647 test_31e() { # bug 2904
3648         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3649 }
3650 run_test 31e "remove of open non-empty directory ==============="
3651
3652 test_31f() { # bug 4554
3653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3654
3655         set -vx
3656         test_mkdir $DIR/d31f
3657         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3658         cp /etc/hosts $DIR/d31f
3659         ls -l $DIR/d31f
3660         $LFS getstripe $DIR/d31f/hosts
3661         multiop_bg_pause $DIR/d31f D_c || return 1
3662         MULTIPID=$!
3663
3664         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3665         test_mkdir $DIR/d31f
3666         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3667         cp /etc/hosts $DIR/d31f
3668         ls -l $DIR/d31f
3669         $LFS getstripe $DIR/d31f/hosts
3670         multiop_bg_pause $DIR/d31f D_c || return 1
3671         MULTIPID2=$!
3672
3673         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3674         wait $MULTIPID || error "first opendir $MULTIPID failed"
3675
3676         sleep 6
3677
3678         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3679         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3680         set +vx
3681 }
3682 run_test 31f "remove of open directory with open-unlink file ==="
3683
3684 test_31g() {
3685         echo "-- cross directory link --"
3686         test_mkdir -c1 $DIR/${tdir}ga
3687         test_mkdir -c1 $DIR/${tdir}gb
3688         touch $DIR/${tdir}ga/f
3689         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3690         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3691         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3692         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3693         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3694 }
3695 run_test 31g "cross directory link==============="
3696
3697 test_31h() {
3698         echo "-- cross directory link --"
3699         test_mkdir -c1 $DIR/${tdir}
3700         test_mkdir -c1 $DIR/${tdir}/dir
3701         touch $DIR/${tdir}/f
3702         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3703         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3704         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3705         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3706         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3707 }
3708 run_test 31h "cross directory link under child==============="
3709
3710 test_31i() {
3711         echo "-- cross directory link --"
3712         test_mkdir -c1 $DIR/$tdir
3713         test_mkdir -c1 $DIR/$tdir/dir
3714         touch $DIR/$tdir/dir/f
3715         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3716         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3717         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3718         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3719         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3720 }
3721 run_test 31i "cross directory link under parent==============="
3722
3723 test_31j() {
3724         test_mkdir -c1 -p $DIR/$tdir
3725         test_mkdir -c1 -p $DIR/$tdir/dir1
3726         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3727         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3728         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3729         return 0
3730 }
3731 run_test 31j "link for directory"
3732
3733 test_31k() {
3734         test_mkdir -c1 -p $DIR/$tdir
3735         touch $DIR/$tdir/s
3736         touch $DIR/$tdir/exist
3737         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3738         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3739         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3740         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3741         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3742         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3743         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3744         return 0
3745 }
3746 run_test 31k "link to file: the same, non-existing, dir"
3747
3748 test_31l() {
3749         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3750
3751         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3752         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3753                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3754
3755         touch $DIR/$tfile || error "create failed"
3756         mkdir $DIR/$tdir || error "mkdir failed"
3757         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3758 }
3759 run_test 31l "link to file: target dir has trailing slash"
3760
3761 test_31m() {
3762         mkdir $DIR/d31m
3763         touch $DIR/d31m/s
3764         mkdir $DIR/d31m2
3765         touch $DIR/d31m2/exist
3766         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3767         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3768         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3769         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3770         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3771         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3772         return 0
3773 }
3774 run_test 31m "link to file: the same, non-existing, dir"
3775
3776 test_31n() {
3777         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3778         nlink=$(stat --format=%h $DIR/$tfile)
3779         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3780         local fd=$(free_fd)
3781         local cmd="exec $fd<$DIR/$tfile"
3782         eval $cmd
3783         cmd="exec $fd<&-"
3784         trap "eval $cmd" EXIT
3785         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3786         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3787         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3788         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3789         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3790         eval $cmd
3791 }
3792 run_test 31n "check link count of unlinked file"
3793
3794 link_one() {
3795         local tempfile=$(mktemp $1_XXXXXX)
3796         link $tempfile $1 2> /dev/null &&
3797                 echo "$BASHPID: link $tempfile to $1 succeeded"
3798         unlink $tempfile
3799 }
3800
3801 test_31o() { # LU-2901
3802         test_mkdir $DIR/$tdir
3803         for LOOP in $(seq 100); do
3804                 rm -f $DIR/$tdir/$tfile*
3805                 for THREAD in $(seq 8); do
3806                         link_one $DIR/$tdir/$tfile.$LOOP &
3807                 done
3808                 wait
3809                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3810                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3811                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3812                         break || true
3813         done
3814 }
3815 run_test 31o "duplicate hard links with same filename"
3816
3817 test_31p() {
3818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3819
3820         test_mkdir $DIR/$tdir
3821         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3822         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3823
3824         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3825                 error "open unlink test1 failed"
3826         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3827                 error "open unlink test2 failed"
3828
3829         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3830                 error "test1 still exists"
3831         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3832                 error "test2 still exists"
3833 }
3834 run_test 31p "remove of open striped directory"
3835
3836 test_31q() {
3837         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3838
3839         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3840         index=$($LFS getdirstripe -i $DIR/$tdir)
3841         [ $index -eq 3 ] || error "first stripe index $index != 3"
3842         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3843         [ $index -eq 1 ] || error "second stripe index $index != 1"
3844
3845         # when "-c <stripe_count>" is set, the number of MDTs specified after
3846         # "-i" should equal to the stripe count
3847         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3848 }
3849 run_test 31q "create striped directory on specific MDTs"
3850
3851 #LU-14949
3852 test_31r() {
3853         touch $DIR/$tfile.target
3854         touch $DIR/$tfile.source
3855
3856         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3857         $LCTL set_param fail_loc=0x1419 fail_val=3
3858         cat $DIR/$tfile.target &
3859         CATPID=$!
3860
3861         # Guarantee open is waiting before we get here
3862         sleep 1
3863         mv $DIR/$tfile.source $DIR/$tfile.target
3864
3865         wait $CATPID
3866         RC=$?
3867         if [[ $RC -ne 0 ]]; then
3868                 error "open with cat failed, rc=$RC"
3869         fi
3870 }
3871 run_test 31r "open-rename(replace) race"
3872
3873 cleanup_test32_mount() {
3874         local rc=0
3875         trap 0
3876         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3877         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3878         losetup -d $loopdev || true
3879         rm -rf $DIR/$tdir
3880         return $rc
3881 }
3882
3883 test_32a() {
3884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3885
3886         echo "== more mountpoints and symlinks ================="
3887         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3888         trap cleanup_test32_mount EXIT
3889         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3890         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3891                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3892         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3893                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3894         cleanup_test32_mount
3895 }
3896 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3897
3898 test_32b() {
3899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3900
3901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3902         trap cleanup_test32_mount EXIT
3903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3904         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3905                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3906         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3907                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3908         cleanup_test32_mount
3909 }
3910 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3911
3912 test_32c() {
3913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3914
3915         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3916         trap cleanup_test32_mount EXIT
3917         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3918         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3919                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3920         test_mkdir -p $DIR/$tdir/d2/test_dir
3921         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3922                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3923         cleanup_test32_mount
3924 }
3925 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3926
3927 test_32d() {
3928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3929
3930         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3931         trap cleanup_test32_mount EXIT
3932         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3933         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3934                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3935         test_mkdir -p $DIR/$tdir/d2/test_dir
3936         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3937                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3938         cleanup_test32_mount
3939 }
3940 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3941
3942 test_32e() {
3943         rm -fr $DIR/$tdir
3944         test_mkdir -p $DIR/$tdir/tmp
3945         local tmp_dir=$DIR/$tdir/tmp
3946         ln -s $DIR/$tdir $tmp_dir/symlink11
3947         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3948         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3949         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3950 }
3951 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3952
3953 test_32f() {
3954         rm -fr $DIR/$tdir
3955         test_mkdir -p $DIR/$tdir/tmp
3956         local tmp_dir=$DIR/$tdir/tmp
3957         ln -s $DIR/$tdir $tmp_dir/symlink11
3958         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3959         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3960         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3961 }
3962 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3963
3964 test_32g() {
3965         local tmp_dir=$DIR/$tdir/tmp
3966         test_mkdir -p $tmp_dir
3967         test_mkdir $DIR/${tdir}2
3968         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3969         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3970         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3971         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3972         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3973         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3974 }
3975 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3976
3977 test_32h() {
3978         rm -fr $DIR/$tdir $DIR/${tdir}2
3979         tmp_dir=$DIR/$tdir/tmp
3980         test_mkdir -p $tmp_dir
3981         test_mkdir $DIR/${tdir}2
3982         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3983         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3984         ls $tmp_dir/symlink12 || error "listing symlink12"
3985         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3986 }
3987 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3988
3989 test_32i() {
3990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3991
3992         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3993         trap cleanup_test32_mount EXIT
3994         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3995         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3996                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3997         touch $DIR/$tdir/test_file
3998         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3999                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4000         cleanup_test32_mount
4001 }
4002 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4003
4004 test_32j() {
4005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4006
4007         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4008         trap cleanup_test32_mount EXIT
4009         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4010         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4011                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4012         touch $DIR/$tdir/test_file
4013         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4014                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4015         cleanup_test32_mount
4016 }
4017 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4018
4019 test_32k() {
4020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4021
4022         rm -fr $DIR/$tdir
4023         trap cleanup_test32_mount EXIT
4024         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4025         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4026                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4027         test_mkdir -p $DIR/$tdir/d2
4028         touch $DIR/$tdir/d2/test_file || error "touch failed"
4029         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4030                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4031         cleanup_test32_mount
4032 }
4033 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4034
4035 test_32l() {
4036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4037
4038         rm -fr $DIR/$tdir
4039         trap cleanup_test32_mount EXIT
4040         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4041         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4042                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4043         test_mkdir -p $DIR/$tdir/d2
4044         touch $DIR/$tdir/d2/test_file || error "touch failed"
4045         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4046                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4047         cleanup_test32_mount
4048 }
4049 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4050
4051 test_32m() {
4052         rm -fr $DIR/d32m
4053         test_mkdir -p $DIR/d32m/tmp
4054         TMP_DIR=$DIR/d32m/tmp
4055         ln -s $DIR $TMP_DIR/symlink11
4056         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4057         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4058                 error "symlink11 not a link"
4059         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4060                 error "symlink01 not a link"
4061 }
4062 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4063
4064 test_32n() {
4065         rm -fr $DIR/d32n
4066         test_mkdir -p $DIR/d32n/tmp
4067         TMP_DIR=$DIR/d32n/tmp
4068         ln -s $DIR $TMP_DIR/symlink11
4069         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4070         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4071         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4072 }
4073 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4074
4075 test_32o() {
4076         touch $DIR/$tfile
4077         test_mkdir -p $DIR/d32o/tmp
4078         TMP_DIR=$DIR/d32o/tmp
4079         ln -s $DIR/$tfile $TMP_DIR/symlink12
4080         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4081         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4082                 error "symlink12 not a link"
4083         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4084         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4085                 error "$DIR/d32o/tmp/symlink12 not file type"
4086         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4087                 error "$DIR/d32o/symlink02 not file type"
4088 }
4089 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4090
4091 test_32p() {
4092         log 32p_1
4093         rm -fr $DIR/d32p
4094         log 32p_2
4095         rm -f $DIR/$tfile
4096         log 32p_3
4097         touch $DIR/$tfile
4098         log 32p_4
4099         test_mkdir -p $DIR/d32p/tmp
4100         log 32p_5
4101         TMP_DIR=$DIR/d32p/tmp
4102         log 32p_6
4103         ln -s $DIR/$tfile $TMP_DIR/symlink12
4104         log 32p_7
4105         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4106         log 32p_8
4107         cat $DIR/d32p/tmp/symlink12 ||
4108                 error "Can't open $DIR/d32p/tmp/symlink12"
4109         log 32p_9
4110         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4111         log 32p_10
4112 }
4113 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4114
4115 test_32q() {
4116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4117
4118         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4119         trap cleanup_test32_mount EXIT
4120         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4121         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4122         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4123                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4124         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4125         cleanup_test32_mount
4126 }
4127 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4128
4129 test_32r() {
4130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4131
4132         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4133         trap cleanup_test32_mount EXIT
4134         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4135         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4136         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4137                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4138         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4139         cleanup_test32_mount
4140 }
4141 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4142
4143 test_33aa() {
4144         rm -f $DIR/$tfile
4145         touch $DIR/$tfile
4146         chmod 444 $DIR/$tfile
4147         chown $RUNAS_ID $DIR/$tfile
4148         log 33_1
4149         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4150         log 33_2
4151 }
4152 run_test 33aa "write file with mode 444 (should return error)"
4153
4154 test_33a() {
4155         rm -fr $DIR/$tdir
4156         test_mkdir $DIR/$tdir
4157         chown $RUNAS_ID $DIR/$tdir
4158         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4159                 error "$RUNAS create $tdir/$tfile failed"
4160         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4161                 error "open RDWR" || true
4162 }
4163 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4164
4165 test_33b() {
4166         rm -fr $DIR/$tdir
4167         test_mkdir $DIR/$tdir
4168         chown $RUNAS_ID $DIR/$tdir
4169         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4170 }
4171 run_test 33b "test open file with malformed flags (No panic)"
4172
4173 test_33c() {
4174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4175         remote_ost_nodsh && skip "remote OST with nodsh"
4176
4177         local ostnum
4178         local ostname
4179         local write_bytes
4180         local all_zeros
4181
4182         all_zeros=true
4183         test_mkdir $DIR/$tdir
4184         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4185
4186         sync
4187         for ostnum in $(seq $OSTCOUNT); do
4188                 # test-framework's OST numbering is one-based, while Lustre's
4189                 # is zero-based
4190                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4191                 # check if at least some write_bytes stats are counted
4192                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4193                               obdfilter.$ostname.stats |
4194                               awk '/^write_bytes/ {print $7}' )
4195                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4196                 if (( ${write_bytes:-0} > 0 )); then
4197                         all_zeros=false
4198                         break
4199                 fi
4200         done
4201
4202         $all_zeros || return 0
4203
4204         # Write four bytes
4205         echo foo > $DIR/$tdir/bar
4206         # Really write them
4207         sync
4208
4209         # Total up write_bytes after writing.  We'd better find non-zeros.
4210         for ostnum in $(seq $OSTCOUNT); do
4211                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4212                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4213                               obdfilter/$ostname/stats |
4214                               awk '/^write_bytes/ {print $7}' )
4215                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4216                 if (( ${write_bytes:-0} > 0 )); then
4217                         all_zeros=false
4218                         break
4219                 fi
4220         done
4221
4222         if $all_zeros; then
4223                 for ostnum in $(seq $OSTCOUNT); do
4224                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4225                         echo "Check write_bytes is in obdfilter.*.stats:"
4226                         do_facet ost$ostnum lctl get_param -n \
4227                                 obdfilter.$ostname.stats
4228                 done
4229                 error "OST not keeping write_bytes stats (b=22312)"
4230         fi
4231 }
4232 run_test 33c "test write_bytes stats"
4233
4234 test_33d() {
4235         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4237
4238         local MDTIDX=1
4239         local remote_dir=$DIR/$tdir/remote_dir
4240
4241         test_mkdir $DIR/$tdir
4242         $LFS mkdir -i $MDTIDX $remote_dir ||
4243                 error "create remote directory failed"
4244
4245         touch $remote_dir/$tfile
4246         chmod 444 $remote_dir/$tfile
4247         chown $RUNAS_ID $remote_dir/$tfile
4248
4249         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4250
4251         chown $RUNAS_ID $remote_dir
4252         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4253                                         error "create" || true
4254         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4255                                     error "open RDWR" || true
4256         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4257 }
4258 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4259
4260 test_33e() {
4261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4262
4263         mkdir $DIR/$tdir
4264
4265         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4266         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4267         mkdir $DIR/$tdir/local_dir
4268
4269         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4270         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4271         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4272
4273         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4274                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4275
4276         rmdir $DIR/$tdir/* || error "rmdir failed"
4277
4278         umask 777
4279         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4280         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4281         mkdir $DIR/$tdir/local_dir
4282
4283         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4284         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4285         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4286
4287         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4288                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4289
4290         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4291
4292         umask 000
4293         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4294         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4295         mkdir $DIR/$tdir/local_dir
4296
4297         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4298         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4299         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4300
4301         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4302                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4303 }
4304 run_test 33e "mkdir and striped directory should have same mode"
4305
4306 cleanup_33f() {
4307         trap 0
4308         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4309 }
4310
4311 test_33f() {
4312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4313         remote_mds_nodsh && skip "remote MDS with nodsh"
4314
4315         mkdir $DIR/$tdir
4316         chmod go+rwx $DIR/$tdir
4317         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4318         trap cleanup_33f EXIT
4319
4320         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4321                 error "cannot create striped directory"
4322
4323         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4324                 error "cannot create files in striped directory"
4325
4326         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4327                 error "cannot remove files in striped directory"
4328
4329         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4330                 error "cannot remove striped directory"
4331
4332         cleanup_33f
4333 }
4334 run_test 33f "nonroot user can create, access, and remove a striped directory"
4335
4336 test_33g() {
4337         mkdir -p $DIR/$tdir/dir2
4338
4339         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4340         echo $err
4341         [[ $err =~ "exists" ]] || error "Not exists error"
4342 }
4343 run_test 33g "nonroot user create already existing root created file"
4344
4345 sub_33h() {
4346         local hash_type=$1
4347         local count=250
4348
4349         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4350                 error "lfs mkdir -H $hash_type $tdir failed"
4351         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4352
4353         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4354         local index2
4355         local fname
4356
4357         for fname in $DIR/$tdir/$tfile.bak \
4358                      $DIR/$tdir/$tfile.SAV \
4359                      $DIR/$tdir/$tfile.orig \
4360                      $DIR/$tdir/$tfile~; do
4361                 touch $fname || error "touch $fname failed"
4362                 index2=$($LFS getstripe -m $fname)
4363                 (( $index == $index2 )) ||
4364                         error "$fname MDT index mismatch $index != $index2"
4365         done
4366
4367         local failed=0
4368         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4369         local pattern
4370
4371         for pattern in ${patterns[*]}; do
4372                 echo "pattern $pattern"
4373                 fname=$DIR/$tdir/$pattern
4374                 for (( i = 0; i < $count; i++ )); do
4375                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4376                                 error "mktemp $DIR/$tdir/$pattern failed"
4377                         index2=$($LFS getstripe -m $fname)
4378                         (( $index == $index2 )) && continue
4379
4380                         failed=$((failed + 1))
4381                         echo "$fname MDT index mismatch $index != $index2"
4382                 done
4383         done
4384
4385         echo "$failed/$count MDT index mismatches, expect ~2-4"
4386         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4387
4388         local same=0
4389         local expect
4390
4391         # verify that "crush" is still broken with all files on same MDT,
4392         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4393         [[ "$hash_type" == "crush" ]] && expect=$count ||
4394                 expect=$((count / MDSCOUNT))
4395
4396         # crush2 doesn't put all-numeric suffixes on the same MDT,
4397         # filename like $tfile.12345678 should *not* be considered temp
4398         for pattern in ${patterns[*]}; do
4399                 local base=${pattern%%X*}
4400                 local suff=${pattern#$base}
4401
4402                 echo "pattern $pattern"
4403                 for (( i = 0; i < $count; i++ )); do
4404                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4405                         touch $fname || error "touch $fname failed"
4406                         index2=$($LFS getstripe -m $fname)
4407                         (( $index != $index2 )) && continue
4408
4409                         same=$((same + 1))
4410                 done
4411         done
4412
4413         # the number of "bad" hashes is random, as it depends on the random
4414         # filenames generated by "mktemp".  Allow some margin in the results.
4415         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4416         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4417            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4418                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4419         same=0
4420
4421         # crush2 doesn't put suffixes with special characters on the same MDT
4422         # filename like $tfile.txt.1234 should *not* be considered temp
4423         for pattern in ${patterns[*]}; do
4424                 local base=${pattern%%X*}
4425                 local suff=${pattern#$base}
4426
4427                 pattern=$base...${suff/XXX}
4428                 echo "pattern=$pattern"
4429                 for (( i = 0; i < $count; i++ )); do
4430                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4431                                 error "touch $fname failed"
4432                         index2=$($LFS getstripe -m $fname)
4433                         (( $index != $index2 )) && continue
4434
4435                         same=$((same + 1))
4436                 done
4437         done
4438
4439         # the number of "bad" hashes is random, as it depends on the random
4440         # filenames generated by "mktemp".  Allow some margin in the results.
4441         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4442         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4443            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4444                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4445 }
4446
4447 test_33h() {
4448         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4449         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4450                 skip "Need MDS version at least 2.13.50"
4451
4452         sub_33h crush
4453 }
4454 run_test 33h "temp file is located on the same MDT as target (crush)"
4455
4456 test_33hh() {
4457         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4458         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4459         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4460                 skip "Need MDS version at least 2.15.0 for crush2"
4461
4462         sub_33h crush2
4463 }
4464 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4465
4466 test_33i()
4467 {
4468         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4469
4470         local FNAME=$(str_repeat 'f' 250)
4471
4472         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4473         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4474
4475         local count
4476         local total
4477
4478         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4479
4480         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4481
4482         lctl --device %$MDC deactivate
4483         stack_trap "lctl --device %$MDC activate"
4484         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4485         total=$(\ls -l $DIR/$tdir | wc -l)
4486         # "ls -l" will list total in the first line
4487         total=$((total - 1))
4488         (( total + count == 1000 )) ||
4489                 error "ls list $total files, $count files on MDT1"
4490 }
4491 run_test 33i "striped directory can be accessed when one MDT is down"
4492
4493 test_33j() {
4494         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4495
4496         mkdir -p $DIR/$tdir/
4497
4498         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4499                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4500
4501         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4502                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4503
4504         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4505                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4506
4507         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4508                 error "-D was not specified, but still failed"
4509 }
4510 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4511
4512 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4513 test_34a() {
4514         rm -f $DIR/f34
4515         $MCREATE $DIR/f34 || error "mcreate failed"
4516         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4517                 error "getstripe failed"
4518         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4519         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4520                 error "getstripe failed"
4521         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4522                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4523 }
4524 run_test 34a "truncate file that has not been opened ==========="
4525
4526 test_34b() {
4527         [ ! -f $DIR/f34 ] && test_34a
4528         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4529                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4530         $OPENFILE -f O_RDONLY $DIR/f34
4531         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4532                 error "getstripe failed"
4533         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4534                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4535 }
4536 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4537
4538 test_34c() {
4539         [ ! -f $DIR/f34 ] && test_34a
4540         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4541                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4542         $OPENFILE -f O_RDWR $DIR/f34
4543         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4544                 error "$LFS getstripe failed"
4545         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4546                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4547 }
4548 run_test 34c "O_RDWR opening file-with-size works =============="
4549
4550 test_34d() {
4551         [ ! -f $DIR/f34 ] && test_34a
4552         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4553                 error "dd failed"
4554         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4555                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4556         rm $DIR/f34
4557 }
4558 run_test 34d "write to sparse file ============================="
4559
4560 test_34e() {
4561         rm -f $DIR/f34e
4562         $MCREATE $DIR/f34e || error "mcreate failed"
4563         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4564         $CHECKSTAT -s 1000 $DIR/f34e ||
4565                 error "Size of $DIR/f34e not equal to 1000 bytes"
4566         $OPENFILE -f O_RDWR $DIR/f34e
4567         $CHECKSTAT -s 1000 $DIR/f34e ||
4568                 error "Size of $DIR/f34e not equal to 1000 bytes"
4569 }
4570 run_test 34e "create objects, some with size and some without =="
4571
4572 test_34f() { # bug 6242, 6243
4573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4574
4575         SIZE34F=48000
4576         rm -f $DIR/f34f
4577         $MCREATE $DIR/f34f || error "mcreate failed"
4578         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4579         dd if=$DIR/f34f of=$TMP/f34f
4580         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4581         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4582         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4583         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4584         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4585 }
4586 run_test 34f "read from a file with no objects until EOF ======="
4587
4588 test_34g() {
4589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4590
4591         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4592                 error "dd failed"
4593         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4594         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4595                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4596         cancel_lru_locks osc
4597         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4598                 error "wrong size after lock cancel"
4599
4600         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4602                 error "expanding truncate failed"
4603         cancel_lru_locks osc
4604         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4605                 error "wrong expanded size after lock cancel"
4606 }
4607 run_test 34g "truncate long file ==============================="
4608
4609 test_34h() {
4610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4611
4612         local gid=10
4613         local sz=1000
4614
4615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4616         sync # Flush the cache so that multiop below does not block on cache
4617              # flush when getting the group lock
4618         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4619         MULTIPID=$!
4620
4621         # Since just timed wait is not good enough, let's do a sync write
4622         # that way we are sure enough time for a roundtrip + processing
4623         # passed + 2 seconds of extra margin.
4624         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4625         rm $DIR/${tfile}-1
4626         sleep 2
4627
4628         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4629                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4630                 kill -9 $MULTIPID
4631         fi
4632         wait $MULTIPID
4633         local nsz=`stat -c %s $DIR/$tfile`
4634         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4635 }
4636 run_test 34h "ftruncate file under grouplock should not block"
4637
4638 test_35a() {
4639         cp /bin/sh $DIR/f35a
4640         chmod 444 $DIR/f35a
4641         chown $RUNAS_ID $DIR/f35a
4642         $RUNAS $DIR/f35a && error || true
4643         rm $DIR/f35a
4644 }
4645 run_test 35a "exec file with mode 444 (should return and not leak)"
4646
4647 test_36a() {
4648         rm -f $DIR/f36
4649         utime $DIR/f36 || error "utime failed for MDS"
4650 }
4651 run_test 36a "MDS utime check (mknod, utime)"
4652
4653 test_36b() {
4654         echo "" > $DIR/f36
4655         utime $DIR/f36 || error "utime failed for OST"
4656 }
4657 run_test 36b "OST utime check (open, utime)"
4658
4659 test_36c() {
4660         rm -f $DIR/d36/f36
4661         test_mkdir $DIR/d36
4662         chown $RUNAS_ID $DIR/d36
4663         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4664 }
4665 run_test 36c "non-root MDS utime check (mknod, utime)"
4666
4667 test_36d() {
4668         [ ! -d $DIR/d36 ] && test_36c
4669         echo "" > $DIR/d36/f36
4670         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4671 }
4672 run_test 36d "non-root OST utime check (open, utime)"
4673
4674 test_36e() {
4675         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4676
4677         test_mkdir $DIR/$tdir
4678         touch $DIR/$tdir/$tfile
4679         $RUNAS utime $DIR/$tdir/$tfile &&
4680                 error "utime worked, expected failure" || true
4681 }
4682 run_test 36e "utime on non-owned file (should return error)"
4683
4684 subr_36fh() {
4685         local fl="$1"
4686         local LANG_SAVE=$LANG
4687         local LC_LANG_SAVE=$LC_LANG
4688         export LANG=C LC_LANG=C # for date language
4689
4690         DATESTR="Dec 20  2000"
4691         test_mkdir $DIR/$tdir
4692         lctl set_param fail_loc=$fl
4693         date; date +%s
4694         cp /etc/hosts $DIR/$tdir/$tfile
4695         sync & # write RPC generated with "current" inode timestamp, but delayed
4696         sleep 1
4697         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4698         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4699         cancel_lru_locks $OSC
4700         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4701         date; date +%s
4702         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4703                 echo "BEFORE: $LS_BEFORE" && \
4704                 echo "AFTER : $LS_AFTER" && \
4705                 echo "WANT  : $DATESTR" && \
4706                 error "$DIR/$tdir/$tfile timestamps changed" || true
4707
4708         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4709 }
4710
4711 test_36f() {
4712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4713
4714         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4715         subr_36fh "0x80000214"
4716 }
4717 run_test 36f "utime on file racing with OST BRW write =========="
4718
4719 test_36g() {
4720         remote_ost_nodsh && skip "remote OST with nodsh"
4721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4722         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4723                 skip "Need MDS version at least 2.12.51"
4724
4725         local fmd_max_age
4726         local fmd
4727         local facet="ost1"
4728         local tgt="obdfilter"
4729
4730         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4731
4732         test_mkdir $DIR/$tdir
4733         fmd_max_age=$(do_facet $facet \
4734                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4735                 head -n 1")
4736
4737         echo "FMD max age: ${fmd_max_age}s"
4738         touch $DIR/$tdir/$tfile
4739         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4740                 gawk '{cnt=cnt+$1}  END{print cnt}')
4741         echo "FMD before: $fmd"
4742         [[ $fmd == 0 ]] &&
4743                 error "FMD wasn't create by touch"
4744         sleep $((fmd_max_age + 12))
4745         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4746                 gawk '{cnt=cnt+$1}  END{print cnt}')
4747         echo "FMD after: $fmd"
4748         [[ $fmd == 0 ]] ||
4749                 error "FMD wasn't expired by ping"
4750 }
4751 run_test 36g "FMD cache expiry ====================="
4752
4753 test_36h() {
4754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4755
4756         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4757         subr_36fh "0x80000227"
4758 }
4759 run_test 36h "utime on file racing with OST BRW write =========="
4760
4761 test_36i() {
4762         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4763
4764         test_mkdir $DIR/$tdir
4765         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4766
4767         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4768         local new_mtime=$((mtime + 200))
4769
4770         #change Modify time of striped dir
4771         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4772                         error "change mtime failed"
4773
4774         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4775
4776         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4777 }
4778 run_test 36i "change mtime on striped directory"
4779
4780 # test_37 - duplicate with tests 32q 32r
4781
4782 test_38() {
4783         local file=$DIR/$tfile
4784         touch $file
4785         openfile -f O_DIRECTORY $file
4786         local RC=$?
4787         local ENOTDIR=20
4788         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4789         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4790 }
4791 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4792
4793 test_39a() { # was test_39
4794         touch $DIR/$tfile
4795         touch $DIR/${tfile}2
4796 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4797 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4798 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4799         sleep 2
4800         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4801         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4802                 echo "mtime"
4803                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4804                 echo "atime"
4805                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4806                 echo "ctime"
4807                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4808                 error "O_TRUNC didn't change timestamps"
4809         fi
4810 }
4811 run_test 39a "mtime changed on create"
4812
4813 test_39b() {
4814         test_mkdir -c1 $DIR/$tdir
4815         cp -p /etc/passwd $DIR/$tdir/fopen
4816         cp -p /etc/passwd $DIR/$tdir/flink
4817         cp -p /etc/passwd $DIR/$tdir/funlink
4818         cp -p /etc/passwd $DIR/$tdir/frename
4819         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4820
4821         sleep 1
4822         echo "aaaaaa" >> $DIR/$tdir/fopen
4823         echo "aaaaaa" >> $DIR/$tdir/flink
4824         echo "aaaaaa" >> $DIR/$tdir/funlink
4825         echo "aaaaaa" >> $DIR/$tdir/frename
4826
4827         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4828         local link_new=`stat -c %Y $DIR/$tdir/flink`
4829         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4830         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4831
4832         cat $DIR/$tdir/fopen > /dev/null
4833         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4834         rm -f $DIR/$tdir/funlink2
4835         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4836
4837         for (( i=0; i < 2; i++ )) ; do
4838                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4839                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4840                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4841                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4842
4843                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4844                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4845                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4846                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4847
4848                 cancel_lru_locks $OSC
4849                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4850         done
4851 }
4852 run_test 39b "mtime change on open, link, unlink, rename  ======"
4853
4854 # this should be set to past
4855 TEST_39_MTIME=`date -d "1 year ago" +%s`
4856
4857 # bug 11063
4858 test_39c() {
4859         touch $DIR1/$tfile
4860         sleep 2
4861         local mtime0=`stat -c %Y $DIR1/$tfile`
4862
4863         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4864         local mtime1=`stat -c %Y $DIR1/$tfile`
4865         [ "$mtime1" = $TEST_39_MTIME ] || \
4866                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4867
4868         local d1=`date +%s`
4869         echo hello >> $DIR1/$tfile
4870         local d2=`date +%s`
4871         local mtime2=`stat -c %Y $DIR1/$tfile`
4872         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4873                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4874
4875         mv $DIR1/$tfile $DIR1/$tfile-1
4876
4877         for (( i=0; i < 2; i++ )) ; do
4878                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4879                 [ "$mtime2" = "$mtime3" ] || \
4880                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4881
4882                 cancel_lru_locks $OSC
4883                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4884         done
4885 }
4886 run_test 39c "mtime change on rename ==========================="
4887
4888 # bug 21114
4889 test_39d() {
4890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4891
4892         touch $DIR1/$tfile
4893         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4894
4895         for (( i=0; i < 2; i++ )) ; do
4896                 local mtime=`stat -c %Y $DIR1/$tfile`
4897                 [ $mtime = $TEST_39_MTIME ] || \
4898                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4899
4900                 cancel_lru_locks $OSC
4901                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4902         done
4903 }
4904 run_test 39d "create, utime, stat =============================="
4905
4906 # bug 21114
4907 test_39e() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         touch $DIR1/$tfile
4911         local mtime1=`stat -c %Y $DIR1/$tfile`
4912
4913         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4914
4915         for (( i=0; i < 2; i++ )) ; do
4916                 local mtime2=`stat -c %Y $DIR1/$tfile`
4917                 [ $mtime2 = $TEST_39_MTIME ] || \
4918                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4919
4920                 cancel_lru_locks $OSC
4921                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4922         done
4923 }
4924 run_test 39e "create, stat, utime, stat ========================"
4925
4926 # bug 21114
4927 test_39f() {
4928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4929
4930         touch $DIR1/$tfile
4931         mtime1=`stat -c %Y $DIR1/$tfile`
4932
4933         sleep 2
4934         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local mtime2=`stat -c %Y $DIR1/$tfile`
4938                 [ $mtime2 = $TEST_39_MTIME ] || \
4939                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4940
4941                 cancel_lru_locks $OSC
4942                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4943         done
4944 }
4945 run_test 39f "create, stat, sleep, utime, stat ================="
4946
4947 # bug 11063
4948 test_39g() {
4949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4950
4951         echo hello >> $DIR1/$tfile
4952         local mtime1=`stat -c %Y $DIR1/$tfile`
4953
4954         sleep 2
4955         chmod o+r $DIR1/$tfile
4956
4957         for (( i=0; i < 2; i++ )) ; do
4958                 local mtime2=`stat -c %Y $DIR1/$tfile`
4959                 [ "$mtime1" = "$mtime2" ] || \
4960                         error "lost mtime: $mtime2, should be $mtime1"
4961
4962                 cancel_lru_locks $OSC
4963                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4964         done
4965 }
4966 run_test 39g "write, chmod, stat ==============================="
4967
4968 # bug 11063
4969 test_39h() {
4970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4971
4972         touch $DIR1/$tfile
4973         sleep 1
4974
4975         local d1=`date`
4976         echo hello >> $DIR1/$tfile
4977         local mtime1=`stat -c %Y $DIR1/$tfile`
4978
4979         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4980         local d2=`date`
4981         if [ "$d1" != "$d2" ]; then
4982                 echo "write and touch not within one second"
4983         else
4984                 for (( i=0; i < 2; i++ )) ; do
4985                         local mtime2=`stat -c %Y $DIR1/$tfile`
4986                         [ "$mtime2" = $TEST_39_MTIME ] || \
4987                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4988
4989                         cancel_lru_locks $OSC
4990                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4991                 done
4992         fi
4993 }
4994 run_test 39h "write, utime within one second, stat ============="
4995
4996 test_39i() {
4997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4998
4999         touch $DIR1/$tfile
5000         sleep 1
5001
5002         echo hello >> $DIR1/$tfile
5003         local mtime1=`stat -c %Y $DIR1/$tfile`
5004
5005         mv $DIR1/$tfile $DIR1/$tfile-1
5006
5007         for (( i=0; i < 2; i++ )) ; do
5008                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5009
5010                 [ "$mtime1" = "$mtime2" ] || \
5011                         error "lost mtime: $mtime2, should be $mtime1"
5012
5013                 cancel_lru_locks $OSC
5014                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5015         done
5016 }
5017 run_test 39i "write, rename, stat =============================="
5018
5019 test_39j() {
5020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5021
5022         start_full_debug_logging
5023         touch $DIR1/$tfile
5024         sleep 1
5025
5026         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5027         lctl set_param fail_loc=0x80000412
5028         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5029                 error "multiop failed"
5030         local multipid=$!
5031         local mtime1=`stat -c %Y $DIR1/$tfile`
5032
5033         mv $DIR1/$tfile $DIR1/$tfile-1
5034
5035         kill -USR1 $multipid
5036         wait $multipid || error "multiop close failed"
5037
5038         for (( i=0; i < 2; i++ )) ; do
5039                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5040                 [ "$mtime1" = "$mtime2" ] ||
5041                         error "mtime is lost on close: $mtime2, " \
5042                               "should be $mtime1"
5043
5044                 cancel_lru_locks
5045                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5046         done
5047         lctl set_param fail_loc=0
5048         stop_full_debug_logging
5049 }
5050 run_test 39j "write, rename, close, stat ======================="
5051
5052 test_39k() {
5053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5054
5055         touch $DIR1/$tfile
5056         sleep 1
5057
5058         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5059         local multipid=$!
5060         local mtime1=`stat -c %Y $DIR1/$tfile`
5061
5062         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5063
5064         kill -USR1 $multipid
5065         wait $multipid || error "multiop close failed"
5066
5067         for (( i=0; i < 2; i++ )) ; do
5068                 local mtime2=`stat -c %Y $DIR1/$tfile`
5069
5070                 [ "$mtime2" = $TEST_39_MTIME ] || \
5071                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5072
5073                 cancel_lru_locks
5074                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5075         done
5076 }
5077 run_test 39k "write, utime, close, stat ========================"
5078
5079 # this should be set to future
5080 TEST_39_ATIME=`date -d "1 year" +%s`
5081
5082 test_39l() {
5083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5084         remote_mds_nodsh && skip "remote MDS with nodsh"
5085
5086         local atime_diff=$(do_facet $SINGLEMDS \
5087                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5088         rm -rf $DIR/$tdir
5089         mkdir_on_mdt0 $DIR/$tdir
5090
5091         # test setting directory atime to future
5092         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5093         local atime=$(stat -c %X $DIR/$tdir)
5094         [ "$atime" = $TEST_39_ATIME ] ||
5095                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5096
5097         # test setting directory atime from future to now
5098         local now=$(date +%s)
5099         touch -a -d @$now $DIR/$tdir
5100
5101         atime=$(stat -c %X $DIR/$tdir)
5102         [ "$atime" -eq "$now"  ] ||
5103                 error "atime is not updated from future: $atime, $now"
5104
5105         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5106         sleep 3
5107
5108         # test setting directory atime when now > dir atime + atime_diff
5109         local d1=$(date +%s)
5110         ls $DIR/$tdir
5111         local d2=$(date +%s)
5112         cancel_lru_locks mdc
5113         atime=$(stat -c %X $DIR/$tdir)
5114         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5115                 error "atime is not updated  : $atime, should be $d2"
5116
5117         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5118         sleep 3
5119
5120         # test not setting directory atime when now < dir atime + atime_diff
5121         ls $DIR/$tdir
5122         cancel_lru_locks mdc
5123         atime=$(stat -c %X $DIR/$tdir)
5124         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5125                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5126
5127         do_facet $SINGLEMDS \
5128                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5129 }
5130 run_test 39l "directory atime update ==========================="
5131
5132 test_39m() {
5133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5134
5135         touch $DIR1/$tfile
5136         sleep 2
5137         local far_past_mtime=$(date -d "May 29 1953" +%s)
5138         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5139
5140         touch -m -d @$far_past_mtime $DIR1/$tfile
5141         touch -a -d @$far_past_atime $DIR1/$tfile
5142
5143         for (( i=0; i < 2; i++ )) ; do
5144                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5145                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5146                         error "atime or mtime set incorrectly"
5147
5148                 cancel_lru_locks $OSC
5149                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5150         done
5151 }
5152 run_test 39m "test atime and mtime before 1970"
5153
5154 test_39n() { # LU-3832
5155         remote_mds_nodsh && skip "remote MDS with nodsh"
5156
5157         local atime_diff=$(do_facet $SINGLEMDS \
5158                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5159         local atime0
5160         local atime1
5161         local atime2
5162
5163         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5164
5165         rm -rf $DIR/$tfile
5166         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5167         atime0=$(stat -c %X $DIR/$tfile)
5168
5169         sleep 5
5170         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5171         atime1=$(stat -c %X $DIR/$tfile)
5172
5173         sleep 5
5174         cancel_lru_locks mdc
5175         cancel_lru_locks osc
5176         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5177         atime2=$(stat -c %X $DIR/$tfile)
5178
5179         do_facet $SINGLEMDS \
5180                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5181
5182         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5183         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5184 }
5185 run_test 39n "check that O_NOATIME is honored"
5186
5187 test_39o() {
5188         TESTDIR=$DIR/$tdir/$tfile
5189         [ -e $TESTDIR ] && rm -rf $TESTDIR
5190         mkdir -p $TESTDIR
5191         cd $TESTDIR
5192         links1=2
5193         ls
5194         mkdir a b
5195         ls
5196         links2=$(stat -c %h .)
5197         [ $(($links1 + 2)) != $links2 ] &&
5198                 error "wrong links count $(($links1 + 2)) != $links2"
5199         rmdir b
5200         links3=$(stat -c %h .)
5201         [ $(($links1 + 1)) != $links3 ] &&
5202                 error "wrong links count $links1 != $links3"
5203         return 0
5204 }
5205 run_test 39o "directory cached attributes updated after create"
5206
5207 test_39p() {
5208         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5209
5210         local MDTIDX=1
5211         TESTDIR=$DIR/$tdir/$tdir
5212         [ -e $TESTDIR ] && rm -rf $TESTDIR
5213         test_mkdir -p $TESTDIR
5214         cd $TESTDIR
5215         links1=2
5216         ls
5217         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5218         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5219         ls
5220         links2=$(stat -c %h .)
5221         [ $(($links1 + 2)) != $links2 ] &&
5222                 error "wrong links count $(($links1 + 2)) != $links2"
5223         rmdir remote_dir2
5224         links3=$(stat -c %h .)
5225         [ $(($links1 + 1)) != $links3 ] &&
5226                 error "wrong links count $links1 != $links3"
5227         return 0
5228 }
5229 run_test 39p "remote directory cached attributes updated after create ========"
5230
5231 test_39r() {
5232         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5233                 skip "no atime update on old OST"
5234         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5235                 skip_env "ldiskfs only test"
5236         fi
5237
5238         local saved_adiff
5239         saved_adiff=$(do_facet ost1 \
5240                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5241         stack_trap "do_facet ost1 \
5242                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5243
5244         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5245
5246         $LFS setstripe -i 0 $DIR/$tfile
5247         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5248                 error "can't write initial file"
5249         cancel_lru_locks osc
5250
5251         # exceed atime_diff and access file
5252         sleep 10
5253         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5254                 error "can't udpate atime"
5255
5256         local atime_cli=$(stat -c %X $DIR/$tfile)
5257         echo "client atime: $atime_cli"
5258         # allow atime update to be written to device
5259         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5260         sleep 5
5261
5262         local ostdev=$(ostdevname 1)
5263         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5264         local seq=${fid[3]#0x}
5265         local oid=${fid[1]}
5266         local oid_hex
5267
5268         if [ $seq == 0 ]; then
5269                 oid_hex=${fid[1]}
5270         else
5271                 oid_hex=${fid[2]#0x}
5272         fi
5273         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5274         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5275
5276         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5277         local atime_ost=$(do_facet ost1 "$cmd" |&
5278                           awk -F'[: ]' '/atime:/ { print $4 }')
5279         (( atime_cli == atime_ost )) ||
5280                 error "atime on client $atime_cli != ost $atime_ost"
5281 }
5282 run_test 39r "lazy atime update on OST"
5283
5284 test_39q() { # LU-8041
5285         local testdir=$DIR/$tdir
5286         mkdir -p $testdir
5287         multiop_bg_pause $testdir D_c || error "multiop failed"
5288         local multipid=$!
5289         cancel_lru_locks mdc
5290         kill -USR1 $multipid
5291         local atime=$(stat -c %X $testdir)
5292         [ "$atime" -ne 0 ] || error "atime is zero"
5293 }
5294 run_test 39q "close won't zero out atime"
5295
5296 test_39s() {
5297         local atime0
5298         local atime1
5299         local atime2
5300         local atime3
5301         local atime4
5302
5303         umount_client $MOUNT
5304         mount_client $MOUNT relatime
5305
5306         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5307         atime0=$(stat -c %X $DIR/$tfile)
5308
5309         # First read updates atime
5310         sleep 1
5311         cat $DIR/$tfile >/dev/null
5312         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5313
5314         # Next reads do not update atime
5315         sleep 1
5316         cat $DIR/$tfile >/dev/null
5317         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5318
5319         # If mtime is greater than atime, atime is updated
5320         sleep 1
5321         touch -m $DIR/$tfile # (mtime = now)
5322         sleep 1
5323         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5324         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5325
5326         # Next reads do not update atime
5327         sleep 1
5328         cat $DIR/$tfile >/dev/null
5329         atime4=$(stat -c %X $DIR/$tfile)
5330
5331         # Remount the client to clear 'relatime' option
5332         remount_client $MOUNT
5333
5334         (( atime0 < atime1 )) ||
5335                 error "atime $atime0 should be smaller than $atime1"
5336         (( atime1 == atime2 )) ||
5337                 error "atime $atime1 was updated to $atime2"
5338         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5339         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5340 }
5341 run_test 39s "relatime is supported"
5342
5343 test_40() {
5344         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5345         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5346                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5347         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5348                 error "$tfile is not 4096 bytes in size"
5349 }
5350 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5351
5352 test_41() {
5353         # bug 1553
5354         small_write $DIR/f41 18
5355 }
5356 run_test 41 "test small file write + fstat ====================="
5357
5358 count_ost_writes() {
5359         lctl get_param -n ${OSC}.*.stats |
5360                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5361                         END { printf("%0.0f", writes) }'
5362 }
5363
5364 # decent default
5365 WRITEBACK_SAVE=500
5366 DIRTY_RATIO_SAVE=40
5367 MAX_DIRTY_RATIO=50
5368 BG_DIRTY_RATIO_SAVE=10
5369 MAX_BG_DIRTY_RATIO=25
5370
5371 start_writeback() {
5372         trap 0
5373         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5374         # dirty_ratio, dirty_background_ratio
5375         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5376                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5377                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5378                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5379         else
5380                 # if file not here, we are a 2.4 kernel
5381                 kill -CONT `pidof kupdated`
5382         fi
5383 }
5384
5385 stop_writeback() {
5386         # setup the trap first, so someone cannot exit the test at the
5387         # exact wrong time and mess up a machine
5388         trap start_writeback EXIT
5389         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5390         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5391                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5392                 sysctl -w vm.dirty_writeback_centisecs=0
5393                 sysctl -w vm.dirty_writeback_centisecs=0
5394                 # save and increase /proc/sys/vm/dirty_ratio
5395                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5396                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5397                 # save and increase /proc/sys/vm/dirty_background_ratio
5398                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5399                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5400         else
5401                 # if file not here, we are a 2.4 kernel
5402                 kill -STOP `pidof kupdated`
5403         fi
5404 }
5405
5406 # ensure that all stripes have some grant before we test client-side cache
5407 setup_test42() {
5408         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5409                 dd if=/dev/zero of=$i bs=4k count=1
5410                 rm $i
5411         done
5412 }
5413
5414 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5415 # file truncation, and file removal.
5416 test_42a() {
5417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5418
5419         setup_test42
5420         cancel_lru_locks $OSC
5421         stop_writeback
5422         sync; sleep 1; sync # just to be safe
5423         BEFOREWRITES=`count_ost_writes`
5424         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5425         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5426         AFTERWRITES=`count_ost_writes`
5427         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5428                 error "$BEFOREWRITES < $AFTERWRITES"
5429         start_writeback
5430 }
5431 run_test 42a "ensure that we don't flush on close"
5432
5433 test_42b() {
5434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5435
5436         setup_test42
5437         cancel_lru_locks $OSC
5438         stop_writeback
5439         sync
5440         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5441         BEFOREWRITES=$(count_ost_writes)
5442         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5443         AFTERWRITES=$(count_ost_writes)
5444         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5445                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5446         fi
5447         BEFOREWRITES=$(count_ost_writes)
5448         sync || error "sync: $?"
5449         AFTERWRITES=$(count_ost_writes)
5450         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5451                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5452         fi
5453         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5454         start_writeback
5455         return 0
5456 }
5457 run_test 42b "test destroy of file with cached dirty data ======"
5458
5459 # if these tests just want to test the effect of truncation,
5460 # they have to be very careful.  consider:
5461 # - the first open gets a {0,EOF}PR lock
5462 # - the first write conflicts and gets a {0, count-1}PW
5463 # - the rest of the writes are under {count,EOF}PW
5464 # - the open for truncate tries to match a {0,EOF}PR
5465 #   for the filesize and cancels the PWs.
5466 # any number of fixes (don't get {0,EOF} on open, match
5467 # composite locks, do smarter file size management) fix
5468 # this, but for now we want these tests to verify that
5469 # the cancellation with truncate intent works, so we
5470 # start the file with a full-file pw lock to match against
5471 # until the truncate.
5472 trunc_test() {
5473         test=$1
5474         file=$DIR/$test
5475         offset=$2
5476         cancel_lru_locks $OSC
5477         stop_writeback
5478         # prime the file with 0,EOF PW to match
5479         touch $file
5480         $TRUNCATE $file 0
5481         sync; sync
5482         # now the real test..
5483         dd if=/dev/zero of=$file bs=1024 count=100
5484         BEFOREWRITES=`count_ost_writes`
5485         $TRUNCATE $file $offset
5486         cancel_lru_locks $OSC
5487         AFTERWRITES=`count_ost_writes`
5488         start_writeback
5489 }
5490
5491 test_42c() {
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493
5494         trunc_test 42c 1024
5495         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5496                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5497         rm $file
5498 }
5499 run_test 42c "test partial truncate of file with cached dirty data"
5500
5501 test_42d() {
5502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5503
5504         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5505         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5506         $LCTL set_param debug=+cache
5507
5508         trunc_test 42d 0
5509         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5510                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5511         rm $file
5512 }
5513 run_test 42d "test complete truncate of file with cached dirty data"
5514
5515 test_42e() { # bug22074
5516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5517
5518         local TDIR=$DIR/${tdir}e
5519         local pages=16 # hardcoded 16 pages, don't change it.
5520         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5521         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5522         local max_dirty_mb
5523         local warmup_files
5524
5525         test_mkdir $DIR/${tdir}e
5526         $LFS setstripe -c 1 $TDIR
5527         createmany -o $TDIR/f $files
5528
5529         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5530
5531         # we assume that with $OSTCOUNT files, at least one of them will
5532         # be allocated on OST0.
5533         warmup_files=$((OSTCOUNT * max_dirty_mb))
5534         createmany -o $TDIR/w $warmup_files
5535
5536         # write a large amount of data into one file and sync, to get good
5537         # avail_grant number from OST.
5538         for ((i=0; i<$warmup_files; i++)); do
5539                 idx=$($LFS getstripe -i $TDIR/w$i)
5540                 [ $idx -ne 0 ] && continue
5541                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5542                 break
5543         done
5544         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5545         sync
5546         $LCTL get_param $proc_osc0/cur_dirty_bytes
5547         $LCTL get_param $proc_osc0/cur_grant_bytes
5548
5549         # create as much dirty pages as we can while not to trigger the actual
5550         # RPCs directly. but depends on the env, VFS may trigger flush during this
5551         # period, hopefully we are good.
5552         for ((i=0; i<$warmup_files; i++)); do
5553                 idx=$($LFS getstripe -i $TDIR/w$i)
5554                 [ $idx -ne 0 ] && continue
5555                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5556         done
5557         $LCTL get_param $proc_osc0/cur_dirty_bytes
5558         $LCTL get_param $proc_osc0/cur_grant_bytes
5559
5560         # perform the real test
5561         $LCTL set_param $proc_osc0/rpc_stats 0
5562         for ((;i<$files; i++)); do
5563                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5564                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5565         done
5566         sync
5567         $LCTL get_param $proc_osc0/rpc_stats
5568
5569         local percent=0
5570         local have_ppr=false
5571         $LCTL get_param $proc_osc0/rpc_stats |
5572                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5573                         # skip lines until we are at the RPC histogram data
5574                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5575                         $have_ppr || continue
5576
5577                         # we only want the percent stat for < 16 pages
5578                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5579
5580                         percent=$((percent + WPCT))
5581                         if [[ $percent -gt 15 ]]; then
5582                                 error "less than 16-pages write RPCs" \
5583                                       "$percent% > 15%"
5584                                 break
5585                         fi
5586                 done
5587         rm -rf $TDIR
5588 }
5589 run_test 42e "verify sub-RPC writes are not done synchronously"
5590
5591 test_43A() { # was test_43
5592         test_mkdir $DIR/$tdir
5593         cp -p /bin/ls $DIR/$tdir/$tfile
5594         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5595         pid=$!
5596         # give multiop a chance to open
5597         sleep 1
5598
5599         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5600         kill -USR1 $pid
5601         # Wait for multiop to exit
5602         wait $pid
5603 }
5604 run_test 43A "execution of file opened for write should return -ETXTBSY"
5605
5606 test_43a() {
5607         test_mkdir $DIR/$tdir
5608         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5609         $DIR/$tdir/sleep 60 &
5610         SLEEP_PID=$!
5611         # Make sure exec of $tdir/sleep wins race with truncate
5612         sleep 1
5613         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5614         kill $SLEEP_PID
5615 }
5616 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5617
5618 test_43b() {
5619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5620
5621         test_mkdir $DIR/$tdir
5622         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5623         $DIR/$tdir/sleep 60 &
5624         SLEEP_PID=$!
5625         # Make sure exec of $tdir/sleep wins race with truncate
5626         sleep 1
5627         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5628         kill $SLEEP_PID
5629 }
5630 run_test 43b "truncate of file being executed should return -ETXTBSY"
5631
5632 test_43c() {
5633         local testdir="$DIR/$tdir"
5634         test_mkdir $testdir
5635         cp $SHELL $testdir/
5636         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5637                 ( cd $testdir && md5sum -c )
5638 }
5639 run_test 43c "md5sum of copy into lustre"
5640
5641 test_44A() { # was test_44
5642         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5643
5644         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5645         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5646 }
5647 run_test 44A "zero length read from a sparse stripe"
5648
5649 test_44a() {
5650         local nstripe=$($LFS getstripe -c -d $DIR)
5651         [ -z "$nstripe" ] && skip "can't get stripe info"
5652         [[ $nstripe -gt $OSTCOUNT ]] &&
5653                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5654
5655         local stride=$($LFS getstripe -S -d $DIR)
5656         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5657                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5658         fi
5659
5660         OFFSETS="0 $((stride/2)) $((stride-1))"
5661         for offset in $OFFSETS; do
5662                 for i in $(seq 0 $((nstripe-1))); do
5663                         local GLOBALOFFSETS=""
5664                         # size in Bytes
5665                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5666                         local myfn=$DIR/d44a-$size
5667                         echo "--------writing $myfn at $size"
5668                         ll_sparseness_write $myfn $size ||
5669                                 error "ll_sparseness_write"
5670                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5671                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5672                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5673
5674                         for j in $(seq 0 $((nstripe-1))); do
5675                                 # size in Bytes
5676                                 size=$((((j + $nstripe )*$stride + $offset)))
5677                                 ll_sparseness_write $myfn $size ||
5678                                         error "ll_sparseness_write"
5679                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5680                         done
5681                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5682                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5683                         rm -f $myfn
5684                 done
5685         done
5686 }
5687 run_test 44a "test sparse pwrite ==============================="
5688
5689 dirty_osc_total() {
5690         tot=0
5691         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5692                 tot=$(($tot + $d))
5693         done
5694         echo $tot
5695 }
5696 do_dirty_record() {
5697         before=`dirty_osc_total`
5698         echo executing "\"$*\""
5699         eval $*
5700         after=`dirty_osc_total`
5701         echo before $before, after $after
5702 }
5703 test_45() {
5704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5705
5706         f="$DIR/f45"
5707         # Obtain grants from OST if it supports it
5708         echo blah > ${f}_grant
5709         stop_writeback
5710         sync
5711         do_dirty_record "echo blah > $f"
5712         [[ $before -eq $after ]] && error "write wasn't cached"
5713         do_dirty_record "> $f"
5714         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5715         do_dirty_record "echo blah > $f"
5716         [[ $before -eq $after ]] && error "write wasn't cached"
5717         do_dirty_record "sync"
5718         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5719         do_dirty_record "echo blah > $f"
5720         [[ $before -eq $after ]] && error "write wasn't cached"
5721         do_dirty_record "cancel_lru_locks osc"
5722         [[ $before -gt $after ]] ||
5723                 error "lock cancellation didn't lower dirty count"
5724         start_writeback
5725 }
5726 run_test 45 "osc io page accounting ============================"
5727
5728 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5729 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5730 # objects offset and an assert hit when an rpc was built with 1023's mapped
5731 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5732 test_46() {
5733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5734
5735         f="$DIR/f46"
5736         stop_writeback
5737         sync
5738         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5739         sync
5740         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5741         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5742         sync
5743         start_writeback
5744 }
5745 run_test 46 "dirtying a previously written page ================"
5746
5747 # test_47 is removed "Device nodes check" is moved to test_28
5748
5749 test_48a() { # bug 2399
5750         [ "$mds1_FSTYPE" = "zfs" ] &&
5751         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5752                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5753
5754         test_mkdir $DIR/$tdir
5755         cd $DIR/$tdir
5756         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5757         test_mkdir $DIR/$tdir
5758         touch foo || error "'touch foo' failed after recreating cwd"
5759         test_mkdir bar
5760         touch .foo || error "'touch .foo' failed after recreating cwd"
5761         test_mkdir .bar
5762         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5763         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5764         cd . || error "'cd .' failed after recreating cwd"
5765         mkdir . && error "'mkdir .' worked after recreating cwd"
5766         rmdir . && error "'rmdir .' worked after recreating cwd"
5767         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5768         cd .. || error "'cd ..' failed after recreating cwd"
5769 }
5770 run_test 48a "Access renamed working dir (should return errors)="
5771
5772 test_48b() { # bug 2399
5773         rm -rf $DIR/$tdir
5774         test_mkdir $DIR/$tdir
5775         cd $DIR/$tdir
5776         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5777         touch foo && error "'touch foo' worked after removing cwd"
5778         mkdir foo && error "'mkdir foo' worked after removing cwd"
5779         touch .foo && error "'touch .foo' worked after removing cwd"
5780         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5781         ls . > /dev/null && error "'ls .' worked after removing cwd"
5782         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5783         mkdir . && error "'mkdir .' worked after removing cwd"
5784         rmdir . && error "'rmdir .' worked after removing cwd"
5785         ln -s . foo && error "'ln -s .' worked after removing cwd"
5786         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5787 }
5788 run_test 48b "Access removed working dir (should return errors)="
5789
5790 test_48c() { # bug 2350
5791         #lctl set_param debug=-1
5792         #set -vx
5793         rm -rf $DIR/$tdir
5794         test_mkdir -p $DIR/$tdir/dir
5795         cd $DIR/$tdir/dir
5796         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5797         $TRACE touch foo && error "touch foo worked after removing cwd"
5798         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5799         touch .foo && error "touch .foo worked after removing cwd"
5800         mkdir .foo && error "mkdir .foo worked after removing cwd"
5801         $TRACE ls . && error "'ls .' worked after removing cwd"
5802         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5803         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5804         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5805         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5806         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5807 }
5808 run_test 48c "Access removed working subdir (should return errors)"
5809
5810 test_48d() { # bug 2350
5811         #lctl set_param debug=-1
5812         #set -vx
5813         rm -rf $DIR/$tdir
5814         test_mkdir -p $DIR/$tdir/dir
5815         cd $DIR/$tdir/dir
5816         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5817         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5818         $TRACE touch foo && error "'touch foo' worked after removing parent"
5819         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5820         touch .foo && error "'touch .foo' worked after removing parent"
5821         mkdir .foo && error "mkdir .foo worked after removing parent"
5822         $TRACE ls . && error "'ls .' worked after removing parent"
5823         $TRACE ls .. && error "'ls ..' worked after removing parent"
5824         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5825         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5826         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5827         true
5828 }
5829 run_test 48d "Access removed parent subdir (should return errors)"
5830
5831 test_48e() { # bug 4134
5832         #lctl set_param debug=-1
5833         #set -vx
5834         rm -rf $DIR/$tdir
5835         test_mkdir -p $DIR/$tdir/dir
5836         cd $DIR/$tdir/dir
5837         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5838         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5839         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5840         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5841         # On a buggy kernel addition of "touch foo" after cd .. will
5842         # produce kernel oops in lookup_hash_it
5843         touch ../foo && error "'cd ..' worked after recreate parent"
5844         cd $DIR
5845         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5846 }
5847 run_test 48e "Access to recreated parent subdir (should return errors)"
5848
5849 test_48f() {
5850         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5851                 skip "need MDS >= 2.13.55"
5852         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5853         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5854                 skip "needs different host for mdt1 mdt2"
5855         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5856
5857         $LFS mkdir -i0 $DIR/$tdir
5858         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5859
5860         for d in sub1 sub2 sub3; do
5861                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5862                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5863                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5864         done
5865
5866         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5867 }
5868 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5869
5870 test_49() { # LU-1030
5871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5872         remote_ost_nodsh && skip "remote OST with nodsh"
5873
5874         # get ost1 size - $FSNAME-OST0000
5875         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5876                 awk '{ print $4 }')
5877         # write 800M at maximum
5878         [[ $ost1_size -lt 2 ]] && ost1_size=2
5879         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5880
5881         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5882         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5883         local dd_pid=$!
5884
5885         # change max_pages_per_rpc while writing the file
5886         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5887         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5888         # loop until dd process exits
5889         while ps ax -opid | grep -wq $dd_pid; do
5890                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5891                 sleep $((RANDOM % 5 + 1))
5892         done
5893         # restore original max_pages_per_rpc
5894         $LCTL set_param $osc1_mppc=$orig_mppc
5895         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5896 }
5897 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5898
5899 test_50() {
5900         # bug 1485
5901         test_mkdir $DIR/$tdir
5902         cd $DIR/$tdir
5903         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5904 }
5905 run_test 50 "special situations: /proc symlinks  ==============="
5906
5907 test_51a() {    # was test_51
5908         # bug 1516 - create an empty entry right after ".." then split dir
5909         test_mkdir -c1 $DIR/$tdir
5910         touch $DIR/$tdir/foo
5911         $MCREATE $DIR/$tdir/bar
5912         rm $DIR/$tdir/foo
5913         createmany -m $DIR/$tdir/longfile 201
5914         FNUM=202
5915         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5916                 $MCREATE $DIR/$tdir/longfile$FNUM
5917                 FNUM=$(($FNUM + 1))
5918                 echo -n "+"
5919         done
5920         echo
5921         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5922 }
5923 run_test 51a "special situations: split htree with empty entry =="
5924
5925 cleanup_print_lfs_df () {
5926         trap 0
5927         $LFS df
5928         $LFS df -i
5929 }
5930
5931 test_51b() {
5932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5933
5934         local dir=$DIR/$tdir
5935         local nrdirs=$((65536 + 100))
5936
5937         # cleanup the directory
5938         rm -fr $dir
5939
5940         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5941
5942         $LFS df
5943         $LFS df -i
5944         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5945         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5946         [[ $numfree -lt $nrdirs ]] &&
5947                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5948
5949         # need to check free space for the directories as well
5950         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5951         numfree=$(( blkfree / $(fs_inode_ksize) ))
5952         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5953
5954         trap cleanup_print_lfs_df EXIT
5955
5956         # create files
5957         createmany -d $dir/d $nrdirs || {
5958                 unlinkmany $dir/d $nrdirs
5959                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5960         }
5961
5962         # really created :
5963         nrdirs=$(ls -U $dir | wc -l)
5964
5965         # unlink all but 100 subdirectories, then check it still works
5966         local left=100
5967         local delete=$((nrdirs - left))
5968
5969         $LFS df
5970         $LFS df -i
5971
5972         # for ldiskfs the nlink count should be 1, but this is OSD specific
5973         # and so this is listed for informational purposes only
5974         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5975         unlinkmany -d $dir/d $delete ||
5976                 error "unlink of first $delete subdirs failed"
5977
5978         echo "nlink between: $(stat -c %h $dir)"
5979         local found=$(ls -U $dir | wc -l)
5980         [ $found -ne $left ] &&
5981                 error "can't find subdirs: found only $found, expected $left"
5982
5983         unlinkmany -d $dir/d $delete $left ||
5984                 error "unlink of second $left subdirs failed"
5985         # regardless of whether the backing filesystem tracks nlink accurately
5986         # or not, the nlink count shouldn't be more than "." and ".." here
5987         local after=$(stat -c %h $dir)
5988         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5989                 echo "nlink after: $after"
5990
5991         cleanup_print_lfs_df
5992 }
5993 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5994
5995 test_51d_sub() {
5996         local stripecount=$1
5997         local nfiles=$2
5998
5999         log "create files with stripecount=$stripecount"
6000         $LFS setstripe -C $stripecount $DIR/$tdir
6001         createmany -o $DIR/$tdir/t- $nfiles
6002         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6003         for ((n = 0; n < $OSTCOUNT; n++)); do
6004                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6005                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6006                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6007                             '($1 == '$n') { objs += 1 } \
6008                             END { printf("%0.0f", objs) }')
6009                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6010         done
6011         unlinkmany $DIR/$tdir/t- $nfiles
6012         rm  -f $TMP/$tfile
6013
6014         local nlast
6015         local min=4
6016         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6017
6018         # For some combinations of stripecount and OSTCOUNT current code
6019         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6020         # than others. Rather than skipping this test entirely, check that
6021         # and keep testing to ensure imbalance does not get worse. LU-15282
6022         (( (OSTCOUNT == 6 && stripecount == 4) ||
6023            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6024            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6025         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6026                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6027                         { $LFS df && $LFS df -i &&
6028                         error "stripecount=$stripecount: " \
6029                               "OST $n has fewer objects vs. OST $nlast " \
6030                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6031                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6032                         { $LFS df && $LFS df -i &&
6033                         error "stripecount=$stripecount: " \
6034                               "OST $n has more objects vs. OST $nlast " \
6035                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6036
6037                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6038                         { $LFS df && $LFS df -i &&
6039                         error "stripecount=$stripecount: " \
6040                               "OST $n has fewer #0 objects vs. OST $nlast " \
6041                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6042                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6043                         { $LFS df && $LFS df -i &&
6044                         error "stripecount=$stripecount: " \
6045                               "OST $n has more #0 objects vs. OST $nlast " \
6046                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6047         done
6048 }
6049
6050 test_51d() {
6051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6052         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6053
6054         local stripecount
6055         local per_ost=100
6056         local nfiles=$((per_ost * OSTCOUNT))
6057         local mdts=$(comma_list $(mdts_nodes))
6058         local param="osp.*.create_count"
6059         local qos_old=$(do_facet mds1 \
6060                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6061
6062         do_nodes $mdts \
6063                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6064         stack_trap "do_nodes $mdts \
6065                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6066
6067         test_mkdir $DIR/$tdir
6068         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6069         (( dirstripes > 0 )) || dirstripes=1
6070
6071         # Ensure enough OST objects precreated for tests to pass without
6072         # running out of objects.  This is an LOV r-r OST algorithm test,
6073         # not an OST object precreation test.
6074         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6075         (( old >= nfiles )) ||
6076         {
6077                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6078
6079                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6080                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6081
6082                 # trigger precreation from all MDTs for all OSTs
6083                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6084                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6085                 done
6086         }
6087
6088         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6089                 sleep 8  # allow object precreation to catch up
6090                 test_51d_sub $stripecount $nfiles
6091         done
6092 }
6093 run_test 51d "check LOV round-robin OST object distribution"
6094
6095 test_51e() {
6096         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6097                 skip_env "ldiskfs only test"
6098         fi
6099
6100         test_mkdir -c1 $DIR/$tdir
6101         test_mkdir -c1 $DIR/$tdir/d0
6102
6103         touch $DIR/$tdir/d0/foo
6104         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6105                 error "file exceed 65000 nlink limit!"
6106         unlinkmany $DIR/$tdir/d0/f- 65001
6107         return 0
6108 }
6109 run_test 51e "check file nlink limit"
6110
6111 test_51f() {
6112         test_mkdir $DIR/$tdir
6113
6114         local max=100000
6115         local ulimit_old=$(ulimit -n)
6116         local spare=20 # number of spare fd's for scripts/libraries, etc.
6117         local mdt=$($LFS getstripe -m $DIR/$tdir)
6118         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6119
6120         echo "MDT$mdt numfree=$numfree, max=$max"
6121         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6122         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6123                 while ! ulimit -n $((numfree + spare)); do
6124                         numfree=$((numfree * 3 / 4))
6125                 done
6126                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6127         else
6128                 echo "left ulimit at $ulimit_old"
6129         fi
6130
6131         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6132                 unlinkmany $DIR/$tdir/f $numfree
6133                 error "create+open $numfree files in $DIR/$tdir failed"
6134         }
6135         ulimit -n $ulimit_old
6136
6137         # if createmany exits at 120s there will be fewer than $numfree files
6138         unlinkmany $DIR/$tdir/f $numfree || true
6139 }
6140 run_test 51f "check many open files limit"
6141
6142 test_52a() {
6143         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6144         test_mkdir $DIR/$tdir
6145         touch $DIR/$tdir/foo
6146         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6147         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6148         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6149         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6150         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6151                                         error "link worked"
6152         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6153         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6154         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6155                                                      error "lsattr"
6156         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6157         cp -r $DIR/$tdir $TMP/
6158         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6159 }
6160 run_test 52a "append-only flag test (should return errors)"
6161
6162 test_52b() {
6163         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6164         test_mkdir $DIR/$tdir
6165         touch $DIR/$tdir/foo
6166         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6167         cat test > $DIR/$tdir/foo && error "cat test worked"
6168         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6169         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6170         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6171                                         error "link worked"
6172         echo foo >> $DIR/$tdir/foo && error "echo worked"
6173         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6174         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6175         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6176         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6177                                                         error "lsattr"
6178         chattr -i $DIR/$tdir/foo || error "chattr failed"
6179
6180         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6181 }
6182 run_test 52b "immutable flag test (should return errors) ======="
6183
6184 test_53() {
6185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6186         remote_mds_nodsh && skip "remote MDS with nodsh"
6187         remote_ost_nodsh && skip "remote OST with nodsh"
6188
6189         local param
6190         local param_seq
6191         local ostname
6192         local mds_last
6193         local mds_last_seq
6194         local ost_last
6195         local ost_last_seq
6196         local ost_last_id
6197         local ostnum
6198         local node
6199         local found=false
6200         local support_last_seq=true
6201
6202         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6203                 support_last_seq=false
6204
6205         # only test MDT0000
6206         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6207         local value
6208         for value in $(do_facet $SINGLEMDS \
6209                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6210                 param=$(echo ${value[0]} | cut -d "=" -f1)
6211                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6212
6213                 if $support_last_seq; then
6214                         param_seq=$(echo $param |
6215                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6216                         mds_last_seq=$(do_facet $SINGLEMDS \
6217                                        $LCTL get_param -n $param_seq)
6218                 fi
6219                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6220
6221                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6222                 node=$(facet_active_host ost$((ostnum+1)))
6223                 param="obdfilter.$ostname.last_id"
6224                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6225                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6226                         ost_last_id=$ost_last
6227
6228                         if $support_last_seq; then
6229                                 ost_last_id=$(echo $ost_last |
6230                                               awk -F':' '{print $2}' |
6231                                               sed -e "s/^0x//g")
6232                                 ost_last_seq=$(echo $ost_last |
6233                                                awk -F':' '{print $1}')
6234                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6235                         fi
6236
6237                         if [[ $ost_last_id != $mds_last ]]; then
6238                                 error "$ost_last_id != $mds_last"
6239                         else
6240                                 found=true
6241                                 break
6242                         fi
6243                 done
6244         done
6245         $found || error "can not match last_seq/last_id for $mdtosc"
6246         return 0
6247 }
6248 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6249
6250 test_54a() {
6251         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6252
6253         LANG=C $SOCKETSERVER $DIR/socket ||
6254                 error "$SOCKETSERVER $DIR/socket failed: $?"
6255         LANG=C $SOCKETCLIENT $DIR/socket ||
6256                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6257         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6258 }
6259 run_test 54a "unix domain socket test =========================="
6260
6261 test_54b() {
6262         f="$DIR/f54b"
6263         mknod $f c 1 3
6264         chmod 0666 $f
6265         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6266 }
6267 run_test 54b "char device works in lustre ======================"
6268
6269 find_loop_dev() {
6270         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6271         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6272         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6273
6274         for i in $(seq 3 7); do
6275                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6276                 LOOPDEV=$LOOPBASE$i
6277                 LOOPNUM=$i
6278                 break
6279         done
6280 }
6281
6282 cleanup_54c() {
6283         local rc=0
6284         loopdev="$DIR/loop54c"
6285
6286         trap 0
6287         $UMOUNT $DIR/$tdir || rc=$?
6288         losetup -d $loopdev || true
6289         losetup -d $LOOPDEV || true
6290         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6291         return $rc
6292 }
6293
6294 test_54c() {
6295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6296
6297         loopdev="$DIR/loop54c"
6298
6299         find_loop_dev
6300         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6301         trap cleanup_54c EXIT
6302         mknod $loopdev b 7 $LOOPNUM
6303         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6304         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6305         losetup $loopdev $DIR/$tfile ||
6306                 error "can't set up $loopdev for $DIR/$tfile"
6307         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6308         test_mkdir $DIR/$tdir
6309         mount -t ext2 $loopdev $DIR/$tdir ||
6310                 error "error mounting $loopdev on $DIR/$tdir"
6311         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6312                 error "dd write"
6313         df $DIR/$tdir
6314         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6315                 error "dd read"
6316         cleanup_54c
6317 }
6318 run_test 54c "block device works in lustre ====================="
6319
6320 test_54d() {
6321         local pipe="$DIR/$tfile.pipe"
6322         local string="aaaaaa"
6323
6324         mknod $pipe p
6325         echo -n "$string" > $pipe &
6326         local result=$(cat $pipe)
6327         [[ "$result" == "$string" ]] || error "$result != $string"
6328 }
6329 run_test 54d "fifo device works in lustre ======================"
6330
6331 test_54e() {
6332         f="$DIR/f54e"
6333         string="aaaaaa"
6334         cp -aL /dev/console $f
6335         echo $string > $f || error "echo $string to $f failed"
6336 }
6337 run_test 54e "console/tty device works in lustre ======================"
6338
6339 test_55a() {
6340         local dev_path="/sys/kernel/debug/lustre/devices"
6341
6342         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6343
6344         # This must be run in iteractive mode, since attach and setup
6345         # are stateful
6346         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6347                 attach obd_test obd_name obd_uuid
6348                 setup obd_test
6349         EOF"
6350
6351         echo "Devices:"
6352         cat "$dev_path" | tail -n 10
6353
6354         $LCTL --device "obd_name" cleanup
6355         $LCTL --device "obd_name" detach
6356
6357         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6358                 error "OBD unit test failed"
6359
6360         rmmod -v obd_test ||
6361                 error "rmmod failed (may trigger a failure in a later test)"
6362 }
6363 run_test 55a "OBD device life cycle unit tests"
6364
6365 test_55b() {
6366         local dev_path="/sys/kernel/debug/lustre/devices"
6367         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6368         local num_dev_to_create="$((8192 - $dev_count))"
6369
6370         load_module obdclass/obd_test || error "load_module failed"
6371
6372         local start=$SECONDS
6373
6374         # This must be run in iteractive mode, since attach and setup
6375         # are stateful
6376         for ((i = 1; i <= num_dev_to_create; i++)); do
6377                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6378                 echo "setup obd_test_$i"
6379         done | $LCTL || error "OBD device creation failed"
6380
6381         echo "Load time: $((SECONDS - start))"
6382         echo "Devices:"
6383         cat "$dev_path" | tail -n 10
6384
6385         for ((i = 1; i <= num_dev_to_create; i++)); do
6386                 echo "--device obd_name_$i cleanup"
6387                 echo "--device obd_name_$i detach"
6388         done | $LCTL || error "OBD device cleanup failed"
6389
6390         echo "Unload time: $((SECONDS - start))"
6391
6392         rmmod -v obd_test ||
6393                 error "rmmod failed (may trigger a failure in a later test)"
6394 }
6395 run_test 55b "Load and unload max OBD devices"
6396
6397 test_56a() {
6398         local numfiles=3
6399         local numdirs=2
6400         local dir=$DIR/$tdir
6401
6402         rm -rf $dir
6403         test_mkdir -p $dir/dir
6404         for i in $(seq $numfiles); do
6405                 touch $dir/file$i
6406                 touch $dir/dir/file$i
6407         done
6408
6409         local numcomp=$($LFS getstripe --component-count $dir)
6410
6411         [[ $numcomp == 0 ]] && numcomp=1
6412
6413         # test lfs getstripe with --recursive
6414         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6415
6416         [[ $filenum -eq $((numfiles * 2)) ]] ||
6417                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6418         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6419         [[ $filenum -eq $numfiles ]] ||
6420                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6421         echo "$LFS getstripe showed obdidx or l_ost_idx"
6422
6423         # test lfs getstripe with file instead of dir
6424         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6425         [[ $filenum -eq 1 ]] ||
6426                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6427         echo "$LFS getstripe file1 passed"
6428
6429         #test lfs getstripe with --verbose
6430         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6431         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6432                 error "$LFS getstripe --verbose $dir: "\
6433                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6434         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6435                 error "$LFS getstripe $dir: showed lmm_magic"
6436
6437         #test lfs getstripe with -v prints lmm_fid
6438         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6439         local countfids=$((numdirs + numfiles * numcomp))
6440         [[ $filenum -eq $countfids ]] ||
6441                 error "$LFS getstripe -v $dir: "\
6442                       "got $filenum want $countfids lmm_fid"
6443         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6444                 error "$LFS getstripe $dir: showed lmm_fid by default"
6445         echo "$LFS getstripe --verbose passed"
6446
6447         #check for FID information
6448         local fid1=$($LFS getstripe --fid $dir/file1)
6449         local fid2=$($LFS getstripe --verbose $dir/file1 |
6450                      awk '/lmm_fid: / { print $2; exit; }')
6451         local fid3=$($LFS path2fid $dir/file1)
6452
6453         [ "$fid1" != "$fid2" ] &&
6454                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6455         [ "$fid1" != "$fid3" ] &&
6456                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6457         echo "$LFS getstripe --fid passed"
6458
6459         #test lfs getstripe with --obd
6460         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6461                 error "$LFS getstripe --obd wrong_uuid: should return error"
6462
6463         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6464
6465         local ostidx=1
6466         local obduuid=$(ostuuid_from_index $ostidx)
6467         local found=$($LFS getstripe -r --obd $obduuid $dir |
6468                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6469
6470         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6471         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6472                 ((filenum--))
6473         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6474                 ((filenum--))
6475
6476         [[ $found -eq $filenum ]] ||
6477                 error "$LFS getstripe --obd: found $found expect $filenum"
6478         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6479                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6480                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6481                 error "$LFS getstripe --obd: should not show file on other obd"
6482         echo "$LFS getstripe --obd passed"
6483 }
6484 run_test 56a "check $LFS getstripe"
6485
6486 test_56b() {
6487         local dir=$DIR/$tdir
6488         local numdirs=3
6489
6490         test_mkdir $dir
6491         for i in $(seq $numdirs); do
6492                 test_mkdir $dir/dir$i
6493         done
6494
6495         # test lfs getdirstripe default mode is non-recursion, which is
6496         # different from lfs getstripe
6497         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6498
6499         [[ $dircnt -eq 1 ]] ||
6500                 error "$LFS getdirstripe: found $dircnt, not 1"
6501         dircnt=$($LFS getdirstripe --recursive $dir |
6502                 grep -c lmv_stripe_count)
6503         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6504                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6505 }
6506 run_test 56b "check $LFS getdirstripe"
6507
6508 test_56bb() {
6509         verify_yaml_available || skip_env "YAML verification not installed"
6510         local output_file=$DIR/$tfile.out
6511
6512         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6513
6514         cat $output_file
6515         cat $output_file | verify_yaml || error "layout is not valid YAML"
6516 }
6517 run_test 56bb "check $LFS getdirstripe layout is YAML"
6518
6519 test_56c() {
6520         remote_ost_nodsh && skip "remote OST with nodsh"
6521
6522         local ost_idx=0
6523         local ost_name=$(ostname_from_index $ost_idx)
6524         local old_status=$(ost_dev_status $ost_idx)
6525         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6526
6527         [[ -z "$old_status" ]] ||
6528                 skip_env "OST $ost_name is in $old_status status"
6529
6530         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6531         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6532                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6533         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6534                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6535                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6536         fi
6537
6538         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6539                 error "$LFS df -v showing inactive devices"
6540         sleep_maxage
6541
6542         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6543
6544         [[ "$new_status" =~ "D" ]] ||
6545                 error "$ost_name status is '$new_status', missing 'D'"
6546         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6547                 [[ "$new_status" =~ "N" ]] ||
6548                         error "$ost_name status is '$new_status', missing 'N'"
6549         fi
6550         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6551                 [[ "$new_status" =~ "f" ]] ||
6552                         error "$ost_name status is '$new_status', missing 'f'"
6553         fi
6554
6555         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6556         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6557                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6558         [[ -z "$p" ]] && restore_lustre_params < $p || true
6559         sleep_maxage
6560
6561         new_status=$(ost_dev_status $ost_idx)
6562         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6563                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6564         # can't check 'f' as devices may actually be on flash
6565 }
6566 run_test 56c "check 'lfs df' showing device status"
6567
6568 test_56d() {
6569         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6570         local osts=$($LFS df -v $MOUNT | grep -c OST)
6571
6572         $LFS df $MOUNT
6573
6574         (( mdts == MDSCOUNT )) ||
6575                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6576         (( osts == OSTCOUNT )) ||
6577                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6578 }
6579 run_test 56d "'lfs df -v' prints only configured devices"
6580
6581 test_56e() {
6582         err_enoent=2 # No such file or directory
6583         err_eopnotsupp=95 # Operation not supported
6584
6585         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6586         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6587
6588         # Check for handling of path not exists
6589         output=$($LFS df $enoent_mnt 2>&1)
6590         ret=$?
6591
6592         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6593         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6594                 error "expect failure $err_enoent, not $ret"
6595
6596         # Check for handling of non-Lustre FS
6597         output=$($LFS df $notsup_mnt)
6598         ret=$?
6599
6600         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6601         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6602                 error "expect success $err_eopnotsupp, not $ret"
6603
6604         # Check for multiple LustreFS argument
6605         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6606         ret=$?
6607
6608         [[ $output -eq 3 && $ret -eq 0 ]] ||
6609                 error "expect success 3, not $output, rc = $ret"
6610
6611         # Check for correct non-Lustre FS handling among multiple
6612         # LustreFS argument
6613         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6614                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6615         ret=$?
6616
6617         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6618                 error "expect success 2, not $output, rc = $ret"
6619 }
6620 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6621
6622 NUMFILES=3
6623 NUMDIRS=3
6624 setup_56() {
6625         local local_tdir="$1"
6626         local local_numfiles="$2"
6627         local local_numdirs="$3"
6628         local dir_params="$4"
6629         local dir_stripe_params="$5"
6630
6631         if [ ! -d "$local_tdir" ] ; then
6632                 test_mkdir -p $dir_stripe_params $local_tdir
6633                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6634                 for i in $(seq $local_numfiles) ; do
6635                         touch $local_tdir/file$i
6636                 done
6637                 for i in $(seq $local_numdirs) ; do
6638                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6639                         for j in $(seq $local_numfiles) ; do
6640                                 touch $local_tdir/dir$i/file$j
6641                         done
6642                 done
6643         fi
6644 }
6645
6646 setup_56_special() {
6647         local local_tdir=$1
6648         local local_numfiles=$2
6649         local local_numdirs=$3
6650
6651         setup_56 $local_tdir $local_numfiles $local_numdirs
6652
6653         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6654                 for i in $(seq $local_numfiles) ; do
6655                         mknod $local_tdir/loop${i}b b 7 $i
6656                         mknod $local_tdir/null${i}c c 1 3
6657                         ln -s $local_tdir/file1 $local_tdir/link${i}
6658                 done
6659                 for i in $(seq $local_numdirs) ; do
6660                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6661                         mknod $local_tdir/dir$i/null${i}c c 1 3
6662                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6663                 done
6664         fi
6665 }
6666
6667 test_56g() {
6668         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6669         local expected=$(($NUMDIRS + 2))
6670
6671         setup_56 $dir $NUMFILES $NUMDIRS
6672
6673         # test lfs find with -name
6674         for i in $(seq $NUMFILES) ; do
6675                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6676
6677                 [ $nums -eq $expected ] ||
6678                         error "lfs find -name '*$i' $dir wrong: "\
6679                               "found $nums, expected $expected"
6680         done
6681 }
6682 run_test 56g "check lfs find -name"
6683
6684 test_56h() {
6685         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6686         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6687
6688         setup_56 $dir $NUMFILES $NUMDIRS
6689
6690         # test lfs find with ! -name
6691         for i in $(seq $NUMFILES) ; do
6692                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6693
6694                 [ $nums -eq $expected ] ||
6695                         error "lfs find ! -name '*$i' $dir wrong: "\
6696                               "found $nums, expected $expected"
6697         done
6698 }
6699 run_test 56h "check lfs find ! -name"
6700
6701 test_56i() {
6702         local dir=$DIR/$tdir
6703
6704         test_mkdir $dir
6705
6706         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6707         local out=$($cmd)
6708
6709         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6710 }
6711 run_test 56i "check 'lfs find -ost UUID' skips directories"
6712
6713 test_56j() {
6714         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6715
6716         setup_56_special $dir $NUMFILES $NUMDIRS
6717
6718         local expected=$((NUMDIRS + 1))
6719         local cmd="$LFS find -type d $dir"
6720         local nums=$($cmd | wc -l)
6721
6722         [ $nums -eq $expected ] ||
6723                 error "'$cmd' wrong: found $nums, expected $expected"
6724 }
6725 run_test 56j "check lfs find -type d"
6726
6727 test_56k() {
6728         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6729
6730         setup_56_special $dir $NUMFILES $NUMDIRS
6731
6732         local expected=$(((NUMDIRS + 1) * NUMFILES))
6733         local cmd="$LFS find -type f $dir"
6734         local nums=$($cmd | wc -l)
6735
6736         [ $nums -eq $expected ] ||
6737                 error "'$cmd' wrong: found $nums, expected $expected"
6738 }
6739 run_test 56k "check lfs find -type f"
6740
6741 test_56l() {
6742         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6743
6744         setup_56_special $dir $NUMFILES $NUMDIRS
6745
6746         local expected=$((NUMDIRS + NUMFILES))
6747         local cmd="$LFS find -type b $dir"
6748         local nums=$($cmd | wc -l)
6749
6750         [ $nums -eq $expected ] ||
6751                 error "'$cmd' wrong: found $nums, expected $expected"
6752 }
6753 run_test 56l "check lfs find -type b"
6754
6755 test_56m() {
6756         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6757
6758         setup_56_special $dir $NUMFILES $NUMDIRS
6759
6760         local expected=$((NUMDIRS + NUMFILES))
6761         local cmd="$LFS find -type c $dir"
6762         local nums=$($cmd | wc -l)
6763         [ $nums -eq $expected ] ||
6764                 error "'$cmd' wrong: found $nums, expected $expected"
6765 }
6766 run_test 56m "check lfs find -type c"
6767
6768 test_56n() {
6769         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6770         setup_56_special $dir $NUMFILES $NUMDIRS
6771
6772         local expected=$((NUMDIRS + NUMFILES))
6773         local cmd="$LFS find -type l $dir"
6774         local nums=$($cmd | wc -l)
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778 }
6779 run_test 56n "check lfs find -type l"
6780
6781 test_56o() {
6782         local dir=$DIR/$tdir
6783
6784         setup_56 $dir $NUMFILES $NUMDIRS
6785         utime $dir/file1 > /dev/null || error "utime (1)"
6786         utime $dir/file2 > /dev/null || error "utime (2)"
6787         utime $dir/dir1 > /dev/null || error "utime (3)"
6788         utime $dir/dir2 > /dev/null || error "utime (4)"
6789         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6790         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6791
6792         local expected=4
6793         local nums=$($LFS find -mtime +0 $dir | wc -l)
6794
6795         [ $nums -eq $expected ] ||
6796                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6797
6798         expected=12
6799         cmd="$LFS find -mtime 0 $dir"
6800         nums=$($cmd | wc -l)
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803 }
6804 run_test 56o "check lfs find -mtime for old files"
6805
6806 test_56ob() {
6807         local dir=$DIR/$tdir
6808         local expected=1
6809         local count=0
6810
6811         # just to make sure there is something that won't be found
6812         test_mkdir $dir
6813         touch $dir/$tfile.now
6814
6815         for age in year week day hour min; do
6816                 count=$((count + 1))
6817
6818                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6819                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6820                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6821
6822                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6823                 local nums=$($cmd | wc -l)
6824                 [ $nums -eq $expected ] ||
6825                         error "'$cmd' wrong: found $nums, expected $expected"
6826
6827                 cmd="$LFS find $dir -atime $count${age:0:1}"
6828                 nums=$($cmd | wc -l)
6829                 [ $nums -eq $expected ] ||
6830                         error "'$cmd' wrong: found $nums, expected $expected"
6831         done
6832
6833         sleep 2
6834         cmd="$LFS find $dir -ctime +1s -type f"
6835         nums=$($cmd | wc -l)
6836         (( $nums == $count * 2 + 1)) ||
6837                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6838 }
6839 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6840
6841 test_newerXY_base() {
6842         local x=$1
6843         local y=$2
6844         local dir=$DIR/$tdir
6845         local ref
6846         local negref
6847
6848         if [ $y == "t" ]; then
6849                 if [ $x == "b" ]; then
6850                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6851                 else
6852                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6853                 fi
6854         else
6855                 ref=$DIR/$tfile.newer.$x$y
6856                 touch $ref || error "touch $ref failed"
6857         fi
6858
6859         echo "before = $ref"
6860         sleep 2
6861         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6862         sleep 2
6863         if [ $y == "t" ]; then
6864                 if [ $x == "b" ]; then
6865                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6866                 else
6867                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6868                 fi
6869         else
6870                 negref=$DIR/$tfile.negnewer.$x$y
6871                 touch $negref || error "touch $negref failed"
6872         fi
6873
6874         echo "after = $negref"
6875         local cmd="$LFS find $dir -newer$x$y $ref"
6876         local nums=$(eval $cmd | wc -l)
6877         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6878
6879         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6880                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6881
6882         cmd="$LFS find $dir ! -newer$x$y $negref"
6883         nums=$(eval $cmd | wc -l)
6884         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6885                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6886
6887         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6888         nums=$(eval $cmd | wc -l)
6889         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6890                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6891
6892         rm -rf $DIR/*
6893 }
6894
6895 test_56oc() {
6896         test_newerXY_base "a" "a"
6897         test_newerXY_base "a" "m"
6898         test_newerXY_base "a" "c"
6899         test_newerXY_base "m" "a"
6900         test_newerXY_base "m" "m"
6901         test_newerXY_base "m" "c"
6902         test_newerXY_base "c" "a"
6903         test_newerXY_base "c" "m"
6904         test_newerXY_base "c" "c"
6905
6906         test_newerXY_base "a" "t"
6907         test_newerXY_base "m" "t"
6908         test_newerXY_base "c" "t"
6909
6910         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6911            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6912                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6913
6914         test_newerXY_base "b" "b"
6915         test_newerXY_base "b" "t"
6916 }
6917 run_test 56oc "check lfs find -newerXY work"
6918
6919 test_56od() {
6920         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6921                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6922
6923         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6924                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6925
6926         local dir=$DIR/$tdir
6927         local ref=$DIR/$tfile.ref
6928         local negref=$DIR/$tfile.negref
6929
6930         mkdir $dir || error "mkdir $dir failed"
6931         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6932         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6933         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6934         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6935         touch $ref || error "touch $ref failed"
6936         # sleep 3 seconds at least
6937         sleep 3
6938
6939         local before=$(do_facet mds1 date +%s)
6940         local skew=$(($(date +%s) - before + 1))
6941
6942         if (( skew < 0 && skew > -5 )); then
6943                 sleep $((0 - skew + 1))
6944                 skew=0
6945         fi
6946
6947         # Set the dir stripe params to limit files all on MDT0,
6948         # otherwise we need to calc the max clock skew between
6949         # the client and MDTs.
6950         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6951         sleep 2
6952         touch $negref || error "touch $negref failed"
6953
6954         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6955         local nums=$($cmd | wc -l)
6956         local expected=$(((NUMFILES + 1) * NUMDIRS))
6957
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6962         nums=$($cmd | wc -l)
6963         expected=$((NUMFILES + 1))
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         [ $skew -lt 0 ] && return
6968
6969         local after=$(do_facet mds1 date +%s)
6970         local age=$((after - before + 1 + skew))
6971
6972         cmd="$LFS find $dir -btime -${age}s -type f"
6973         nums=$($cmd | wc -l)
6974         expected=$(((NUMFILES + 1) * NUMDIRS))
6975
6976         echo "Clock skew between client and server: $skew, age:$age"
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=$(($NUMDIRS + 1))
6981         cmd="$LFS find $dir -btime -${age}s -type d"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985         rm -f $ref $negref || error "Failed to remove $ref $negref"
6986 }
6987 run_test 56od "check lfs find -btime with units"
6988
6989 test_56p() {
6990         [ $RUNAS_ID -eq $UID ] &&
6991                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6992
6993         local dir=$DIR/$tdir
6994
6995         setup_56 $dir $NUMFILES $NUMDIRS
6996         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6997
6998         local expected=$NUMFILES
6999         local cmd="$LFS find -uid $RUNAS_ID $dir"
7000         local nums=$($cmd | wc -l)
7001
7002         [ $nums -eq $expected ] ||
7003                 error "'$cmd' wrong: found $nums, expected $expected"
7004
7005         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7006         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7007         nums=$($cmd | wc -l)
7008         [ $nums -eq $expected ] ||
7009                 error "'$cmd' wrong: found $nums, expected $expected"
7010 }
7011 run_test 56p "check lfs find -uid and ! -uid"
7012
7013 test_56q() {
7014         [ $RUNAS_ID -eq $UID ] &&
7015                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7016
7017         local dir=$DIR/$tdir
7018
7019         setup_56 $dir $NUMFILES $NUMDIRS
7020         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7021
7022         local expected=$NUMFILES
7023         local cmd="$LFS find -gid $RUNAS_GID $dir"
7024         local nums=$($cmd | wc -l)
7025
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7030         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034 }
7035 run_test 56q "check lfs find -gid and ! -gid"
7036
7037 test_56r() {
7038         local dir=$DIR/$tdir
7039
7040         setup_56 $dir $NUMFILES $NUMDIRS
7041
7042         local expected=12
7043         local cmd="$LFS find -size 0 -type f -lazy $dir"
7044         local nums=$($cmd | wc -l)
7045
7046         [ $nums -eq $expected ] ||
7047                 error "'$cmd' wrong: found $nums, expected $expected"
7048         cmd="$LFS find -size 0 -type f $dir"
7049         nums=$($cmd | wc -l)
7050         [ $nums -eq $expected ] ||
7051                 error "'$cmd' wrong: found $nums, expected $expected"
7052
7053         expected=0
7054         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7055         nums=$($cmd | wc -l)
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058         cmd="$LFS find ! -size 0 -type f $dir"
7059         nums=$($cmd | wc -l)
7060         [ $nums -eq $expected ] ||
7061                 error "'$cmd' wrong: found $nums, expected $expected"
7062
7063         echo "test" > $dir/$tfile
7064         echo "test2" > $dir/$tfile.2 && sync
7065         expected=1
7066         cmd="$LFS find -size 5 -type f -lazy $dir"
7067         nums=$($cmd | wc -l)
7068         [ $nums -eq $expected ] ||
7069                 error "'$cmd' wrong: found $nums, expected $expected"
7070         cmd="$LFS find -size 5 -type f $dir"
7071         nums=$($cmd | wc -l)
7072         [ $nums -eq $expected ] ||
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074
7075         expected=1
7076         cmd="$LFS find -size +5 -type f -lazy $dir"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         cmd="$LFS find -size +5 -type f $dir"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] ||
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084
7085         expected=2
7086         cmd="$LFS find -size +0 -type f -lazy $dir"
7087         nums=$($cmd | wc -l)
7088         [ $nums -eq $expected ] ||
7089                 error "'$cmd' wrong: found $nums, expected $expected"
7090         cmd="$LFS find -size +0 -type f $dir"
7091         nums=$($cmd | wc -l)
7092         [ $nums -eq $expected ] ||
7093                 error "'$cmd' wrong: found $nums, expected $expected"
7094
7095         expected=2
7096         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7097         nums=$($cmd | wc -l)
7098         [ $nums -eq $expected ] ||
7099                 error "'$cmd' wrong: found $nums, expected $expected"
7100         cmd="$LFS find ! -size -5 -type f $dir"
7101         nums=$($cmd | wc -l)
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         expected=12
7106         cmd="$LFS find -size -5 -type f -lazy $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110         cmd="$LFS find -size -5 -type f $dir"
7111         nums=$($cmd | wc -l)
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114 }
7115 run_test 56r "check lfs find -size works"
7116
7117 test_56ra_sub() {
7118         local expected=$1
7119         local glimpses=$2
7120         local cmd="$3"
7121
7122         cancel_lru_locks $OSC
7123
7124         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7125         local nums=$($cmd | wc -l)
7126
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129
7130         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7131
7132         if (( rpcs_before + glimpses != rpcs_after )); then
7133                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7134                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7135
7136                 if [[ $glimpses == 0 ]]; then
7137                         error "'$cmd' should not send glimpse RPCs to OST"
7138                 else
7139                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7140                 fi
7141         fi
7142 }
7143
7144 test_56ra() {
7145         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7146                 skip "MDS < 2.12.58 doesn't return LSOM data"
7147         local dir=$DIR/$tdir
7148         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7149
7150         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7151
7152         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7153         $LCTL set_param -n llite.*.statahead_agl=0
7154         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7155
7156         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7157         # open and close all files to ensure LSOM is updated
7158         cancel_lru_locks $OSC
7159         find $dir -type f | xargs cat > /dev/null
7160
7161         #   expect_found  glimpse_rpcs  command_to_run
7162         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7163         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7164         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7165         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7166
7167         echo "test" > $dir/$tfile
7168         echo "test2" > $dir/$tfile.2 && sync
7169         cancel_lru_locks $OSC
7170         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7171
7172         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7173         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7174         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7175         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7176
7177         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7178         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7179         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7180         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7181         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7182         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7183 }
7184 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7185
7186 test_56rb() {
7187         local dir=$DIR/$tdir
7188         local tmp=$TMP/$tfile.log
7189         local mdt_idx;
7190
7191         test_mkdir -p $dir || error "failed to mkdir $dir"
7192         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7193                 error "failed to setstripe $dir/$tfile"
7194         mdt_idx=$($LFS getdirstripe -i $dir)
7195         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7196
7197         stack_trap "rm -f $tmp" EXIT
7198         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7199         ! grep -q obd_uuid $tmp ||
7200                 error "failed to find --size +100K --ost 0 $dir"
7201         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7202         ! grep -q obd_uuid $tmp ||
7203                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7204 }
7205 run_test 56rb "check lfs find --size --ost/--mdt works"
7206
7207 test_56rc() {
7208         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7209         local dir=$DIR/$tdir
7210         local found
7211
7212         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7213         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7214         (( $MDSCOUNT > 2 )) &&
7215                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7216         mkdir $dir/$tdir-{1..10}
7217         touch $dir/$tfile-{1..10}
7218
7219         found=$($LFS find $dir --mdt-count 2 | wc -l)
7220         expect=11
7221         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7222
7223         found=$($LFS find $dir -T +1 | wc -l)
7224         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7225         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7226
7227         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7228         expect=11
7229         (( $found == $expect )) || error "found $found all_char, expect $expect"
7230
7231         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7232         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7233         (( $found == $expect )) || error "found $found all_char, expect $expect"
7234 }
7235 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7236
7237 test_56rd() {
7238         local dir=$DIR/$tdir
7239
7240         test_mkdir $dir
7241         rm -f $dir/*
7242
7243         mkfifo $dir/fifo || error "failed to create fifo file"
7244         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7245                 error "should not fail even cannot get projid from pipe file"
7246         found=$($LFS find $dir -t p --printf "%y")
7247         [[ "p" == $found ]] || error "found $found, expect p"
7248
7249         mknod $dir/chardev c 1 5 ||
7250                 error "failed to create character device file"
7251         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7252                 error "should not fail even cannot get projid from chardev file"
7253         found=$($LFS find $dir -t c --printf "%y")
7254         [[ "c" == $found ]] || error "found $found, expect c"
7255
7256         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7257         (( found == 2 )) || error "unable to list all files"
7258 }
7259 run_test 56rd "check lfs find --printf special files"
7260
7261 test_56s() { # LU-611 #LU-9369
7262         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7263
7264         local dir=$DIR/$tdir
7265         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7266
7267         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7268         for i in $(seq $NUMDIRS); do
7269                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7270         done
7271
7272         local expected=$NUMDIRS
7273         local cmd="$LFS find -c $OSTCOUNT $dir"
7274         local nums=$($cmd | wc -l)
7275
7276         [ $nums -eq $expected ] || {
7277                 $LFS getstripe -R $dir
7278                 error "'$cmd' wrong: found $nums, expected $expected"
7279         }
7280
7281         expected=$((NUMDIRS + onestripe))
7282         cmd="$LFS find -stripe-count +0 -type f $dir"
7283         nums=$($cmd | wc -l)
7284         [ $nums -eq $expected ] || {
7285                 $LFS getstripe -R $dir
7286                 error "'$cmd' wrong: found $nums, expected $expected"
7287         }
7288
7289         expected=$onestripe
7290         cmd="$LFS find -stripe-count 1 -type f $dir"
7291         nums=$($cmd | wc -l)
7292         [ $nums -eq $expected ] || {
7293                 $LFS getstripe -R $dir
7294                 error "'$cmd' wrong: found $nums, expected $expected"
7295         }
7296
7297         cmd="$LFS find -stripe-count -2 -type f $dir"
7298         nums=$($cmd | wc -l)
7299         [ $nums -eq $expected ] || {
7300                 $LFS getstripe -R $dir
7301                 error "'$cmd' wrong: found $nums, expected $expected"
7302         }
7303
7304         expected=0
7305         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7306         nums=$($cmd | wc -l)
7307         [ $nums -eq $expected ] || {
7308                 $LFS getstripe -R $dir
7309                 error "'$cmd' wrong: found $nums, expected $expected"
7310         }
7311 }
7312 run_test 56s "check lfs find -stripe-count works"
7313
7314 test_56t() { # LU-611 #LU-9369
7315         local dir=$DIR/$tdir
7316
7317         setup_56 $dir 0 $NUMDIRS
7318         for i in $(seq $NUMDIRS); do
7319                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7320         done
7321
7322         local expected=$NUMDIRS
7323         local cmd="$LFS find -S 8M $dir"
7324         local nums=$($cmd | wc -l)
7325
7326         [ $nums -eq $expected ] || {
7327                 $LFS getstripe -R $dir
7328                 error "'$cmd' wrong: found $nums, expected $expected"
7329         }
7330         rm -rf $dir
7331
7332         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7333
7334         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7335
7336         expected=$(((NUMDIRS + 1) * NUMFILES))
7337         cmd="$LFS find -stripe-size 512k -type f $dir"
7338         nums=$($cmd | wc -l)
7339         [ $nums -eq $expected ] ||
7340                 error "'$cmd' wrong: found $nums, expected $expected"
7341
7342         cmd="$LFS find -stripe-size +320k -type f $dir"
7343         nums=$($cmd | wc -l)
7344         [ $nums -eq $expected ] ||
7345                 error "'$cmd' wrong: found $nums, expected $expected"
7346
7347         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7348         cmd="$LFS find -stripe-size +200k -type f $dir"
7349         nums=$($cmd | wc -l)
7350         [ $nums -eq $expected ] ||
7351                 error "'$cmd' wrong: found $nums, expected $expected"
7352
7353         cmd="$LFS find -stripe-size -640k -type f $dir"
7354         nums=$($cmd | wc -l)
7355         [ $nums -eq $expected ] ||
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357
7358         expected=4
7359         cmd="$LFS find -stripe-size 256k -type f $dir"
7360         nums=$($cmd | wc -l)
7361         [ $nums -eq $expected ] ||
7362                 error "'$cmd' wrong: found $nums, expected $expected"
7363
7364         cmd="$LFS find -stripe-size -320k -type f $dir"
7365         nums=$($cmd | wc -l)
7366         [ $nums -eq $expected ] ||
7367                 error "'$cmd' wrong: found $nums, expected $expected"
7368
7369         expected=0
7370         cmd="$LFS find -stripe-size 1024k -type f $dir"
7371         nums=$($cmd | wc -l)
7372         [ $nums -eq $expected ] ||
7373                 error "'$cmd' wrong: found $nums, expected $expected"
7374 }
7375 run_test 56t "check lfs find -stripe-size works"
7376
7377 test_56u() { # LU-611
7378         local dir=$DIR/$tdir
7379
7380         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7381
7382         if [[ $OSTCOUNT -gt 1 ]]; then
7383                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7384                 onestripe=4
7385         else
7386                 onestripe=0
7387         fi
7388
7389         local expected=$(((NUMDIRS + 1) * NUMFILES))
7390         local cmd="$LFS find -stripe-index 0 -type f $dir"
7391         local nums=$($cmd | wc -l)
7392
7393         [ $nums -eq $expected ] ||
7394                 error "'$cmd' wrong: found $nums, expected $expected"
7395
7396         expected=$onestripe
7397         cmd="$LFS find -stripe-index 1 -type f $dir"
7398         nums=$($cmd | wc -l)
7399         [ $nums -eq $expected ] ||
7400                 error "'$cmd' wrong: found $nums, expected $expected"
7401
7402         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7403         nums=$($cmd | wc -l)
7404         [ $nums -eq $expected ] ||
7405                 error "'$cmd' wrong: found $nums, expected $expected"
7406
7407         expected=0
7408         # This should produce an error and not return any files
7409         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7410         nums=$($cmd 2>/dev/null | wc -l)
7411         [ $nums -eq $expected ] ||
7412                 error "'$cmd' wrong: found $nums, expected $expected"
7413
7414         if [[ $OSTCOUNT -gt 1 ]]; then
7415                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7416                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7417                 nums=$($cmd | wc -l)
7418                 [ $nums -eq $expected ] ||
7419                         error "'$cmd' wrong: found $nums, expected $expected"
7420         fi
7421 }
7422 run_test 56u "check lfs find -stripe-index works"
7423
7424 test_56v() {
7425         local mdt_idx=0
7426         local dir=$DIR/$tdir
7427
7428         setup_56 $dir $NUMFILES $NUMDIRS
7429
7430         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7431         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7432
7433         for file in $($LFS find -m $UUID $dir); do
7434                 file_midx=$($LFS getstripe -m $file)
7435                 [ $file_midx -eq $mdt_idx ] ||
7436                         error "lfs find -m $UUID != getstripe -m $file_midx"
7437         done
7438 }
7439 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7440
7441 test_56wa() {
7442         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7444
7445         local dir=$DIR/$tdir
7446
7447         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7448         stack_trap "rm -rf $dir"
7449
7450         local stripe_size=$($LFS getstripe -S -d $dir) ||
7451                 error "$LFS getstripe -S -d $dir failed"
7452         stripe_size=${stripe_size%% *}
7453
7454         local file_size=$((stripe_size * OSTCOUNT))
7455         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7456         local required_space=$((file_num * file_size))
7457         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7458                            head -n1)
7459         (( free_space >= required_space / 1024 )) ||
7460                 skip_env "need $required_space, have $free_space kbytes"
7461
7462         local dd_bs=65536
7463         local dd_count=$((file_size / dd_bs))
7464
7465         # write data into the files
7466         local i
7467         local j
7468         local file
7469
7470         for ((i = 1; i <= NUMFILES; i++ )); do
7471                 file=$dir/file$i
7472                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7473                         error "write data into $file failed"
7474         done
7475         for ((i = 1; i <= NUMDIRS; i++ )); do
7476                 for ((j = 1; j <= NUMFILES; j++ )); do
7477                         file=$dir/dir$i/file$j
7478                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7479                                 error "write data into $file failed"
7480                 done
7481         done
7482
7483         # $LFS_MIGRATE will fail if hard link migration is unsupported
7484         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7485                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7486                         error "creating links to $dir/dir1/file1 failed"
7487         fi
7488
7489         local expected=-1
7490
7491         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7492
7493         # lfs_migrate file
7494         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7495
7496         echo "$cmd"
7497         eval $cmd || error "$cmd failed"
7498
7499         check_stripe_count $dir/file1 $expected
7500
7501         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7502                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7503                 # OST 1 if it is on OST 0. This file is small enough to
7504                 # be on only one stripe.
7505                 file=$dir/migr_1_ost
7506                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7507                         error "write data into $file failed"
7508                 local obdidx=$($LFS getstripe -i $file)
7509                 local oldmd5=$(md5sum $file)
7510                 local newobdidx=0
7511
7512                 (( obdidx != 0 )) || newobdidx=1
7513                 cmd="$LFS migrate -i $newobdidx $file"
7514                 echo $cmd
7515                 eval $cmd || error "$cmd failed"
7516
7517                 local realobdix=$($LFS getstripe -i $file)
7518                 local newmd5=$(md5sum $file)
7519
7520                 (( $newobdidx == $realobdix )) ||
7521                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7522                 [[ "$oldmd5" == "$newmd5" ]] ||
7523                         error "md5sum differ: $oldmd5, $newmd5"
7524         fi
7525
7526         # lfs_migrate dir
7527         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7528         echo "$cmd"
7529         eval $cmd || error "$cmd failed"
7530
7531         for (( j = 1; j <= NUMFILES; j++ )); do
7532                 check_stripe_count $dir/dir1/file$j $expected
7533         done
7534
7535         # lfs_migrate works with lfs find
7536         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7537              $LFS_MIGRATE -y -c $expected"
7538         echo "$cmd"
7539         eval $cmd || error "$cmd failed"
7540
7541         for (( i = 2; i <= NUMFILES; i++ )); do
7542                 check_stripe_count $dir/file$i $expected
7543         done
7544         for (( i = 2; i <= NUMDIRS; i++ )); do
7545                 for (( j = 1; j <= NUMFILES; j++ )); do
7546                         check_stripe_count $dir/dir$i/file$j $expected
7547                 done
7548         done
7549 }
7550 run_test 56wa "check lfs_migrate -c stripe_count works"
7551
7552 test_56wb() {
7553         local file1=$DIR/$tdir/file1
7554         local create_pool=false
7555         local initial_pool=$($LFS getstripe -p $DIR)
7556         local pool_list=()
7557         local pool=""
7558
7559         echo -n "Creating test dir..."
7560         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7561         echo "done."
7562
7563         echo -n "Creating test file..."
7564         touch $file1 || error "cannot create file"
7565         echo "done."
7566
7567         echo -n "Detecting existing pools..."
7568         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7569
7570         if [ ${#pool_list[@]} -gt 0 ]; then
7571                 echo "${pool_list[@]}"
7572                 for thispool in "${pool_list[@]}"; do
7573                         if [[ -z "$initial_pool" ||
7574                               "$initial_pool" != "$thispool" ]]; then
7575                                 pool="$thispool"
7576                                 echo "Using existing pool '$pool'"
7577                                 break
7578                         fi
7579                 done
7580         else
7581                 echo "none detected."
7582         fi
7583         if [ -z "$pool" ]; then
7584                 pool=${POOL:-testpool}
7585                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7586                 echo -n "Creating pool '$pool'..."
7587                 create_pool=true
7588                 pool_add $pool &> /dev/null ||
7589                         error "pool_add failed"
7590                 echo "done."
7591
7592                 echo -n "Adding target to pool..."
7593                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7594                         error "pool_add_targets failed"
7595                 echo "done."
7596         fi
7597
7598         echo -n "Setting pool using -p option..."
7599         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7600                 error "migrate failed rc = $?"
7601         echo "done."
7602
7603         echo -n "Verifying test file is in pool after migrating..."
7604         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7605                 error "file was not migrated to pool $pool"
7606         echo "done."
7607
7608         echo -n "Removing test file from pool '$pool'..."
7609         # "lfs migrate $file" won't remove the file from the pool
7610         # until some striping information is changed.
7611         $LFS migrate -c 1 $file1 &> /dev/null ||
7612                 error "cannot remove from pool"
7613         [ "$($LFS getstripe -p $file1)" ] &&
7614                 error "pool still set"
7615         echo "done."
7616
7617         echo -n "Setting pool using --pool option..."
7618         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7619                 error "migrate failed rc = $?"
7620         echo "done."
7621
7622         # Clean up
7623         rm -f $file1
7624         if $create_pool; then
7625                 destroy_test_pools 2> /dev/null ||
7626                         error "destroy test pools failed"
7627         fi
7628 }
7629 run_test 56wb "check lfs_migrate pool support"
7630
7631 test_56wc() {
7632         local file1="$DIR/$tdir/$tfile"
7633         local md5
7634         local parent_ssize
7635         local parent_scount
7636         local cur_ssize
7637         local cur_scount
7638         local orig_ssize
7639         local new_scount
7640         local cur_comp
7641
7642         echo -n "Creating test dir..."
7643         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7644         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7645                 error "cannot set stripe by '-S 1M -c 1'"
7646         echo "done"
7647
7648         echo -n "Setting initial stripe for test file..."
7649         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7650                 error "cannot set stripe"
7651         cur_ssize=$($LFS getstripe -S "$file1")
7652         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7653         echo "done."
7654
7655         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7656         stack_trap "rm -f $file1"
7657         md5="$(md5sum $file1)"
7658
7659         # File currently set to -S 512K -c 1
7660
7661         # Ensure -c and -S options are rejected when -R is set
7662         echo -n "Verifying incompatible options are detected..."
7663         $LFS_MIGRATE -R -c 1 "$file1" &&
7664                 error "incompatible -R and -c options not detected"
7665         $LFS_MIGRATE -R -S 1M "$file1" &&
7666                 error "incompatible -R and -S options not detected"
7667         $LFS_MIGRATE -R -p pool "$file1" &&
7668                 error "incompatible -R and -p options not detected"
7669         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7670                 error "incompatible -R and -E options not detected"
7671         $LFS_MIGRATE -R -A "$file1" &&
7672                 error "incompatible -R and -A options not detected"
7673         $LFS_MIGRATE -A -c 1 "$file1" &&
7674                 error "incompatible -A and -c options not detected"
7675         $LFS_MIGRATE -A -S 1M "$file1" &&
7676                 error "incompatible -A and -S options not detected"
7677         $LFS_MIGRATE -A -p pool "$file1" &&
7678                 error "incompatible -A and -p options not detected"
7679         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7680                 error "incompatible -A and -E options not detected"
7681         echo "done."
7682
7683         # Ensure unrecognized options are passed through to 'lfs migrate'
7684         echo -n "Verifying -S option is passed through to lfs migrate..."
7685         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7686         cur_ssize=$($LFS getstripe -S "$file1")
7687         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7688         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7689         echo "done."
7690
7691         # File currently set to -S 1M -c 1
7692
7693         # Ensure long options are supported
7694         echo -n "Verifying long options supported..."
7695         $LFS_MIGRATE --non-block "$file1" ||
7696                 error "long option without argument not supported"
7697         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7698                 error "long option with argument not supported"
7699         cur_ssize=$($LFS getstripe -S "$file1")
7700         (( cur_ssize == 524288 )) ||
7701                 error "migrate --stripe-size $cur_ssize != 524288"
7702         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7703         echo "done."
7704
7705         # File currently set to -S 512K -c 1
7706
7707         if (( OSTCOUNT > 1 )); then
7708                 echo -n "Verifying explicit stripe count can be set..."
7709                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7710                 cur_scount=$($LFS getstripe -c "$file1")
7711                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7712                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7713                         error "file data has changed (3)"
7714                 echo "done."
7715         fi
7716
7717         # File currently set to -S 512K -c 1 or -S 512K -c 2
7718
7719         # Ensure parent striping is used if -R is set, and no stripe
7720         # count or size is specified
7721         echo -n "Setting stripe for parent directory..."
7722         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7723                 error "cannot set stripe '-S 2M -c 1'"
7724         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7725         echo "done."
7726
7727         echo -n "Verifying restripe option uses parent stripe settings..."
7728         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7729         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7730         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7731         cur_ssize=$($LFS getstripe -S "$file1")
7732         (( cur_ssize == parent_ssize )) ||
7733                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7734         cur_scount=$($LFS getstripe -c "$file1")
7735         (( cur_scount == parent_scount )) ||
7736                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7737         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7738         echo "done."
7739
7740         # File currently set to -S 1M -c 1
7741
7742         # Ensure striping is preserved if -R is not set, and no stripe
7743         # count or size is specified
7744         echo -n "Verifying striping size preserved when not specified..."
7745         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7746         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7747                 error "cannot set stripe on parent directory"
7748         $LFS_MIGRATE "$file1" || error "migrate failed"
7749         cur_ssize=$($LFS getstripe -S "$file1")
7750         (( cur_ssize == orig_ssize )) ||
7751                 error "migrate by default $cur_ssize != $orig_ssize"
7752         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7753         echo "done."
7754
7755         # Ensure file name properly detected when final option has no argument
7756         echo -n "Verifying file name properly detected..."
7757         $LFS_MIGRATE "$file1" ||
7758                 error "file name interpreted as option argument"
7759         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7760         echo "done."
7761
7762         # Ensure PFL arguments are passed through properly
7763         echo -n "Verifying PFL options passed through..."
7764         new_scount=$(((OSTCOUNT + 1) / 2))
7765         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7766                 error "migrate PFL arguments failed"
7767         cur_comp=$($LFS getstripe --comp-count $file1)
7768         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7769         cur_scount=$($LFS getstripe --stripe-count $file1)
7770         (( cur_scount == new_scount)) ||
7771                 error "PFL stripe count $cur_scount != $new_scount"
7772         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7773         echo "done."
7774 }
7775 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7776
7777 test_56wd() {
7778         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7779
7780         local file1=$DIR/$tdir/$tfile
7781
7782         echo -n "Creating test dir..."
7783         test_mkdir $DIR/$tdir || error "cannot create dir"
7784         echo "done."
7785
7786         echo -n "Creating test file..."
7787         echo "$tfile" > $file1
7788         echo "done."
7789
7790         # Ensure 'lfs migrate' will fail by using a non-existent option,
7791         # and make sure rsync is not called to recover
7792         echo -n "Make sure --no-rsync option works..."
7793         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7794                 grep -q 'refusing to fall back to rsync' ||
7795                 error "rsync was called with --no-rsync set"
7796         echo "done."
7797
7798         # Ensure rsync is called without trying 'lfs migrate' first
7799         echo -n "Make sure --rsync option works..."
7800         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7801                 grep -q 'falling back to rsync' &&
7802                 error "lfs migrate was called with --rsync set"
7803         echo "done."
7804 }
7805 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7806
7807 test_56we() {
7808         local td=$DIR/$tdir
7809         local tf=$td/$tfile
7810
7811         test_mkdir $td || error "cannot create $td"
7812         touch $tf || error "cannot touch $tf"
7813
7814         echo -n "Make sure --non-direct|-D works..."
7815         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7816                 grep -q "lfs migrate --non-direct" ||
7817                 error "--non-direct option cannot work correctly"
7818         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7819                 grep -q "lfs migrate -D" ||
7820                 error "-D option cannot work correctly"
7821         echo "done."
7822 }
7823 run_test 56we "check lfs_migrate --non-direct|-D support"
7824
7825 test_56x() {
7826         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7827         check_swap_layouts_support
7828
7829         local dir=$DIR/$tdir
7830         local ref1=/etc/passwd
7831         local file1=$dir/file1
7832
7833         test_mkdir $dir || error "creating dir $dir"
7834         $LFS setstripe -c 2 $file1
7835         cp $ref1 $file1
7836         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7837         stripe=$($LFS getstripe -c $file1)
7838         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7839         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7840
7841         # clean up
7842         rm -f $file1
7843 }
7844 run_test 56x "lfs migration support"
7845
7846 test_56xa() {
7847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7848         check_swap_layouts_support
7849
7850         local dir=$DIR/$tdir/$testnum
7851
7852         test_mkdir -p $dir
7853
7854         local ref1=/etc/passwd
7855         local file1=$dir/file1
7856
7857         $LFS setstripe -c 2 $file1
7858         cp $ref1 $file1
7859         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7860
7861         local stripe=$($LFS getstripe -c $file1)
7862
7863         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7864         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7865
7866         # clean up
7867         rm -f $file1
7868 }
7869 run_test 56xa "lfs migration --block support"
7870
7871 check_migrate_links() {
7872         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7873         local dir="$1"
7874         local file1="$dir/file1"
7875         local begin="$2"
7876         local count="$3"
7877         local runas="$4"
7878         local total_count=$(($begin + $count - 1))
7879         local symlink_count=10
7880         local uniq_count=10
7881
7882         if [ ! -f "$file1" ]; then
7883                 echo -n "creating initial file..."
7884                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7885                         error "cannot setstripe initial file"
7886                 echo "done"
7887
7888                 echo -n "creating symlinks..."
7889                 for s in $(seq 1 $symlink_count); do
7890                         ln -s "$file1" "$dir/slink$s" ||
7891                                 error "cannot create symlinks"
7892                 done
7893                 echo "done"
7894
7895                 echo -n "creating nonlinked files..."
7896                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7897                         error "cannot create nonlinked files"
7898                 echo "done"
7899         fi
7900
7901         # create hard links
7902         if [ ! -f "$dir/file$total_count" ]; then
7903                 echo -n "creating hard links $begin:$total_count..."
7904                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7905                         /dev/null || error "cannot create hard links"
7906                 echo "done"
7907         fi
7908
7909         echo -n "checking number of hard links listed in xattrs..."
7910         local fid=$($LFS getstripe -F "$file1")
7911         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7912
7913         echo "${#paths[*]}"
7914         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7915                         skip "hard link list has unexpected size, skipping test"
7916         fi
7917         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7918                         error "link names should exceed xattrs size"
7919         fi
7920
7921         echo -n "migrating files..."
7922         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7923         local rc=$?
7924         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7925         echo "done"
7926
7927         # make sure all links have been properly migrated
7928         echo -n "verifying files..."
7929         fid=$($LFS getstripe -F "$file1") ||
7930                 error "cannot get fid for file $file1"
7931         for i in $(seq 2 $total_count); do
7932                 local fid2=$($LFS getstripe -F $dir/file$i)
7933
7934                 [ "$fid2" == "$fid" ] ||
7935                         error "migrated hard link has mismatched FID"
7936         done
7937
7938         # make sure hard links were properly detected, and migration was
7939         # performed only once for the entire link set; nonlinked files should
7940         # also be migrated
7941         local actual=$(grep -c 'done' <<< "$migrate_out")
7942         local expected=$(($uniq_count + 1))
7943
7944         [ "$actual" -eq  "$expected" ] ||
7945                 error "hard links individually migrated ($actual != $expected)"
7946
7947         # make sure the correct number of hard links are present
7948         local hardlinks=$(stat -c '%h' "$file1")
7949
7950         [ $hardlinks -eq $total_count ] ||
7951                 error "num hard links $hardlinks != $total_count"
7952         echo "done"
7953
7954         return 0
7955 }
7956
7957 test_56xb() {
7958         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7959                 skip "Need MDS version at least 2.10.55"
7960
7961         local dir="$DIR/$tdir"
7962
7963         test_mkdir "$dir" || error "cannot create dir $dir"
7964
7965         echo "testing lfs migrate mode when all links fit within xattrs"
7966         check_migrate_links "$dir" 2 99
7967
7968         echo "testing rsync mode when all links fit within xattrs"
7969         check_migrate_links --rsync "$dir" 2 99
7970
7971         echo "testing lfs migrate mode when all links do not fit within xattrs"
7972         check_migrate_links "$dir" 101 100
7973
7974         echo "testing rsync mode when all links do not fit within xattrs"
7975         check_migrate_links --rsync "$dir" 101 100
7976
7977         chown -R $RUNAS_ID $dir
7978         echo "testing non-root lfs migrate mode when not all links are in xattr"
7979         check_migrate_links "$dir" 101 100 "$RUNAS"
7980
7981         # clean up
7982         rm -rf $dir
7983 }
7984 run_test 56xb "lfs migration hard link support"
7985
7986 test_56xc() {
7987         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7988
7989         local dir="$DIR/$tdir"
7990
7991         test_mkdir "$dir" || error "cannot create dir $dir"
7992
7993         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7994         echo -n "Setting initial stripe for 20MB test file..."
7995         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7996                 error "cannot setstripe 20MB file"
7997         echo "done"
7998         echo -n "Sizing 20MB test file..."
7999         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8000         echo "done"
8001         echo -n "Verifying small file autostripe count is 1..."
8002         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8003                 error "cannot migrate 20MB file"
8004         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8005                 error "cannot get stripe for $dir/20mb"
8006         [ $stripe_count -eq 1 ] ||
8007                 error "unexpected stripe count $stripe_count for 20MB file"
8008         rm -f "$dir/20mb"
8009         echo "done"
8010
8011         # Test 2: File is small enough to fit within the available space on
8012         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8013         # have at least an additional 1KB for each desired stripe for test 3
8014         echo -n "Setting stripe for 1GB test file..."
8015         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8016         echo "done"
8017         echo -n "Sizing 1GB test file..."
8018         # File size is 1GB + 3KB
8019         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8020         echo "done"
8021
8022         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8023         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8024         if (( avail > 524288 * OSTCOUNT )); then
8025                 echo -n "Migrating 1GB file..."
8026                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8027                         error "cannot migrate 1GB file"
8028                 echo "done"
8029                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8030                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8031                         error "cannot getstripe for 1GB file"
8032                 [ $stripe_count -eq 2 ] ||
8033                         error "unexpected stripe count $stripe_count != 2"
8034                 echo "done"
8035         fi
8036
8037         # Test 3: File is too large to fit within the available space on
8038         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8039         if [ $OSTCOUNT -ge 3 ]; then
8040                 # The required available space is calculated as
8041                 # file size (1GB + 3KB) / OST count (3).
8042                 local kb_per_ost=349526
8043
8044                 echo -n "Migrating 1GB file with limit..."
8045                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8046                         error "cannot migrate 1GB file with limit"
8047                 echo "done"
8048
8049                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8050                 echo -n "Verifying 1GB autostripe count with limited space..."
8051                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8052                         error "unexpected stripe count $stripe_count (min 3)"
8053                 echo "done"
8054         fi
8055
8056         # clean up
8057         rm -rf $dir
8058 }
8059 run_test 56xc "lfs migration autostripe"
8060
8061 test_56xd() {
8062         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8063
8064         local dir=$DIR/$tdir
8065         local f_mgrt=$dir/$tfile.mgrt
8066         local f_yaml=$dir/$tfile.yaml
8067         local f_copy=$dir/$tfile.copy
8068         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8069         local layout_copy="-c 2 -S 2M -i 1"
8070         local yamlfile=$dir/yamlfile
8071         local layout_before;
8072         local layout_after;
8073
8074         test_mkdir "$dir" || error "cannot create dir $dir"
8075         stack_trap "rm -rf $dir"
8076         $LFS setstripe $layout_yaml $f_yaml ||
8077                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8078         $LFS getstripe --yaml $f_yaml > $yamlfile
8079         $LFS setstripe $layout_copy $f_copy ||
8080                 error "cannot setstripe $f_copy with layout $layout_copy"
8081         touch $f_mgrt
8082         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8083
8084         # 1. test option --yaml
8085         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8086                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8087         layout_before=$(get_layout_param $f_yaml)
8088         layout_after=$(get_layout_param $f_mgrt)
8089         [ "$layout_after" == "$layout_before" ] ||
8090                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8091
8092         # 2. test option --copy
8093         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8094                 error "cannot migrate $f_mgrt with --copy $f_copy"
8095         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8096         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8097         [ "$layout_after" == "$layout_before" ] ||
8098                 error "lfs_migrate --copy: $layout_after != $layout_before"
8099 }
8100 run_test 56xd "check lfs_migrate --yaml and --copy support"
8101
8102 test_56xe() {
8103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8104
8105         local dir=$DIR/$tdir
8106         local f_comp=$dir/$tfile
8107         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8108         local layout_before=""
8109         local layout_after=""
8110
8111         test_mkdir "$dir" || error "cannot create dir $dir"
8112         stack_trap "rm -rf $dir"
8113         $LFS setstripe $layout $f_comp ||
8114                 error "cannot setstripe $f_comp with layout $layout"
8115         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8116         dd if=/dev/zero of=$f_comp bs=1M count=4
8117
8118         # 1. migrate a comp layout file by lfs_migrate
8119         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8120         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8121         [ "$layout_before" == "$layout_after" ] ||
8122                 error "lfs_migrate: $layout_before != $layout_after"
8123
8124         # 2. migrate a comp layout file by lfs migrate
8125         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8126         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8127         [ "$layout_before" == "$layout_after" ] ||
8128                 error "lfs migrate: $layout_before != $layout_after"
8129 }
8130 run_test 56xe "migrate a composite layout file"
8131
8132 test_56xf() {
8133         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8134
8135         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8136                 skip "Need server version at least 2.13.53"
8137
8138         local dir=$DIR/$tdir
8139         local f_comp=$dir/$tfile
8140         local layout="-E 1M -c1 -E -1 -c2"
8141         local fid_before=""
8142         local fid_after=""
8143
8144         test_mkdir "$dir" || error "cannot create dir $dir"
8145         stack_trap "rm -rf $dir"
8146         $LFS setstripe $layout $f_comp ||
8147                 error "cannot setstripe $f_comp with layout $layout"
8148         fid_before=$($LFS getstripe --fid $f_comp)
8149         dd if=/dev/zero of=$f_comp bs=1M count=4
8150
8151         # 1. migrate a comp layout file to a comp layout
8152         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8153         fid_after=$($LFS getstripe --fid $f_comp)
8154         [ "$fid_before" == "$fid_after" ] ||
8155                 error "comp-to-comp migrate: $fid_before != $fid_after"
8156
8157         # 2. migrate a comp layout file to a plain layout
8158         $LFS migrate -c2 $f_comp ||
8159                 error "cannot migrate $f_comp by lfs migrate"
8160         fid_after=$($LFS getstripe --fid $f_comp)
8161         [ "$fid_before" == "$fid_after" ] ||
8162                 error "comp-to-plain migrate: $fid_before != $fid_after"
8163
8164         # 3. migrate a plain layout file to a comp layout
8165         $LFS migrate $layout $f_comp ||
8166                 error "cannot migrate $f_comp by lfs migrate"
8167         fid_after=$($LFS getstripe --fid $f_comp)
8168         [ "$fid_before" == "$fid_after" ] ||
8169                 error "plain-to-comp migrate: $fid_before != $fid_after"
8170 }
8171 run_test 56xf "FID is not lost during migration of a composite layout file"
8172
8173 check_file_ost_range() {
8174         local file="$1"
8175         shift
8176         local range="$*"
8177         local -a file_range
8178         local idx
8179
8180         file_range=($($LFS getstripe -y "$file" |
8181                 awk '/l_ost_idx:/ { print $NF }'))
8182
8183         if [[ "${#file_range[@]}" = 0 ]]; then
8184                 echo "No osts found for $file"
8185                 return 1
8186         fi
8187
8188         for idx in "${file_range[@]}"; do
8189                 [[ " $range " =~ " $idx " ]] ||
8190                         return 1
8191         done
8192
8193         return 0
8194 }
8195
8196 sub_test_56xg() {
8197         local stripe_opt="$1"
8198         local pool="$2"
8199         shift 2
8200         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8201
8202         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8203                 error "Fail to migrate $tfile on $pool"
8204         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8205                 error "$tfile is not in pool $pool"
8206         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8207                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8208 }
8209
8210 test_56xg() {
8211         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8212         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8213         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8214                 skip "Need MDS version newer than 2.14.52"
8215
8216         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8217         local -a pool_ranges=("0 0" "1 1" "0 1")
8218
8219         # init pools
8220         for i in "${!pool_names[@]}"; do
8221                 pool_add ${pool_names[$i]} ||
8222                         error "pool_add failed (pool: ${pool_names[$i]})"
8223                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8224                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8225         done
8226
8227         # init the file to migrate
8228         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8229                 error "Unable to create $tfile on OST1"
8230         stack_trap "rm -f $DIR/$tfile"
8231         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8232                 error "Unable to write on $tfile"
8233
8234         echo "1. migrate $tfile on pool ${pool_names[0]}"
8235         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8236
8237         echo "2. migrate $tfile on pool ${pool_names[2]}"
8238         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8239
8240         echo "3. migrate $tfile on pool ${pool_names[1]}"
8241         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8242
8243         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8244         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8245         echo
8246
8247         # Clean pools
8248         destroy_test_pools ||
8249                 error "pool_destroy failed"
8250 }
8251 run_test 56xg "lfs migrate pool support"
8252
8253 test_56xh() {
8254         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8255
8256         local size_mb=25
8257         local file1=$DIR/$tfile
8258         local tmp1=$TMP/$tfile.tmp
8259
8260         $LFS setstripe -c 2 $file1
8261
8262         stack_trap "rm -f $file1 $tmp1"
8263         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8264                         error "error creating $tmp1"
8265         ls -lsh $tmp1
8266         cp $tmp1 $file1
8267
8268         local start=$SECONDS
8269
8270         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8271                 error "migrate failed rc = $?"
8272
8273         local elapsed=$((SECONDS - start))
8274
8275         # with 1MB/s, elapsed should equal size_mb
8276         (( elapsed >= size_mb * 95 / 100 )) ||
8277                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8278
8279         (( elapsed <= size_mb * 120 / 100 )) ||
8280                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8281
8282         (( elapsed <= size_mb * 350 / 100 )) ||
8283                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8284
8285         stripe=$($LFS getstripe -c $file1)
8286         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8287         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8288
8289         # Clean up file (since it is multiple MB)
8290         rm -f $file1 $tmp1
8291 }
8292 run_test 56xh "lfs migrate bandwidth limitation support"
8293
8294 test_56xi() {
8295         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8296         verify_yaml_available || skip_env "YAML verification not installed"
8297
8298         local size_mb=5
8299         local file1=$DIR/$tfile.1
8300         local file2=$DIR/$tfile.2
8301         local file3=$DIR/$tfile.3
8302         local output_file=$DIR/$tfile.out
8303         local tmp1=$TMP/$tfile.tmp
8304
8305         $LFS setstripe -c 2 $file1
8306         $LFS setstripe -c 2 $file2
8307         $LFS setstripe -c 2 $file3
8308
8309         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8310         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8311                         error "error creating $tmp1"
8312         ls -lsh $tmp1
8313         cp $tmp1 $file1
8314         cp $tmp1 $file2
8315         cp $tmp1 $file3
8316
8317         $LFS migrate --stats --stats-interval=1 \
8318                 -c 1 $file1 $file2 $file3 1> $output_file ||
8319                 error "migrate failed rc = $?"
8320
8321         cat $output_file
8322         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8323
8324         # Clean up file (since it is multiple MB)
8325         rm -f $file1 $file2 $file3 $tmp1 $output_file
8326 }
8327 run_test 56xi "lfs migrate stats support"
8328
8329 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8330         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8331
8332         local file=$DIR/$tfile
8333         local linkdir=$DIR/$tdir
8334
8335         test_mkdir $linkdir || error "fail to create $linkdir"
8336         $LFS setstripe -i 0 -c 1 -S1M $file
8337         stack_trap "rm -rf $file $linkdir"
8338         dd if=/dev/urandom of=$file bs=1M count=10 ||
8339                 error "fail to create $file"
8340
8341         # Create file links
8342         local cpts
8343         local threads_max
8344         local nlinks
8345
8346         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8347         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8348         (( nlinks = thread_max * 3 / 2 / cpts))
8349
8350         echo "create $nlinks hard links of $file"
8351         createmany -l $file $linkdir/link $nlinks
8352
8353         # Parallel migrates (should not block)
8354         local i
8355         for ((i = 0; i < nlinks; i++)); do
8356                 echo $linkdir/link$i
8357         done | xargs -n1 -P $nlinks $LFS migrate -c2
8358
8359         local stripe_count
8360         stripe_count=$($LFS getstripe -c $file) ||
8361                 error "fail to get stripe count on $file"
8362
8363         ((stripe_count == 2)) ||
8364                 error "fail to migrate $file (stripe_count = $stripe_count)"
8365 }
8366 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8367
8368 test_56xk() {
8369         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8370
8371         local size_mb=5
8372         local file1=$DIR/$tfile
8373
8374         stack_trap "rm -f $file1"
8375         $LFS setstripe -c 1 $file1
8376         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8377                 error "error creating $file1"
8378         $LFS mirror extend -N $file1 || error "can't mirror"
8379         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8380                 error "can't dd"
8381         $LFS getstripe $file1 | grep stale ||
8382                 error "one component must be stale"
8383
8384         local start=$SECONDS
8385         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8386                 error "migrate failed rc = $?"
8387         local elapsed=$((SECONDS - start))
8388         $LFS getstripe $file1 | grep stale &&
8389                 error "all components must be sync"
8390
8391         # with 1MB/s, elapsed should equal size_mb
8392         (( elapsed >= size_mb * 95 / 100 )) ||
8393                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8394
8395         (( elapsed <= size_mb * 120 / 100 )) ||
8396                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8397
8398         (( elapsed <= size_mb * 350 / 100 )) ||
8399                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8400 }
8401 run_test 56xk "lfs mirror resync bandwidth limitation support"
8402
8403 test_56xl() {
8404         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8405         verify_yaml_available || skip_env "YAML verification not installed"
8406
8407         local size_mb=5
8408         local file1=$DIR/$tfile.1
8409         local output_file=$DIR/$tfile.out
8410
8411         stack_trap "rm -f $file1"
8412         $LFS setstripe -c 1 $file1
8413         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8414                 error "error creating $file1"
8415         $LFS mirror extend -N $file1 || error "can't mirror"
8416         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8417                 error "can't dd"
8418         $LFS getstripe $file1 | grep stale ||
8419                 error "one component must be stale"
8420         $LFS getstripe $file1
8421
8422         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8423                 error "resync failed rc = $?"
8424         $LFS getstripe $file1 | grep stale &&
8425                 error "all components must be sync"
8426
8427         cat $output_file
8428         cat $output_file | verify_yaml || error "stats is not valid YAML"
8429 }
8430 run_test 56xl "lfs mirror resync stats support"
8431
8432 test_56y() {
8433         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8434                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8435
8436         local res=""
8437         local dir=$DIR/$tdir
8438         local f1=$dir/file1
8439         local f2=$dir/file2
8440
8441         test_mkdir -p $dir || error "creating dir $dir"
8442         touch $f1 || error "creating std file $f1"
8443         $MULTIOP $f2 H2c || error "creating released file $f2"
8444
8445         # a directory can be raid0, so ask only for files
8446         res=$($LFS find $dir -L raid0 -type f | wc -l)
8447         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8448
8449         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8450         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8451
8452         # only files can be released, so no need to force file search
8453         res=$($LFS find $dir -L released)
8454         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8455
8456         res=$($LFS find $dir -type f \! -L released)
8457         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8458 }
8459 run_test 56y "lfs find -L raid0|released"
8460
8461 test_56z() { # LU-4824
8462         # This checks to make sure 'lfs find' continues after errors
8463         # There are two classes of errors that should be caught:
8464         # - If multiple paths are provided, all should be searched even if one
8465         #   errors out
8466         # - If errors are encountered during the search, it should not terminate
8467         #   early
8468         local dir=$DIR/$tdir
8469         local i
8470
8471         test_mkdir $dir
8472         for i in d{0..9}; do
8473                 test_mkdir $dir/$i
8474                 touch $dir/$i/$tfile
8475         done
8476         $LFS find $DIR/non_existent_dir $dir &&
8477                 error "$LFS find did not return an error"
8478         # Make a directory unsearchable. This should NOT be the last entry in
8479         # directory order.  Arbitrarily pick the 6th entry
8480         chmod 700 $($LFS find $dir -type d | sed '6!d')
8481
8482         $RUNAS $LFS find $DIR/non_existent $dir
8483         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8484
8485         # The user should be able to see 10 directories and 9 files
8486         (( count == 19 )) ||
8487                 error "$LFS find found $count != 19 entries after error"
8488 }
8489 run_test 56z "lfs find should continue after an error"
8490
8491 test_56aa() { # LU-5937
8492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8493
8494         local dir=$DIR/$tdir
8495
8496         mkdir $dir
8497         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8498
8499         createmany -o $dir/striped_dir/${tfile}- 1024
8500         local dirs=$($LFS find --size +8k $dir/)
8501
8502         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8503 }
8504 run_test 56aa "lfs find --size under striped dir"
8505
8506 test_56ab() { # LU-10705
8507         test_mkdir $DIR/$tdir
8508         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8509         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8510         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8511         # Flush writes to ensure valid blocks.  Need to be more thorough for
8512         # ZFS, since blocks are not allocated/returned to client immediately.
8513         sync_all_data
8514         wait_zfs_commit ost1 2
8515         cancel_lru_locks osc
8516         ls -ls $DIR/$tdir
8517
8518         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8519
8520         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8521
8522         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8523         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8524
8525         rm -f $DIR/$tdir/$tfile.[123]
8526 }
8527 run_test 56ab "lfs find --blocks"
8528
8529 # LU-11188
8530 test_56aca() {
8531         local dir="$DIR/$tdir"
8532         local perms=(001 002 003 004 005 006 007
8533                      010 020 030 040 050 060 070
8534                      100 200 300 400 500 600 700
8535                      111 222 333 444 555 666 777)
8536         local perm_minus=(8 8 4 8 4 4 2
8537                           8 8 4 8 4 4 2
8538                           8 8 4 8 4 4 2
8539                           4 4 2 4 2 2 1)
8540         local perm_slash=(8  8 12  8 12 12 14
8541                           8  8 12  8 12 12 14
8542                           8  8 12  8 12 12 14
8543                          16 16 24 16 24 24 28)
8544
8545         test_mkdir "$dir"
8546         for perm in ${perms[*]}; do
8547                 touch "$dir/$tfile.$perm"
8548                 chmod $perm "$dir/$tfile.$perm"
8549         done
8550
8551         for ((i = 0; i < ${#perms[*]}; i++)); do
8552                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8553                 (( $num == 1 )) ||
8554                         error "lfs find -perm ${perms[i]}:"\
8555                               "$num != 1"
8556
8557                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8558                 (( $num == ${perm_minus[i]} )) ||
8559                         error "lfs find -perm -${perms[i]}:"\
8560                               "$num != ${perm_minus[i]}"
8561
8562                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8563                 (( $num == ${perm_slash[i]} )) ||
8564                         error "lfs find -perm /${perms[i]}:"\
8565                               "$num != ${perm_slash[i]}"
8566         done
8567 }
8568 run_test 56aca "check lfs find -perm with octal representation"
8569
8570 test_56acb() {
8571         local dir=$DIR/$tdir
8572         # p is the permission of write and execute for user, group and other
8573         # without the umask. It is used to test +wx.
8574         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8575         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8576         local symbolic=(+t  a+t u+t g+t o+t
8577                         g+s u+s o+s +s o+sr
8578                         o=r,ug+o,u+w
8579                         u+ g+ o+ a+ ugo+
8580                         u- g- o- a- ugo-
8581                         u= g= o= a= ugo=
8582                         o=r,ug+o,u+w u=r,a+u,u+w
8583                         g=r,ugo=g,u+w u+x,+X +X
8584                         u+x,u+X u+X u+x,g+X o+r,+X
8585                         u+x,go+X +wx +rwx)
8586
8587         test_mkdir $dir
8588         for perm in ${perms[*]}; do
8589                 touch "$dir/$tfile.$perm"
8590                 chmod $perm "$dir/$tfile.$perm"
8591         done
8592
8593         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8594                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8595
8596                 (( $num == 1 )) ||
8597                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8598         done
8599 }
8600 run_test 56acb "check lfs find -perm with symbolic representation"
8601
8602 test_56acc() {
8603         local dir=$DIR/$tdir
8604         local tests="17777 787 789 abcd
8605                 ug=uu ug=a ug=gu uo=ou urw
8606                 u+xg+x a=r,u+x,"
8607
8608         test_mkdir $dir
8609         for err in $tests; do
8610                 if $LFS find $dir -perm $err 2>/dev/null; then
8611                         error "lfs find -perm $err: parsing should have failed"
8612                 fi
8613         done
8614 }
8615 run_test 56acc "check parsing error for lfs find -perm"
8616
8617 test_56ba() {
8618         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8619                 skip "Need MDS version at least 2.10.50"
8620
8621         # Create composite files with one component
8622         local dir=$DIR/$tdir
8623
8624         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8625         # Create composite files with three components
8626         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8627         # LU-16904 Create plain layout files
8628         lfs setstripe -c 1 $dir/$tfile-{1..10}
8629
8630         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8631
8632         [[ $nfiles == 10 ]] ||
8633                 error "lfs find -E 1M found $nfiles != 10 files"
8634
8635         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8636         [[ $nfiles == 25 ]] ||
8637                 error "lfs find ! -E 1M found $nfiles != 25 files"
8638
8639         # All files have a component that starts at 0
8640         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8641         [[ $nfiles == 35 ]] ||
8642                 error "lfs find --component-start 0 - $nfiles != 35 files"
8643
8644         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8645         [[ $nfiles == 15 ]] ||
8646                 error "lfs find --component-start 2M - $nfiles != 15 files"
8647
8648         # All files created here have a componenet that does not starts at 2M
8649         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8650         [[ $nfiles == 35 ]] ||
8651                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8652
8653         # Find files with a specified number of components
8654         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8655         [[ $nfiles == 15 ]] ||
8656                 error "lfs find --component-count 3 - $nfiles != 15 files"
8657
8658         # Remember non-composite files have a component count of zero
8659         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8660         [[ $nfiles == 10 ]] ||
8661                 error "lfs find --component-count 0 - $nfiles != 10 files"
8662
8663         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8664         [[ $nfiles == 20 ]] ||
8665                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8666
8667         # All files have a flag called "init"
8668         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8669         [[ $nfiles == 35 ]] ||
8670                 error "lfs find --component-flags init - $nfiles != 35 files"
8671
8672         # Multi-component files will have a component not initialized
8673         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8674         [[ $nfiles == 15 ]] ||
8675                 error "lfs find !--component-flags init - $nfiles != 15 files"
8676
8677         rm -rf $dir
8678
8679 }
8680 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8681
8682 test_56ca() {
8683         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8684                 skip "Need MDS version at least 2.10.57"
8685
8686         local td=$DIR/$tdir
8687         local tf=$td/$tfile
8688         local dir
8689         local nfiles
8690         local cmd
8691         local i
8692         local j
8693
8694         # create mirrored directories and mirrored files
8695         mkdir $td || error "mkdir $td failed"
8696         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8697         createmany -o $tf- 10 || error "create $tf- failed"
8698
8699         for i in $(seq 2); do
8700                 dir=$td/dir$i
8701                 mkdir $dir || error "mkdir $dir failed"
8702                 $LFS mirror create -N$((3 + i)) $dir ||
8703                         error "create mirrored dir $dir failed"
8704                 createmany -o $dir/$tfile- 10 ||
8705                         error "create $dir/$tfile- failed"
8706         done
8707
8708         # change the states of some mirrored files
8709         echo foo > $tf-6
8710         for i in $(seq 2); do
8711                 dir=$td/dir$i
8712                 for j in $(seq 4 9); do
8713                         echo foo > $dir/$tfile-$j
8714                 done
8715         done
8716
8717         # find mirrored files with specific mirror count
8718         cmd="$LFS find --mirror-count 3 --type f $td"
8719         nfiles=$($cmd | wc -l)
8720         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8721
8722         cmd="$LFS find ! --mirror-count 3 --type f $td"
8723         nfiles=$($cmd | wc -l)
8724         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8725
8726         cmd="$LFS find --mirror-count +2 --type f $td"
8727         nfiles=$($cmd | wc -l)
8728         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8729
8730         cmd="$LFS find --mirror-count -6 --type f $td"
8731         nfiles=$($cmd | wc -l)
8732         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8733
8734         # find mirrored files with specific file state
8735         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8736         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8737
8738         cmd="$LFS find --mirror-state=ro --type f $td"
8739         nfiles=$($cmd | wc -l)
8740         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8741
8742         cmd="$LFS find ! --mirror-state=ro --type f $td"
8743         nfiles=$($cmd | wc -l)
8744         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8745
8746         cmd="$LFS find --mirror-state=wp --type f $td"
8747         nfiles=$($cmd | wc -l)
8748         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8749
8750         cmd="$LFS find ! --mirror-state=sp --type f $td"
8751         nfiles=$($cmd | wc -l)
8752         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8753 }
8754 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8755
8756 test_56da() { # LU-14179
8757         local path=$DIR/$tdir
8758
8759         test_mkdir $path
8760         cd $path
8761
8762         local longdir=$(str_repeat 'a' 255)
8763
8764         for i in {1..15}; do
8765                 path=$path/$longdir
8766                 test_mkdir $longdir
8767                 cd $longdir
8768         done
8769
8770         local len=${#path}
8771         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8772
8773         test_mkdir $lastdir
8774         cd $lastdir
8775         # PATH_MAX-1
8776         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8777
8778         # NAME_MAX
8779         touch $(str_repeat 'f' 255)
8780
8781         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8782                 error "lfs find reported an error"
8783
8784         rm -rf $DIR/$tdir
8785 }
8786 run_test 56da "test lfs find with long paths"
8787
8788 test_56ea() { #LU-10378
8789         local path=$DIR/$tdir
8790         local pool=$TESTNAME
8791
8792         # Create ost pool
8793         pool_add $pool || error "pool_add $pool failed"
8794         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8795                 error "adding targets to $pool failed"
8796
8797         # Set default pool on directory before creating file
8798         mkdir $path || error "mkdir $path failed"
8799         $LFS setstripe -p $pool $path ||
8800                 error "set OST pool on $pool failed"
8801         touch $path/$tfile || error "touch $path/$tfile failed"
8802
8803         # Compare basic file attributes from -printf and stat
8804         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8805         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8806
8807         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8808                 error "Attrs from lfs find and stat don't match"
8809
8810         # Compare Lustre attributes from lfs find and lfs getstripe
8811         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8812         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8813         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8814         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8815         local fpool=$($LFS getstripe --pool $path/$tfile)
8816         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8817
8818         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8819                 error "Attrs from lfs find and lfs getstripe don't match"
8820
8821         # Verify behavior for unknown escape/format sequences
8822         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8823
8824         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8825                 error "Escape/format codes don't match"
8826 }
8827 run_test 56ea "test lfs find -printf option"
8828
8829 test_56eb() {
8830         local dir=$DIR/$tdir
8831         local subdir_1=$dir/subdir_1
8832
8833         test_mkdir -p $subdir_1
8834         ln -s subdir_1 $dir/link_1
8835
8836         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8837                 error "symlink is not followed"
8838
8839         $LFS getstripe --no-follow $dir |
8840                 grep "^$dir/link_1 has no stripe info$" ||
8841                 error "symlink should not have stripe info"
8842
8843         touch $dir/testfile
8844         ln -s testfile $dir/file_link_2
8845
8846         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8847                 error "symlink is not followed"
8848
8849         $LFS getstripe --no-follow $dir |
8850                 grep "^$dir/file_link_2 has no stripe info$" ||
8851                 error "symlink should not have stripe info"
8852 }
8853 run_test 56eb "check lfs getstripe on symlink"
8854
8855 test_56ec() {
8856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8857         local dir=$DIR/$tdir
8858         local srcfile=$dir/srcfile
8859         local srcyaml=$dir/srcyaml
8860         local destfile=$dir/destfile
8861
8862         test_mkdir -p $dir
8863
8864         $LFS setstripe -i 1 $srcfile
8865         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8866         # if the setstripe yaml parsing fails for any reason, the command can
8867         # randomly assign the correct OST index, leading to an erroneous
8868         # success. but the chance of false success is low enough that a
8869         # regression should still be quickly caught.
8870         $LFS setstripe --yaml=$srcyaml $destfile
8871
8872         local srcindex=$($LFS getstripe -i $srcfile)
8873         local destindex=$($LFS getstripe -i $destfile)
8874
8875         if [[ ! $srcindex -eq $destindex ]]; then
8876                 error "setstripe did not set OST index correctly"
8877         fi
8878 }
8879 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8880
8881 test_56eda() {
8882         local dir=$DIR/$tdir
8883         local subdir=$dir/subdir
8884         local file1=$dir/$tfile
8885         local file2=$dir/$tfile\2
8886         local link=$dir/$tfile-link
8887         local nfiles
8888
8889         test_mkdir -p $dir
8890         $LFS setdirstripe -c1 $subdir
8891         touch $file1
8892         touch $file2
8893         ln $file2 $link
8894
8895         nfiles=$($LFS find --links 1 $dir | wc -l)
8896         (( $nfiles == 1 )) ||
8897                 error "lfs find --links expected 1 file, got $nfiles"
8898
8899         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8900         (( $nfiles == 2 )) ||
8901                 error "lfs find --links expected 2 files, got $nfiles"
8902
8903         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8904         (( $nfiles == 1 )) ||
8905                 error "lfs find --links expected 1 directory, got $nfiles"
8906 }
8907 run_test 56eda "check lfs find --links"
8908
8909 test_56edb() {
8910         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8911
8912         local dir=$DIR/$tdir
8913         local stripedir=$dir/stripedir
8914         local nfiles
8915
8916         test_mkdir -p $dir
8917
8918         $LFS setdirstripe -c2 $stripedir
8919
8920         $LFS getdirstripe $stripedir
8921
8922         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8923         (( $nfiles == 1 )) ||
8924                 error "lfs find --links expected 1 directory, got $nfiles"
8925 }
8926 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8927
8928 test_56ef() {
8929         local dir=$DIR/$tdir
8930         local dir1=$dir/d1
8931         local dir2=$dir/d2
8932         local nfiles
8933
8934         test_mkdir -p $dir
8935
8936         mkdir $dir1
8937         mkdir $dir2
8938
8939         touch $dir1/f
8940         touch $dir2/f
8941
8942         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8943         (( $nfiles == 2 )) ||
8944                 error "(1) lfs find expected 2 files, got $nfiles"
8945
8946         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8947         (( $nfiles == 2 )) ||
8948                 error "(2) lfs find expected 2 files, got $nfiles"
8949
8950         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8951         (( $nfiles == 2 )) ||
8952                 error "(3) lfs find expected 2 files, got $nfiles"
8953 }
8954 run_test 56ef "lfs find with multiple paths"
8955
8956 test_57a() {
8957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8958         # note test will not do anything if MDS is not local
8959         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8960                 skip_env "ldiskfs only test"
8961         fi
8962         remote_mds_nodsh && skip "remote MDS with nodsh"
8963
8964         local MNTDEV="osd*.*MDT*.mntdev"
8965         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8966         [ -z "$DEV" ] && error "can't access $MNTDEV"
8967         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8968                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8969                         error "can't access $DEV"
8970                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8971                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8972                 rm $TMP/t57a.dump
8973         done
8974 }
8975 run_test 57a "verify MDS filesystem created with large inodes =="
8976
8977 test_57b() {
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8980                 skip_env "ldiskfs only test"
8981         fi
8982         remote_mds_nodsh && skip "remote MDS with nodsh"
8983
8984         local dir=$DIR/$tdir
8985         local filecount=100
8986         local file1=$dir/f1
8987         local fileN=$dir/f$filecount
8988
8989         rm -rf $dir || error "removing $dir"
8990         test_mkdir -c1 $dir
8991         local mdtidx=$($LFS getstripe -m $dir)
8992         local mdtname=MDT$(printf %04x $mdtidx)
8993         local facet=mds$((mdtidx + 1))
8994
8995         echo "mcreating $filecount files"
8996         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8997
8998         # verify that files do not have EAs yet
8999         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9000                 error "$file1 has an EA"
9001         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9002                 error "$fileN has an EA"
9003
9004         sync
9005         sleep 1
9006         df $dir  #make sure we get new statfs data
9007         local mdsfree=$(do_facet $facet \
9008                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9009         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9010         local file
9011
9012         echo "opening files to create objects/EAs"
9013         for file in $(seq -f $dir/f%g 1 $filecount); do
9014                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9015                         error "opening $file"
9016         done
9017
9018         # verify that files have EAs now
9019         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9020                 error "$file1 missing EA"
9021         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9022                 error "$fileN missing EA"
9023
9024         sleep 1  #make sure we get new statfs data
9025         df $dir
9026         local mdsfree2=$(do_facet $facet \
9027                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9028         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9029
9030         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9031                 if [ "$mdsfree" != "$mdsfree2" ]; then
9032                         error "MDC before $mdcfree != after $mdcfree2"
9033                 else
9034                         echo "MDC before $mdcfree != after $mdcfree2"
9035                         echo "unable to confirm if MDS has large inodes"
9036                 fi
9037         fi
9038         rm -rf $dir
9039 }
9040 run_test 57b "default LOV EAs are stored inside large inodes ==="
9041
9042 test_58() {
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044         [ -z "$(which wiretest 2>/dev/null)" ] &&
9045                         skip_env "could not find wiretest"
9046
9047         wiretest
9048 }
9049 run_test 58 "verify cross-platform wire constants =============="
9050
9051 test_59() {
9052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9053
9054         echo "touch 130 files"
9055         createmany -o $DIR/f59- 130
9056         echo "rm 130 files"
9057         unlinkmany $DIR/f59- 130
9058         sync
9059         # wait for commitment of removal
9060         wait_delete_completed
9061 }
9062 run_test 59 "verify cancellation of llog records async ========="
9063
9064 TEST60_HEAD="test_60 run $RANDOM"
9065 test_60a() {
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         remote_mgs_nodsh && skip "remote MGS with nodsh"
9068         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9069                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9070                         skip_env "missing subtest run-llog.sh"
9071
9072         log "$TEST60_HEAD - from kernel mode"
9073         do_facet mgs "$LCTL dk > /dev/null"
9074         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9075         do_facet mgs $LCTL dk > $TMP/$tfile
9076
9077         # LU-6388: test llog_reader
9078         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9079         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9080         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9081                         skip_env "missing llog_reader"
9082         local fstype=$(facet_fstype mgs)
9083         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9084                 skip_env "Only for ldiskfs or zfs type mgs"
9085
9086         local mntpt=$(facet_mntpt mgs)
9087         local mgsdev=$(mgsdevname 1)
9088         local fid_list
9089         local fid
9090         local rec_list
9091         local rec
9092         local rec_type
9093         local obj_file
9094         local path
9095         local seq
9096         local oid
9097         local pass=true
9098
9099         #get fid and record list
9100         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9101                 tail -n 4))
9102         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9103                 tail -n 4))
9104         #remount mgs as ldiskfs or zfs type
9105         stop mgs || error "stop mgs failed"
9106         mount_fstype mgs || error "remount mgs failed"
9107         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9108                 fid=${fid_list[i]}
9109                 rec=${rec_list[i]}
9110                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9111                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9112                 oid=$((16#$oid))
9113
9114                 case $fstype in
9115                         ldiskfs )
9116                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9117                         zfs )
9118                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9119                 esac
9120                 echo "obj_file is $obj_file"
9121                 do_facet mgs $llog_reader $obj_file
9122
9123                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9124                         awk '{ print $3 }' | sed -e "s/^type=//g")
9125                 if [ $rec_type != $rec ]; then
9126                         echo "FAILED test_60a wrong record type $rec_type," \
9127                               "should be $rec"
9128                         pass=false
9129                         break
9130                 fi
9131
9132                 #check obj path if record type is LLOG_LOGID_MAGIC
9133                 if [ "$rec" == "1064553b" ]; then
9134                         path=$(do_facet mgs $llog_reader $obj_file |
9135                                 grep "path=" | awk '{ print $NF }' |
9136                                 sed -e "s/^path=//g")
9137                         if [ $obj_file != $mntpt/$path ]; then
9138                                 echo "FAILED test_60a wrong obj path" \
9139                                       "$montpt/$path, should be $obj_file"
9140                                 pass=false
9141                                 break
9142                         fi
9143                 fi
9144         done
9145         rm -f $TMP/$tfile
9146         #restart mgs before "error", otherwise it will block the next test
9147         stop mgs || error "stop mgs failed"
9148         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9149         $pass || error "test failed, see FAILED test_60a messages for specifics"
9150 }
9151 run_test 60a "llog_test run from kernel module and test llog_reader"
9152
9153 test_60b() { # bug 6411
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155
9156         dmesg > $DIR/$tfile
9157         LLOG_COUNT=$(do_facet mgs dmesg |
9158                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9159                           /llog_[a-z]*.c:[0-9]/ {
9160                                 if (marker)
9161                                         from_marker++
9162                                 from_begin++
9163                           }
9164                           END {
9165                                 if (marker)
9166                                         print from_marker
9167                                 else
9168                                         print from_begin
9169                           }")
9170
9171         [[ $LLOG_COUNT -gt 120 ]] &&
9172                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9173 }
9174 run_test 60b "limit repeated messages from CERROR/CWARN"
9175
9176 test_60c() {
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178
9179         echo "create 5000 files"
9180         createmany -o $DIR/f60c- 5000
9181 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9182         lctl set_param fail_loc=0x80000137
9183         unlinkmany $DIR/f60c- 5000
9184         lctl set_param fail_loc=0
9185 }
9186 run_test 60c "unlink file when mds full"
9187
9188 test_60d() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190
9191         SAVEPRINTK=$(lctl get_param -n printk)
9192         # verify "lctl mark" is even working"
9193         MESSAGE="test message ID $RANDOM $$"
9194         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9195         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9196
9197         lctl set_param printk=0 || error "set lnet.printk failed"
9198         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9199         MESSAGE="new test message ID $RANDOM $$"
9200         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9201         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9202         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9203
9204         lctl set_param -n printk="$SAVEPRINTK"
9205 }
9206 run_test 60d "test printk console message masking"
9207
9208 test_60e() {
9209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9210         remote_mds_nodsh && skip "remote MDS with nodsh"
9211
9212         touch $DIR/$tfile
9213 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9214         do_facet mds1 lctl set_param fail_loc=0x15b
9215         rm $DIR/$tfile
9216 }
9217 run_test 60e "no space while new llog is being created"
9218
9219 test_60f() {
9220         local old_path=$($LCTL get_param -n debug_path)
9221
9222         stack_trap "$LCTL set_param debug_path=$old_path"
9223         stack_trap "rm -f $TMP/$tfile*"
9224         rm -f $TMP/$tfile* 2> /dev/null
9225         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9226         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9227         test_mkdir $DIR/$tdir
9228         # retry in case the open is cached and not released
9229         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9230                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9231                 sleep 0.1
9232         done
9233         ls $TMP/$tfile*
9234         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9235 }
9236 run_test 60f "change debug_path works"
9237
9238 test_60g() {
9239         local pid
9240         local i
9241
9242         test_mkdir -c $MDSCOUNT $DIR/$tdir
9243
9244         (
9245                 local index=0
9246                 while true; do
9247                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9248                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9249                                 2>/dev/null
9250                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9251                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9252                         index=$((index + 1))
9253                 done
9254         ) &
9255
9256         pid=$!
9257
9258         for i in {0..100}; do
9259                 # define OBD_FAIL_OSD_TXN_START    0x19a
9260                 local index=$((i % MDSCOUNT + 1))
9261
9262                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9263                         > /dev/null
9264                 sleep 0.01
9265         done
9266
9267         kill -9 $pid
9268
9269         for i in $(seq $MDSCOUNT); do
9270                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9271         done
9272
9273         mkdir $DIR/$tdir/new || error "mkdir failed"
9274         rmdir $DIR/$tdir/new || error "rmdir failed"
9275
9276         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9277                 -t namespace
9278         for i in $(seq $MDSCOUNT); do
9279                 wait_update_facet mds$i "$LCTL get_param -n \
9280                         mdd.$(facet_svc mds$i).lfsck_namespace |
9281                         awk '/^status/ { print \\\$2 }'" "completed"
9282         done
9283
9284         ls -R $DIR/$tdir
9285         rm -rf $DIR/$tdir || error "rmdir failed"
9286 }
9287 run_test 60g "transaction abort won't cause MDT hung"
9288
9289 test_60h() {
9290         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9291                 skip "Need MDS version at least 2.12.52"
9292         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9293
9294         local f
9295
9296         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9297         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9298         for fail_loc in 0x80000188 0x80000189; do
9299                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9300                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9301                         error "mkdir $dir-$fail_loc failed"
9302                 for i in {0..10}; do
9303                         # create may fail on missing stripe
9304                         echo $i > $DIR/$tdir-$fail_loc/$i
9305                 done
9306                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9307                         error "getdirstripe $tdir-$fail_loc failed"
9308                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9309                         error "migrate $tdir-$fail_loc failed"
9310                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9311                         error "getdirstripe $tdir-$fail_loc failed"
9312                 pushd $DIR/$tdir-$fail_loc
9313                 for f in *; do
9314                         echo $f | cmp $f - || error "$f data mismatch"
9315                 done
9316                 popd
9317                 rm -rf $DIR/$tdir-$fail_loc
9318         done
9319 }
9320 run_test 60h "striped directory with missing stripes can be accessed"
9321
9322 function t60i_load() {
9323         mkdir $DIR/$tdir
9324         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9325         $LCTL set_param fail_loc=0x131c fail_val=1
9326         for ((i=0; i<5000; i++)); do
9327                 touch $DIR/$tdir/f$i
9328         done
9329 }
9330
9331 test_60i() {
9332         changelog_register || error "changelog_register failed"
9333         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9334         changelog_users $SINGLEMDS | grep -q $cl_user ||
9335                 error "User $cl_user not found in changelog_users"
9336         changelog_chmask "ALL"
9337         t60i_load &
9338         local PID=$!
9339         for((i=0; i<100; i++)); do
9340                 changelog_dump >/dev/null ||
9341                         error "can't read changelog"
9342         done
9343         kill $PID
9344         wait $PID
9345         changelog_deregister || error "changelog_deregister failed"
9346         $LCTL set_param fail_loc=0
9347 }
9348 run_test 60i "llog: new record vs reader race"
9349
9350 test_60j() {
9351         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9352                 skip "need MDS version at least 2.15.50"
9353         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9354         remote_mds_nodsh && skip "remote MDS with nodsh"
9355         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9356
9357         changelog_users $SINGLEMDS | grep "^cl" &&
9358                 skip "active changelog user"
9359
9360         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9361
9362         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9363                 skip_env "missing llog_reader"
9364
9365         mkdir_on_mdt0 $DIR/$tdir
9366
9367         local f=$DIR/$tdir/$tfile
9368         local mdt_dev
9369         local tmpfile
9370         local plain
9371
9372         changelog_register || error "cannot register changelog user"
9373
9374         # set changelog_mask to ALL
9375         changelog_chmask "ALL"
9376         changelog_clear
9377
9378         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9379         unlinkmany ${f}- 100 || error "unlinkmany failed"
9380
9381         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9382         mdt_dev=$(facet_device $SINGLEMDS)
9383
9384         do_facet $SINGLEMDS sync
9385         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9386                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9387                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9388
9389         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9390
9391         # if $tmpfile is not on EXT3 filesystem for some reason
9392         [[ ${plain:0:1} == 'O' ]] ||
9393                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9394
9395         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9396                 $mdt_dev; stat -c %s $tmpfile")
9397         echo "Truncate llog from $size to $((size - size % 8192))"
9398         size=$((size - size % 8192))
9399         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9400         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9401                 grep -c 'in bitmap only')
9402         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9403
9404         size=$((size - 9000))
9405         echo "Corrupt llog in the middle at $size"
9406         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9407                 count=333 conv=notrunc
9408         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9409                 grep -c 'next chunk')
9410         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9411 }
9412 run_test 60j "llog_reader reports corruptions"
9413
9414 test_61a() {
9415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9416
9417         f="$DIR/f61"
9418         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9419         cancel_lru_locks osc
9420         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9421         sync
9422 }
9423 run_test 61a "mmap() writes don't make sync hang ================"
9424
9425 test_61b() {
9426         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9427 }
9428 run_test 61b "mmap() of unstriped file is successful"
9429
9430 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9431 # Though this test is irrelevant anymore, it helped to reveal some
9432 # other grant bugs (LU-4482), let's keep it.
9433 test_63a() {   # was test_63
9434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9435
9436         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9437
9438         for i in `seq 10` ; do
9439                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9440                 sleep 5
9441                 kill $!
9442                 sleep 1
9443         done
9444
9445         rm -f $DIR/f63 || true
9446 }
9447 run_test 63a "Verify oig_wait interruption does not crash ======="
9448
9449 # bug 2248 - async write errors didn't return to application on sync
9450 # bug 3677 - async write errors left page locked
9451 test_63b() {
9452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9453
9454         debugsave
9455         lctl set_param debug=-1
9456
9457         # ensure we have a grant to do async writes
9458         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9459         rm $DIR/$tfile
9460
9461         sync    # sync lest earlier test intercept the fail_loc
9462
9463         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9464         lctl set_param fail_loc=0x80000406
9465         $MULTIOP $DIR/$tfile Owy && \
9466                 error "sync didn't return ENOMEM"
9467         sync; sleep 2; sync     # do a real sync this time to flush page
9468         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9469                 error "locked page left in cache after async error" || true
9470         debugrestore
9471 }
9472 run_test 63b "async write errors should be returned to fsync ==="
9473
9474 test_64a () {
9475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9476
9477         lfs df $DIR
9478         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9479 }
9480 run_test 64a "verify filter grant calculations (in kernel) ====="
9481
9482 test_64b () {
9483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9484
9485         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9486 }
9487 run_test 64b "check out-of-space detection on client"
9488
9489 test_64c() {
9490         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9491 }
9492 run_test 64c "verify grant shrink"
9493
9494 import_param() {
9495         local tgt=$1
9496         local param=$2
9497
9498         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9499 }
9500
9501 # this does exactly what osc_request.c:osc_announce_cached() does in
9502 # order to calculate max amount of grants to ask from server
9503 want_grant() {
9504         local tgt=$1
9505
9506         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9507         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9508
9509         ((rpc_in_flight++));
9510         nrpages=$((nrpages * rpc_in_flight))
9511
9512         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9513
9514         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9515
9516         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9517         local undirty=$((nrpages * PAGE_SIZE))
9518
9519         local max_extent_pages
9520         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9521         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9522         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9523         local grant_extent_tax
9524         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9525
9526         undirty=$((undirty + nrextents * grant_extent_tax))
9527
9528         echo $undirty
9529 }
9530
9531 # this is size of unit for grant allocation. It should be equal to
9532 # what tgt_grant.c:tgt_grant_chunk() calculates
9533 grant_chunk() {
9534         local tgt=$1
9535         local max_brw_size
9536         local grant_extent_tax
9537
9538         max_brw_size=$(import_param $tgt max_brw_size)
9539
9540         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9541
9542         echo $(((max_brw_size + grant_extent_tax) * 2))
9543 }
9544
9545 test_64d() {
9546         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9547                 skip "OST < 2.10.55 doesn't limit grants enough"
9548
9549         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9550
9551         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9552                 skip "no grant_param connect flag"
9553
9554         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9555
9556         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9557         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9558
9559
9560         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9561         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9562
9563         $LFS setstripe $DIR/$tfile -i 0 -c 1
9564         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9565         ddpid=$!
9566
9567         while kill -0 $ddpid; do
9568                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9569
9570                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9571                         kill $ddpid
9572                         error "cur_grant $cur_grant > $max_cur_granted"
9573                 fi
9574
9575                 sleep 1
9576         done
9577 }
9578 run_test 64d "check grant limit exceed"
9579
9580 check_grants() {
9581         local tgt=$1
9582         local expected=$2
9583         local msg=$3
9584         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9585
9586         ((cur_grants == expected)) ||
9587                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9588 }
9589
9590 round_up_p2() {
9591         echo $((($1 + $2 - 1) & ~($2 - 1)))
9592 }
9593
9594 test_64e() {
9595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9596         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9597                 skip "Need OSS version at least 2.11.56"
9598
9599         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9600         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9601         $LCTL set_param debug=+cache
9602
9603         # Remount client to reset grant
9604         remount_client $MOUNT || error "failed to remount client"
9605         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9606
9607         local init_grants=$(import_param $osc_tgt initial_grant)
9608
9609         check_grants $osc_tgt $init_grants "init grants"
9610
9611         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9612         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9613         local gbs=$(import_param $osc_tgt grant_block_size)
9614
9615         # write random number of bytes from max_brw_size / 4 to max_brw_size
9616         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9617         # align for direct io
9618         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9619         # round to grant consumption unit
9620         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9621
9622         local grants=$((wb_round_up + extent_tax))
9623
9624         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9625         stack_trap "rm -f $DIR/$tfile"
9626
9627         # define OBD_FAIL_TGT_NO_GRANT 0x725
9628         # make the server not grant more back
9629         do_facet ost1 $LCTL set_param fail_loc=0x725
9630         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9631
9632         do_facet ost1 $LCTL set_param fail_loc=0
9633
9634         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9635
9636         rm -f $DIR/$tfile || error "rm failed"
9637
9638         # Remount client to reset grant
9639         remount_client $MOUNT || error "failed to remount client"
9640         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9641
9642         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9643
9644         # define OBD_FAIL_TGT_NO_GRANT 0x725
9645         # make the server not grant more back
9646         do_facet ost1 $LCTL set_param fail_loc=0x725
9647         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9648         do_facet ost1 $LCTL set_param fail_loc=0
9649
9650         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9651 }
9652 run_test 64e "check grant consumption (no grant allocation)"
9653
9654 test_64f() {
9655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9656
9657         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9658         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9659         $LCTL set_param debug=+cache
9660
9661         # Remount client to reset grant
9662         remount_client $MOUNT || error "failed to remount client"
9663         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9664
9665         local init_grants=$(import_param $osc_tgt initial_grant)
9666         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9667         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9668         local gbs=$(import_param $osc_tgt grant_block_size)
9669         local chunk=$(grant_chunk $osc_tgt)
9670
9671         # write random number of bytes from max_brw_size / 4 to max_brw_size
9672         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9673         # align for direct io
9674         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9675         # round to grant consumption unit
9676         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9677
9678         local grants=$((wb_round_up + extent_tax))
9679
9680         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9681         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9682                 error "error writing to $DIR/$tfile"
9683
9684         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9685                 "direct io with grant allocation"
9686
9687         rm -f $DIR/$tfile || error "rm failed"
9688
9689         # Remount client to reset grant
9690         remount_client $MOUNT || error "failed to remount client"
9691         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9692
9693         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9694
9695         # Testing that buffered IO consumes grant on the client
9696
9697         # Delay the RPC on the server so it's guaranteed to not complete even
9698         # if the RPC is sent from the client
9699         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9700         $LCTL set_param fail_loc=0x50a fail_val=3
9701         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9702                 error "error writing to $DIR/$tfile with buffered IO"
9703
9704         check_grants $osc_tgt $((init_grants - grants)) \
9705                 "buffered io, not write rpc"
9706
9707         # Clear the fail loc and do a sync on the client
9708         $LCTL set_param fail_loc=0 fail_val=0
9709         sync
9710
9711         # RPC is now known to have sent
9712         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9713                 "buffered io, one RPC"
9714 }
9715 run_test 64f "check grant consumption (with grant allocation)"
9716
9717 test_64g() {
9718         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9719                 skip "Need MDS version at least 2.14.56"
9720
9721         local mdts=$(comma_list $(mdts_nodes))
9722
9723         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9724                         tr '\n' ' ')
9725         stack_trap "$LCTL set_param $old"
9726
9727         # generate dirty pages and increase dirty granted on MDT
9728         stack_trap "rm -f $DIR/$tfile-*"
9729         for (( i = 0; i < 10; i++)); do
9730                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9731                         error "can't set stripe"
9732                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9733                         error "can't dd"
9734                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9735                         $LFS getstripe $DIR/$tfile-$i
9736                         error "not DoM file"
9737                 }
9738         done
9739
9740         # flush dirty pages
9741         sync
9742
9743         # wait until grant shrink reset grant dirty on MDTs
9744         for ((i = 0; i < 120; i++)); do
9745                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9746                         awk '{sum=sum+$1} END {print sum}')
9747                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9748                 echo "$grant_dirty grants, $vm_dirty pages"
9749                 (( grant_dirty + vm_dirty == 0 )) && break
9750                 (( i == 3 )) && sync &&
9751                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9752                 sleep 1
9753         done
9754
9755         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9756                 awk '{sum=sum+$1} END {print sum}')
9757         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9758 }
9759 run_test 64g "grant shrink on MDT"
9760
9761 test_64h() {
9762         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9763                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9764
9765         local instance=$($LFS getname -i $DIR)
9766         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9767         local num_exps=$(do_facet ost1 \
9768             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9769         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9770         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9771         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9772
9773         # 10MiB is for file to be written, max_brw_size * 16 *
9774         # num_exps is space reserve so that tgt_grant_shrink() decided
9775         # to not shrink
9776         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9777         (( avail * 1024 < expect )) &&
9778                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9779
9780         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9781         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9782         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9783         $LCTL set_param osc.*OST0000*.grant_shrink=1
9784         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9785
9786         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9787         stack_trap "rm -f $DIR/$tfile"
9788         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9789
9790         # drop cache so that coming read would do rpc
9791         cancel_lru_locks osc
9792
9793         # shrink interval is set to 10, pause for 7 seconds so that
9794         # grant thread did not wake up yet but coming read entered
9795         # shrink mode for rpc (osc_should_shrink_grant())
9796         sleep 7
9797
9798         declare -a cur_grant_bytes
9799         declare -a tot_granted
9800         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9801         tot_granted[0]=$(do_facet ost1 \
9802             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9803
9804         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9805
9806         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9807         tot_granted[1]=$(do_facet ost1 \
9808             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9809
9810         # grant change should be equal on both sides
9811         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9812                 tot_granted[0] - tot_granted[1])) ||
9813                 error "grant change mismatch, "                                \
9814                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9815                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9816 }
9817 run_test 64h "grant shrink on read"
9818
9819 test_64i() {
9820         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9821                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9822
9823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9824         remote_ost_nodsh && skip "remote OSTs with nodsh"
9825
9826         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9827         stack_trap "rm -f $DIR/$tfile"
9828
9829         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9830
9831         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9832         local instance=$($LFS getname -i $DIR)
9833
9834         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9835         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9836
9837         # shrink grants and simulate rpc loss
9838         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9839         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9840         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9841
9842         fail ost1
9843
9844         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9845
9846         local testid=$(echo $TESTNAME | tr '_' ' ')
9847
9848         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9849                 grep "GRANT, real grant" &&
9850                 error "client has more grants then it owns" || true
9851 }
9852 run_test 64i "shrink on reconnect"
9853
9854 # bug 1414 - set/get directories' stripe info
9855 test_65a() {
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857
9858         test_mkdir $DIR/$tdir
9859         touch $DIR/$tdir/f1
9860         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9861 }
9862 run_test 65a "directory with no stripe info"
9863
9864 test_65b() {
9865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9866
9867         test_mkdir $DIR/$tdir
9868         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9869
9870         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9871                                                 error "setstripe"
9872         touch $DIR/$tdir/f2
9873         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9874 }
9875 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9876
9877 test_65c() {
9878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9879         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9880
9881         test_mkdir $DIR/$tdir
9882         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9883
9884         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9885                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9886         touch $DIR/$tdir/f3
9887         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9888 }
9889 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9890
9891 test_65d() {
9892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9893
9894         test_mkdir $DIR/$tdir
9895         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9896         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9897
9898         if [[ $STRIPECOUNT -le 0 ]]; then
9899                 sc=1
9900         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9901                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9902                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9903         else
9904                 sc=$(($STRIPECOUNT - 1))
9905         fi
9906         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9907         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9908         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9909                 error "lverify failed"
9910 }
9911 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9912
9913 test_65e() {
9914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9915
9916         # LU-16904 delete layout when root is set as PFL layout
9917         save_layout_restore_at_exit $MOUNT
9918         $LFS setstripe -d $MOUNT || error "setstripe failed"
9919
9920         test_mkdir $DIR/$tdir
9921
9922         $LFS setstripe $DIR/$tdir || error "setstripe"
9923         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9924                                         error "no stripe info failed"
9925         touch $DIR/$tdir/f6
9926         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9927 }
9928 run_test 65e "directory setstripe defaults"
9929
9930 test_65f() {
9931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9932
9933         test_mkdir $DIR/${tdir}f
9934         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9935                 error "setstripe succeeded" || true
9936 }
9937 run_test 65f "dir setstripe permission (should return error) ==="
9938
9939 test_65g() {
9940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9941
9942         # LU-16904 delete layout when root is set as PFL layout
9943         save_layout_restore_at_exit $MOUNT
9944         $LFS setstripe -d $MOUNT || error "setstripe failed"
9945
9946         test_mkdir $DIR/$tdir
9947         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9948
9949         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9950                 error "setstripe -S failed"
9951         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9952         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9953                 error "delete default stripe failed"
9954 }
9955 run_test 65g "directory setstripe -d"
9956
9957 test_65h() {
9958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9959
9960         test_mkdir $DIR/$tdir
9961         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9962
9963         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9964                 error "setstripe -S failed"
9965         test_mkdir $DIR/$tdir/dd1
9966         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9967                 error "stripe info inherit failed"
9968 }
9969 run_test 65h "directory stripe info inherit ===================="
9970
9971 test_65i() {
9972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9973
9974         save_layout_restore_at_exit $MOUNT
9975
9976         # bug6367: set non-default striping on root directory
9977         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9978
9979         # bug12836: getstripe on -1 default directory striping
9980         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9981
9982         # bug12836: getstripe -v on -1 default directory striping
9983         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9984
9985         # bug12836: new find on -1 default directory striping
9986         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9987 }
9988 run_test 65i "various tests to set root directory striping"
9989
9990 test_65j() { # bug6367
9991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9992
9993         sync; sleep 1
9994
9995         # if we aren't already remounting for each test, do so for this test
9996         if [ "$I_MOUNTED" = "yes" ]; then
9997                 cleanup || error "failed to unmount"
9998                 setup
9999         fi
10000
10001         save_layout_restore_at_exit $MOUNT
10002
10003         $LFS setstripe -d $MOUNT || error "setstripe failed"
10004 }
10005 run_test 65j "set default striping on root directory (bug 6367)="
10006
10007 cleanup_65k() {
10008         rm -rf $DIR/$tdir
10009         wait_delete_completed
10010         do_facet $SINGLEMDS "lctl set_param -n \
10011                 osp.$ost*MDT0000.max_create_count=$max_count"
10012         do_facet $SINGLEMDS "lctl set_param -n \
10013                 osp.$ost*MDT0000.create_count=$count"
10014         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10015         echo $INACTIVE_OSC "is Activate"
10016
10017         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10018 }
10019
10020 test_65k() { # bug11679
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10023         remote_mds_nodsh && skip "remote MDS with nodsh"
10024
10025         local disable_precreate=true
10026         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10027                 disable_precreate=false
10028
10029         echo "Check OST status: "
10030         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10031                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10032
10033         for OSC in $MDS_OSCS; do
10034                 echo $OSC "is active"
10035                 do_facet $SINGLEMDS lctl --device %$OSC activate
10036         done
10037
10038         for INACTIVE_OSC in $MDS_OSCS; do
10039                 local ost=$(osc_to_ost $INACTIVE_OSC)
10040                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10041                                lov.*md*.target_obd |
10042                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10043
10044                 mkdir -p $DIR/$tdir
10045                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10046                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10047
10048                 echo "Deactivate: " $INACTIVE_OSC
10049                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10050
10051                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10052                               osp.$ost*MDT0000.create_count")
10053                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10054                                   osp.$ost*MDT0000.max_create_count")
10055                 $disable_precreate &&
10056                         do_facet $SINGLEMDS "lctl set_param -n \
10057                                 osp.$ost*MDT0000.max_create_count=0"
10058
10059                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10060                         [ -f $DIR/$tdir/$idx ] && continue
10061                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10062                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10063                                 { cleanup_65k;
10064                                   error "setstripe $idx should succeed"; }
10065                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10066                 done
10067                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10068                 rmdir $DIR/$tdir
10069
10070                 do_facet $SINGLEMDS "lctl set_param -n \
10071                         osp.$ost*MDT0000.max_create_count=$max_count"
10072                 do_facet $SINGLEMDS "lctl set_param -n \
10073                         osp.$ost*MDT0000.create_count=$count"
10074                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10075                 echo $INACTIVE_OSC "is Activate"
10076
10077                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10078         done
10079 }
10080 run_test 65k "validate manual striping works properly with deactivated OSCs"
10081
10082 test_65l() { # bug 12836
10083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10084
10085         test_mkdir -p $DIR/$tdir/test_dir
10086         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10087         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10088 }
10089 run_test 65l "lfs find on -1 stripe dir ========================"
10090
10091 test_65m() {
10092         local layout=$(save_layout $MOUNT)
10093         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10094                 restore_layout $MOUNT $layout
10095                 error "setstripe should fail by non-root users"
10096         }
10097         true
10098 }
10099 run_test 65m "normal user can't set filesystem default stripe"
10100
10101 test_65n() {
10102         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10103         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10104                 skip "Need MDS version at least 2.12.50"
10105         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10106
10107         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10108         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10109         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10110
10111         save_layout_restore_at_exit $MOUNT
10112
10113         # new subdirectory under root directory should not inherit
10114         # the default layout from root
10115         # LU-16904 check if the root is set as PFL layout
10116         local numcomp=$($LFS getstripe --component-count $MOUNT)
10117
10118         if [[ $numcomp -eq 0 ]]; then
10119                 local dir1=$MOUNT/$tdir-1
10120                 mkdir $dir1 || error "mkdir $dir1 failed"
10121                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10122                         error "$dir1 shouldn't have LOV EA"
10123         fi
10124
10125         # delete the default layout on root directory
10126         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10127
10128         local dir2=$MOUNT/$tdir-2
10129         mkdir $dir2 || error "mkdir $dir2 failed"
10130         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10131                 error "$dir2 shouldn't have LOV EA"
10132
10133         # set a new striping pattern on root directory
10134         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10135         local new_def_stripe_size=$((def_stripe_size * 2))
10136         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10137                 error "set stripe size on $MOUNT failed"
10138
10139         # new file created in $dir2 should inherit the new stripe size from
10140         # the filesystem default
10141         local file2=$dir2/$tfile-2
10142         touch $file2 || error "touch $file2 failed"
10143
10144         local file2_stripe_size=$($LFS getstripe -S $file2)
10145         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10146         {
10147                 echo "file2_stripe_size: '$file2_stripe_size'"
10148                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10149                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10150         }
10151
10152         local dir3=$MOUNT/$tdir-3
10153         mkdir $dir3 || error "mkdir $dir3 failed"
10154         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10155         # the root layout, which is the actual default layout that will be used
10156         # when new files are created in $dir3.
10157         local dir3_layout=$(get_layout_param $dir3)
10158         local root_dir_layout=$(get_layout_param $MOUNT)
10159         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10160         {
10161                 echo "dir3_layout: '$dir3_layout'"
10162                 echo "root_dir_layout: '$root_dir_layout'"
10163                 error "$dir3 should show the default layout from $MOUNT"
10164         }
10165
10166         # set OST pool on root directory
10167         local pool=$TESTNAME
10168         pool_add $pool || error "add $pool failed"
10169         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10170                 error "add targets to $pool failed"
10171
10172         $LFS setstripe -p $pool $MOUNT ||
10173                 error "set OST pool on $MOUNT failed"
10174
10175         # new file created in $dir3 should inherit the pool from
10176         # the filesystem default
10177         local file3=$dir3/$tfile-3
10178         touch $file3 || error "touch $file3 failed"
10179
10180         local file3_pool=$($LFS getstripe -p $file3)
10181         [[ "$file3_pool" = "$pool" ]] ||
10182                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10183
10184         local dir4=$MOUNT/$tdir-4
10185         mkdir $dir4 || error "mkdir $dir4 failed"
10186         local dir4_layout=$(get_layout_param $dir4)
10187         root_dir_layout=$(get_layout_param $MOUNT)
10188         echo "$LFS getstripe -d $dir4"
10189         $LFS getstripe -d $dir4
10190         echo "$LFS getstripe -d $MOUNT"
10191         $LFS getstripe -d $MOUNT
10192         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10193         {
10194                 echo "dir4_layout: '$dir4_layout'"
10195                 echo "root_dir_layout: '$root_dir_layout'"
10196                 error "$dir4 should show the default layout from $MOUNT"
10197         }
10198
10199         # new file created in $dir4 should inherit the pool from
10200         # the filesystem default
10201         local file4=$dir4/$tfile-4
10202         touch $file4 || error "touch $file4 failed"
10203
10204         local file4_pool=$($LFS getstripe -p $file4)
10205         [[ "$file4_pool" = "$pool" ]] ||
10206                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10207
10208         # new subdirectory under non-root directory should inherit
10209         # the default layout from its parent directory
10210         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10211                 error "set directory layout on $dir4 failed"
10212
10213         local dir5=$dir4/$tdir-5
10214         mkdir $dir5 || error "mkdir $dir5 failed"
10215
10216         dir4_layout=$(get_layout_param $dir4)
10217         local dir5_layout=$(get_layout_param $dir5)
10218         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10219         {
10220                 echo "dir4_layout: '$dir4_layout'"
10221                 echo "dir5_layout: '$dir5_layout'"
10222                 error "$dir5 should inherit the default layout from $dir4"
10223         }
10224
10225         # though subdir under ROOT doesn't inherit default layout, but
10226         # its sub dir/file should be created with default layout.
10227         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10228         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10229                 skip "Need MDS version at least 2.12.59"
10230
10231         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10232         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10233         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10234
10235         if [ $default_lmv_hash == "none" ]; then
10236                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10237         else
10238                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10239                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10240         fi
10241
10242         $LFS setdirstripe -D -c 2 $MOUNT ||
10243                 error "setdirstripe -D -c 2 failed"
10244         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10245         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10246         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10247
10248         # $dir4 layout includes pool
10249         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10250         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10251                 error "pool lost on setstripe"
10252         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10253         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10254                 error "pool lost on compound layout setstripe"
10255 }
10256 run_test 65n "don't inherit default layout from root for new subdirectories"
10257
10258 test_65o() {
10259         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10260                 skip "need MDS version at least 2.14.57"
10261
10262         # set OST pool on root directory
10263         local pool=$TESTNAME
10264
10265         pool_add $pool || error "add $pool failed"
10266         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10267                 error "add targets to $pool failed"
10268
10269         local dir1=$MOUNT/$tdir
10270
10271         mkdir $dir1 || error "mkdir $dir1 failed"
10272
10273         # set a new striping pattern on root directory
10274         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10275
10276         $LFS setstripe -p $pool $dir1 ||
10277                 error "set directory layout on $dir1 failed"
10278
10279         # $dir1 layout includes pool
10280         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10281         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10282                 error "pool lost on setstripe"
10283         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10284         $LFS getstripe $dir1
10285         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10286                 error "pool lost on compound layout setstripe"
10287
10288         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10289                 error "setdirstripe failed on sub-dir with inherited pool"
10290         $LFS getstripe $dir1/dir2
10291         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10292                 error "pool lost on compound layout setdirstripe"
10293
10294         $LFS setstripe -E -1 -c 1 $dir1
10295         $LFS getstripe -d $dir1
10296         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10297                 error "pool lost on setstripe"
10298 }
10299 run_test 65o "pool inheritance for mdt component"
10300
10301 test_65p () { # LU-16152
10302         local src_dir=$DIR/$tdir/src_dir
10303         local dst_dir=$DIR/$tdir/dst_dir
10304         local yaml_file=$DIR/$tdir/layout.yaml
10305         local border
10306
10307         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10308                 skip "Need at least version 2.15.51"
10309
10310         test_mkdir -p $src_dir
10311         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10312                 error "failed to setstripe"
10313         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10314                 error "failed to getstripe"
10315
10316         test_mkdir -p $dst_dir
10317         $LFS setstripe --yaml $yaml_file $dst_dir ||
10318                 error "failed to setstripe with yaml file"
10319         border=$($LFS getstripe -d $dst_dir |
10320                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10321                 error "failed to getstripe"
10322
10323         # 2048M is 0x80000000, or 2147483648
10324         (( $border == 2147483648 )) ||
10325                 error "failed to handle huge number in yaml layout"
10326 }
10327 run_test 65p "setstripe with yaml file and huge number"
10328
10329 test_65p () { # LU-16194
10330         local src_dir=$DIR/$tdir/src_dir
10331
10332         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10333                 skip "Need at least version 2.15.51"
10334
10335         test_mkdir -p $src_dir
10336         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10337         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10338                 error "should fail if extent start/end >=8E"
10339
10340         # EOF should work as before
10341         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10342                 error "failed to setstripe normally"
10343 }
10344 run_test 65p "setstripe with >=8E offset should fail"
10345
10346 # bug 2543 - update blocks count on client
10347 test_66() {
10348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10349
10350         local COUNT=${COUNT:-8}
10351         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10352         sync; sync_all_data; sync; sync_all_data
10353         cancel_lru_locks osc
10354         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10355         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10356 }
10357 run_test 66 "update inode blocks count on client ==============="
10358
10359 meminfo() {
10360         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10361 }
10362
10363 swap_used() {
10364         swapon -s | awk '($1 == "'$1'") { print $4 }'
10365 }
10366
10367 # bug5265, obdfilter oa2dentry return -ENOENT
10368 # #define OBD_FAIL_SRV_ENOENT 0x217
10369 test_69() {
10370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10371         remote_ost_nodsh && skip "remote OST with nodsh"
10372
10373         f="$DIR/$tfile"
10374         $LFS setstripe -c 1 -i 0 $f
10375         stack_trap "rm -f $f ${f}.2"
10376
10377         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10378
10379         do_facet ost1 lctl set_param fail_loc=0x217
10380         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10381         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10382
10383         do_facet ost1 lctl set_param fail_loc=0
10384         $DIRECTIO write $f 0 2 || error "write error"
10385
10386         cancel_lru_locks osc
10387         $DIRECTIO read $f 0 1 || error "read error"
10388
10389         do_facet ost1 lctl set_param fail_loc=0x217
10390         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10391
10392         do_facet ost1 lctl set_param fail_loc=0
10393 }
10394 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10395
10396 test_71() {
10397         test_mkdir $DIR/$tdir
10398         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10399         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10400 }
10401 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10402
10403 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10405         [ "$RUNAS_ID" = "$UID" ] &&
10406                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10407         # Check that testing environment is properly set up. Skip if not
10408         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10409                 skip_env "User $RUNAS_ID does not exist - skipping"
10410
10411         touch $DIR/$tfile
10412         chmod 777 $DIR/$tfile
10413         chmod ug+s $DIR/$tfile
10414         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10415                 error "$RUNAS dd $DIR/$tfile failed"
10416         # See if we are still setuid/sgid
10417         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10418                 error "S/gid is not dropped on write"
10419         # Now test that MDS is updated too
10420         cancel_lru_locks mdc
10421         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10422                 error "S/gid is not dropped on MDS"
10423         rm -f $DIR/$tfile
10424 }
10425 run_test 72a "Test that remove suid works properly (bug5695) ===="
10426
10427 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10428         local perm
10429
10430         [ "$RUNAS_ID" = "$UID" ] &&
10431                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10432         [ "$RUNAS_ID" -eq 0 ] &&
10433                 skip_env "RUNAS_ID = 0 -- skipping"
10434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10435         # Check that testing environment is properly set up. Skip if not
10436         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10437                 skip_env "User $RUNAS_ID does not exist - skipping"
10438
10439         touch $DIR/${tfile}-f{g,u}
10440         test_mkdir $DIR/${tfile}-dg
10441         test_mkdir $DIR/${tfile}-du
10442         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10443         chmod g+s $DIR/${tfile}-{f,d}g
10444         chmod u+s $DIR/${tfile}-{f,d}u
10445         for perm in 777 2777 4777; do
10446                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10447                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10448                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10449                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10450         done
10451         true
10452 }
10453 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10454
10455 # bug 3462 - multiple simultaneous MDC requests
10456 test_73() {
10457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10458
10459         test_mkdir $DIR/d73-1
10460         test_mkdir $DIR/d73-2
10461         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10462         pid1=$!
10463
10464         lctl set_param fail_loc=0x80000129
10465         $MULTIOP $DIR/d73-1/f73-2 Oc &
10466         sleep 1
10467         lctl set_param fail_loc=0
10468
10469         $MULTIOP $DIR/d73-2/f73-3 Oc &
10470         pid3=$!
10471
10472         kill -USR1 $pid1
10473         wait $pid1 || return 1
10474
10475         sleep 25
10476
10477         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10478         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10479         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10480
10481         rm -rf $DIR/d73-*
10482 }
10483 run_test 73 "multiple MDC requests (should not deadlock)"
10484
10485 test_74a() { # bug 6149, 6184
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487
10488         touch $DIR/f74a
10489         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10490         #
10491         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10492         # will spin in a tight reconnection loop
10493         $LCTL set_param fail_loc=0x8000030e
10494         # get any lock that won't be difficult - lookup works.
10495         ls $DIR/f74a
10496         $LCTL set_param fail_loc=0
10497         rm -f $DIR/f74a
10498         true
10499 }
10500 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10501
10502 test_74b() { # bug 13310
10503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10504
10505         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10506         #
10507         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10508         # will spin in a tight reconnection loop
10509         $LCTL set_param fail_loc=0x8000030e
10510         # get a "difficult" lock
10511         touch $DIR/f74b
10512         $LCTL set_param fail_loc=0
10513         rm -f $DIR/f74b
10514         true
10515 }
10516 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10517
10518 test_74c() {
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520
10521         #define OBD_FAIL_LDLM_NEW_LOCK
10522         $LCTL set_param fail_loc=0x319
10523         touch $DIR/$tfile && error "touch successful"
10524         $LCTL set_param fail_loc=0
10525         true
10526 }
10527 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10528
10529 slab_lic=/sys/kernel/slab/lustre_inode_cache
10530 num_objects() {
10531         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10532         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10533                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10534 }
10535
10536 test_76a() { # Now for b=20433, added originally in b=1443
10537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10538
10539         cancel_lru_locks osc
10540         # there may be some slab objects cached per core
10541         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10542         local before=$(num_objects)
10543         local count=$((512 * cpus))
10544         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10545         local margin=$((count / 10))
10546         if [[ -f $slab_lic/aliases ]]; then
10547                 local aliases=$(cat $slab_lic/aliases)
10548                 (( aliases > 0 )) && margin=$((margin * aliases))
10549         fi
10550
10551         echo "before slab objects: $before"
10552         for i in $(seq $count); do
10553                 touch $DIR/$tfile
10554                 rm -f $DIR/$tfile
10555         done
10556         cancel_lru_locks osc
10557         local after=$(num_objects)
10558         echo "created: $count, after slab objects: $after"
10559         # shared slab counts are not very accurate, allow significant margin
10560         # the main goal is that the cache growth is not permanently > $count
10561         while (( after > before + margin )); do
10562                 sleep 1
10563                 after=$(num_objects)
10564                 wait=$((wait + 1))
10565                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10566                 if (( wait > 60 )); then
10567                         error "inode slab grew from $before+$margin to $after"
10568                 fi
10569         done
10570 }
10571 run_test 76a "confirm clients recycle inodes properly ===="
10572
10573 test_76b() {
10574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10575         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10576
10577         local count=512
10578         local before=$(num_objects)
10579
10580         for i in $(seq $count); do
10581                 mkdir $DIR/$tdir
10582                 rmdir $DIR/$tdir
10583         done
10584
10585         local after=$(num_objects)
10586         local wait=0
10587
10588         while (( after > before )); do
10589                 sleep 1
10590                 after=$(num_objects)
10591                 wait=$((wait + 1))
10592                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10593                 if (( wait > 60 )); then
10594                         error "inode slab grew from $before to $after"
10595                 fi
10596         done
10597
10598         echo "slab objects before: $before, after: $after"
10599 }
10600 run_test 76b "confirm clients recycle directory inodes properly ===="
10601
10602 export ORIG_CSUM=""
10603 set_checksums()
10604 {
10605         # Note: in sptlrpc modes which enable its own bulk checksum, the
10606         # original crc32_le bulk checksum will be automatically disabled,
10607         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10608         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10609         # In this case set_checksums() will not be no-op, because sptlrpc
10610         # bulk checksum will be enabled all through the test.
10611
10612         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10613         lctl set_param -n osc.*.checksums $1
10614         return 0
10615 }
10616
10617 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10618                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10619 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10620                              tr -d [] | head -n1)}
10621 set_checksum_type()
10622 {
10623         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10624         rc=$?
10625         log "set checksum type to $1, rc = $rc"
10626         return $rc
10627 }
10628
10629 get_osc_checksum_type()
10630 {
10631         # arugment 1: OST name, like OST0000
10632         ost=$1
10633         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10634                         sed 's/.*\[\(.*\)\].*/\1/g')
10635         rc=$?
10636         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10637         echo $checksum_type
10638 }
10639
10640 F77_TMP=$TMP/f77-temp
10641 F77SZ=8
10642 setup_f77() {
10643         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10644                 error "error writing to $F77_TMP"
10645 }
10646
10647 test_77a() { # bug 10889
10648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10649         $GSS && skip_env "could not run with gss"
10650
10651         [ ! -f $F77_TMP ] && setup_f77
10652         set_checksums 1
10653         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10654         set_checksums 0
10655         rm -f $DIR/$tfile
10656 }
10657 run_test 77a "normal checksum read/write operation"
10658
10659 test_77b() { # bug 10889
10660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10661         $GSS && skip_env "could not run with gss"
10662
10663         [ ! -f $F77_TMP ] && setup_f77
10664         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10665         $LCTL set_param fail_loc=0x80000409
10666         set_checksums 1
10667
10668         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10669                 error "dd error: $?"
10670         $LCTL set_param fail_loc=0
10671
10672         for algo in $CKSUM_TYPES; do
10673                 cancel_lru_locks osc
10674                 set_checksum_type $algo
10675                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10676                 $LCTL set_param fail_loc=0x80000408
10677                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10678                 $LCTL set_param fail_loc=0
10679         done
10680         set_checksums 0
10681         set_checksum_type $ORIG_CSUM_TYPE
10682         rm -f $DIR/$tfile
10683 }
10684 run_test 77b "checksum error on client write, read"
10685
10686 cleanup_77c() {
10687         trap 0
10688         set_checksums 0
10689         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10690         $check_ost &&
10691                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10692         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10693         $check_ost && [ -n "$ost_file_prefix" ] &&
10694                 do_facet ost1 rm -f ${ost_file_prefix}\*
10695 }
10696
10697 test_77c() {
10698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10699         $GSS && skip_env "could not run with gss"
10700         remote_ost_nodsh && skip "remote OST with nodsh"
10701
10702         local bad1
10703         local osc_file_prefix
10704         local osc_file
10705         local check_ost=false
10706         local ost_file_prefix
10707         local ost_file
10708         local orig_cksum
10709         local dump_cksum
10710         local fid
10711
10712         # ensure corruption will occur on first OSS/OST
10713         $LFS setstripe -i 0 $DIR/$tfile
10714
10715         [ ! -f $F77_TMP ] && setup_f77
10716         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10717                 error "dd write error: $?"
10718         fid=$($LFS path2fid $DIR/$tfile)
10719
10720         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10721         then
10722                 check_ost=true
10723                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10724                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10725         else
10726                 echo "OSS do not support bulk pages dump upon error"
10727         fi
10728
10729         osc_file_prefix=$($LCTL get_param -n debug_path)
10730         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10731
10732         trap cleanup_77c EXIT
10733
10734         set_checksums 1
10735         # enable bulk pages dump upon error on Client
10736         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10737         # enable bulk pages dump upon error on OSS
10738         $check_ost &&
10739                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10740
10741         # flush Client cache to allow next read to reach OSS
10742         cancel_lru_locks osc
10743
10744         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10745         $LCTL set_param fail_loc=0x80000408
10746         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10747         $LCTL set_param fail_loc=0
10748
10749         rm -f $DIR/$tfile
10750
10751         # check cksum dump on Client
10752         osc_file=$(ls ${osc_file_prefix}*)
10753         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10754         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10755         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10756         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10757         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10758                      cksum)
10759         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10760         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10761                 error "dump content does not match on Client"
10762
10763         $check_ost || skip "No need to check cksum dump on OSS"
10764
10765         # check cksum dump on OSS
10766         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10767         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10768         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10769         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10770         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10771                 error "dump content does not match on OSS"
10772
10773         cleanup_77c
10774 }
10775 run_test 77c "checksum error on client read with debug"
10776
10777 test_77d() { # bug 10889
10778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10779         $GSS && skip_env "could not run with gss"
10780
10781         stack_trap "rm -f $DIR/$tfile"
10782         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10783         $LCTL set_param fail_loc=0x80000409
10784         set_checksums 1
10785         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10786                 error "direct write: rc=$?"
10787         $LCTL set_param fail_loc=0
10788         set_checksums 0
10789
10790         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10791         $LCTL set_param fail_loc=0x80000408
10792         set_checksums 1
10793         cancel_lru_locks osc
10794         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10795                 error "direct read: rc=$?"
10796         $LCTL set_param fail_loc=0
10797         set_checksums 0
10798 }
10799 run_test 77d "checksum error on OST direct write, read"
10800
10801 test_77f() { # bug 10889
10802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10803         $GSS && skip_env "could not run with gss"
10804
10805         set_checksums 1
10806         stack_trap "rm -f $DIR/$tfile"
10807         for algo in $CKSUM_TYPES; do
10808                 cancel_lru_locks osc
10809                 set_checksum_type $algo
10810                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10811                 $LCTL set_param fail_loc=0x409
10812                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10813                         error "direct write succeeded"
10814                 $LCTL set_param fail_loc=0
10815         done
10816         set_checksum_type $ORIG_CSUM_TYPE
10817         set_checksums 0
10818 }
10819 run_test 77f "repeat checksum error on write (expect error)"
10820
10821 test_77g() { # bug 10889
10822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10823         $GSS && skip_env "could not run with gss"
10824         remote_ost_nodsh && skip "remote OST with nodsh"
10825
10826         [ ! -f $F77_TMP ] && setup_f77
10827
10828         local file=$DIR/$tfile
10829         stack_trap "rm -f $file" EXIT
10830
10831         $LFS setstripe -c 1 -i 0 $file
10832         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10833         do_facet ost1 lctl set_param fail_loc=0x8000021a
10834         set_checksums 1
10835         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10836                 error "write error: rc=$?"
10837         do_facet ost1 lctl set_param fail_loc=0
10838         set_checksums 0
10839
10840         cancel_lru_locks osc
10841         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10842         do_facet ost1 lctl set_param fail_loc=0x8000021b
10843         set_checksums 1
10844         cmp $F77_TMP $file || error "file compare failed"
10845         do_facet ost1 lctl set_param fail_loc=0
10846         set_checksums 0
10847 }
10848 run_test 77g "checksum error on OST write, read"
10849
10850 test_77k() { # LU-10906
10851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10852         $GSS && skip_env "could not run with gss"
10853
10854         local cksum_param="osc.$FSNAME*.checksums"
10855         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10856         local checksum
10857         local i
10858
10859         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10860         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10861         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10862
10863         for i in 0 1; do
10864                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10865                         error "failed to set checksum=$i on MGS"
10866                 wait_update $HOSTNAME "$get_checksum" $i
10867                 #remount
10868                 echo "remount client, checksum should be $i"
10869                 remount_client $MOUNT || error "failed to remount client"
10870                 checksum=$(eval $get_checksum)
10871                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10872         done
10873         # remove persistent param to avoid races with checksum mountopt below
10874         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10875                 error "failed to delete checksum on MGS"
10876
10877         for opt in "checksum" "nochecksum"; do
10878                 #remount with mount option
10879                 echo "remount client with option $opt, checksum should be $i"
10880                 umount_client $MOUNT || error "failed to umount client"
10881                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10882                         error "failed to mount client with option '$opt'"
10883                 checksum=$(eval $get_checksum)
10884                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10885                 i=$((i - 1))
10886         done
10887
10888         remount_client $MOUNT || error "failed to remount client"
10889 }
10890 run_test 77k "enable/disable checksum correctly"
10891
10892 test_77l() {
10893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10894         $GSS && skip_env "could not run with gss"
10895
10896         set_checksums 1
10897         stack_trap "set_checksums $ORIG_CSUM" EXIT
10898         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10899
10900         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10901
10902         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10903         for algo in $CKSUM_TYPES; do
10904                 set_checksum_type $algo || error "fail to set checksum type $algo"
10905                 osc_algo=$(get_osc_checksum_type OST0000)
10906                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10907
10908                 # no locks, no reqs to let the connection idle
10909                 cancel_lru_locks osc
10910                 lru_resize_disable osc
10911                 wait_osc_import_state client ost1 IDLE
10912
10913                 # ensure ost1 is connected
10914                 stat $DIR/$tfile >/dev/null || error "can't stat"
10915                 wait_osc_import_state client ost1 FULL
10916
10917                 osc_algo=$(get_osc_checksum_type OST0000)
10918                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10919         done
10920         return 0
10921 }
10922 run_test 77l "preferred checksum type is remembered after reconnected"
10923
10924 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10925 rm -f $F77_TMP
10926 unset F77_TMP
10927
10928 test_77m() {
10929         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10930                 skip "Need at least version 2.14.52"
10931         local param=checksum_speed
10932
10933         $LCTL get_param $param || error "reading $param failed"
10934
10935         csum_speeds=$($LCTL get_param -n $param)
10936
10937         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10938                 error "known checksum types are missing"
10939 }
10940 run_test 77m "Verify checksum_speed is correctly read"
10941
10942 check_filefrag_77n() {
10943         local nr_ext=0
10944         local starts=()
10945         local ends=()
10946
10947         while read extidx a b start end rest; do
10948                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10949                         nr_ext=$(( $nr_ext + 1 ))
10950                         starts+=( ${start%..} )
10951                         ends+=( ${end%:} )
10952                 fi
10953         done < <( filefrag -sv $1 )
10954
10955         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10956         return 1
10957 }
10958
10959 test_77n() {
10960         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10961
10962         touch $DIR/$tfile
10963         $TRUNCATE $DIR/$tfile 0
10964         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10965         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10966         check_filefrag_77n $DIR/$tfile ||
10967                 skip "$tfile blocks not contiguous around hole"
10968
10969         set_checksums 1
10970         stack_trap "set_checksums $ORIG_CSUM" EXIT
10971         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10972         stack_trap "rm -f $DIR/$tfile"
10973
10974         for algo in $CKSUM_TYPES; do
10975                 if [[ "$algo" =~ ^t10 ]]; then
10976                         set_checksum_type $algo ||
10977                                 error "fail to set checksum type $algo"
10978                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10979                                 error "fail to read $tfile with $algo"
10980                 fi
10981         done
10982         rm -f $DIR/$tfile
10983         return 0
10984 }
10985 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10986
10987 test_77o() {
10988         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10989                 skip "Need MDS version at least 2.14.55"
10990         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10991                 skip "Need OST version at least 2.14.55"
10992         local ofd=obdfilter
10993         local mdt=mdt
10994
10995         # print OST checksum_type
10996         echo "$ofd.$FSNAME-*.checksum_type:"
10997         do_nodes $(comma_list $(osts_nodes)) \
10998                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10999
11000         # print MDT checksum_type
11001         echo "$mdt.$FSNAME-*.checksum_type:"
11002         do_nodes $(comma_list $(mdts_nodes)) \
11003                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11004
11005         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11006                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11007
11008         (( $o_count == $OSTCOUNT )) ||
11009                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11010
11011         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11012                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11013
11014         (( $m_count == $MDSCOUNT )) ||
11015                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11016 }
11017 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11018
11019 cleanup_test_78() {
11020         trap 0
11021         rm -f $DIR/$tfile
11022 }
11023
11024 test_78() { # bug 10901
11025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11026         remote_ost || skip_env "local OST"
11027
11028         NSEQ=5
11029         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11030         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11031         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11032         echo "MemTotal: $MEMTOTAL"
11033
11034         # reserve 256MB of memory for the kernel and other running processes,
11035         # and then take 1/2 of the remaining memory for the read/write buffers.
11036         if [ $MEMTOTAL -gt 512 ] ;then
11037                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11038         else
11039                 # for those poor memory-starved high-end clusters...
11040                 MEMTOTAL=$((MEMTOTAL / 2))
11041         fi
11042         echo "Mem to use for directio: $MEMTOTAL"
11043
11044         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11045         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11046         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11047         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11048                 head -n1)
11049         echo "Smallest OST: $SMALLESTOST"
11050         [[ $SMALLESTOST -lt 10240 ]] &&
11051                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11052
11053         trap cleanup_test_78 EXIT
11054
11055         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11056                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11057
11058         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11059         echo "File size: $F78SIZE"
11060         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11061         for i in $(seq 1 $NSEQ); do
11062                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11063                 echo directIO rdwr round $i of $NSEQ
11064                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11065         done
11066
11067         cleanup_test_78
11068 }
11069 run_test 78 "handle large O_DIRECT writes correctly ============"
11070
11071 test_79() { # bug 12743
11072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11073
11074         wait_delete_completed
11075
11076         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11077         BKFREE=$(calc_osc_kbytes kbytesfree)
11078         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11079
11080         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11081         DFTOTAL=`echo $STRING | cut -d, -f1`
11082         DFUSED=`echo $STRING  | cut -d, -f2`
11083         DFAVAIL=`echo $STRING | cut -d, -f3`
11084         DFFREE=$(($DFTOTAL - $DFUSED))
11085
11086         ALLOWANCE=$((64 * $OSTCOUNT))
11087
11088         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11089            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11090                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11091         fi
11092         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11093            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11094                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11095         fi
11096         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11097            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11098                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11099         fi
11100 }
11101 run_test 79 "df report consistency check ======================="
11102
11103 test_80() { # bug 10718
11104         remote_ost_nodsh && skip "remote OST with nodsh"
11105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11106
11107         # relax strong synchronous semantics for slow backends like ZFS
11108         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11109                 local soc="obdfilter.*.sync_lock_cancel"
11110                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11111
11112                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11113                 if [ -z "$save" ]; then
11114                         soc="obdfilter.*.sync_on_lock_cancel"
11115                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11116                 fi
11117
11118                 if [ "$save" != "never" ]; then
11119                         local hosts=$(comma_list $(osts_nodes))
11120
11121                         do_nodes $hosts $LCTL set_param $soc=never
11122                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11123                 fi
11124         fi
11125
11126         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11127         sync; sleep 1; sync
11128         local before=$(date +%s)
11129         cancel_lru_locks osc
11130         local after=$(date +%s)
11131         local diff=$((after - before))
11132         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11133
11134         rm -f $DIR/$tfile
11135 }
11136 run_test 80 "Page eviction is equally fast at high offsets too"
11137
11138 test_81a() { # LU-456
11139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11140         remote_ost_nodsh && skip "remote OST with nodsh"
11141
11142         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11143         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11144         do_facet ost1 lctl set_param fail_loc=0x80000228
11145
11146         # write should trigger a retry and success
11147         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11148         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11149         RC=$?
11150         if [ $RC -ne 0 ] ; then
11151                 error "write should success, but failed for $RC"
11152         fi
11153 }
11154 run_test 81a "OST should retry write when get -ENOSPC ==============="
11155
11156 test_81b() { # LU-456
11157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11158         remote_ost_nodsh && skip "remote OST with nodsh"
11159
11160         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11161         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11162         do_facet ost1 lctl set_param fail_loc=0x228
11163
11164         # write should retry several times and return -ENOSPC finally
11165         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11167         RC=$?
11168         ENOSPC=28
11169         if [ $RC -ne $ENOSPC ] ; then
11170                 error "dd should fail for -ENOSPC, but succeed."
11171         fi
11172 }
11173 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11174
11175 test_99() {
11176         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11177
11178         test_mkdir $DIR/$tdir.cvsroot
11179         chown $RUNAS_ID $DIR/$tdir.cvsroot
11180
11181         cd $TMP
11182         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11183
11184         cd /etc/init.d
11185         # some versions of cvs import exit(1) when asked to import links or
11186         # files they can't read.  ignore those files.
11187         local toignore=$(find . -type l -printf '-I %f\n' -o \
11188                          ! -perm /4 -printf '-I %f\n')
11189         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11190                 $tdir.reposname vtag rtag
11191
11192         cd $DIR
11193         test_mkdir $DIR/$tdir.reposname
11194         chown $RUNAS_ID $DIR/$tdir.reposname
11195         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11196
11197         cd $DIR/$tdir.reposname
11198         $RUNAS touch foo99
11199         $RUNAS cvs add -m 'addmsg' foo99
11200         $RUNAS cvs update
11201         $RUNAS cvs commit -m 'nomsg' foo99
11202         rm -fr $DIR/$tdir.cvsroot
11203 }
11204 run_test 99 "cvs strange file/directory operations"
11205
11206 test_100() {
11207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11208         [[ "$NETTYPE" =~ tcp ]] ||
11209                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11210         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11211         remote_ost_nodsh && skip "remote OST with nodsh"
11212         remote_mds_nodsh && skip "remote MDS with nodsh"
11213         remote_servers || skip "useless for local single node setup"
11214
11215         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11216                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11217
11218                 rc=0
11219                 if (( ${LOCAL/*:/} >= 1024 )); then
11220                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11221                         ss -tna
11222                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11223                 fi
11224         done
11225         (( $rc == 0 )) || error "privileged port not found" )
11226 }
11227 run_test 100 "check local port using privileged port"
11228
11229 function get_named_value()
11230 {
11231     local tag=$1
11232
11233     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11234 }
11235
11236 test_101a() {
11237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11238
11239         local s
11240         local discard
11241         local nreads=10000
11242         local cache_limit=32
11243
11244         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11245         $LCTL set_param -n llite.*.read_ahead_stats=0
11246         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11247                               awk '/^max_cached_mb/ { print $2 }')
11248         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11249         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11250
11251         #
11252         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11253         #
11254         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11255         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11256
11257         discard=0
11258         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11259                    get_named_value 'read.but.discarded'); do
11260                         discard=$(($discard + $s))
11261         done
11262
11263         $LCTL get_param osc.*-osc*.rpc_stats
11264         $LCTL get_param llite.*.read_ahead_stats
11265
11266         # Discard is generally zero, but sometimes a few random reads line up
11267         # and trigger larger readahead, which is wasted & leads to discards.
11268         if [[ $(($discard)) -gt $nreads ]]; then
11269                 error "too many ($discard) discarded pages"
11270         fi
11271         rm -f $DIR/$tfile || true
11272 }
11273 run_test 101a "check read-ahead for random reads"
11274
11275 setup_test101bc() {
11276         test_mkdir $DIR/$tdir
11277         local ssize=$1
11278         local FILE_LENGTH=$2
11279         STRIPE_OFFSET=0
11280
11281         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11282
11283         local list=$(comma_list $(osts_nodes))
11284         set_osd_param $list '' read_cache_enable 0
11285         set_osd_param $list '' writethrough_cache_enable 0
11286
11287         trap cleanup_test101bc EXIT
11288         # prepare the read-ahead file
11289         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11290
11291         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11292                                 count=$FILE_SIZE_MB 2> /dev/null
11293
11294 }
11295
11296 cleanup_test101bc() {
11297         trap 0
11298         rm -rf $DIR/$tdir
11299         rm -f $DIR/$tfile
11300
11301         local list=$(comma_list $(osts_nodes))
11302         set_osd_param $list '' read_cache_enable 1
11303         set_osd_param $list '' writethrough_cache_enable 1
11304 }
11305
11306 calc_total() {
11307         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11308 }
11309
11310 ra_check_101() {
11311         local read_size=$1
11312         local stripe_size=$2
11313         local stride_length=$((stripe_size / read_size))
11314         local stride_width=$((stride_length * OSTCOUNT))
11315         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11316                                 (stride_width - stride_length) ))
11317         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11318                   get_named_value 'read.but.discarded' | calc_total)
11319
11320         if [[ $discard -gt $discard_limit ]]; then
11321                 $LCTL get_param llite.*.read_ahead_stats
11322                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11323         else
11324                 echo "Read-ahead success for size ${read_size}"
11325         fi
11326 }
11327
11328 test_101b() {
11329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11331
11332         local STRIPE_SIZE=1048576
11333         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11334
11335         if [ $SLOW == "yes" ]; then
11336                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11337         else
11338                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11339         fi
11340
11341         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11342
11343         # prepare the read-ahead file
11344         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11345         cancel_lru_locks osc
11346         for BIDX in 2 4 8 16 32 64 128 256
11347         do
11348                 local BSIZE=$((BIDX*4096))
11349                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11350                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11351                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11352                 $LCTL set_param -n llite.*.read_ahead_stats=0
11353                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11354                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11355                 cancel_lru_locks osc
11356                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11357         done
11358         cleanup_test101bc
11359         true
11360 }
11361 run_test 101b "check stride-io mode read-ahead ================="
11362
11363 test_101c() {
11364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11365
11366         local STRIPE_SIZE=1048576
11367         local FILE_LENGTH=$((STRIPE_SIZE*100))
11368         local nreads=10000
11369         local rsize=65536
11370         local osc_rpc_stats
11371
11372         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11373
11374         cancel_lru_locks osc
11375         $LCTL set_param osc.*.rpc_stats=0
11376         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11377         $LCTL get_param osc.*.rpc_stats
11378         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11379                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11380                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11381                 local size
11382
11383                 if [ $lines -le 20 ]; then
11384                         echo "continue debug"
11385                         continue
11386                 fi
11387                 for size in 1 2 4 8; do
11388                         local rpc=$(echo "$stats" |
11389                                     awk '($1 == "'$size':") {print $2; exit; }')
11390                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11391                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11392                 done
11393                 echo "$osc_rpc_stats check passed!"
11394         done
11395         cleanup_test101bc
11396         true
11397 }
11398 run_test 101c "check stripe_size aligned read-ahead"
11399
11400 test_101d() {
11401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11402
11403         local file=$DIR/$tfile
11404         local sz_MB=${FILESIZE_101d:-80}
11405         local ra_MB=${READAHEAD_MB:-40}
11406
11407         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11408         [ $free_MB -lt $sz_MB ] &&
11409                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11410
11411         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11412         $LFS setstripe -c -1 $file || error "setstripe failed"
11413
11414         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11415         echo Cancel LRU locks on lustre client to flush the client cache
11416         cancel_lru_locks osc
11417
11418         echo Disable read-ahead
11419         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11420         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11421         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11422         $LCTL get_param -n llite.*.max_read_ahead_mb
11423
11424         echo "Reading the test file $file with read-ahead disabled"
11425         local sz_KB=$((sz_MB * 1024 / 4))
11426         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11427         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11428         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11429                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11430
11431         echo "Cancel LRU locks on lustre client to flush the client cache"
11432         cancel_lru_locks osc
11433         echo Enable read-ahead with ${ra_MB}MB
11434         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11435
11436         echo "Reading the test file $file with read-ahead enabled"
11437         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11438                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11439
11440         echo "read-ahead disabled time read $raOFF"
11441         echo "read-ahead enabled time read $raON"
11442
11443         rm -f $file
11444         wait_delete_completed
11445
11446         # use awk for this check instead of bash because it handles decimals
11447         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11448                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11449 }
11450 run_test 101d "file read with and without read-ahead enabled"
11451
11452 test_101e() {
11453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11454
11455         local file=$DIR/$tfile
11456         local size_KB=500  #KB
11457         local count=100
11458         local bsize=1024
11459
11460         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11461         local need_KB=$((count * size_KB))
11462         [[ $free_KB -le $need_KB ]] &&
11463                 skip_env "Need free space $need_KB, have $free_KB"
11464
11465         echo "Creating $count ${size_KB}K test files"
11466         for ((i = 0; i < $count; i++)); do
11467                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11468         done
11469
11470         echo "Cancel LRU locks on lustre client to flush the client cache"
11471         cancel_lru_locks $OSC
11472
11473         echo "Reset readahead stats"
11474         $LCTL set_param -n llite.*.read_ahead_stats=0
11475
11476         for ((i = 0; i < $count; i++)); do
11477                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11478         done
11479
11480         $LCTL get_param llite.*.max_cached_mb
11481         $LCTL get_param llite.*.read_ahead_stats
11482         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11483                      get_named_value 'misses' | calc_total)
11484
11485         for ((i = 0; i < $count; i++)); do
11486                 rm -rf $file.$i 2>/dev/null
11487         done
11488
11489         #10000 means 20% reads are missing in readahead
11490         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11491 }
11492 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11493
11494 test_101f() {
11495         which iozone || skip_env "no iozone installed"
11496
11497         local old_debug=$($LCTL get_param debug)
11498         old_debug=${old_debug#*=}
11499         $LCTL set_param debug="reada mmap"
11500
11501         # create a test file
11502         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11503
11504         echo Cancel LRU locks on lustre client to flush the client cache
11505         cancel_lru_locks osc
11506
11507         echo Reset readahead stats
11508         $LCTL set_param -n llite.*.read_ahead_stats=0
11509
11510         echo mmap read the file with small block size
11511         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11512                 > /dev/null 2>&1
11513
11514         echo checking missing pages
11515         $LCTL get_param llite.*.read_ahead_stats
11516         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11517                         get_named_value 'misses' | calc_total)
11518
11519         $LCTL set_param debug="$old_debug"
11520         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11521         rm -f $DIR/$tfile
11522 }
11523 run_test 101f "check mmap read performance"
11524
11525 test_101g_brw_size_test() {
11526         local mb=$1
11527         local pages=$((mb * 1048576 / PAGE_SIZE))
11528         local file=$DIR/$tfile
11529
11530         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11531                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11532         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11533                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11534                         return 2
11535         done
11536
11537         stack_trap "rm -f $file" EXIT
11538         $LCTL set_param -n osc.*.rpc_stats=0
11539
11540         # 10 RPCs should be enough for the test
11541         local count=10
11542         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11543                 { error "dd write ${mb} MB blocks failed"; return 3; }
11544         cancel_lru_locks osc
11545         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11546                 { error "dd write ${mb} MB blocks failed"; return 4; }
11547
11548         # calculate number of full-sized read and write RPCs
11549         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11550                 sed -n '/pages per rpc/,/^$/p' |
11551                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11552                 END { print reads,writes }'))
11553         # allow one extra full-sized read RPC for async readahead
11554         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11555                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11556         [[ ${rpcs[1]} == $count ]] ||
11557                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11558 }
11559
11560 test_101g() {
11561         remote_ost_nodsh && skip "remote OST with nodsh"
11562
11563         local rpcs
11564         local osts=$(get_facets OST)
11565         local list=$(comma_list $(osts_nodes))
11566         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11567         local brw_size="obdfilter.*.brw_size"
11568
11569         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11570
11571         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11572
11573         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11574                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11575                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11576            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11577                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11578                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11579
11580                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11581                         suffix="M"
11582
11583                 if [[ $orig_mb -lt 16 ]]; then
11584                         save_lustre_params $osts "$brw_size" > $p
11585                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11586                                 error "set 16MB RPC size failed"
11587
11588                         echo "remount client to enable new RPC size"
11589                         remount_client $MOUNT || error "remount_client failed"
11590                 fi
11591
11592                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11593                 # should be able to set brw_size=12, but no rpc_stats for that
11594                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11595         fi
11596
11597         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11598
11599         if [[ $orig_mb -lt 16 ]]; then
11600                 restore_lustre_params < $p
11601                 remount_client $MOUNT || error "remount_client restore failed"
11602         fi
11603
11604         rm -f $p $DIR/$tfile
11605 }
11606 run_test 101g "Big bulk(4/16 MiB) readahead"
11607
11608 test_101h() {
11609         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11610
11611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11612                 error "dd 70M file failed"
11613         echo Cancel LRU locks on lustre client to flush the client cache
11614         cancel_lru_locks osc
11615
11616         echo "Reset readahead stats"
11617         $LCTL set_param -n llite.*.read_ahead_stats 0
11618
11619         echo "Read 10M of data but cross 64M bundary"
11620         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11621         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11622                      get_named_value 'misses' | calc_total)
11623         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11624         rm -f $p $DIR/$tfile
11625 }
11626 run_test 101h "Readahead should cover current read window"
11627
11628 test_101i() {
11629         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11630                 error "dd 10M file failed"
11631
11632         local max_per_file_mb=$($LCTL get_param -n \
11633                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11634         cancel_lru_locks osc
11635         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11636         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11637                 error "set max_read_ahead_per_file_mb to 1 failed"
11638
11639         echo "Reset readahead stats"
11640         $LCTL set_param llite.*.read_ahead_stats=0
11641
11642         dd if=$DIR/$tfile of=/dev/null bs=2M
11643
11644         $LCTL get_param llite.*.read_ahead_stats
11645         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11646                      awk '/misses/ { print $2 }')
11647         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11648         rm -f $DIR/$tfile
11649 }
11650 run_test 101i "allow current readahead to exceed reservation"
11651
11652 test_101j() {
11653         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11654                 error "setstripe $DIR/$tfile failed"
11655         local file_size=$((1048576 * 16))
11656         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11657         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11658
11659         echo Disable read-ahead
11660         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11661
11662         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11663         for blk in $PAGE_SIZE 1048576 $file_size; do
11664                 cancel_lru_locks osc
11665                 echo "Reset readahead stats"
11666                 $LCTL set_param -n llite.*.read_ahead_stats=0
11667                 local count=$(($file_size / $blk))
11668                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11669                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11670                              get_named_value 'failed.to.fast.read' | calc_total)
11671                 $LCTL get_param -n llite.*.read_ahead_stats
11672                 [ $miss -eq $count ] || error "expected $count got $miss"
11673         done
11674
11675         rm -f $p $DIR/$tfile
11676 }
11677 run_test 101j "A complete read block should be submitted when no RA"
11678
11679 test_readahead_base() {
11680         local file=$DIR/$tfile
11681         local size=$1
11682         local iosz
11683         local ramax
11684         local ranum
11685
11686         $LCTL set_param -n llite.*.read_ahead_stats=0
11687         # The first page is not accounted into readahead
11688         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11689         iosz=$(((size + 1048575) / 1048576 * 1048576))
11690         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11691
11692         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11693         fallocate -l $size $file || error "failed to fallocate $file"
11694         cancel_lru_locks osc
11695         $MULTIOP $file or${iosz}c || error "failed to read $file"
11696         $LCTL get_param -n llite.*.read_ahead_stats
11697         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11698                 awk '/readahead.pages/ { print $7 }' | calc_total)
11699         (( $ranum <= $ramax )) ||
11700                 error "read-ahead pages is $ranum more than $ramax"
11701         rm -rf $file || error "failed to remove $file"
11702 }
11703
11704 test_101m()
11705 {
11706         local file=$DIR/$tfile
11707         local ramax
11708         local ranum
11709         local size
11710         local iosz
11711
11712         check_set_fallocate_or_skip
11713         stack_trap "rm -f $file" EXIT
11714
11715         test_readahead_base 4096
11716
11717         # file size: 16K = 16384
11718         test_readahead_base 16384
11719         test_readahead_base 16385
11720         test_readahead_base 16383
11721
11722         # file size: 1M + 1 = 1048576 + 1
11723         test_readahead_base 1048577
11724         # file size: 1M + 16K
11725         test_readahead_base $((1048576 + 16384))
11726
11727         # file size: stripe_size * (stripe_count - 1) + 16K
11728         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11729         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11730         # file size: stripe_size * stripe_count + 16K
11731         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11732         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11733         # file size: 2 * stripe_size * stripe_count + 16K
11734         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11735         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11736 }
11737 run_test 101m "read ahead for small file and last stripe of the file"
11738
11739 setup_test102() {
11740         test_mkdir $DIR/$tdir
11741         chown $RUNAS_ID $DIR/$tdir
11742         STRIPE_SIZE=65536
11743         STRIPE_OFFSET=1
11744         STRIPE_COUNT=$OSTCOUNT
11745         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11746
11747         trap cleanup_test102 EXIT
11748         cd $DIR
11749         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11750         cd $DIR/$tdir
11751         for num in 1 2 3 4; do
11752                 for count in $(seq 1 $STRIPE_COUNT); do
11753                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11754                                 local size=`expr $STRIPE_SIZE \* $num`
11755                                 local file=file"$num-$idx-$count"
11756                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11757                         done
11758                 done
11759         done
11760
11761         cd $DIR
11762         $1 tar cf $TMP/f102.tar $tdir --xattrs
11763 }
11764
11765 cleanup_test102() {
11766         trap 0
11767         rm -f $TMP/f102.tar
11768         rm -rf $DIR/d0.sanity/d102
11769 }
11770
11771 test_102a() {
11772         [ "$UID" != 0 ] && skip "must run as root"
11773         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11774                 skip_env "must have user_xattr"
11775
11776         [ -z "$(which setfattr 2>/dev/null)" ] &&
11777                 skip_env "could not find setfattr"
11778
11779         local testfile=$DIR/$tfile
11780
11781         touch $testfile
11782         echo "set/get xattr..."
11783         setfattr -n trusted.name1 -v value1 $testfile ||
11784                 error "setfattr -n trusted.name1=value1 $testfile failed"
11785         getfattr -n trusted.name1 $testfile 2> /dev/null |
11786           grep "trusted.name1=.value1" ||
11787                 error "$testfile missing trusted.name1=value1"
11788
11789         setfattr -n user.author1 -v author1 $testfile ||
11790                 error "setfattr -n user.author1=author1 $testfile failed"
11791         getfattr -n user.author1 $testfile 2> /dev/null |
11792           grep "user.author1=.author1" ||
11793                 error "$testfile missing trusted.author1=author1"
11794
11795         echo "listxattr..."
11796         setfattr -n trusted.name2 -v value2 $testfile ||
11797                 error "$testfile unable to set trusted.name2"
11798         setfattr -n trusted.name3 -v value3 $testfile ||
11799                 error "$testfile unable to set trusted.name3"
11800         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11801             grep "trusted.name" | wc -l) -eq 3 ] ||
11802                 error "$testfile missing 3 trusted.name xattrs"
11803
11804         setfattr -n user.author2 -v author2 $testfile ||
11805                 error "$testfile unable to set user.author2"
11806         setfattr -n user.author3 -v author3 $testfile ||
11807                 error "$testfile unable to set user.author3"
11808         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11809             grep "user.author" | wc -l) -eq 3 ] ||
11810                 error "$testfile missing 3 user.author xattrs"
11811
11812         echo "remove xattr..."
11813         setfattr -x trusted.name1 $testfile ||
11814                 error "$testfile error deleting trusted.name1"
11815         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11816                 error "$testfile did not delete trusted.name1 xattr"
11817
11818         setfattr -x user.author1 $testfile ||
11819                 error "$testfile error deleting user.author1"
11820         echo "set lustre special xattr ..."
11821         $LFS setstripe -c1 $testfile
11822         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11823                 awk -F "=" '/trusted.lov/ { print $2 }' )
11824         setfattr -n "trusted.lov" -v $lovea $testfile ||
11825                 error "$testfile doesn't ignore setting trusted.lov again"
11826         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11827                 error "$testfile allow setting invalid trusted.lov"
11828         rm -f $testfile
11829 }
11830 run_test 102a "user xattr test =================================="
11831
11832 check_102b_layout() {
11833         local layout="$*"
11834         local testfile=$DIR/$tfile
11835
11836         echo "test layout '$layout'"
11837         $LFS setstripe $layout $testfile || error "setstripe failed"
11838         $LFS getstripe -y $testfile
11839
11840         echo "get/set/list trusted.lov xattr ..." # b=10930
11841         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11842         [[ "$value" =~ "trusted.lov" ]] ||
11843                 error "can't get trusted.lov from $testfile"
11844         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11845                 error "getstripe failed"
11846
11847         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11848
11849         value=$(cut -d= -f2 <<<$value)
11850         # LU-13168: truncated xattr should fail if short lov_user_md header
11851         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11852                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11853         for len in $lens; do
11854                 echo "setfattr $len $testfile.2"
11855                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11856                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11857         done
11858         local stripe_size=$($LFS getstripe -S $testfile.2)
11859         local stripe_count=$($LFS getstripe -c $testfile.2)
11860         [[ $stripe_size -eq 65536 ]] ||
11861                 error "stripe size $stripe_size != 65536"
11862         [[ $stripe_count -eq $stripe_count_orig ]] ||
11863                 error "stripe count $stripe_count != $stripe_count_orig"
11864         rm $testfile $testfile.2
11865 }
11866
11867 test_102b() {
11868         [ -z "$(which setfattr 2>/dev/null)" ] &&
11869                 skip_env "could not find setfattr"
11870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11871
11872         # check plain layout
11873         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11874
11875         # and also check composite layout
11876         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11877
11878 }
11879 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11880
11881 test_102c() {
11882         [ -z "$(which setfattr 2>/dev/null)" ] &&
11883                 skip_env "could not find setfattr"
11884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11885
11886         # b10930: get/set/list lustre.lov xattr
11887         echo "get/set/list lustre.lov xattr ..."
11888         test_mkdir $DIR/$tdir
11889         chown $RUNAS_ID $DIR/$tdir
11890         local testfile=$DIR/$tdir/$tfile
11891         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11892                 error "setstripe failed"
11893         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11894                 error "getstripe failed"
11895         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11896         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11897
11898         local testfile2=${testfile}2
11899         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11900                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11901
11902         $RUNAS $MCREATE $testfile2
11903         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11904         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11905         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11906         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11907         [ $stripe_count -eq $STRIPECOUNT ] ||
11908                 error "stripe count $stripe_count != $STRIPECOUNT"
11909 }
11910 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11911
11912 compare_stripe_info1() {
11913         local stripe_index_all_zero=true
11914
11915         for num in 1 2 3 4; do
11916                 for count in $(seq 1 $STRIPE_COUNT); do
11917                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11918                                 local size=$((STRIPE_SIZE * num))
11919                                 local file=file"$num-$offset-$count"
11920                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11921                                 [[ $stripe_size -ne $size ]] &&
11922                                     error "$file: size $stripe_size != $size"
11923                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11924                                 # allow fewer stripes to be created, ORI-601
11925                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11926                                     error "$file: count $stripe_count != $count"
11927                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11928                                 [[ $stripe_index -ne 0 ]] &&
11929                                         stripe_index_all_zero=false
11930                         done
11931                 done
11932         done
11933         $stripe_index_all_zero &&
11934                 error "all files are being extracted starting from OST index 0"
11935         return 0
11936 }
11937
11938 have_xattrs_include() {
11939         tar --help | grep -q xattrs-include &&
11940                 echo --xattrs-include="lustre.*"
11941 }
11942
11943 test_102d() {
11944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11945         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11946
11947         XINC=$(have_xattrs_include)
11948         setup_test102
11949         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11950         cd $DIR/$tdir/$tdir
11951         compare_stripe_info1
11952 }
11953 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11954
11955 test_102f() {
11956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11957         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11958
11959         XINC=$(have_xattrs_include)
11960         setup_test102
11961         test_mkdir $DIR/$tdir.restore
11962         cd $DIR
11963         tar cf - --xattrs $tdir | tar xf - \
11964                 -C $DIR/$tdir.restore --xattrs $XINC
11965         cd $DIR/$tdir.restore/$tdir
11966         compare_stripe_info1
11967 }
11968 run_test 102f "tar copy files, not keep osts"
11969
11970 grow_xattr() {
11971         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11972                 skip "must have user_xattr"
11973         [ -z "$(which setfattr 2>/dev/null)" ] &&
11974                 skip_env "could not find setfattr"
11975         [ -z "$(which getfattr 2>/dev/null)" ] &&
11976                 skip_env "could not find getfattr"
11977
11978         local xsize=${1:-1024}  # in bytes
11979         local file=$DIR/$tfile
11980         local value="$(generate_string $xsize)"
11981         local xbig=trusted.big
11982         local toobig=$2
11983
11984         touch $file
11985         log "save $xbig on $file"
11986         if [ -z "$toobig" ]
11987         then
11988                 setfattr -n $xbig -v $value $file ||
11989                         error "saving $xbig on $file failed"
11990         else
11991                 setfattr -n $xbig -v $value $file &&
11992                         error "saving $xbig on $file succeeded"
11993                 return 0
11994         fi
11995
11996         local orig=$(get_xattr_value $xbig $file)
11997         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11998
11999         local xsml=trusted.sml
12000         log "save $xsml on $file"
12001         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12002
12003         local new=$(get_xattr_value $xbig $file)
12004         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12005
12006         log "grow $xsml on $file"
12007         setfattr -n $xsml -v "$value" $file ||
12008                 error "growing $xsml on $file failed"
12009
12010         new=$(get_xattr_value $xbig $file)
12011         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12012         log "$xbig still valid after growing $xsml"
12013
12014         rm -f $file
12015 }
12016
12017 test_102h() { # bug 15777
12018         grow_xattr 1024
12019 }
12020 run_test 102h "grow xattr from inside inode to external block"
12021
12022 test_102ha() {
12023         large_xattr_enabled || skip_env "ea_inode feature disabled"
12024
12025         echo "setting xattr of max xattr size: $(max_xattr_size)"
12026         grow_xattr $(max_xattr_size)
12027
12028         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12029         echo "This should fail:"
12030         grow_xattr $(($(max_xattr_size) + 10)) 1
12031 }
12032 run_test 102ha "grow xattr from inside inode to external inode"
12033
12034 test_102i() { # bug 17038
12035         [ -z "$(which getfattr 2>/dev/null)" ] &&
12036                 skip "could not find getfattr"
12037
12038         touch $DIR/$tfile
12039         ln -s $DIR/$tfile $DIR/${tfile}link
12040         getfattr -n trusted.lov $DIR/$tfile ||
12041                 error "lgetxattr on $DIR/$tfile failed"
12042         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12043                 grep -i "no such attr" ||
12044                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12045         rm -f $DIR/$tfile $DIR/${tfile}link
12046 }
12047 run_test 102i "lgetxattr test on symbolic link ============"
12048
12049 test_102j() {
12050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12052
12053         XINC=$(have_xattrs_include)
12054         setup_test102 "$RUNAS"
12055         chown $RUNAS_ID $DIR/$tdir
12056         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12057         cd $DIR/$tdir/$tdir
12058         compare_stripe_info1 "$RUNAS"
12059 }
12060 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12061
12062 test_102k() {
12063         [ -z "$(which setfattr 2>/dev/null)" ] &&
12064                 skip "could not find setfattr"
12065
12066         touch $DIR/$tfile
12067         # b22187 just check that does not crash for regular file.
12068         setfattr -n trusted.lov $DIR/$tfile
12069         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12070         local test_kdir=$DIR/$tdir
12071         test_mkdir $test_kdir
12072         local default_size=$($LFS getstripe -S $test_kdir)
12073         local default_count=$($LFS getstripe -c $test_kdir)
12074         local default_offset=$($LFS getstripe -i $test_kdir)
12075         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12076                 error 'dir setstripe failed'
12077         setfattr -n trusted.lov $test_kdir
12078         local stripe_size=$($LFS getstripe -S $test_kdir)
12079         local stripe_count=$($LFS getstripe -c $test_kdir)
12080         local stripe_offset=$($LFS getstripe -i $test_kdir)
12081         [ $stripe_size -eq $default_size ] ||
12082                 error "stripe size $stripe_size != $default_size"
12083         [ $stripe_count -eq $default_count ] ||
12084                 error "stripe count $stripe_count != $default_count"
12085         [ $stripe_offset -eq $default_offset ] ||
12086                 error "stripe offset $stripe_offset != $default_offset"
12087         rm -rf $DIR/$tfile $test_kdir
12088 }
12089 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12090
12091 test_102l() {
12092         [ -z "$(which getfattr 2>/dev/null)" ] &&
12093                 skip "could not find getfattr"
12094
12095         # LU-532 trusted. xattr is invisible to non-root
12096         local testfile=$DIR/$tfile
12097
12098         touch $testfile
12099
12100         echo "listxattr as user..."
12101         chown $RUNAS_ID $testfile
12102         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12103             grep -q "trusted" &&
12104                 error "$testfile trusted xattrs are user visible"
12105
12106         return 0;
12107 }
12108 run_test 102l "listxattr size test =================================="
12109
12110 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12111         local path=$DIR/$tfile
12112         touch $path
12113
12114         listxattr_size_check $path || error "listattr_size_check $path failed"
12115 }
12116 run_test 102m "Ensure listxattr fails on small bufffer ========"
12117
12118 cleanup_test102
12119
12120 getxattr() { # getxattr path name
12121         # Return the base64 encoding of the value of xattr name on path.
12122         local path=$1
12123         local name=$2
12124
12125         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12126         # file: $path
12127         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12128         #
12129         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12130
12131         getfattr --absolute-names --encoding=base64 --name=$name $path |
12132                 awk -F= -v name=$name '$1 == name {
12133                         print substr($0, index($0, "=") + 1);
12134         }'
12135 }
12136
12137 test_102n() { # LU-4101 mdt: protect internal xattrs
12138         [ -z "$(which setfattr 2>/dev/null)" ] &&
12139                 skip "could not find setfattr"
12140         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12141         then
12142                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12143         fi
12144
12145         local file0=$DIR/$tfile.0
12146         local file1=$DIR/$tfile.1
12147         local xattr0=$TMP/$tfile.0
12148         local xattr1=$TMP/$tfile.1
12149         local namelist="lov lma lmv link fid version som hsm"
12150         local name
12151         local value
12152
12153         rm -rf $file0 $file1 $xattr0 $xattr1
12154         touch $file0 $file1
12155
12156         # Get 'before' xattrs of $file1.
12157         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12158
12159         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12160                 namelist+=" lfsck_namespace"
12161         for name in $namelist; do
12162                 # Try to copy xattr from $file0 to $file1.
12163                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12164
12165                 setfattr --name=trusted.$name --value="$value" $file1 ||
12166                         error "setxattr 'trusted.$name' failed"
12167
12168                 # Try to set a garbage xattr.
12169                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12170
12171                 if [[ x$name == "xlov" ]]; then
12172                         setfattr --name=trusted.lov --value="$value" $file1 &&
12173                         error "setxattr invalid 'trusted.lov' success"
12174                 else
12175                         setfattr --name=trusted.$name --value="$value" $file1 ||
12176                                 error "setxattr invalid 'trusted.$name' failed"
12177                 fi
12178
12179                 # Try to remove the xattr from $file1. We don't care if this
12180                 # appears to succeed or fail, we just don't want there to be
12181                 # any changes or crashes.
12182                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12183         done
12184
12185         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12186         then
12187                 name="lfsck_ns"
12188                 # Try to copy xattr from $file0 to $file1.
12189                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12190
12191                 setfattr --name=trusted.$name --value="$value" $file1 ||
12192                         error "setxattr 'trusted.$name' failed"
12193
12194                 # Try to set a garbage xattr.
12195                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12196
12197                 setfattr --name=trusted.$name --value="$value" $file1 ||
12198                         error "setxattr 'trusted.$name' failed"
12199
12200                 # Try to remove the xattr from $file1. We don't care if this
12201                 # appears to succeed or fail, we just don't want there to be
12202                 # any changes or crashes.
12203                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12204         fi
12205
12206         # Get 'after' xattrs of file1.
12207         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12208
12209         if ! diff $xattr0 $xattr1; then
12210                 error "before and after xattrs of '$file1' differ"
12211         fi
12212
12213         rm -rf $file0 $file1 $xattr0 $xattr1
12214
12215         return 0
12216 }
12217 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12218
12219 test_102p() { # LU-4703 setxattr did not check ownership
12220         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12221                 skip "MDS needs to be at least 2.5.56"
12222
12223         local testfile=$DIR/$tfile
12224
12225         touch $testfile
12226
12227         echo "setfacl as user..."
12228         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12229         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12230
12231         echo "setfattr as user..."
12232         setfacl -m "u:$RUNAS_ID:---" $testfile
12233         $RUNAS setfattr -x system.posix_acl_access $testfile
12234         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12235 }
12236 run_test 102p "check setxattr(2) correctly fails without permission"
12237
12238 test_102q() {
12239         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12240                 skip "MDS needs to be at least 2.6.92"
12241
12242         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12243 }
12244 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12245
12246 test_102r() {
12247         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12248                 skip "MDS needs to be at least 2.6.93"
12249
12250         touch $DIR/$tfile || error "touch"
12251         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12252         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12253         rm $DIR/$tfile || error "rm"
12254
12255         #normal directory
12256         mkdir -p $DIR/$tdir || error "mkdir"
12257         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12258         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12259         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12260                 error "$testfile error deleting user.author1"
12261         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12262                 grep "user.$(basename $tdir)" &&
12263                 error "$tdir did not delete user.$(basename $tdir)"
12264         rmdir $DIR/$tdir || error "rmdir"
12265
12266         #striped directory
12267         test_mkdir $DIR/$tdir
12268         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12269         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12270         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12271                 error "$testfile error deleting user.author1"
12272         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12273                 grep "user.$(basename $tdir)" &&
12274                 error "$tdir did not delete user.$(basename $tdir)"
12275         rmdir $DIR/$tdir || error "rm striped dir"
12276 }
12277 run_test 102r "set EAs with empty values"
12278
12279 test_102s() {
12280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12281                 skip "MDS needs to be at least 2.11.52"
12282
12283         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12284
12285         save_lustre_params client "llite.*.xattr_cache" > $save
12286
12287         for cache in 0 1; do
12288                 lctl set_param llite.*.xattr_cache=$cache
12289
12290                 rm -f $DIR/$tfile
12291                 touch $DIR/$tfile || error "touch"
12292                 for prefix in lustre security system trusted user; do
12293                         # Note getxattr() may fail with 'Operation not
12294                         # supported' or 'No such attribute' depending
12295                         # on prefix and cache.
12296                         getfattr -n $prefix.n102s $DIR/$tfile &&
12297                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12298                 done
12299         done
12300
12301         restore_lustre_params < $save
12302 }
12303 run_test 102s "getting nonexistent xattrs should fail"
12304
12305 test_102t() {
12306         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12307                 skip "MDS needs to be at least 2.11.52"
12308
12309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12310
12311         save_lustre_params client "llite.*.xattr_cache" > $save
12312
12313         for cache in 0 1; do
12314                 lctl set_param llite.*.xattr_cache=$cache
12315
12316                 for buf_size in 0 256; do
12317                         rm -f $DIR/$tfile
12318                         touch $DIR/$tfile || error "touch"
12319                         setfattr -n user.multiop $DIR/$tfile
12320                         $MULTIOP $DIR/$tfile oa$buf_size ||
12321                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12322                 done
12323         done
12324
12325         restore_lustre_params < $save
12326 }
12327 run_test 102t "zero length xattr values handled correctly"
12328
12329 run_acl_subtest()
12330 {
12331         local test=$LUSTRE/tests/acl/$1.test
12332         local tmp=$(mktemp -t $1-XXXXXX).test
12333         local bin=$2
12334         local dmn=$3
12335         local grp=$4
12336         local nbd=$5
12337         export LANG=C
12338
12339
12340         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12341         local sedgroups="-e s/:users/:$grp/g"
12342         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12343
12344         sed $sedusers $sedgroups < $test > $tmp
12345         stack_trap "rm -f $tmp"
12346         [[ -s $tmp ]] || error "sed failed to create test script"
12347
12348         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12349         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12350 }
12351
12352 test_103a() {
12353         [ "$UID" != 0 ] && skip "must run as root"
12354         $GSS && skip_env "could not run under gss"
12355         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12356                 skip_env "must have acl enabled"
12357         which setfacl || skip_env "could not find setfacl"
12358         remote_mds_nodsh && skip "remote MDS with nodsh"
12359
12360         local mdts=$(comma_list $(mdts_nodes))
12361         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12362
12363         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12364         stack_trap "[[ -z \"$saved\" ]] || \
12365                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12366
12367         ACLBIN=${ACLBIN:-"bin"}
12368         ACLDMN=${ACLDMN:-"daemon"}
12369         ACLGRP=${ACLGRP:-"users"}
12370         ACLNBD=${ACLNBD:-"nobody"}
12371
12372         if ! id $ACLBIN ||
12373            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12374                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12375                 ACLBIN=$USER0
12376                 if ! id $ACLBIN ; then
12377                         cat /etc/passwd
12378                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12379                 fi
12380         fi
12381         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12382            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12383                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12384                 ACLDMN=$USER1
12385                 if ! id $ACLDMN ; then
12386                         cat /etc/passwd
12387                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12388                 fi
12389         fi
12390         if ! getent group $ACLGRP; then
12391                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12392                 ACLGRP="$TSTUSR"
12393                 if ! getent group $ACLGRP; then
12394                         echo "cannot find group '$ACLGRP', adding it"
12395                         cat /etc/group
12396                         add_group 60000 $ACLGRP
12397                 fi
12398         fi
12399
12400         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12401         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12402         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12403
12404         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12405                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12406                 ACLGRP="$TSTUSR"
12407                 if ! getent group $ACLGRP; then
12408                         echo "cannot find group '$ACLGRP', adding it"
12409                         cat /etc/group
12410                         add_group 60000 $ACLGRP
12411                 fi
12412                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12413                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12414                         cat /etc/group
12415                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12416                 fi
12417         fi
12418
12419         gpasswd -a $ACLDMN $ACLBIN ||
12420                 error "setting client group failed"             # LU-5641
12421         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12422                 error "setting MDS group failed"                # LU-5641
12423
12424         declare -a identity_old
12425
12426         for num in $(seq $MDSCOUNT); do
12427                 switch_identity $num true || identity_old[$num]=$?
12428         done
12429
12430         SAVE_UMASK=$(umask)
12431         umask 0022
12432         mkdir -p $DIR/$tdir
12433         cd $DIR/$tdir
12434
12435         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12436         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12437         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12438         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12439         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12440         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12441         if ! id -u $ACLNBD ||
12442            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12443                 ACLNBD="nfsnobody"
12444                 if ! id -u $ACLNBD; then
12445                         ACLNBD=""
12446                 fi
12447         fi
12448         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12449                 add_group $(id -u $ACLNBD) $ACLNBD
12450                 if ! getent group $ACLNBD; then
12451                         ACLNBD=""
12452                 fi
12453         fi
12454         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12455            [[ -n "$ACLNBD" ]] && which setfattr; then
12456                 run_acl_subtest permissions_xattr \
12457                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12458         elif [[ -z "$ACLNBD" ]]; then
12459                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12460         else
12461                 echo "skip 'permission_xattr' test - missing setfattr command"
12462         fi
12463         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12464
12465         # inheritance test got from HP
12466         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12467         chmod +x make-tree || error "chmod +x failed"
12468         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12469         rm -f make-tree
12470
12471         echo "LU-974 ignore umask when acl is enabled..."
12472         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12473         if [ $MDSCOUNT -ge 2 ]; then
12474                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12475         fi
12476
12477         echo "LU-2561 newly created file is same size as directory..."
12478         if [ "$mds1_FSTYPE" != "zfs" ]; then
12479                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12480         else
12481                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12482         fi
12483
12484         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12485
12486         cd $SAVE_PWD
12487         umask $SAVE_UMASK
12488
12489         for num in $(seq $MDSCOUNT); do
12490                 if [ "${identity_old[$num]}" = 1 ]; then
12491                         switch_identity $num false || identity_old[$num]=$?
12492                 fi
12493         done
12494 }
12495 run_test 103a "acl test"
12496
12497 test_103b() {
12498         declare -a pids
12499         local U
12500
12501         stack_trap "rm -f $DIR/$tfile.*"
12502         for U in {0..511}; do
12503                 {
12504                 local O=$(printf "%04o" $U)
12505
12506                 umask $(printf "%04o" $((511 ^ $O)))
12507                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12508                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12509
12510                 (( $S == ($O & 0666) )) ||
12511                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12512
12513                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12514                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12515                 (( $S == ($O & 0666) )) ||
12516                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12517
12518                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12519                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12520                 (( $S == ($O & 0666) )) ||
12521                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12522                 rm -f $DIR/$tfile.[smp]$0
12523                 } &
12524                 local pid=$!
12525
12526                 # limit the concurrently running threads to 64. LU-11878
12527                 local idx=$((U % 64))
12528                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12529                 pids[idx]=$pid
12530         done
12531         wait
12532 }
12533 run_test 103b "umask lfs setstripe"
12534
12535 test_103c() {
12536         mkdir -p $DIR/$tdir
12537         cp -rp $DIR/$tdir $DIR/$tdir.bak
12538
12539         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12540                 error "$DIR/$tdir shouldn't contain default ACL"
12541         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12542                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12543         true
12544 }
12545 run_test 103c "'cp -rp' won't set empty acl"
12546
12547 test_103e() {
12548         local numacl
12549         local fileacl
12550         local saved_debug=$($LCTL get_param -n debug)
12551
12552         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12553                 skip "MDS needs to be at least 2.14.52"
12554
12555         large_xattr_enabled || skip_env "ea_inode feature disabled"
12556
12557         mkdir -p $DIR/$tdir
12558         # add big LOV EA to cause reply buffer overflow earlier
12559         $LFS setstripe -C 1000 $DIR/$tdir
12560         lctl set_param mdc.*-mdc*.stats=clear
12561
12562         $LCTL set_param debug=0
12563         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12564         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12565
12566         # add a large number of default ACLs (expect 8000+ for 2.13+)
12567         for U in {2..7000}; do
12568                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12569                         error "Able to add just $U default ACLs"
12570         done
12571         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12572         echo "$numacl default ACLs created"
12573
12574         stat $DIR/$tdir || error "Cannot stat directory"
12575         # check file creation
12576         touch $DIR/$tdir/$tfile ||
12577                 error "failed to create $tfile with $numacl default ACLs"
12578         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12579         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12580         echo "$fileacl ACLs were inherited"
12581         (( $fileacl == $numacl )) ||
12582                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12583         # check that new ACLs creation adds new ACLs to inherited ACLs
12584         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12585                 error "Cannot set new ACL"
12586         numacl=$((numacl + 1))
12587         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12588         (( $fileacl == $numacl )) ||
12589                 error "failed to add new ACL: $fileacl != $numacl as expected"
12590         # adds more ACLs to a file to reach their maximum at 8000+
12591         numacl=0
12592         for U in {20000..25000}; do
12593                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12594                 numacl=$((numacl + 1))
12595         done
12596         echo "Added $numacl more ACLs to the file"
12597         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12598         echo "Total $fileacl ACLs in file"
12599         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12600         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12601         rmdir $DIR/$tdir || error "Cannot remove directory"
12602 }
12603 run_test 103e "inheritance of big amount of default ACLs"
12604
12605 test_103f() {
12606         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12607                 skip "MDS needs to be at least 2.14.51"
12608
12609         large_xattr_enabled || skip_env "ea_inode feature disabled"
12610
12611         # enable changelog to consume more internal MDD buffers
12612         changelog_register
12613
12614         mkdir -p $DIR/$tdir
12615         # add big LOV EA
12616         $LFS setstripe -C 1000 $DIR/$tdir
12617         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12618         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12619         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12620         rmdir $DIR/$tdir || error "Cannot remove directory"
12621 }
12622 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12623
12624 test_104a() {
12625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12626
12627         touch $DIR/$tfile
12628         lfs df || error "lfs df failed"
12629         lfs df -ih || error "lfs df -ih failed"
12630         lfs df -h $DIR || error "lfs df -h $DIR failed"
12631         lfs df -i $DIR || error "lfs df -i $DIR failed"
12632         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12633         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12634
12635         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12636         lctl --device %$OSC deactivate
12637         lfs df || error "lfs df with deactivated OSC failed"
12638         lctl --device %$OSC activate
12639         # wait the osc back to normal
12640         wait_osc_import_ready client ost
12641
12642         lfs df || error "lfs df with reactivated OSC failed"
12643         rm -f $DIR/$tfile
12644 }
12645 run_test 104a "lfs df [-ih] [path] test ========================="
12646
12647 test_104b() {
12648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12649         [ $RUNAS_ID -eq $UID ] &&
12650                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12651
12652         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12653                         grep "Permission denied" | wc -l)))
12654         if [ $denied_cnt -ne 0 ]; then
12655                 error "lfs check servers test failed"
12656         fi
12657 }
12658 run_test 104b "$RUNAS lfs check servers test ===================="
12659
12660 #
12661 # Verify $1 is within range of $2.
12662 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12663 # $1 is <= 2% of $2. Else Fail.
12664 #
12665 value_in_range() {
12666         # Strip all units (M, G, T)
12667         actual=$(echo $1 | tr -d A-Z)
12668         expect=$(echo $2 | tr -d A-Z)
12669
12670         expect_lo=$(($expect * 98 / 100)) # 2% below
12671         expect_hi=$(($expect * 102 / 100)) # 2% above
12672
12673         # permit 2% drift above and below
12674         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12675 }
12676
12677 test_104c() {
12678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12679         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12680
12681         local ost_param="osd-zfs.$FSNAME-OST0000."
12682         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12683         local ofacets=$(get_facets OST)
12684         local mfacets=$(get_facets MDS)
12685         local saved_ost_blocks=
12686         local saved_mdt_blocks=
12687
12688         echo "Before recordsize change"
12689         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12690         df=($(df -h | grep "$MOUNT"$))
12691
12692         # For checking.
12693         echo "lfs output : ${lfs_df[*]}"
12694         echo "df  output : ${df[*]}"
12695
12696         for facet in ${ofacets//,/ }; do
12697                 if [ -z $saved_ost_blocks ]; then
12698                         saved_ost_blocks=$(do_facet $facet \
12699                                 lctl get_param -n $ost_param.blocksize)
12700                         echo "OST Blocksize: $saved_ost_blocks"
12701                 fi
12702                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12703                 do_facet $facet zfs set recordsize=32768 $ost
12704         done
12705
12706         # BS too small. Sufficient for functional testing.
12707         for facet in ${mfacets//,/ }; do
12708                 if [ -z $saved_mdt_blocks ]; then
12709                         saved_mdt_blocks=$(do_facet $facet \
12710                                 lctl get_param -n $mdt_param.blocksize)
12711                         echo "MDT Blocksize: $saved_mdt_blocks"
12712                 fi
12713                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12714                 do_facet $facet zfs set recordsize=32768 $mdt
12715         done
12716
12717         # Give new values chance to reflect change
12718         sleep 2
12719
12720         echo "After recordsize change"
12721         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12722         df_after=($(df -h | grep "$MOUNT"$))
12723
12724         # For checking.
12725         echo "lfs output : ${lfs_df_after[*]}"
12726         echo "df  output : ${df_after[*]}"
12727
12728         # Verify lfs df
12729         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12730                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12731         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12732                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12733         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12734                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12735
12736         # Verify df
12737         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12738                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12739         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12740                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12741         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12742                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12743
12744         # Restore MDT recordize back to original
12745         for facet in ${mfacets//,/ }; do
12746                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12747                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12748         done
12749
12750         # Restore OST recordize back to original
12751         for facet in ${ofacets//,/ }; do
12752                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12753                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12754         done
12755
12756         return 0
12757 }
12758 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12759
12760 test_104d() {
12761         (( $RUNAS_ID != $UID )) ||
12762                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12763
12764         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12765                 skip "lustre version doesn't support lctl dl with non-root"
12766
12767         # debugfs only allows root users to access files, so the
12768         # previous move of the "devices" file to debugfs broke
12769         # "lctl dl" for non-root users. The LU-9680 Netlink
12770         # interface again allows non-root users to list devices.
12771         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12772                 error "lctl dl doesn't work for non root"
12773
12774         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12775         [ "$ost_count" -eq $OSTCOUNT ]  ||
12776                 error "lctl dl reports wrong number of OST devices"
12777
12778         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12779         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12780                 error "lctl dl reports wrong number of MDT devices"
12781 }
12782 run_test 104d "$RUNAS lctl dl test"
12783
12784 test_105a() {
12785         # doesn't work on 2.4 kernels
12786         touch $DIR/$tfile
12787         if $(flock_is_enabled); then
12788                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12789         else
12790                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12791         fi
12792         rm -f $DIR/$tfile
12793 }
12794 run_test 105a "flock when mounted without -o flock test ========"
12795
12796 test_105b() {
12797         touch $DIR/$tfile
12798         if $(flock_is_enabled); then
12799                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12800         else
12801                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12802         fi
12803         rm -f $DIR/$tfile
12804 }
12805 run_test 105b "fcntl when mounted without -o flock test ========"
12806
12807 test_105c() {
12808         touch $DIR/$tfile
12809         if $(flock_is_enabled); then
12810                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12811         else
12812                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12813         fi
12814         rm -f $DIR/$tfile
12815 }
12816 run_test 105c "lockf when mounted without -o flock test"
12817
12818 test_105d() { # bug 15924
12819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12820
12821         test_mkdir $DIR/$tdir
12822         flock_is_enabled || skip_env "mount w/o flock enabled"
12823         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12824         $LCTL set_param fail_loc=0x80000315
12825         flocks_test 2 $DIR/$tdir
12826 }
12827 run_test 105d "flock race (should not freeze) ========"
12828
12829 test_105e() { # bug 22660 && 22040
12830         flock_is_enabled || skip_env "mount w/o flock enabled"
12831
12832         touch $DIR/$tfile
12833         flocks_test 3 $DIR/$tfile
12834 }
12835 run_test 105e "Two conflicting flocks from same process"
12836
12837 test_106() { #bug 10921
12838         test_mkdir $DIR/$tdir
12839         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12840         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12841 }
12842 run_test 106 "attempt exec of dir followed by chown of that dir"
12843
12844 test_107() {
12845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12846
12847         CDIR=`pwd`
12848         local file=core
12849
12850         cd $DIR
12851         rm -f $file
12852
12853         local save_pattern=$(sysctl -n kernel.core_pattern)
12854         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12855         sysctl -w kernel.core_pattern=$file
12856         sysctl -w kernel.core_uses_pid=0
12857
12858         ulimit -c unlimited
12859         sleep 60 &
12860         SLEEPPID=$!
12861
12862         sleep 1
12863
12864         kill -s 11 $SLEEPPID
12865         wait $SLEEPPID
12866         if [ -e $file ]; then
12867                 size=`stat -c%s $file`
12868                 [ $size -eq 0 ] && error "Fail to create core file $file"
12869         else
12870                 error "Fail to create core file $file"
12871         fi
12872         rm -f $file
12873         sysctl -w kernel.core_pattern=$save_pattern
12874         sysctl -w kernel.core_uses_pid=$save_uses_pid
12875         cd $CDIR
12876 }
12877 run_test 107 "Coredump on SIG"
12878
12879 test_110() {
12880         test_mkdir $DIR/$tdir
12881         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12882         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12883                 error "mkdir with 256 char should fail, but did not"
12884         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12885                 error "create with 255 char failed"
12886         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12887                 error "create with 256 char should fail, but did not"
12888
12889         ls -l $DIR/$tdir
12890         rm -rf $DIR/$tdir
12891 }
12892 run_test 110 "filename length checking"
12893
12894 test_116a() { # was previously test_116()
12895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12897         remote_mds_nodsh && skip "remote MDS with nodsh"
12898
12899         echo -n "Free space priority "
12900         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12901                 head -n1
12902         declare -a AVAIL
12903         free_min_max
12904
12905         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12906         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12907         stack_trap simple_cleanup_common
12908
12909         # Check if we need to generate uneven OSTs
12910         test_mkdir -p $DIR/$tdir/OST${MINI}
12911         local FILL=$((MINV / 4))
12912         local DIFF=$((MAXV - MINV))
12913         local DIFF2=$((DIFF * 100 / MINV))
12914
12915         local threshold=$(do_facet $SINGLEMDS \
12916                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12917         threshold=${threshold%%%}
12918         echo -n "Check for uneven OSTs: "
12919         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12920
12921         if [[ $DIFF2 -gt $threshold ]]; then
12922                 echo "ok"
12923                 echo "Don't need to fill OST$MINI"
12924         else
12925                 # generate uneven OSTs. Write 2% over the QOS threshold value
12926                 echo "no"
12927                 DIFF=$((threshold - DIFF2 + 2))
12928                 DIFF2=$((MINV * DIFF / 100))
12929                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12930                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12931                         error "setstripe failed"
12932                 DIFF=$((DIFF2 / 2048))
12933                 i=0
12934                 while [ $i -lt $DIFF ]; do
12935                         i=$((i + 1))
12936                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12937                                 bs=2M count=1 2>/dev/null
12938                         echo -n .
12939                 done
12940                 echo .
12941                 sync
12942                 sleep_maxage
12943                 free_min_max
12944         fi
12945
12946         DIFF=$((MAXV - MINV))
12947         DIFF2=$((DIFF * 100 / MINV))
12948         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12949         if [ $DIFF2 -gt $threshold ]; then
12950                 echo "ok"
12951         else
12952                 skip "QOS imbalance criteria not met"
12953         fi
12954
12955         MINI1=$MINI
12956         MINV1=$MINV
12957         MAXI1=$MAXI
12958         MAXV1=$MAXV
12959
12960         # now fill using QOS
12961         $LFS setstripe -c 1 $DIR/$tdir
12962         FILL=$((FILL / 200))
12963         if [ $FILL -gt 600 ]; then
12964                 FILL=600
12965         fi
12966         echo "writing $FILL files to QOS-assigned OSTs"
12967         i=0
12968         while [ $i -lt $FILL ]; do
12969                 i=$((i + 1))
12970                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12971                         count=1 2>/dev/null
12972                 echo -n .
12973         done
12974         echo "wrote $i 200k files"
12975         sync
12976         sleep_maxage
12977
12978         echo "Note: free space may not be updated, so measurements might be off"
12979         free_min_max
12980         DIFF2=$((MAXV - MINV))
12981         echo "free space delta: orig $DIFF final $DIFF2"
12982         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12983         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12984         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12985         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12986         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12987         if [[ $DIFF -gt 0 ]]; then
12988                 FILL=$((DIFF2 * 100 / DIFF - 100))
12989                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12990         fi
12991
12992         # Figure out which files were written where
12993         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12994                awk '/'$MINI1': / {print $2; exit}')
12995         echo $UUID
12996         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12997         echo "$MINC files created on smaller OST $MINI1"
12998         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12999                awk '/'$MAXI1': / {print $2; exit}')
13000         echo $UUID
13001         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13002         echo "$MAXC files created on larger OST $MAXI1"
13003         if [[ $MINC -gt 0 ]]; then
13004                 FILL=$((MAXC * 100 / MINC - 100))
13005                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13006         fi
13007         [[ $MAXC -gt $MINC ]] ||
13008                 error_ignore LU-9 "stripe QOS didn't balance free space"
13009 }
13010 run_test 116a "stripe QOS: free space balance ==================="
13011
13012 test_116b() { # LU-2093
13013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13014         remote_mds_nodsh && skip "remote MDS with nodsh"
13015
13016 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13017         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13018                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13019         [ -z "$old_rr" ] && skip "no QOS"
13020         do_facet $SINGLEMDS lctl set_param \
13021                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13022         mkdir -p $DIR/$tdir
13023         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13024         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13025         do_facet $SINGLEMDS lctl set_param fail_loc=0
13026         rm -rf $DIR/$tdir
13027         do_facet $SINGLEMDS lctl set_param \
13028                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13029 }
13030 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13031
13032 test_117() # bug 10891
13033 {
13034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13035
13036         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13037         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13038         lctl set_param fail_loc=0x21e
13039         > $DIR/$tfile || error "truncate failed"
13040         lctl set_param fail_loc=0
13041         echo "Truncate succeeded."
13042         rm -f $DIR/$tfile
13043 }
13044 run_test 117 "verify osd extend =========="
13045
13046 NO_SLOW_RESENDCOUNT=4
13047 export OLD_RESENDCOUNT=""
13048 set_resend_count () {
13049         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13050         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13051         lctl set_param -n $PROC_RESENDCOUNT $1
13052         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13053 }
13054
13055 # for reduce test_118* time (b=14842)
13056 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13057
13058 # Reset async IO behavior after error case
13059 reset_async() {
13060         FILE=$DIR/reset_async
13061
13062         # Ensure all OSCs are cleared
13063         $LFS setstripe -c -1 $FILE
13064         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13065         sync
13066         rm $FILE
13067 }
13068
13069 test_118a() #bug 11710
13070 {
13071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13072
13073         reset_async
13074
13075         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13076         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13077         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13078
13079         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13080                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13081                 return 1;
13082         fi
13083         rm -f $DIR/$tfile
13084 }
13085 run_test 118a "verify O_SYNC works =========="
13086
13087 test_118b()
13088 {
13089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13090         remote_ost_nodsh && skip "remote OST with nodsh"
13091
13092         reset_async
13093
13094         #define OBD_FAIL_SRV_ENOENT 0x217
13095         set_nodes_failloc "$(osts_nodes)" 0x217
13096         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13097         RC=$?
13098         set_nodes_failloc "$(osts_nodes)" 0
13099         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13100         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13101                     grep -c writeback)
13102
13103         if [[ $RC -eq 0 ]]; then
13104                 error "Must return error due to dropped pages, rc=$RC"
13105                 return 1;
13106         fi
13107
13108         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13109                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13110                 return 1;
13111         fi
13112
13113         echo "Dirty pages not leaked on ENOENT"
13114
13115         # Due to the above error the OSC will issue all RPCs syncronously
13116         # until a subsequent RPC completes successfully without error.
13117         $MULTIOP $DIR/$tfile Ow4096yc
13118         rm -f $DIR/$tfile
13119
13120         return 0
13121 }
13122 run_test 118b "Reclaim dirty pages on fatal error =========="
13123
13124 test_118c()
13125 {
13126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13127
13128         # for 118c, restore the original resend count, LU-1940
13129         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13130                                 set_resend_count $OLD_RESENDCOUNT
13131         remote_ost_nodsh && skip "remote OST with nodsh"
13132
13133         reset_async
13134
13135         #define OBD_FAIL_OST_EROFS               0x216
13136         set_nodes_failloc "$(osts_nodes)" 0x216
13137
13138         # multiop should block due to fsync until pages are written
13139         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13140         MULTIPID=$!
13141         sleep 1
13142
13143         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13144                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13145         fi
13146
13147         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13148                     grep -c writeback)
13149         if [[ $WRITEBACK -eq 0 ]]; then
13150                 error "No page in writeback, writeback=$WRITEBACK"
13151         fi
13152
13153         set_nodes_failloc "$(osts_nodes)" 0
13154         wait $MULTIPID
13155         RC=$?
13156         if [[ $RC -ne 0 ]]; then
13157                 error "Multiop fsync failed, rc=$RC"
13158         fi
13159
13160         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13161         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13162                     grep -c writeback)
13163         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13164                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13165         fi
13166
13167         rm -f $DIR/$tfile
13168         echo "Dirty pages flushed via fsync on EROFS"
13169         return 0
13170 }
13171 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13172
13173 # continue to use small resend count to reduce test_118* time (b=14842)
13174 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13175
13176 test_118d()
13177 {
13178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13179         remote_ost_nodsh && skip "remote OST with nodsh"
13180
13181         reset_async
13182
13183         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13184         set_nodes_failloc "$(osts_nodes)" 0x214
13185         # multiop should block due to fsync until pages are written
13186         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13187         MULTIPID=$!
13188         sleep 1
13189
13190         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13191                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13192         fi
13193
13194         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13195                     grep -c writeback)
13196         if [[ $WRITEBACK -eq 0 ]]; then
13197                 error "No page in writeback, writeback=$WRITEBACK"
13198         fi
13199
13200         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13201         set_nodes_failloc "$(osts_nodes)" 0
13202
13203         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13204         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13205                     grep -c writeback)
13206         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13207                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13208         fi
13209
13210         rm -f $DIR/$tfile
13211         echo "Dirty pages gaurenteed flushed via fsync"
13212         return 0
13213 }
13214 run_test 118d "Fsync validation inject a delay of the bulk =========="
13215
13216 test_118f() {
13217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13218
13219         reset_async
13220
13221         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13222         lctl set_param fail_loc=0x8000040a
13223
13224         # Should simulate EINVAL error which is fatal
13225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13226         RC=$?
13227         if [[ $RC -eq 0 ]]; then
13228                 error "Must return error due to dropped pages, rc=$RC"
13229         fi
13230
13231         lctl set_param fail_loc=0x0
13232
13233         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13234         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13235         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13236                     grep -c writeback)
13237         if [[ $LOCKED -ne 0 ]]; then
13238                 error "Locked pages remain in cache, locked=$LOCKED"
13239         fi
13240
13241         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13242                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13243         fi
13244
13245         rm -f $DIR/$tfile
13246         echo "No pages locked after fsync"
13247
13248         reset_async
13249         return 0
13250 }
13251 run_test 118f "Simulate unrecoverable OSC side error =========="
13252
13253 test_118g() {
13254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13255
13256         reset_async
13257
13258         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13259         lctl set_param fail_loc=0x406
13260
13261         # simulate local -ENOMEM
13262         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13263         RC=$?
13264
13265         lctl set_param fail_loc=0
13266         if [[ $RC -eq 0 ]]; then
13267                 error "Must return error due to dropped pages, rc=$RC"
13268         fi
13269
13270         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13271         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13272         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13273                         grep -c writeback)
13274         if [[ $LOCKED -ne 0 ]]; then
13275                 error "Locked pages remain in cache, locked=$LOCKED"
13276         fi
13277
13278         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13279                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13280         fi
13281
13282         rm -f $DIR/$tfile
13283         echo "No pages locked after fsync"
13284
13285         reset_async
13286         return 0
13287 }
13288 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13289
13290 test_118h() {
13291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13292         remote_ost_nodsh && skip "remote OST with nodsh"
13293
13294         reset_async
13295
13296         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13297         set_nodes_failloc "$(osts_nodes)" 0x20e
13298         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13299         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13300         RC=$?
13301
13302         set_nodes_failloc "$(osts_nodes)" 0
13303         if [[ $RC -eq 0 ]]; then
13304                 error "Must return error due to dropped pages, rc=$RC"
13305         fi
13306
13307         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13308         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13309         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13310                     grep -c writeback)
13311         if [[ $LOCKED -ne 0 ]]; then
13312                 error "Locked pages remain in cache, locked=$LOCKED"
13313         fi
13314
13315         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13316                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13317         fi
13318
13319         rm -f $DIR/$tfile
13320         echo "No pages locked after fsync"
13321
13322         return 0
13323 }
13324 run_test 118h "Verify timeout in handling recoverables errors  =========="
13325
13326 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13327
13328 test_118i() {
13329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13330         remote_ost_nodsh && skip "remote OST with nodsh"
13331
13332         reset_async
13333
13334         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13335         set_nodes_failloc "$(osts_nodes)" 0x20e
13336
13337         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13338         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13339         PID=$!
13340         sleep 5
13341         set_nodes_failloc "$(osts_nodes)" 0
13342
13343         wait $PID
13344         RC=$?
13345         if [[ $RC -ne 0 ]]; then
13346                 error "got error, but should be not, rc=$RC"
13347         fi
13348
13349         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13350         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13351         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13352         if [[ $LOCKED -ne 0 ]]; then
13353                 error "Locked pages remain in cache, locked=$LOCKED"
13354         fi
13355
13356         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13357                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13358         fi
13359
13360         rm -f $DIR/$tfile
13361         echo "No pages locked after fsync"
13362
13363         return 0
13364 }
13365 run_test 118i "Fix error before timeout in recoverable error  =========="
13366
13367 [ "$SLOW" = "no" ] && set_resend_count 4
13368
13369 test_118j() {
13370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13371         remote_ost_nodsh && skip "remote OST with nodsh"
13372
13373         reset_async
13374
13375         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13376         set_nodes_failloc "$(osts_nodes)" 0x220
13377
13378         # return -EIO from OST
13379         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13380         RC=$?
13381         set_nodes_failloc "$(osts_nodes)" 0x0
13382         if [[ $RC -eq 0 ]]; then
13383                 error "Must return error due to dropped pages, rc=$RC"
13384         fi
13385
13386         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13387         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13388         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13389         if [[ $LOCKED -ne 0 ]]; then
13390                 error "Locked pages remain in cache, locked=$LOCKED"
13391         fi
13392
13393         # in recoverable error on OST we want resend and stay until it finished
13394         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13395                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13396         fi
13397
13398         rm -f $DIR/$tfile
13399         echo "No pages locked after fsync"
13400
13401         return 0
13402 }
13403 run_test 118j "Simulate unrecoverable OST side error =========="
13404
13405 test_118k()
13406 {
13407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13408         remote_ost_nodsh && skip "remote OSTs with nodsh"
13409
13410         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13411         set_nodes_failloc "$(osts_nodes)" 0x20e
13412         test_mkdir $DIR/$tdir
13413
13414         for ((i=0;i<10;i++)); do
13415                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13416                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13417                 SLEEPPID=$!
13418                 sleep 0.500s
13419                 kill $SLEEPPID
13420                 wait $SLEEPPID
13421         done
13422
13423         set_nodes_failloc "$(osts_nodes)" 0
13424         rm -rf $DIR/$tdir
13425 }
13426 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13427
13428 test_118l() # LU-646
13429 {
13430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13431
13432         test_mkdir $DIR/$tdir
13433         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13434         rm -rf $DIR/$tdir
13435 }
13436 run_test 118l "fsync dir"
13437
13438 test_118m() # LU-3066
13439 {
13440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13441
13442         test_mkdir $DIR/$tdir
13443         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13444         rm -rf $DIR/$tdir
13445 }
13446 run_test 118m "fdatasync dir ========="
13447
13448 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13449
13450 test_118n()
13451 {
13452         local begin
13453         local end
13454
13455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13456         remote_ost_nodsh && skip "remote OSTs with nodsh"
13457
13458         # Sleep to avoid a cached response.
13459         #define OBD_STATFS_CACHE_SECONDS 1
13460         sleep 2
13461
13462         # Inject a 10 second delay in the OST_STATFS handler.
13463         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13464         set_nodes_failloc "$(osts_nodes)" 0x242
13465
13466         begin=$SECONDS
13467         stat --file-system $MOUNT > /dev/null
13468         end=$SECONDS
13469
13470         set_nodes_failloc "$(osts_nodes)" 0
13471
13472         if ((end - begin > 20)); then
13473             error "statfs took $((end - begin)) seconds, expected 10"
13474         fi
13475 }
13476 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13477
13478 test_119a() # bug 11737
13479 {
13480         BSIZE=$((512 * 1024))
13481         directio write $DIR/$tfile 0 1 $BSIZE
13482         # We ask to read two blocks, which is more than a file size.
13483         # directio will indicate an error when requested and actual
13484         # sizes aren't equeal (a normal situation in this case) and
13485         # print actual read amount.
13486         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13487         if [ "$NOB" != "$BSIZE" ]; then
13488                 error "read $NOB bytes instead of $BSIZE"
13489         fi
13490         rm -f $DIR/$tfile
13491 }
13492 run_test 119a "Short directIO read must return actual read amount"
13493
13494 test_119b() # bug 11737
13495 {
13496         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13497
13498         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13499         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13500         sync
13501         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13502                 error "direct read failed"
13503         rm -f $DIR/$tfile
13504 }
13505 run_test 119b "Sparse directIO read must return actual read amount"
13506
13507 test_119c() # bug 13099
13508 {
13509         BSIZE=1048576
13510         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13511         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13512         rm -f $DIR/$tfile
13513 }
13514 run_test 119c "Testing for direct read hitting hole"
13515
13516 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13517 # Maloo test history
13518
13519 test_119e()
13520 {
13521         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13522
13523         local stripe_size=$((1024 * 1024)) #1 MiB
13524         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13525         local file_size=$((25 * stripe_size))
13526         local bsizes
13527
13528         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13529         stack_trap "rm -f $DIR/$tfile*"
13530
13531         # Just a bit bigger than the largest size in the test set below
13532         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13533                 error "buffered i/o to create file failed"
13534
13535         if zfs_or_rotational; then
13536                 # DIO on ZFS can take up to 2 seconds per IO
13537                 # rotational is better, but still slow.
13538                 # Limit testing on those media to larger sizes
13539                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13540         else
13541                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13542                         $((stripe_size * 4))"
13543         fi
13544
13545         for bs in $bsizes; do
13546                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13547                 echo "Read/write with DIO at size $bs"
13548                 # Read and write with DIO from source to dest
13549                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13550                         iflag=direct oflag=direct ||
13551                         error "dio failed"
13552
13553                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13554                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13555                         error "size incorrect, file copy read/write bsize: $bs"
13556                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13557                         error "files differ, bsize $bs"
13558                 rm -f $DIR/$tfile.2
13559         done
13560 }
13561 run_test 119e "Basic tests of dio read and write at various sizes"
13562
13563 test_119f()
13564 {
13565         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13566
13567         local stripe_size=$((1024 * 1024)) #1 MiB
13568         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13569         local file_size=$((25 * stripe_size))
13570         local bsizes
13571
13572         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13573         stack_trap "rm -f $DIR/$tfile*"
13574
13575         # Just a bit bigger than the largest size in the test set below
13576         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13577                 error "buffered i/o to create file failed"
13578
13579         if zfs_or_rotational; then
13580                 # DIO on ZFS can take up to 2 seconds per IO
13581                 # rotational is better, but still slow.
13582                 # Limit testing on those media to larger sizes
13583                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13584         else
13585                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13586                         $((stripe_size * 4))"
13587         fi
13588
13589         for bs in $bsizes; do
13590                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13591                 # Read and write with DIO from source to dest in two
13592                 # threads - should give correct copy of file
13593
13594                 echo "bs: $bs"
13595                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13596                         oflag=direct conv=notrunc &
13597                 pid_dio1=$!
13598                 # Note block size is different here for a more interesting race
13599                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13600                         iflag=direct oflag=direct conv=notrunc &
13601                 pid_dio2=$!
13602                 wait $pid_dio1
13603                 rc1=$?
13604                 wait $pid_dio2
13605                 rc2=$?
13606                 if (( rc1 != 0 )); then
13607                         error "dio copy 1 w/bsize $bs failed: $rc1"
13608                 fi
13609                 if (( rc2 != 0 )); then
13610                         error "dio copy 2 w/bsize $bs failed: $rc2"
13611                 fi
13612
13613
13614                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13615                         error "size incorrect, file copy read/write bsize: $bs"
13616                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13617                         error "files differ, bsize $bs"
13618                 rm -f $DIR/$tfile.2
13619         done
13620 }
13621 run_test 119f "dio vs dio race"
13622
13623 test_119g()
13624 {
13625         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13626
13627         local stripe_size=$((1024 * 1024)) #1 MiB
13628         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13629         local file_size=$((25 * stripe_size))
13630         local bsizes
13631
13632         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13633         stack_trap "rm -f $DIR/$tfile*"
13634
13635         # Just a bit bigger than the largest size in the test set below
13636         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13637                 error "buffered i/o to create file failed"
13638
13639         if zfs_or_rotational; then
13640                 # DIO on ZFS can take up to 2 seconds per IO
13641                 # rotational is better, but still slow.
13642                 # Limit testing on those media to larger sizes
13643                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13644         else
13645                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13646                         $((stripe_size * 4))"
13647         fi
13648
13649         for bs in $bsizes; do
13650                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13651                 echo "bs: $bs"
13652                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13653                         oflag=direct conv=notrunc &
13654                 pid_dio1=$!
13655                 # Buffered I/O with similar but not the same block size
13656                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13657                 pid_bio2=$!
13658                 wait $pid_dio1
13659                 rc1=$?
13660                 wait $pid_bio2
13661                 rc2=$?
13662                 if (( rc1 != 0 )); then
13663                         error "dio copy 1 w/bsize $bs failed: $rc1"
13664                 fi
13665                 if (( rc2 != 0 )); then
13666                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13667                 fi
13668
13669                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13670                         error "size incorrect"
13671                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13672                         error "files differ, bsize $bs"
13673                 rm -f $DIR/$tfile.2
13674         done
13675 }
13676 run_test 119g "dio vs buffered I/O race"
13677
13678 test_120a() {
13679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13680         remote_mds_nodsh && skip "remote MDS with nodsh"
13681         test_mkdir -i0 -c1 $DIR/$tdir
13682         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13683                 skip_env "no early lock cancel on server"
13684
13685         lru_resize_disable mdc
13686         lru_resize_disable osc
13687         cancel_lru_locks mdc
13688         # asynchronous object destroy at MDT could cause bl ast to client
13689         cancel_lru_locks osc
13690
13691         stat $DIR/$tdir > /dev/null
13692         can1=$(do_facet mds1 \
13693                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13694                awk '/ldlm_cancel/ {print $2}')
13695         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13696                awk '/ldlm_bl_callback/ {print $2}')
13697         test_mkdir -i0 -c1 $DIR/$tdir/d1
13698         can2=$(do_facet mds1 \
13699                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13700                awk '/ldlm_cancel/ {print $2}')
13701         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13702                awk '/ldlm_bl_callback/ {print $2}')
13703         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13704         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13705         lru_resize_enable mdc
13706         lru_resize_enable osc
13707 }
13708 run_test 120a "Early Lock Cancel: mkdir test"
13709
13710 test_120b() {
13711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13712         remote_mds_nodsh && skip "remote MDS with nodsh"
13713         test_mkdir $DIR/$tdir
13714         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13715                 skip_env "no early lock cancel on server"
13716
13717         lru_resize_disable mdc
13718         lru_resize_disable osc
13719         cancel_lru_locks mdc
13720         stat $DIR/$tdir > /dev/null
13721         can1=$(do_facet $SINGLEMDS \
13722                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13723                awk '/ldlm_cancel/ {print $2}')
13724         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13725                awk '/ldlm_bl_callback/ {print $2}')
13726         touch $DIR/$tdir/f1
13727         can2=$(do_facet $SINGLEMDS \
13728                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13729                awk '/ldlm_cancel/ {print $2}')
13730         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13731                awk '/ldlm_bl_callback/ {print $2}')
13732         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13733         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13734         lru_resize_enable mdc
13735         lru_resize_enable osc
13736 }
13737 run_test 120b "Early Lock Cancel: create test"
13738
13739 test_120c() {
13740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13741         remote_mds_nodsh && skip "remote MDS with nodsh"
13742         test_mkdir -i0 -c1 $DIR/$tdir
13743         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13744                 skip "no early lock cancel on server"
13745
13746         lru_resize_disable mdc
13747         lru_resize_disable osc
13748         test_mkdir -i0 -c1 $DIR/$tdir/d1
13749         test_mkdir -i0 -c1 $DIR/$tdir/d2
13750         touch $DIR/$tdir/d1/f1
13751         cancel_lru_locks mdc
13752         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13753         can1=$(do_facet mds1 \
13754                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13755                awk '/ldlm_cancel/ {print $2}')
13756         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13757                awk '/ldlm_bl_callback/ {print $2}')
13758         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13759         can2=$(do_facet mds1 \
13760                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13761                awk '/ldlm_cancel/ {print $2}')
13762         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13763                awk '/ldlm_bl_callback/ {print $2}')
13764         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13765         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13766         lru_resize_enable mdc
13767         lru_resize_enable osc
13768 }
13769 run_test 120c "Early Lock Cancel: link test"
13770
13771 test_120d() {
13772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13773         remote_mds_nodsh && skip "remote MDS with nodsh"
13774         test_mkdir -i0 -c1 $DIR/$tdir
13775         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13776                 skip_env "no early lock cancel on server"
13777
13778         lru_resize_disable mdc
13779         lru_resize_disable osc
13780         touch $DIR/$tdir
13781         cancel_lru_locks mdc
13782         stat $DIR/$tdir > /dev/null
13783         can1=$(do_facet mds1 \
13784                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13785                awk '/ldlm_cancel/ {print $2}')
13786         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13787                awk '/ldlm_bl_callback/ {print $2}')
13788         chmod a+x $DIR/$tdir
13789         can2=$(do_facet mds1 \
13790                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13791                awk '/ldlm_cancel/ {print $2}')
13792         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13793                awk '/ldlm_bl_callback/ {print $2}')
13794         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13795         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13796         lru_resize_enable mdc
13797         lru_resize_enable osc
13798 }
13799 run_test 120d "Early Lock Cancel: setattr test"
13800
13801 test_120e() {
13802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13803         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13804                 skip_env "no early lock cancel on server"
13805         remote_mds_nodsh && skip "remote MDS with nodsh"
13806
13807         local dlmtrace_set=false
13808
13809         test_mkdir -i0 -c1 $DIR/$tdir
13810         lru_resize_disable mdc
13811         lru_resize_disable osc
13812         ! $LCTL get_param debug | grep -q dlmtrace &&
13813                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13814         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13815         cancel_lru_locks mdc
13816         cancel_lru_locks osc
13817         dd if=$DIR/$tdir/f1 of=/dev/null
13818         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13819         # XXX client can not do early lock cancel of OST lock
13820         # during unlink (LU-4206), so cancel osc lock now.
13821         sleep 2
13822         cancel_lru_locks osc
13823         can1=$(do_facet mds1 \
13824                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13825                awk '/ldlm_cancel/ {print $2}')
13826         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13827                awk '/ldlm_bl_callback/ {print $2}')
13828         unlink $DIR/$tdir/f1
13829         sleep 5
13830         can2=$(do_facet mds1 \
13831                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13832                awk '/ldlm_cancel/ {print $2}')
13833         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13834                awk '/ldlm_bl_callback/ {print $2}')
13835         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13836                 $LCTL dk $TMP/cancel.debug.txt
13837         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13838                 $LCTL dk $TMP/blocking.debug.txt
13839         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13840         lru_resize_enable mdc
13841         lru_resize_enable osc
13842 }
13843 run_test 120e "Early Lock Cancel: unlink test"
13844
13845 test_120f() {
13846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13847         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13848                 skip_env "no early lock cancel on server"
13849         remote_mds_nodsh && skip "remote MDS with nodsh"
13850
13851         test_mkdir -i0 -c1 $DIR/$tdir
13852         lru_resize_disable mdc
13853         lru_resize_disable osc
13854         test_mkdir -i0 -c1 $DIR/$tdir/d1
13855         test_mkdir -i0 -c1 $DIR/$tdir/d2
13856         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13857         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13858         cancel_lru_locks mdc
13859         cancel_lru_locks osc
13860         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13861         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13862         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13863         # XXX client can not do early lock cancel of OST lock
13864         # during rename (LU-4206), so cancel osc lock now.
13865         sleep 2
13866         cancel_lru_locks osc
13867         can1=$(do_facet mds1 \
13868                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13869                awk '/ldlm_cancel/ {print $2}')
13870         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13871                awk '/ldlm_bl_callback/ {print $2}')
13872         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13873         sleep 5
13874         can2=$(do_facet mds1 \
13875                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13876                awk '/ldlm_cancel/ {print $2}')
13877         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13878                awk '/ldlm_bl_callback/ {print $2}')
13879         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13880         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13881         lru_resize_enable mdc
13882         lru_resize_enable osc
13883 }
13884 run_test 120f "Early Lock Cancel: rename test"
13885
13886 test_120g() {
13887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13888         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13889                 skip_env "no early lock cancel on server"
13890         remote_mds_nodsh && skip "remote MDS with nodsh"
13891
13892         lru_resize_disable mdc
13893         lru_resize_disable osc
13894         count=10000
13895         echo create $count files
13896         test_mkdir $DIR/$tdir
13897         cancel_lru_locks mdc
13898         cancel_lru_locks osc
13899         t0=$(date +%s)
13900
13901         can0=$(do_facet $SINGLEMDS \
13902                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13903                awk '/ldlm_cancel/ {print $2}')
13904         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13905                awk '/ldlm_bl_callback/ {print $2}')
13906         createmany -o $DIR/$tdir/f $count
13907         sync
13908         can1=$(do_facet $SINGLEMDS \
13909                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13910                awk '/ldlm_cancel/ {print $2}')
13911         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13912                awk '/ldlm_bl_callback/ {print $2}')
13913         t1=$(date +%s)
13914         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13915         echo rm $count files
13916         rm -r $DIR/$tdir
13917         sync
13918         can2=$(do_facet $SINGLEMDS \
13919                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13920                awk '/ldlm_cancel/ {print $2}')
13921         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13922                awk '/ldlm_bl_callback/ {print $2}')
13923         t2=$(date +%s)
13924         echo total: $count removes in $((t2-t1))
13925         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13926         sleep 2
13927         # wait for commitment of removal
13928         lru_resize_enable mdc
13929         lru_resize_enable osc
13930 }
13931 run_test 120g "Early Lock Cancel: performance test"
13932
13933 test_121() { #bug #10589
13934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13935
13936         rm -rf $DIR/$tfile
13937         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13938 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13939         lctl set_param fail_loc=0x310
13940         cancel_lru_locks osc > /dev/null
13941         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13942         lctl set_param fail_loc=0
13943         [[ $reads -eq $writes ]] ||
13944                 error "read $reads blocks, must be $writes blocks"
13945 }
13946 run_test 121 "read cancel race ========="
13947
13948 test_123a_base() { # was test 123, statahead(bug 11401)
13949         local lsx="$1"
13950
13951         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13952
13953         SLOWOK=0
13954         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13955                 log "testing UP system. Performance may be lower than expected."
13956                 SLOWOK=1
13957         fi
13958         running_in_vm && SLOWOK=1
13959
13960         $LCTL set_param mdc.*.batch_stats=0
13961
13962         rm -rf $DIR/$tdir
13963         test_mkdir $DIR/$tdir
13964         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13965         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13966         MULT=10
13967         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13968                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13969
13970                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13971                 lctl set_param -n llite.*.statahead_max 0
13972                 lctl get_param llite.*.statahead_max
13973                 cancel_lru_locks mdc
13974                 cancel_lru_locks osc
13975                 stime=$(date +%s)
13976                 time $lsx $DIR/$tdir | wc -l
13977                 etime=$(date +%s)
13978                 delta=$((etime - stime))
13979                 log "$lsx $i files without statahead: $delta sec"
13980                 lctl set_param llite.*.statahead_max=$max
13981
13982                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13983                          awk '/statahead.wrong:/ { print $NF }')
13984                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13985                 cancel_lru_locks mdc
13986                 cancel_lru_locks osc
13987                 stime=$(date +%s)
13988                 time $lsx $DIR/$tdir | wc -l
13989                 etime=$(date +%s)
13990                 delta_sa=$((etime - stime))
13991                 log "$lsx $i files with statahead: $delta_sa sec"
13992                 lctl get_param -n llite.*.statahead_stats
13993                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13994                          awk '/statahead.wrong:/ { print $NF }')
13995
13996                 [[ $swrong -lt $ewrong ]] &&
13997                         log "statahead was stopped, maybe too many locks held!"
13998                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13999
14000                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14001                         max=$(lctl get_param -n llite.*.statahead_max |
14002                                 head -n 1)
14003                         lctl set_param -n llite.*.statahead_max 0
14004                         lctl get_param llite.*.statahead_max
14005                         cancel_lru_locks mdc
14006                         cancel_lru_locks osc
14007                         stime=$(date +%s)
14008                         time $lsx $DIR/$tdir | wc -l
14009                         etime=$(date +%s)
14010                         delta=$((etime - stime))
14011                         log "$lsx $i files again without statahead: $delta sec"
14012                         lctl set_param llite.*.statahead_max=$max
14013                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14014                                 if [ $SLOWOK -eq 0 ]; then
14015                                         error "$lsx $i files is slower with statahead!"
14016                                 else
14017                                         log "$lsx $i files is slower with statahead!"
14018                                 fi
14019                                 break
14020                         fi
14021                 fi
14022
14023                 [ $delta -gt 20 ] && break
14024                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14025                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14026         done
14027         log "$lsx done"
14028
14029         stime=$(date +%s)
14030         rm -r $DIR/$tdir
14031         sync
14032         etime=$(date +%s)
14033         delta=$((etime - stime))
14034         log "rm -r $DIR/$tdir/: $delta seconds"
14035         log "rm done"
14036         lctl get_param -n llite.*.statahead_stats
14037         $LCTL get_param mdc.*.batch_stats
14038 }
14039
14040 test_123aa() {
14041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14042
14043         test_123a_base "ls -l"
14044 }
14045 run_test 123aa "verify statahead work"
14046
14047 test_123ab() {
14048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14049
14050         statx_supported || skip_env "Test must be statx() syscall supported"
14051
14052         test_123a_base "$STATX -l"
14053 }
14054 run_test 123ab "verify statahead work by using statx"
14055
14056 test_123ac() {
14057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14058
14059         statx_supported || skip_env "Test must be statx() syscall supported"
14060
14061         local rpcs_before
14062         local rpcs_after
14063         local agl_before
14064         local agl_after
14065
14066         cancel_lru_locks $OSC
14067         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14068         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14069                      awk '/agl.total:/ { print $NF }')
14070         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14071         test_123a_base "$STATX --cached=always -D"
14072         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14073                     awk '/agl.total:/ { print $NF }')
14074         [ $agl_before -eq $agl_after ] ||
14075                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14076         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14077         [ $rpcs_after -eq $rpcs_before ] ||
14078                 error "$STATX should not send glimpse RPCs to $OSC"
14079 }
14080 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14081
14082 test_batch_statahead() {
14083         local max=$1
14084         local batch_max=$2
14085         local num=10000
14086         local batch_rpcs
14087         local unbatch_rpcs
14088         local hit_total
14089
14090         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14091         $LCTL set_param mdc.*.batch_stats=0
14092         $LCTL set_param llite.*.statahead_max=$max
14093         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14094         # Verify that batched statahead is faster than one without statahead
14095         test_123a_base "ls -l"
14096
14097         stack_trap "rm -rf $DIR/$tdir" EXIT
14098         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14099         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14100
14101         # unbatched statahead
14102         $LCTL set_param llite.*.statahead_batch_max=0
14103         $LCTL set_param llite.*.statahead_stats=clear
14104         $LCTL set_param mdc.*.stats=clear
14105         cancel_lru_locks mdc
14106         cancel_lru_locks osc
14107         time ls -l $DIR/$tdir | wc -l
14108         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14109         sleep 2
14110         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14111                     awk '/hit.total:/ { print $NF }')
14112         # hit ratio should be larger than 75% (7500).
14113         (( $hit_total > 7500 )) ||
14114                 error "unbatched statahead hit count ($hit_total) is too low"
14115
14116         # batched statahead
14117         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14118         $LCTL set_param llite.*.statahead_stats=clear
14119         $LCTL set_param mdc.*.batch_stats=clear
14120         $LCTL set_param mdc.*.stats=clear
14121         cancel_lru_locks mdc
14122         cancel_lru_locks osc
14123         time ls -l $DIR/$tdir | wc -l
14124         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14125         # wait for statahead thread to quit and update statahead stats
14126         sleep 2
14127         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14128                     awk '/hit.total:/ { print $NF }')
14129         # hit ratio should be larger than 75% (7500).
14130         (( $hit_total > 7500 )) ||
14131                 error "batched statahead hit count ($hit_total) is too low"
14132
14133         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14134         (( $unbatch_rpcs > $batch_rpcs )) ||
14135                 error "batched statahead does not reduce RPC count"
14136         $LCTL get_param mdc.*.batch_stats
14137 }
14138
14139 test_123ad() {
14140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14141
14142         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14143                 skip "Need server version at least 2.15.53"
14144
14145         local max
14146         local batch_max
14147
14148         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14149         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14150
14151         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14152         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14153
14154         test_batch_statahead 32 32
14155         test_batch_statahead 2048 256
14156 }
14157 run_test 123ad "Verify batching statahead works correctly"
14158
14159 test_123b () { # statahead(bug 15027)
14160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14161
14162         test_mkdir $DIR/$tdir
14163         createmany -o $DIR/$tdir/$tfile-%d 1000
14164
14165         cancel_lru_locks mdc
14166         cancel_lru_locks osc
14167
14168 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14169         lctl set_param fail_loc=0x80000803
14170         ls -lR $DIR/$tdir > /dev/null
14171         log "ls done"
14172         lctl set_param fail_loc=0x0
14173         lctl get_param -n llite.*.statahead_stats
14174         rm -r $DIR/$tdir
14175         sync
14176
14177 }
14178 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14179
14180 test_123c() {
14181         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14182
14183         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14184         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14185         touch $DIR/$tdir.1/{1..3}
14186         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14187
14188         remount_client $MOUNT
14189
14190         $MULTIOP $DIR/$tdir.0 Q
14191
14192         # let statahead to complete
14193         ls -l $DIR/$tdir.0 > /dev/null
14194
14195         testid=$(echo $TESTNAME | tr '_' ' ')
14196         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14197                 error "statahead warning" || true
14198 }
14199 run_test 123c "Can not initialize inode warning on DNE statahead"
14200
14201 test_123d() {
14202         local num=100
14203         local swrong
14204         local ewrong
14205
14206         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14207         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14208                 error "setdirstripe $DIR/$tdir failed"
14209         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14210         remount_client $MOUNT
14211         $LCTL get_param llite.*.statahead_max
14212         $LCTL set_param llite.*.statahead_stats=0 ||
14213                 error "clear statahead_stats failed"
14214         swrong=$(lctl get_param -n llite.*.statahead_stats |
14215                  awk '/statahead.wrong:/ { print $NF }')
14216         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14217         # wait for statahead thread finished to update hit/miss stats.
14218         sleep 1
14219         $LCTL get_param -n llite.*.statahead_stats
14220         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14221                  awk '/statahead.wrong:/ { print $NF }')
14222         (( $swrong == $ewrong )) ||
14223                 log "statahead was stopped, maybe too many locks held!"
14224 }
14225 run_test 123d "Statahead on striped directories works correctly"
14226
14227 test_123e() {
14228         local max
14229         local batch_max
14230         local dir=$DIR/$tdir
14231
14232         mkdir $dir || error "mkdir $dir failed"
14233         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14234         stack_trap "rm -rf $dir"
14235
14236         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14237
14238         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14239         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14240         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14241         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14242
14243         $LCTL set_param llite.*.statahead_max=2048
14244         $LCTL set_param llite.*.statahead_batch_max=1024
14245
14246         ls -l $dir
14247         $LCTL get_param mdc.*.batch_stats
14248         $LCTL get_param llite.*.statahead_*
14249 }
14250 run_test 123e "statahead with large wide striping"
14251
14252 test_123f() {
14253         local max
14254         local batch_max
14255         local dir=$DIR/$tdir
14256
14257         mkdir $dir || error "mkdir $dir failed"
14258         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14259         stack_trap "rm -rf $dir"
14260
14261         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14262
14263         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14264         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14265
14266         $LCTL set_param llite.*.statahead_max=64
14267         $LCTL set_param llite.*.statahead_batch_max=64
14268
14269         ls -l $dir
14270         lctl get_param mdc.*.batch_stats
14271         lctl get_param llite.*.statahead_*
14272
14273         $LCTL set_param llite.*.statahead_max=$max
14274         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14275 }
14276 run_test 123f "Retry mechanism with large wide striping files"
14277
14278 test_124a() {
14279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14280         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14281                 skip_env "no lru resize on server"
14282
14283         local NR=2000
14284
14285         test_mkdir $DIR/$tdir
14286
14287         log "create $NR files at $DIR/$tdir"
14288         createmany -o $DIR/$tdir/f $NR ||
14289                 error "failed to create $NR files in $DIR/$tdir"
14290
14291         cancel_lru_locks mdc
14292         ls -l $DIR/$tdir > /dev/null
14293
14294         local NSDIR=""
14295         local LRU_SIZE=0
14296         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14297                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14298                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14299                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14300                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14301                         log "NSDIR=$NSDIR"
14302                         log "NS=$(basename $NSDIR)"
14303                         break
14304                 fi
14305         done
14306
14307         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14308                 skip "Not enough cached locks created!"
14309         fi
14310         log "LRU=$LRU_SIZE"
14311
14312         local SLEEP=30
14313
14314         # We know that lru resize allows one client to hold $LIMIT locks
14315         # for 10h. After that locks begin to be killed by client.
14316         local MAX_HRS=10
14317         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14318         log "LIMIT=$LIMIT"
14319         if [ $LIMIT -lt $LRU_SIZE ]; then
14320                 skip "Limit is too small $LIMIT"
14321         fi
14322
14323         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14324         # killing locks. Some time was spent for creating locks. This means
14325         # that up to the moment of sleep finish we must have killed some of
14326         # them (10-100 locks). This depends on how fast ther were created.
14327         # Many of them were touched in almost the same moment and thus will
14328         # be killed in groups.
14329         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14330
14331         # Use $LRU_SIZE_B here to take into account real number of locks
14332         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14333         local LRU_SIZE_B=$LRU_SIZE
14334         log "LVF=$LVF"
14335         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14336         log "OLD_LVF=$OLD_LVF"
14337         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14338
14339         # Let's make sure that we really have some margin. Client checks
14340         # cached locks every 10 sec.
14341         SLEEP=$((SLEEP+20))
14342         log "Sleep ${SLEEP} sec"
14343         local SEC=0
14344         while ((SEC<$SLEEP)); do
14345                 echo -n "..."
14346                 sleep 5
14347                 SEC=$((SEC+5))
14348                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14349                 echo -n "$LRU_SIZE"
14350         done
14351         echo ""
14352         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14353         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14354
14355         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14356                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14357                 unlinkmany $DIR/$tdir/f $NR
14358                 return
14359         }
14360
14361         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14362         log "unlink $NR files at $DIR/$tdir"
14363         unlinkmany $DIR/$tdir/f $NR
14364 }
14365 run_test 124a "lru resize ======================================="
14366
14367 get_max_pool_limit()
14368 {
14369         local limit=$($LCTL get_param \
14370                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14371         local max=0
14372         for l in $limit; do
14373                 if [[ $l -gt $max ]]; then
14374                         max=$l
14375                 fi
14376         done
14377         echo $max
14378 }
14379
14380 test_124b() {
14381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14382         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14383                 skip_env "no lru resize on server"
14384
14385         LIMIT=$(get_max_pool_limit)
14386
14387         NR=$(($(default_lru_size)*20))
14388         if [[ $NR -gt $LIMIT ]]; then
14389                 log "Limit lock number by $LIMIT locks"
14390                 NR=$LIMIT
14391         fi
14392
14393         IFree=$(mdsrate_inodes_available)
14394         if [ $IFree -lt $NR ]; then
14395                 log "Limit lock number by $IFree inodes"
14396                 NR=$IFree
14397         fi
14398
14399         lru_resize_disable mdc
14400         test_mkdir -p $DIR/$tdir/disable_lru_resize
14401
14402         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14403         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14404         cancel_lru_locks mdc
14405         stime=`date +%s`
14406         PID=""
14407         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14408         PID="$PID $!"
14409         sleep 2
14410         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14411         PID="$PID $!"
14412         sleep 2
14413         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14414         PID="$PID $!"
14415         wait $PID
14416         etime=`date +%s`
14417         nolruresize_delta=$((etime-stime))
14418         log "ls -la time: $nolruresize_delta seconds"
14419         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14420         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14421
14422         lru_resize_enable mdc
14423         test_mkdir -p $DIR/$tdir/enable_lru_resize
14424
14425         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14426         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14427         cancel_lru_locks mdc
14428         stime=`date +%s`
14429         PID=""
14430         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14431         PID="$PID $!"
14432         sleep 2
14433         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14434         PID="$PID $!"
14435         sleep 2
14436         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14437         PID="$PID $!"
14438         wait $PID
14439         etime=`date +%s`
14440         lruresize_delta=$((etime-stime))
14441         log "ls -la time: $lruresize_delta seconds"
14442         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14443
14444         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14445                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14446         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14447                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14448         else
14449                 log "lru resize performs the same with no lru resize"
14450         fi
14451         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14452 }
14453 run_test 124b "lru resize (performance test) ======================="
14454
14455 test_124c() {
14456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14457         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14458                 skip_env "no lru resize on server"
14459
14460         # cache ununsed locks on client
14461         local nr=100
14462         cancel_lru_locks mdc
14463         test_mkdir $DIR/$tdir
14464         createmany -o $DIR/$tdir/f $nr ||
14465                 error "failed to create $nr files in $DIR/$tdir"
14466         ls -l $DIR/$tdir > /dev/null
14467
14468         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14469         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14470         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14471         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14472         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14473
14474         # set lru_max_age to 1 sec
14475         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14476         echo "sleep $((recalc_p * 2)) seconds..."
14477         sleep $((recalc_p * 2))
14478
14479         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14480         # restore lru_max_age
14481         $LCTL set_param -n $nsdir.lru_max_age $max_age
14482         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14483         unlinkmany $DIR/$tdir/f $nr
14484 }
14485 run_test 124c "LRUR cancel very aged locks"
14486
14487 test_124d() {
14488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14489         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14490                 skip_env "no lru resize on server"
14491
14492         # cache ununsed locks on client
14493         local nr=100
14494
14495         lru_resize_disable mdc
14496         stack_trap "lru_resize_enable mdc" EXIT
14497
14498         cancel_lru_locks mdc
14499
14500         # asynchronous object destroy at MDT could cause bl ast to client
14501         test_mkdir $DIR/$tdir
14502         createmany -o $DIR/$tdir/f $nr ||
14503                 error "failed to create $nr files in $DIR/$tdir"
14504         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14505
14506         ls -l $DIR/$tdir > /dev/null
14507
14508         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14509         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14510         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14511         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14512
14513         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14514
14515         # set lru_max_age to 1 sec
14516         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14517         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14518
14519         echo "sleep $((recalc_p * 2)) seconds..."
14520         sleep $((recalc_p * 2))
14521
14522         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14523
14524         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14525 }
14526 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14527
14528 test_125() { # 13358
14529         $LCTL get_param -n llite.*.client_type | grep -q local ||
14530                 skip "must run as local client"
14531         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14532                 skip_env "must have acl enabled"
14533         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14534         id $USER0 || skip_env "missing user $USER0"
14535
14536         test_mkdir $DIR/$tdir
14537         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14538         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14539                 error "setfacl $DIR/$tdir failed"
14540         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14541 }
14542 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14543
14544 test_126() { # bug 12829/13455
14545         $GSS && skip_env "must run as gss disabled"
14546         $LCTL get_param -n llite.*.client_type | grep -q local ||
14547                 skip "must run as local client"
14548         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14549
14550         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14551         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14552         rm -f $DIR/$tfile
14553         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14554 }
14555 run_test 126 "check that the fsgid provided by the client is taken into account"
14556
14557 test_127a() { # bug 15521
14558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14559         local name count samp unit min max sum sumsq
14560         local tmpfile=$TMP/$tfile.tmp
14561
14562         # enable stats header if it is disabled
14563         $LCTL set_param enable_stats_header=1
14564
14565         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14566         echo "stats before reset"
14567         stack_trap "rm -f $tmpfile"
14568         local now=$(date +%s)
14569
14570         $LCTL get_param osc.*.stats | tee $tmpfile
14571
14572         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14573         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14574         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14575         local uptime=$(awk '{ print $1 }' /proc/uptime)
14576
14577         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14578         (( ${snapshot_time%\.*} >= $now - 5 &&
14579            ${snapshot_time%\.*} <= $now + 5 )) ||
14580                 error "snapshot_time=$snapshot_time != now=$now"
14581         # elapsed _should_ be from mount, but at least less than uptime
14582         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14583                 error "elapsed=$elapsed > uptime=$uptime"
14584         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14585            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14586                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14587
14588         $LCTL set_param osc.*.stats=0
14589         local reset=$(date +%s)
14590         local fsize=$((2048 * 1024))
14591
14592         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14593         cancel_lru_locks osc
14594         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14595
14596         now=$(date +%s)
14597         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14598         while read name count samp unit min max sum sumsq; do
14599                 [[ "$samp" == "samples" ]] || continue
14600
14601                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14602                 [ ! $min ] && error "Missing min value for $name proc entry"
14603                 eval $name=$count || error "Wrong proc format"
14604
14605                 case $name in
14606                 read_bytes|write_bytes)
14607                         [[ "$unit" =~ "bytes" ]] ||
14608                                 error "unit is not 'bytes': $unit"
14609                         (( $min >= 4096 )) || error "min is too small: $min"
14610                         (( $min <= $fsize )) || error "min is too big: $min"
14611                         (( $max >= 4096 )) || error "max is too small: $max"
14612                         (( $max <= $fsize )) || error "max is too big: $max"
14613                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14614                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14615                                 error "sumsquare is too small: $sumsq"
14616                         (( $sumsq <= $fsize * $fsize )) ||
14617                                 error "sumsquare is too big: $sumsq"
14618                         ;;
14619                 ost_read|ost_write)
14620                         [[ "$unit" =~ "usec" ]] ||
14621                                 error "unit is not 'usec': $unit"
14622                         ;;
14623                 *)      ;;
14624                 esac
14625         done < $tmpfile
14626
14627         #check that we actually got some stats
14628         [ "$read_bytes" ] || error "Missing read_bytes stats"
14629         [ "$write_bytes" ] || error "Missing write_bytes stats"
14630         [ "$read_bytes" != 0 ] || error "no read done"
14631         [ "$write_bytes" != 0 ] || error "no write done"
14632
14633         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14634         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14635         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14636
14637         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14638         (( ${snapshot_time%\.*} >= $now - 5 &&
14639            ${snapshot_time%\.*} <= $now + 5 )) ||
14640                 error "reset snapshot_time=$snapshot_time != now=$now"
14641         # elapsed should be from time of stats reset
14642         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14643            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14644                 error "reset elapsed=$elapsed > $now - $reset"
14645         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14646            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14647                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14648 }
14649 run_test 127a "verify the client stats are sane"
14650
14651 test_127b() { # bug LU-333
14652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14653         local name count samp unit min max sum sumsq
14654
14655         echo "stats before reset"
14656         $LCTL get_param llite.*.stats
14657         $LCTL set_param llite.*.stats=0
14658
14659         # perform 2 reads and writes so MAX is different from SUM.
14660         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14661         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14662         cancel_lru_locks osc
14663         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14664         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14665
14666         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14667         stack_trap "rm -f $TMP/$tfile.tmp"
14668         while read name count samp unit min max sum sumsq; do
14669                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14670                 eval $name=$count || error "Wrong proc format"
14671
14672                 case $name in
14673                 read_bytes|write_bytes)
14674                         [[ "$unit" =~ "bytes" ]] ||
14675                                 error "unit is not 'bytes': $unit"
14676                         (( $count == 2 )) || error "count is not 2: $count"
14677                         (( $min == $PAGE_SIZE )) ||
14678                                 error "min is not $PAGE_SIZE: $min"
14679                         (( $max == $PAGE_SIZE )) ||
14680                                 error "max is not $PAGE_SIZE: $max"
14681                         (( $sum == $PAGE_SIZE * 2 )) ||
14682                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14683                         ;;
14684                 read|write)
14685                         [[ "$unit" =~ "usec" ]] ||
14686                                 error "unit is not 'usec': $unit"
14687                         ;;
14688                 *)      ;;
14689                 esac
14690         done < $TMP/$tfile.tmp
14691
14692         #check that we actually got some stats
14693         [ "$read_bytes" ] || error "Missing read_bytes stats"
14694         [ "$write_bytes" ] || error "Missing write_bytes stats"
14695         [ "$read_bytes" != 0 ] || error "no read done"
14696         [ "$write_bytes" != 0 ] || error "no write done"
14697 }
14698 run_test 127b "verify the llite client stats are sane"
14699
14700 test_127c() { # LU-12394
14701         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14702         local size
14703         local bsize
14704         local reads
14705         local writes
14706         local count
14707
14708         $LCTL set_param llite.*.extents_stats=1
14709         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14710
14711         # Use two stripes so there is enough space in default config
14712         $LFS setstripe -c 2 $DIR/$tfile
14713
14714         # Extent stats start at 0-4K and go in power of two buckets
14715         # LL_HIST_START = 12 --> 2^12 = 4K
14716         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14717         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14718         # small configs
14719         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14720                 do
14721                 # Write and read, 2x each, second time at a non-zero offset
14722                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14723                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14724                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14725                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14726                 rm -f $DIR/$tfile
14727         done
14728
14729         $LCTL get_param llite.*.extents_stats
14730
14731         count=2
14732         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14733                 do
14734                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14735                                 grep -m 1 $bsize)
14736                 reads=$(echo $bucket | awk '{print $5}')
14737                 writes=$(echo $bucket | awk '{print $9}')
14738                 [ "$reads" -eq $count ] ||
14739                         error "$reads reads in < $bsize bucket, expect $count"
14740                 [ "$writes" -eq $count ] ||
14741                         error "$writes writes in < $bsize bucket, expect $count"
14742         done
14743
14744         # Test mmap write and read
14745         $LCTL set_param llite.*.extents_stats=c
14746         size=512
14747         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14748         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14749         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14750
14751         $LCTL get_param llite.*.extents_stats
14752
14753         count=$(((size*1024) / PAGE_SIZE))
14754
14755         bsize=$((2 * PAGE_SIZE / 1024))K
14756
14757         bucket=$($LCTL get_param -n llite.*.extents_stats |
14758                         grep -m 1 $bsize)
14759         reads=$(echo $bucket | awk '{print $5}')
14760         writes=$(echo $bucket | awk '{print $9}')
14761         # mmap writes fault in the page first, creating an additonal read
14762         [ "$reads" -eq $((2 * count)) ] ||
14763                 error "$reads reads in < $bsize bucket, expect $count"
14764         [ "$writes" -eq $count ] ||
14765                 error "$writes writes in < $bsize bucket, expect $count"
14766 }
14767 run_test 127c "test llite extent stats with regular & mmap i/o"
14768
14769 test_128() { # bug 15212
14770         touch $DIR/$tfile
14771         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14772                 find $DIR/$tfile
14773                 find $DIR/$tfile
14774         EOF
14775
14776         result=$(grep error $TMP/$tfile.log)
14777         rm -f $DIR/$tfile $TMP/$tfile.log
14778         [ -z "$result" ] ||
14779                 error "consecutive find's under interactive lfs failed"
14780 }
14781 run_test 128 "interactive lfs for 2 consecutive find's"
14782
14783 set_dir_limits () {
14784         local mntdev
14785         local canondev
14786         local node
14787
14788         local ldproc=/proc/fs/ldiskfs
14789         local facets=$(get_facets MDS)
14790
14791         for facet in ${facets//,/ }; do
14792                 canondev=$(ldiskfs_canon \
14793                            *.$(convert_facet2label $facet).mntdev $facet)
14794                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14795                         ldproc=/sys/fs/ldiskfs
14796                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14797                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14798         done
14799 }
14800
14801 check_mds_dmesg() {
14802         local facets=$(get_facets MDS)
14803         for facet in ${facets//,/ }; do
14804                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14805         done
14806         return 1
14807 }
14808
14809 test_129() {
14810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14811         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14812                 skip "Need MDS version with at least 2.5.56"
14813         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14814                 skip_env "ldiskfs only test"
14815         fi
14816         remote_mds_nodsh && skip "remote MDS with nodsh"
14817
14818         local ENOSPC=28
14819         local has_warning=false
14820
14821         rm -rf $DIR/$tdir
14822         mkdir -p $DIR/$tdir
14823
14824         # block size of mds1
14825         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14826         set_dir_limits $maxsize $((maxsize * 6 / 8))
14827         stack_trap "set_dir_limits 0 0"
14828         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14829         local dirsize=$(stat -c%s "$DIR/$tdir")
14830         local nfiles=0
14831         while (( $dirsize <= $maxsize )); do
14832                 $MCREATE $DIR/$tdir/file_base_$nfiles
14833                 rc=$?
14834                 # check two errors:
14835                 # ENOSPC for ext4 max_dir_size, which has been used since
14836                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14837                 if (( rc == ENOSPC )); then
14838                         set_dir_limits 0 0
14839                         echo "rc=$rc returned as expected after $nfiles files"
14840
14841                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14842                                 error "create failed w/o dir size limit"
14843
14844                         # messages may be rate limited if test is run repeatedly
14845                         check_mds_dmesg '"is approaching max"' ||
14846                                 echo "warning message should be output"
14847                         check_mds_dmesg '"has reached max"' ||
14848                                 echo "reached message should be output"
14849
14850                         dirsize=$(stat -c%s "$DIR/$tdir")
14851
14852                         [[ $dirsize -ge $maxsize ]] && return 0
14853                         error "dirsize $dirsize < $maxsize after $nfiles files"
14854                 elif (( rc != 0 )); then
14855                         break
14856                 fi
14857                 nfiles=$((nfiles + 1))
14858                 dirsize=$(stat -c%s "$DIR/$tdir")
14859         done
14860
14861         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14862 }
14863 run_test 129 "test directory size limit ========================"
14864
14865 OLDIFS="$IFS"
14866 cleanup_130() {
14867         trap 0
14868         IFS="$OLDIFS"
14869         rm -f $DIR/$tfile
14870 }
14871
14872 test_130a() {
14873         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14874         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14875
14876         trap cleanup_130 EXIT RETURN
14877
14878         local fm_file=$DIR/$tfile
14879         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14880         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14881                 error "dd failed for $fm_file"
14882
14883         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14884         filefrag -ves $fm_file
14885         local rc=$?
14886         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14887                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14888         (( $rc == 0 )) || error "filefrag $fm_file failed"
14889
14890         filefrag_op=$(filefrag -ve -k $fm_file |
14891                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14892         local lun=$($LFS getstripe -i $fm_file)
14893
14894         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14895         IFS=$'\n'
14896         local tot_len=0
14897         for line in $filefrag_op; do
14898                 local frag_lun=$(echo $line | cut -d: -f5)
14899                 local ext_len=$(echo $line | cut -d: -f4)
14900
14901                 if (( $frag_lun != $lun )); then
14902                         error "FIEMAP on 1-stripe file($fm_file) failed"
14903                         return
14904                 fi
14905                 (( tot_len += ext_len ))
14906         done
14907
14908         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14909                 error "FIEMAP on 1-stripe file($fm_file) failed"
14910                 return
14911         fi
14912
14913         echo "FIEMAP on single striped file succeeded"
14914 }
14915 run_test 130a "FIEMAP (1-stripe file)"
14916
14917 test_130b() {
14918         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14919
14920         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14921         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14922         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14923                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14924
14925         trap cleanup_130 EXIT RETURN
14926
14927         local fm_file=$DIR/$tfile
14928         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14929                 error "setstripe on $fm_file"
14930
14931         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14932                 error "dd failed on $fm_file"
14933
14934         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14935         filefrag_op=$(filefrag -ve -k $fm_file |
14936                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14937
14938         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14939                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14940
14941         IFS=$'\n'
14942         local tot_len=0
14943         local num_luns=1
14944
14945         for line in $filefrag_op; do
14946                 local frag_lun=$(echo $line | cut -d: -f5 |
14947                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14948                 local ext_len=$(echo $line | cut -d: -f4)
14949                 if (( $frag_lun != $last_lun )); then
14950                         if (( tot_len != 1024 )); then
14951                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14952                                 return
14953                         else
14954                                 (( num_luns += 1 ))
14955                                 tot_len=0
14956                         fi
14957                 fi
14958                 (( tot_len += ext_len ))
14959                 last_lun=$frag_lun
14960         done
14961         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14962                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14963                 return
14964         fi
14965
14966         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14967 }
14968 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14969
14970 test_130c() {
14971         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14972
14973         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14974         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14975         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14976                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14977
14978         trap cleanup_130 EXIT RETURN
14979
14980         local fm_file=$DIR/$tfile
14981         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14982
14983         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14984                 error "dd failed on $fm_file"
14985
14986         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14987         filefrag_op=$(filefrag -ve -k $fm_file |
14988                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14989
14990         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14991                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14992
14993         IFS=$'\n'
14994         local tot_len=0
14995         local num_luns=1
14996         for line in $filefrag_op; do
14997                 local frag_lun=$(echo $line | cut -d: -f5 |
14998                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14999                 local ext_len=$(echo $line | cut -d: -f4)
15000                 if (( $frag_lun != $last_lun )); then
15001                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15002                         if (( logical != 512 )); then
15003                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15004                                 return
15005                         fi
15006                         if (( tot_len != 512 )); then
15007                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15008                                 return
15009                         else
15010                                 (( num_luns += 1 ))
15011                                 tot_len=0
15012                         fi
15013                 fi
15014                 (( tot_len += ext_len ))
15015                 last_lun=$frag_lun
15016         done
15017         if (( num_luns != 2 || tot_len != 512 )); then
15018                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15019                 return
15020         fi
15021
15022         echo "FIEMAP on 2-stripe file with hole succeeded"
15023 }
15024 run_test 130c "FIEMAP (2-stripe file with hole)"
15025
15026 test_130d() {
15027         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15028
15029         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15030         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15031         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15032                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15033
15034         trap cleanup_130 EXIT RETURN
15035
15036         local fm_file=$DIR/$tfile
15037         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15038                         error "setstripe on $fm_file"
15039
15040         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15041         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15042                 error "dd failed on $fm_file"
15043
15044         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15045         filefrag_op=$(filefrag -ve -k $fm_file |
15046                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15047
15048         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15049                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15050
15051         IFS=$'\n'
15052         local tot_len=0
15053         local num_luns=1
15054         for line in $filefrag_op; do
15055                 local frag_lun=$(echo $line | cut -d: -f5 |
15056                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15057                 local ext_len=$(echo $line | cut -d: -f4)
15058                 if (( $frag_lun != $last_lun )); then
15059                         if (( tot_len != 1024 )); then
15060                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15061                                 return
15062                         else
15063                                 (( num_luns += 1 ))
15064                                 local tot_len=0
15065                         fi
15066                 fi
15067                 (( tot_len += ext_len ))
15068                 last_lun=$frag_lun
15069         done
15070         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15071                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15072                 return
15073         fi
15074
15075         echo "FIEMAP on N-stripe file succeeded"
15076 }
15077 run_test 130d "FIEMAP (N-stripe file)"
15078
15079 test_130e() {
15080         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15081
15082         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15083         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15084         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15085                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15086
15087         trap cleanup_130 EXIT RETURN
15088
15089         local fm_file=$DIR/$tfile
15090         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15091         stack_trap "rm -f $fm_file"
15092
15093         local num_blks=512
15094         local expected_len=$(( (num_blks / 2) * 64 ))
15095         for ((i = 0; i < $num_blks; i++)); do
15096                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15097                         conv=notrunc > /dev/null 2>&1
15098         done
15099
15100         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15101         filefrag_op=$(filefrag -ve -k $fm_file |
15102                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15103
15104         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15105
15106         IFS=$'\n'
15107         local tot_len=0
15108         local num_luns=1
15109         for line in $filefrag_op; do
15110                 local frag_lun=$(echo $line | cut -d: -f5)
15111                 local ext_len=$(echo $line | cut -d: -f4)
15112                 if (( $frag_lun != $last_lun )); then
15113                         if (( tot_len != $expected_len )); then
15114                                 error "OST$last_lun $tot_len != $expected_len"
15115                         else
15116                                 (( num_luns += 1 ))
15117                                 tot_len=0
15118                         fi
15119                 fi
15120                 (( tot_len += ext_len ))
15121                 last_lun=$frag_lun
15122         done
15123         if (( num_luns != 2 || tot_len != $expected_len )); then
15124                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15125         fi
15126
15127         echo "FIEMAP with continuation calls succeeded"
15128 }
15129 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15130
15131 test_130f() {
15132         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15133         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15134         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15135                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15136
15137         local fm_file=$DIR/$tfile
15138         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15139                 error "multiop create with lov_delay_create on $fm_file"
15140
15141         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15142         filefrag_extents=$(filefrag -vek $fm_file |
15143                            awk '/extents? found/ { print $2 }')
15144         if (( $filefrag_extents != 0 )); then
15145                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15146         fi
15147
15148         rm -f $fm_file
15149 }
15150 run_test 130f "FIEMAP (unstriped file)"
15151
15152 test_130g() {
15153         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15154                 skip "Need MDS version with at least 2.12.53 for overstriping"
15155         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15156         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15157         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15158                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15159
15160         local file=$DIR/$tfile
15161         local nr=$((OSTCOUNT * 100))
15162
15163         $LFS setstripe -C $nr -S1M $file ||
15164                 error "failed to setstripe -C $nr $file"
15165
15166         stack_trap "rm -f $file"
15167         dd if=/dev/zero of=$file count=$nr bs=1M
15168         sync
15169         nr=$($LFS getstripe -c $file)
15170
15171         local extents=$(filefrag -v $file |
15172                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15173
15174         echo "filefrag list $extents extents in file with stripecount $nr"
15175         if (( extents < nr )); then
15176                 $LFS getstripe $file
15177                 filefrag -v $file
15178                 error "filefrag printed $extents < $nr extents"
15179         fi
15180 }
15181 run_test 130g "FIEMAP (overstripe file)"
15182
15183 # Test for writev/readv
15184 test_131a() {
15185         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15186                 error "writev test failed"
15187         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15188                 error "readv failed"
15189         rm -f $DIR/$tfile
15190 }
15191 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15192
15193 test_131b() {
15194         local fsize=$((524288 + 1048576 + 1572864))
15195         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15196                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15197                         error "append writev test failed"
15198
15199         ((fsize += 1572864 + 1048576))
15200         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15201                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15202                         error "append writev test failed"
15203         rm -f $DIR/$tfile
15204 }
15205 run_test 131b "test append writev"
15206
15207 test_131c() {
15208         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15209         error "NOT PASS"
15210 }
15211 run_test 131c "test read/write on file w/o objects"
15212
15213 test_131d() {
15214         rwv -f $DIR/$tfile -w -n 1 1572864
15215         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15216         if [ "$NOB" != 1572864 ]; then
15217                 error "Short read filed: read $NOB bytes instead of 1572864"
15218         fi
15219         rm -f $DIR/$tfile
15220 }
15221 run_test 131d "test short read"
15222
15223 test_131e() {
15224         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15225         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15226         error "read hitting hole failed"
15227         rm -f $DIR/$tfile
15228 }
15229 run_test 131e "test read hitting hole"
15230
15231 check_stats() {
15232         local facet=$1
15233         local op=$2
15234         local want=${3:-0}
15235         local res
15236
15237         # open             11 samples [usecs] 468 4793 13658 35791898
15238         case $facet in
15239         mds*) res=($(do_facet $facet \
15240                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15241                  ;;
15242         ost*) res=($(do_facet $facet \
15243                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15244                  ;;
15245         *) error "Wrong facet '$facet'" ;;
15246         esac
15247         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15248         # if $want is zero, it means any stat increment is ok.
15249         if (( $want > 0 )); then
15250                 local count=${res[1]}
15251
15252                 if (( $count != $want )); then
15253                         if [[ $facet =~ "mds" ]]; then
15254                                 do_nodes $(comma_list $(mdts_nodes)) \
15255                                         $LCTL get_param mdt.*.md_stats
15256                         else
15257                                 do_nodes $(comma_list $(osts-nodes)) \
15258                                         $LCTL get_param obdfilter.*.stats
15259                         fi
15260                         error "The $op counter on $facet is $count, not $want"
15261                 fi
15262         fi
15263 }
15264
15265 test_133a() {
15266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15267         remote_ost_nodsh && skip "remote OST with nodsh"
15268         remote_mds_nodsh && skip "remote MDS with nodsh"
15269         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15270                 skip_env "MDS doesn't support rename stats"
15271
15272         local testdir=$DIR/${tdir}/stats_testdir
15273
15274         mkdir -p $DIR/${tdir}
15275
15276         # clear stats.
15277         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15278         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15279
15280         # verify mdt stats first.
15281         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15282         check_stats $SINGLEMDS "mkdir" 1
15283
15284         # clear "open" from "lfs mkdir" above
15285         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15286         touch ${testdir}/${tfile} || error "touch failed"
15287         check_stats $SINGLEMDS "open" 1
15288         check_stats $SINGLEMDS "close" 1
15289         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15290                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15291                 check_stats $SINGLEMDS "mknod" 2
15292         }
15293         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15294         check_stats $SINGLEMDS "unlink" 1
15295         rm -f ${testdir}/${tfile} || error "file remove failed"
15296         check_stats $SINGLEMDS "unlink" 2
15297
15298         # remove working dir and check mdt stats again.
15299         rmdir ${testdir} || error "rmdir failed"
15300         check_stats $SINGLEMDS "rmdir" 1
15301
15302         local testdir1=$DIR/${tdir}/stats_testdir1
15303         mkdir_on_mdt0 -p ${testdir}
15304         mkdir_on_mdt0 -p ${testdir1}
15305         touch ${testdir1}/test1
15306         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15307         check_stats $SINGLEMDS "crossdir_rename" 1
15308
15309         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15310         check_stats $SINGLEMDS "samedir_rename" 1
15311
15312         rm -rf $DIR/${tdir}
15313 }
15314 run_test 133a "Verifying MDT stats ========================================"
15315
15316 test_133b() {
15317         local res
15318
15319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15320         remote_ost_nodsh && skip "remote OST with nodsh"
15321         remote_mds_nodsh && skip "remote MDS with nodsh"
15322
15323         local testdir=$DIR/${tdir}/stats_testdir
15324
15325         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15326         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15327         touch ${testdir}/${tfile} || error "touch failed"
15328         cancel_lru_locks mdc
15329
15330         # clear stats.
15331         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15332         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15333
15334         # extra mdt stats verification.
15335         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15336         check_stats $SINGLEMDS "setattr" 1
15337         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15338         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15339         then            # LU-1740
15340                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15341                 check_stats $SINGLEMDS "getattr" 1
15342         fi
15343         rm -rf $DIR/${tdir}
15344
15345         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15346         # so the check below is not reliable
15347         [ $MDSCOUNT -eq 1 ] || return 0
15348
15349         # Sleep to avoid a cached response.
15350         #define OBD_STATFS_CACHE_SECONDS 1
15351         sleep 2
15352         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15353         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15354         $LFS df || error "lfs failed"
15355         check_stats $SINGLEMDS "statfs" 1
15356
15357         # check aggregated statfs (LU-10018)
15358         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15359                 return 0
15360         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15361                 return 0
15362         sleep 2
15363         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15364         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15365         df $DIR
15366         check_stats $SINGLEMDS "statfs" 1
15367
15368         # We want to check that the client didn't send OST_STATFS to
15369         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15370         # extra care is needed here.
15371         if remote_mds; then
15372                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15373                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15374
15375                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15376                 [ "$res" ] && error "OST got STATFS"
15377         fi
15378
15379         return 0
15380 }
15381 run_test 133b "Verifying extra MDT stats =================================="
15382
15383 test_133c() {
15384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15385         remote_ost_nodsh && skip "remote OST with nodsh"
15386         remote_mds_nodsh && skip "remote MDS with nodsh"
15387
15388         local testdir=$DIR/$tdir/stats_testdir
15389
15390         test_mkdir -p $testdir
15391
15392         # verify obdfilter stats.
15393         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15394         sync
15395         cancel_lru_locks osc
15396         wait_delete_completed
15397
15398         # clear stats.
15399         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15400         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15401
15402         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15403                 error "dd failed"
15404         sync
15405         cancel_lru_locks osc
15406         check_stats ost1 "write" 1
15407
15408         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15409         check_stats ost1 "read" 1
15410
15411         > $testdir/$tfile || error "truncate failed"
15412         check_stats ost1 "punch" 1
15413
15414         rm -f $testdir/$tfile || error "file remove failed"
15415         wait_delete_completed
15416         check_stats ost1 "destroy" 1
15417
15418         rm -rf $DIR/$tdir
15419 }
15420 run_test 133c "Verifying OST stats ========================================"
15421
15422 order_2() {
15423         local value=$1
15424         local orig=$value
15425         local order=1
15426
15427         while [ $value -ge 2 ]; do
15428                 order=$((order*2))
15429                 value=$((value/2))
15430         done
15431
15432         if [ $orig -gt $order ]; then
15433                 order=$((order*2))
15434         fi
15435         echo $order
15436 }
15437
15438 size_in_KMGT() {
15439     local value=$1
15440     local size=('K' 'M' 'G' 'T');
15441     local i=0
15442     local size_string=$value
15443
15444     while [ $value -ge 1024 ]; do
15445         if [ $i -gt 3 ]; then
15446             #T is the biggest unit we get here, if that is bigger,
15447             #just return XXXT
15448             size_string=${value}T
15449             break
15450         fi
15451         value=$((value >> 10))
15452         if [ $value -lt 1024 ]; then
15453             size_string=${value}${size[$i]}
15454             break
15455         fi
15456         i=$((i + 1))
15457     done
15458
15459     echo $size_string
15460 }
15461
15462 get_rename_size() {
15463         local size=$1
15464         local context=${2:-.}
15465         local sample=$(do_facet $SINGLEMDS $LCTL \
15466                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15467                 grep -A1 $context |
15468                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15469         echo $sample
15470 }
15471
15472 test_133d() {
15473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15474         remote_ost_nodsh && skip "remote OST with nodsh"
15475         remote_mds_nodsh && skip "remote MDS with nodsh"
15476         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15477                 skip_env "MDS doesn't support rename stats"
15478
15479         local testdir1=$DIR/${tdir}/stats_testdir1
15480         local testdir2=$DIR/${tdir}/stats_testdir2
15481         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15482
15483         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15484
15485         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15486         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15487
15488         createmany -o $testdir1/test 512 || error "createmany failed"
15489
15490         # check samedir rename size
15491         mv ${testdir1}/test0 ${testdir1}/test_0
15492
15493         local testdir1_size=$(ls -l $DIR/${tdir} |
15494                 awk '/stats_testdir1/ {print $5}')
15495         local testdir2_size=$(ls -l $DIR/${tdir} |
15496                 awk '/stats_testdir2/ {print $5}')
15497
15498         testdir1_size=$(order_2 $testdir1_size)
15499         testdir2_size=$(order_2 $testdir2_size)
15500
15501         testdir1_size=$(size_in_KMGT $testdir1_size)
15502         testdir2_size=$(size_in_KMGT $testdir2_size)
15503
15504         echo "source rename dir size: ${testdir1_size}"
15505         echo "target rename dir size: ${testdir2_size}"
15506
15507         local cmd="do_facet $SINGLEMDS $LCTL "
15508         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15509
15510         eval $cmd || error "$cmd failed"
15511         local samedir=$($cmd | grep 'same_dir')
15512         local same_sample=$(get_rename_size $testdir1_size)
15513         [ -z "$samedir" ] && error "samedir_rename_size count error"
15514         [[ $same_sample -eq 1 ]] ||
15515                 error "samedir_rename_size error $same_sample"
15516         echo "Check same dir rename stats success"
15517
15518         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15519
15520         # check crossdir rename size
15521         mv ${testdir1}/test_0 ${testdir2}/test_0
15522
15523         testdir1_size=$(ls -l $DIR/${tdir} |
15524                 awk '/stats_testdir1/ {print $5}')
15525         testdir2_size=$(ls -l $DIR/${tdir} |
15526                 awk '/stats_testdir2/ {print $5}')
15527
15528         testdir1_size=$(order_2 $testdir1_size)
15529         testdir2_size=$(order_2 $testdir2_size)
15530
15531         testdir1_size=$(size_in_KMGT $testdir1_size)
15532         testdir2_size=$(size_in_KMGT $testdir2_size)
15533
15534         echo "source rename dir size: ${testdir1_size}"
15535         echo "target rename dir size: ${testdir2_size}"
15536
15537         eval $cmd || error "$cmd failed"
15538         local crossdir=$($cmd | grep 'crossdir')
15539         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15540         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15541         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15542         [[ $src_sample -eq 1 ]] ||
15543                 error "crossdir_rename_size error $src_sample"
15544         [[ $tgt_sample -eq 1 ]] ||
15545                 error "crossdir_rename_size error $tgt_sample"
15546         echo "Check cross dir rename stats success"
15547         rm -rf $DIR/${tdir}
15548 }
15549 run_test 133d "Verifying rename_stats ========================================"
15550
15551 test_133e() {
15552         remote_mds_nodsh && skip "remote MDS with nodsh"
15553         remote_ost_nodsh && skip "remote OST with nodsh"
15554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15555
15556         local testdir=$DIR/${tdir}/stats_testdir
15557         local ctr f0 f1 bs=32768 count=42 sum
15558
15559         mkdir -p ${testdir} || error "mkdir failed"
15560
15561         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15562
15563         for ctr in {write,read}_bytes; do
15564                 sync
15565                 cancel_lru_locks osc
15566
15567                 do_facet ost1 $LCTL set_param -n \
15568                         "obdfilter.*.exports.clear=clear"
15569
15570                 if [ $ctr = write_bytes ]; then
15571                         f0=/dev/zero
15572                         f1=${testdir}/${tfile}
15573                 else
15574                         f0=${testdir}/${tfile}
15575                         f1=/dev/null
15576                 fi
15577
15578                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15579                         error "dd failed"
15580                 sync
15581                 cancel_lru_locks osc
15582
15583                 sum=$(do_facet ost1 $LCTL get_param \
15584                         "obdfilter.*.exports.*.stats" |
15585                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15586                                 $1 == ctr { sum += $7 }
15587                                 END { printf("%0.0f", sum) }')
15588
15589                 if ((sum != bs * count)); then
15590                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15591                 fi
15592         done
15593
15594         rm -rf $DIR/${tdir}
15595 }
15596 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15597
15598 test_133f() {
15599         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15600                 skip "too old lustre for get_param -R ($facet_ver)"
15601
15602         # verifying readability.
15603         $LCTL get_param -R '*' &> /dev/null
15604
15605         # Verifing writability with badarea_io.
15606         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15607         local skipped_params='force_lbug|changelog_mask|daemon_file'
15608         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15609                 egrep -v "$skipped_params" |
15610                 xargs -n 1 find $proc_dirs -name |
15611                 xargs -n 1 badarea_io ||
15612                 error "client badarea_io failed"
15613
15614         # remount the FS in case writes/reads /proc break the FS
15615         cleanup || error "failed to unmount"
15616         setup || error "failed to setup"
15617 }
15618 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15619
15620 test_133g() {
15621         remote_mds_nodsh && skip "remote MDS with nodsh"
15622         remote_ost_nodsh && skip "remote OST with nodsh"
15623
15624         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15625         local proc_dirs_str=$(eval echo $proc_dirs)
15626         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15627         local facet
15628         for facet in mds1 ost1; do
15629                 local facet_ver=$(lustre_version_code $facet)
15630                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15631                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15632                 else
15633                         log "$facet: too old lustre for get_param -R"
15634                 fi
15635                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15636                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15637                                 tr -d = | egrep -v $skipped_params |
15638                                 xargs -n 1 find $proc_dirs_str -name |
15639                                 xargs -n 1 badarea_io" ||
15640                                         error "$facet badarea_io failed"
15641                 else
15642                         skip_noexit "$facet: too old lustre for get_param -R"
15643                 fi
15644         done
15645
15646         # remount the FS in case writes/reads /proc break the FS
15647         cleanup || error "failed to unmount"
15648         setup || error "failed to setup"
15649 }
15650 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15651
15652 test_133h() {
15653         remote_mds_nodsh && skip "remote MDS with nodsh"
15654         remote_ost_nodsh && skip "remote OST with nodsh"
15655         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15656                 skip "Need MDS version at least 2.9.54"
15657
15658         local facet
15659         for facet in client mds1 ost1; do
15660                 # Get the list of files that are missing the terminating newline
15661                 local plist=$(do_facet $facet
15662                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15663                 local ent
15664                 for ent in $plist; do
15665                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15666                                 awk -v FS='\v' -v RS='\v\v' \
15667                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15668                                         print FILENAME}'" 2>/dev/null)
15669                         [ -z $missing ] || {
15670                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15671                                 error "file does not end with newline: $facet-$ent"
15672                         }
15673                 done
15674         done
15675 }
15676 run_test 133h "Proc files should end with newlines"
15677
15678 test_134a() {
15679         remote_mds_nodsh && skip "remote MDS with nodsh"
15680         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15681                 skip "Need MDS version at least 2.7.54"
15682
15683         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15684         cancel_lru_locks mdc
15685
15686         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15687         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15688         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15689
15690         local nr=1000
15691         createmany -o $DIR/$tdir/f $nr ||
15692                 error "failed to create $nr files in $DIR/$tdir"
15693         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15694
15695         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15696         do_facet mds1 $LCTL set_param fail_loc=0x327
15697         do_facet mds1 $LCTL set_param fail_val=500
15698         touch $DIR/$tdir/m
15699
15700         echo "sleep 10 seconds ..."
15701         sleep 10
15702         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15703
15704         do_facet mds1 $LCTL set_param fail_loc=0
15705         do_facet mds1 $LCTL set_param fail_val=0
15706         [ $lck_cnt -lt $unused ] ||
15707                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15708
15709         rm $DIR/$tdir/m
15710         unlinkmany $DIR/$tdir/f $nr
15711 }
15712 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15713
15714 test_134b() {
15715         remote_mds_nodsh && skip "remote MDS with nodsh"
15716         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15717                 skip "Need MDS version at least 2.7.54"
15718
15719         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15720         cancel_lru_locks mdc
15721
15722         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15723                         ldlm.lock_reclaim_threshold_mb)
15724         # disable reclaim temporarily
15725         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15726
15727         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15728         do_facet mds1 $LCTL set_param fail_loc=0x328
15729         do_facet mds1 $LCTL set_param fail_val=500
15730
15731         $LCTL set_param debug=+trace
15732
15733         local nr=600
15734         createmany -o $DIR/$tdir/f $nr &
15735         local create_pid=$!
15736
15737         echo "Sleep $TIMEOUT seconds ..."
15738         sleep $TIMEOUT
15739         if ! ps -p $create_pid  > /dev/null 2>&1; then
15740                 do_facet mds1 $LCTL set_param fail_loc=0
15741                 do_facet mds1 $LCTL set_param fail_val=0
15742                 do_facet mds1 $LCTL set_param \
15743                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15744                 error "createmany finished incorrectly!"
15745         fi
15746         do_facet mds1 $LCTL set_param fail_loc=0
15747         do_facet mds1 $LCTL set_param fail_val=0
15748         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15749         wait $create_pid || return 1
15750
15751         unlinkmany $DIR/$tdir/f $nr
15752 }
15753 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15754
15755 test_135() {
15756         remote_mds_nodsh && skip "remote MDS with nodsh"
15757         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15758                 skip "Need MDS version at least 2.13.50"
15759         local fname
15760
15761         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15762
15763 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15764         #set only one record at plain llog
15765         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15766
15767         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15768
15769         #fill already existed plain llog each 64767
15770         #wrapping whole catalog
15771         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15772
15773         createmany -o $DIR/$tdir/$tfile_ 64700
15774         for (( i = 0; i < 64700; i = i + 2 ))
15775         do
15776                 rm $DIR/$tdir/$tfile_$i &
15777                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15778                 local pid=$!
15779                 wait $pid
15780         done
15781
15782         #waiting osp synchronization
15783         wait_delete_completed
15784 }
15785 run_test 135 "Race catalog processing"
15786
15787 test_136() {
15788         remote_mds_nodsh && skip "remote MDS with nodsh"
15789         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15790                 skip "Need MDS version at least 2.13.50"
15791         local fname
15792
15793         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15794         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15795         #set only one record at plain llog
15796 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15797         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15798
15799         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15800
15801         #fill already existed 2 plain llogs each 64767
15802         #wrapping whole catalog
15803         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15804         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15805         wait_delete_completed
15806
15807         createmany -o $DIR/$tdir/$tfile_ 10
15808         sleep 25
15809
15810         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15811         for (( i = 0; i < 10; i = i + 3 ))
15812         do
15813                 rm $DIR/$tdir/$tfile_$i &
15814                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15815                 local pid=$!
15816                 wait $pid
15817                 sleep 7
15818                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15819         done
15820
15821         #waiting osp synchronization
15822         wait_delete_completed
15823 }
15824 run_test 136 "Race catalog processing 2"
15825
15826 test_140() { #bug-17379
15827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15828
15829         test_mkdir $DIR/$tdir
15830         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15831         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15832
15833         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15834         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15835         local i=0
15836         while i=$((i + 1)); do
15837                 test_mkdir $i
15838                 cd $i || error "Changing to $i"
15839                 ln -s ../stat stat || error "Creating stat symlink"
15840                 # Read the symlink until ELOOP present,
15841                 # not LBUGing the system is considered success,
15842                 # we didn't overrun the stack.
15843                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15844                 if [ $ret -ne 0 ]; then
15845                         if [ $ret -eq 40 ]; then
15846                                 break  # -ELOOP
15847                         else
15848                                 error "Open stat symlink"
15849                                         return
15850                         fi
15851                 fi
15852         done
15853         i=$((i - 1))
15854         echo "The symlink depth = $i"
15855         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15856                 error "Invalid symlink depth"
15857
15858         # Test recursive symlink
15859         ln -s symlink_self symlink_self
15860         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15861         echo "open symlink_self returns $ret"
15862         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15863 }
15864 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15865
15866 test_150a() {
15867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15868
15869         local TF="$TMP/$tfile"
15870
15871         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15872         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15873         cp $TF $DIR/$tfile
15874         cancel_lru_locks $OSC
15875         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15876         remount_client $MOUNT
15877         df -P $MOUNT
15878         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15879
15880         $TRUNCATE $TF 6000
15881         $TRUNCATE $DIR/$tfile 6000
15882         cancel_lru_locks $OSC
15883         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15884
15885         echo "12345" >>$TF
15886         echo "12345" >>$DIR/$tfile
15887         cancel_lru_locks $OSC
15888         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15889
15890         echo "12345" >>$TF
15891         echo "12345" >>$DIR/$tfile
15892         cancel_lru_locks $OSC
15893         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15894 }
15895 run_test 150a "truncate/append tests"
15896
15897 test_150b() {
15898         check_set_fallocate_or_skip
15899         local out
15900
15901         touch $DIR/$tfile
15902         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15903         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15904                 skip_eopnotsupp "$out|check_fallocate failed"
15905 }
15906 run_test 150b "Verify fallocate (prealloc) functionality"
15907
15908 test_150bb() {
15909         check_set_fallocate_or_skip
15910
15911         touch $DIR/$tfile
15912         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15913         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15914         > $DIR/$tfile
15915         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15916         # precomputed md5sum for 20MB of zeroes
15917         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15918         local sum=($(md5sum $DIR/$tfile))
15919
15920         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15921
15922         check_set_fallocate 1
15923
15924         > $DIR/$tfile
15925         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15926         sum=($(md5sum $DIR/$tfile))
15927
15928         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15929 }
15930 run_test 150bb "Verify fallocate modes both zero space"
15931
15932 test_150c() {
15933         check_set_fallocate_or_skip
15934         local striping="-c2"
15935
15936         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15937         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15938         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15939         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15940         local want=$((OSTCOUNT * 1048576))
15941
15942         # Must allocate all requested space, not more than 5% extra
15943         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15944                 error "bytes $bytes is not $want"
15945
15946         rm -f $DIR/$tfile
15947
15948         echo "verify fallocate on PFL file"
15949
15950         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15951
15952         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15953                 error "Create $DIR/$tfile failed"
15954         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15955         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15956         want=$((512 * 1048576))
15957
15958         # Must allocate all requested space, not more than 5% extra
15959         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15960                 error "bytes $bytes is not $want"
15961 }
15962 run_test 150c "Verify fallocate Size and Blocks"
15963
15964 test_150d() {
15965         check_set_fallocate_or_skip
15966         local striping="-c2"
15967
15968         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15969
15970         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15971         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15972                 error "setstripe failed"
15973         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15974         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15975         local want=$((OSTCOUNT * 1048576))
15976
15977         # Must allocate all requested space, not more than 5% extra
15978         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15979                 error "bytes $bytes is not $want"
15980 }
15981 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15982
15983 test_150e() {
15984         check_set_fallocate_or_skip
15985
15986         echo "df before:"
15987         $LFS df
15988         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15989         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15990                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15991
15992         # Find OST with Minimum Size
15993         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15994                        sort -un | head -1)
15995
15996         # Get 100MB per OST of the available space to reduce run time
15997         # else 60% of the available space if we are running SLOW tests
15998         if [ $SLOW == "no" ]; then
15999                 local space=$((1024 * 100 * OSTCOUNT))
16000         else
16001                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16002         fi
16003
16004         fallocate -l${space}k $DIR/$tfile ||
16005                 error "fallocate ${space}k $DIR/$tfile failed"
16006         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16007
16008         # get size immediately after fallocate. This should be correctly
16009         # updated
16010         local size=$(stat -c '%s' $DIR/$tfile)
16011         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16012
16013         # Sleep for a while for statfs to get updated. And not pull from cache.
16014         sleep 2
16015
16016         echo "df after fallocate:"
16017         $LFS df
16018
16019         (( size / 1024 == space )) || error "size $size != requested $space"
16020         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16021                 error "used $used < space $space"
16022
16023         rm $DIR/$tfile || error "rm failed"
16024         sync
16025         wait_delete_completed
16026
16027         echo "df after unlink:"
16028         $LFS df
16029 }
16030 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16031
16032 test_150f() {
16033         local size
16034         local blocks
16035         local want_size_before=20480 # in bytes
16036         local want_blocks_before=40 # 512 sized blocks
16037         local want_blocks_after=24  # 512 sized blocks
16038         local length=$(((want_blocks_before - want_blocks_after) * 512))
16039
16040         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16041                 skip "need at least 2.14.0 for fallocate punch"
16042
16043         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16044                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16045         fi
16046
16047         check_set_fallocate_or_skip
16048         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16049
16050         [[ "x$DOM" == "xyes" ]] &&
16051                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16052
16053         echo "Verify fallocate punch: Range within the file range"
16054         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16055                 error "dd failed for bs 4096 and count 5"
16056
16057         # Call fallocate with punch range which is within the file range
16058         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16059                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16060         # client must see changes immediately after fallocate
16061         size=$(stat -c '%s' $DIR/$tfile)
16062         blocks=$(stat -c '%b' $DIR/$tfile)
16063
16064         # Verify punch worked.
16065         (( blocks == want_blocks_after )) ||
16066                 error "punch failed: blocks $blocks != $want_blocks_after"
16067
16068         (( size == want_size_before )) ||
16069                 error "punch failed: size $size != $want_size_before"
16070
16071         # Verify there is hole in file
16072         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16073         # precomputed md5sum
16074         local expect="4a9a834a2db02452929c0a348273b4aa"
16075
16076         cksum=($(md5sum $DIR/$tfile))
16077         [[ "${cksum[0]}" == "$expect" ]] ||
16078                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16079
16080         # Start second sub-case for fallocate punch.
16081         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16082         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16083                 error "dd failed for bs 4096 and count 5"
16084
16085         # Punch range less than block size will have no change in block count
16086         want_blocks_after=40  # 512 sized blocks
16087
16088         # Punch overlaps two blocks and less than blocksize
16089         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16090                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16091         size=$(stat -c '%s' $DIR/$tfile)
16092         blocks=$(stat -c '%b' $DIR/$tfile)
16093
16094         # Verify punch worked.
16095         (( blocks == want_blocks_after )) ||
16096                 error "punch failed: blocks $blocks != $want_blocks_after"
16097
16098         (( size == want_size_before )) ||
16099                 error "punch failed: size $size != $want_size_before"
16100
16101         # Verify if range is really zero'ed out. We expect Zeros.
16102         # precomputed md5sum
16103         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16104         cksum=($(md5sum $DIR/$tfile))
16105         [[ "${cksum[0]}" == "$expect" ]] ||
16106                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16107 }
16108 run_test 150f "Verify fallocate punch functionality"
16109
16110 test_150g() {
16111         local space
16112         local size
16113         local blocks
16114         local blocks_after
16115         local size_after
16116         local BS=4096 # Block size in bytes
16117
16118         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16119                 skip "need at least 2.14.0 for fallocate punch"
16120
16121         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16122                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16123         fi
16124
16125         check_set_fallocate_or_skip
16126         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16127
16128         if [[ "x$DOM" == "xyes" ]]; then
16129                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16130                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16131         else
16132                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16133                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16134         fi
16135
16136         # Get 100MB per OST of the available space to reduce run time
16137         # else 60% of the available space if we are running SLOW tests
16138         if [ $SLOW == "no" ]; then
16139                 space=$((1024 * 100 * OSTCOUNT))
16140         else
16141                 # Find OST with Minimum Size
16142                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16143                         sort -un | head -1)
16144                 echo "min size OST: $space"
16145                 space=$(((space * 60)/100 * OSTCOUNT))
16146         fi
16147         # space in 1k units, round to 4k blocks
16148         local blkcount=$((space * 1024 / $BS))
16149
16150         echo "Verify fallocate punch: Very large Range"
16151         fallocate -l${space}k $DIR/$tfile ||
16152                 error "fallocate ${space}k $DIR/$tfile failed"
16153         # write 1M at the end, start and in the middle
16154         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16155                 error "dd failed: bs $BS count 256"
16156         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16157                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16158         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16159                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16160
16161         # Gather stats.
16162         size=$(stat -c '%s' $DIR/$tfile)
16163
16164         # gather punch length.
16165         local punch_size=$((size - (BS * 2)))
16166
16167         echo "punch_size = $punch_size"
16168         echo "size - punch_size: $((size - punch_size))"
16169         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16170
16171         # Call fallocate to punch all except 2 blocks. We leave the
16172         # first and the last block
16173         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16174         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16175                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16176
16177         size_after=$(stat -c '%s' $DIR/$tfile)
16178         blocks_after=$(stat -c '%b' $DIR/$tfile)
16179
16180         # Verify punch worked.
16181         # Size should be kept
16182         (( size == size_after )) ||
16183                 error "punch failed: size $size != $size_after"
16184
16185         # two 4k data blocks to remain plus possible 1 extra extent block
16186         (( blocks_after <= ((BS / 512) * 3) )) ||
16187                 error "too many blocks remains: $blocks_after"
16188
16189         # Verify that file has hole between the first and the last blocks
16190         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16191         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16192
16193         echo "Hole at [$hole_start, $hole_end)"
16194         (( hole_start == BS )) ||
16195                 error "no hole at offset $BS after punch"
16196
16197         (( hole_end == BS + punch_size )) ||
16198                 error "data at offset $hole_end < $((BS + punch_size))"
16199 }
16200 run_test 150g "Verify fallocate punch on large range"
16201
16202 test_150h() {
16203         local file=$DIR/$tfile
16204         local size
16205
16206         check_set_fallocate_or_skip
16207         statx_supported || skip_env "Test must be statx() syscall supported"
16208
16209         # fallocate() does not update the size information on the MDT
16210         fallocate -l 16K $file || error "failed to fallocate $file"
16211         cancel_lru_locks $OSC
16212         # STATX with cached-always mode will not send glimpse RPCs to OST,
16213         # it uses the caching attrs on the client side as much as possible.
16214         size=$($STATX --cached=always -c %s $file)
16215         [ $size == 16384 ] ||
16216                 error "size after fallocate() is $size, expected 16384"
16217 }
16218 run_test 150h "Verify extend fallocate updates the file size"
16219
16220 #LU-2902 roc_hit was not able to read all values from lproc
16221 function roc_hit_init() {
16222         local list=$(comma_list $(osts_nodes))
16223         local dir=$DIR/$tdir-check
16224         local file=$dir/$tfile
16225         local BEFORE
16226         local AFTER
16227         local idx
16228
16229         test_mkdir $dir
16230         #use setstripe to do a write to every ost
16231         for i in $(seq 0 $((OSTCOUNT-1))); do
16232                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16233                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16234                 idx=$(printf %04x $i)
16235                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16236                         awk '$1 == "cache_access" {sum += $7}
16237                                 END { printf("%0.0f", sum) }')
16238
16239                 cancel_lru_locks osc
16240                 cat $file >/dev/null
16241
16242                 AFTER=$(get_osd_param $list *OST*$idx stats |
16243                         awk '$1 == "cache_access" {sum += $7}
16244                                 END { printf("%0.0f", sum) }')
16245
16246                 echo BEFORE:$BEFORE AFTER:$AFTER
16247                 if ! let "AFTER - BEFORE == 4"; then
16248                         rm -rf $dir
16249                         error "roc_hit is not safe to use"
16250                 fi
16251                 rm $file
16252         done
16253
16254         rm -rf $dir
16255 }
16256
16257 function roc_hit() {
16258         local list=$(comma_list $(osts_nodes))
16259         echo $(get_osd_param $list '' stats |
16260                 awk '$1 == "cache_hit" {sum += $7}
16261                         END { printf("%0.0f", sum) }')
16262 }
16263
16264 function set_cache() {
16265         local on=1
16266
16267         if [ "$2" == "off" ]; then
16268                 on=0;
16269         fi
16270         local list=$(comma_list $(osts_nodes))
16271         set_osd_param $list '' $1_cache_enable $on
16272
16273         cancel_lru_locks osc
16274 }
16275
16276 test_151() {
16277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16278         remote_ost_nodsh && skip "remote OST with nodsh"
16279         (( CLIENT_VERSION == OST1_VERSION )) ||
16280                 skip "LU-13081: no interop testing for OSS cache"
16281
16282         local CPAGES=3
16283         local list=$(comma_list $(osts_nodes))
16284
16285         # check whether obdfilter is cache capable at all
16286         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16287                 skip "not cache-capable obdfilter"
16288         fi
16289
16290         # check cache is enabled on all obdfilters
16291         if get_osd_param $list '' read_cache_enable | grep 0; then
16292                 skip "oss cache is disabled"
16293         fi
16294
16295         set_osd_param $list '' writethrough_cache_enable 1
16296
16297         # check write cache is enabled on all obdfilters
16298         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16299                 skip "oss write cache is NOT enabled"
16300         fi
16301
16302         roc_hit_init
16303
16304         #define OBD_FAIL_OBD_NO_LRU  0x609
16305         do_nodes $list $LCTL set_param fail_loc=0x609
16306
16307         # pages should be in the case right after write
16308         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16309                 error "dd failed"
16310
16311         local BEFORE=$(roc_hit)
16312         cancel_lru_locks osc
16313         cat $DIR/$tfile >/dev/null
16314         local AFTER=$(roc_hit)
16315
16316         do_nodes $list $LCTL set_param fail_loc=0
16317
16318         if ! let "AFTER - BEFORE == CPAGES"; then
16319                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16320         fi
16321
16322         cancel_lru_locks osc
16323         # invalidates OST cache
16324         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16325         set_osd_param $list '' read_cache_enable 0
16326         cat $DIR/$tfile >/dev/null
16327
16328         # now data shouldn't be found in the cache
16329         BEFORE=$(roc_hit)
16330         cancel_lru_locks osc
16331         cat $DIR/$tfile >/dev/null
16332         AFTER=$(roc_hit)
16333         if let "AFTER - BEFORE != 0"; then
16334                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16335         fi
16336
16337         set_osd_param $list '' read_cache_enable 1
16338         rm -f $DIR/$tfile
16339 }
16340 run_test 151 "test cache on oss and controls ==============================="
16341
16342 test_152() {
16343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16344
16345         local TF="$TMP/$tfile"
16346
16347         # simulate ENOMEM during write
16348 #define OBD_FAIL_OST_NOMEM      0x226
16349         lctl set_param fail_loc=0x80000226
16350         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16351         cp $TF $DIR/$tfile
16352         sync || error "sync failed"
16353         lctl set_param fail_loc=0
16354
16355         # discard client's cache
16356         cancel_lru_locks osc
16357
16358         # simulate ENOMEM during read
16359         lctl set_param fail_loc=0x80000226
16360         cmp $TF $DIR/$tfile || error "cmp failed"
16361         lctl set_param fail_loc=0
16362
16363         rm -f $TF
16364 }
16365 run_test 152 "test read/write with enomem ============================"
16366
16367 test_153() {
16368         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16369 }
16370 run_test 153 "test if fdatasync does not crash ======================="
16371
16372 dot_lustre_fid_permission_check() {
16373         local fid=$1
16374         local ffid=$MOUNT/.lustre/fid/$fid
16375         local test_dir=$2
16376
16377         echo "stat fid $fid"
16378         stat $ffid || error "stat $ffid failed."
16379         echo "touch fid $fid"
16380         touch $ffid || error "touch $ffid failed."
16381         echo "write to fid $fid"
16382         cat /etc/hosts > $ffid || error "write $ffid failed."
16383         echo "read fid $fid"
16384         diff /etc/hosts $ffid || error "read $ffid failed."
16385         echo "append write to fid $fid"
16386         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16387         echo "rename fid $fid"
16388         mv $ffid $test_dir/$tfile.1 &&
16389                 error "rename $ffid to $tfile.1 should fail."
16390         touch $test_dir/$tfile.1
16391         mv $test_dir/$tfile.1 $ffid &&
16392                 error "rename $tfile.1 to $ffid should fail."
16393         rm -f $test_dir/$tfile.1
16394         echo "truncate fid $fid"
16395         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16396         echo "link fid $fid"
16397         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16398         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16399                 id $USER0 || skip_env "missing user $USER0"
16400                 echo "setfacl fid $fid"
16401                 setfacl -R -m u:$USER0:rwx $ffid ||
16402                         error "setfacl $ffid failed"
16403                 echo "getfacl fid $fid"
16404                 getfacl $ffid || error "getfacl $ffid failed."
16405         fi
16406         echo "unlink fid $fid"
16407         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16408         echo "mknod fid $fid"
16409         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16410
16411         fid=[0xf00000400:0x1:0x0]
16412         ffid=$MOUNT/.lustre/fid/$fid
16413
16414         echo "stat non-exist fid $fid"
16415         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16416         echo "write to non-exist fid $fid"
16417         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16418         echo "link new fid $fid"
16419         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16420
16421         mkdir -p $test_dir/$tdir
16422         touch $test_dir/$tdir/$tfile
16423         fid=$($LFS path2fid $test_dir/$tdir)
16424         rc=$?
16425         [ $rc -ne 0 ] &&
16426                 error "error: could not get fid for $test_dir/$dir/$tfile."
16427
16428         ffid=$MOUNT/.lustre/fid/$fid
16429
16430         echo "ls $fid"
16431         ls $ffid || error "ls $ffid failed."
16432         echo "touch $fid/$tfile.1"
16433         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16434
16435         echo "touch $MOUNT/.lustre/fid/$tfile"
16436         touch $MOUNT/.lustre/fid/$tfile && \
16437                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16438
16439         echo "setxattr to $MOUNT/.lustre/fid"
16440         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16441
16442         echo "listxattr for $MOUNT/.lustre/fid"
16443         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16444
16445         echo "delxattr from $MOUNT/.lustre/fid"
16446         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16447
16448         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16449         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16450                 error "touch invalid fid should fail."
16451
16452         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16453         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16454                 error "touch non-normal fid should fail."
16455
16456         echo "rename $tdir to $MOUNT/.lustre/fid"
16457         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16458                 error "rename to $MOUNT/.lustre/fid should fail."
16459
16460         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16461         then            # LU-3547
16462                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16463                 local new_obf_mode=777
16464
16465                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16466                 chmod $new_obf_mode $DIR/.lustre/fid ||
16467                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16468
16469                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16470                 [ $obf_mode -eq $new_obf_mode ] ||
16471                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16472
16473                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16474                 chmod $old_obf_mode $DIR/.lustre/fid ||
16475                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16476         fi
16477
16478         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16479         fid=$($LFS path2fid $test_dir/$tfile-2)
16480
16481         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16482         then # LU-5424
16483                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16484                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16485                         error "create lov data thru .lustre failed"
16486         fi
16487         echo "cp /etc/passwd $test_dir/$tfile-2"
16488         cp /etc/passwd $test_dir/$tfile-2 ||
16489                 error "copy to $test_dir/$tfile-2 failed."
16490         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16491         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16492                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16493
16494         rm -rf $test_dir/tfile.lnk
16495         rm -rf $test_dir/$tfile-2
16496 }
16497
16498 test_154A() {
16499         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16500                 skip "Need MDS version at least 2.4.1"
16501
16502         local tf=$DIR/$tfile
16503         touch $tf
16504
16505         local fid=$($LFS path2fid $tf)
16506         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16507
16508         # check that we get the same pathname back
16509         local rootpath
16510         local found
16511         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16512                 echo "$rootpath $fid"
16513                 found=$($LFS fid2path $rootpath "$fid")
16514                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16515                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16516         done
16517
16518         # check wrong root path format
16519         rootpath=$MOUNT"_wrong"
16520         found=$($LFS fid2path $rootpath "$fid")
16521         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16522 }
16523 run_test 154A "lfs path2fid and fid2path basic checks"
16524
16525 test_154B() {
16526         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16527                 skip "Need MDS version at least 2.4.1"
16528
16529         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16530         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16531         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16532         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16533
16534         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16535         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16536
16537         # check that we get the same pathname
16538         echo "PFID: $PFID, name: $name"
16539         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16540         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16541         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16542                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16543
16544         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16545 }
16546 run_test 154B "verify the ll_decode_linkea tool"
16547
16548 test_154a() {
16549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16550         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16551         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16552                 skip "Need MDS version at least 2.2.51"
16553         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16554
16555         cp /etc/hosts $DIR/$tfile
16556
16557         fid=$($LFS path2fid $DIR/$tfile)
16558         rc=$?
16559         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16560
16561         dot_lustre_fid_permission_check "$fid" $DIR ||
16562                 error "dot lustre permission check $fid failed"
16563
16564         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16565
16566         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16567
16568         touch $MOUNT/.lustre/file &&
16569                 error "creation is not allowed under .lustre"
16570
16571         mkdir $MOUNT/.lustre/dir &&
16572                 error "mkdir is not allowed under .lustre"
16573
16574         rm -rf $DIR/$tfile
16575 }
16576 run_test 154a "Open-by-FID"
16577
16578 test_154b() {
16579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16580         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16582         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16583                 skip "Need MDS version at least 2.2.51"
16584
16585         local remote_dir=$DIR/$tdir/remote_dir
16586         local MDTIDX=1
16587         local rc=0
16588
16589         mkdir -p $DIR/$tdir
16590         $LFS mkdir -i $MDTIDX $remote_dir ||
16591                 error "create remote directory failed"
16592
16593         cp /etc/hosts $remote_dir/$tfile
16594
16595         fid=$($LFS path2fid $remote_dir/$tfile)
16596         rc=$?
16597         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16598
16599         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16600                 error "dot lustre permission check $fid failed"
16601         rm -rf $DIR/$tdir
16602 }
16603 run_test 154b "Open-by-FID for remote directory"
16604
16605 test_154c() {
16606         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16607                 skip "Need MDS version at least 2.4.1"
16608
16609         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16610         local FID1=$($LFS path2fid $DIR/$tfile.1)
16611         local FID2=$($LFS path2fid $DIR/$tfile.2)
16612         local FID3=$($LFS path2fid $DIR/$tfile.3)
16613
16614         local N=1
16615         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16616                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16617                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16618                 local want=FID$N
16619                 [ "$FID" = "${!want}" ] ||
16620                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16621                 N=$((N + 1))
16622         done
16623
16624         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16625         do
16626                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16627                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16628                 N=$((N + 1))
16629         done
16630 }
16631 run_test 154c "lfs path2fid and fid2path multiple arguments"
16632
16633 test_154d() {
16634         remote_mds_nodsh && skip "remote MDS with nodsh"
16635         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16636                 skip "Need MDS version at least 2.5.53"
16637
16638         if remote_mds; then
16639                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16640         else
16641                 nid="0@lo"
16642         fi
16643         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16644         local fd
16645         local cmd
16646
16647         rm -f $DIR/$tfile
16648         touch $DIR/$tfile
16649
16650         local fid=$($LFS path2fid $DIR/$tfile)
16651         # Open the file
16652         fd=$(free_fd)
16653         cmd="exec $fd<$DIR/$tfile"
16654         eval $cmd
16655         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16656         echo "$fid_list" | grep "$fid"
16657         rc=$?
16658
16659         cmd="exec $fd>/dev/null"
16660         eval $cmd
16661         if [ $rc -ne 0 ]; then
16662                 error "FID $fid not found in open files list $fid_list"
16663         fi
16664 }
16665 run_test 154d "Verify open file fid"
16666
16667 test_154e()
16668 {
16669         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16670                 skip "Need MDS version at least 2.6.50"
16671
16672         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16673                 error ".lustre returned by readdir"
16674         fi
16675 }
16676 run_test 154e ".lustre is not returned by readdir"
16677
16678 test_154f() {
16679         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16680
16681         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16682         mkdir_on_mdt0 $DIR/$tdir
16683         # test dirs inherit from its stripe
16684         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16685         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16686         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16687         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16688         touch $DIR/f
16689
16690         # get fid of parents
16691         local FID0=$($LFS path2fid $DIR/$tdir)
16692         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16693         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16694         local FID3=$($LFS path2fid $DIR)
16695
16696         # check that path2fid --parents returns expected <parent_fid>/name
16697         # 1) test for a directory (single parent)
16698         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16699         [ "$parent" == "$FID0/foo1" ] ||
16700                 error "expected parent: $FID0/foo1, got: $parent"
16701
16702         # 2) test for a file with nlink > 1 (multiple parents)
16703         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16704         echo "$parent" | grep -F "$FID1/$tfile" ||
16705                 error "$FID1/$tfile not returned in parent list"
16706         echo "$parent" | grep -F "$FID2/link" ||
16707                 error "$FID2/link not returned in parent list"
16708
16709         # 3) get parent by fid
16710         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16711         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16712         echo "$parent" | grep -F "$FID1/$tfile" ||
16713                 error "$FID1/$tfile not returned in parent list (by fid)"
16714         echo "$parent" | grep -F "$FID2/link" ||
16715                 error "$FID2/link not returned in parent list (by fid)"
16716
16717         # 4) test for entry in root directory
16718         parent=$($LFS path2fid --parents $DIR/f)
16719         echo "$parent" | grep -F "$FID3/f" ||
16720                 error "$FID3/f not returned in parent list"
16721
16722         # 5) test it on root directory
16723         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16724                 error "$MOUNT should not have parents"
16725
16726         # enable xattr caching and check that linkea is correctly updated
16727         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16728         save_lustre_params client "llite.*.xattr_cache" > $save
16729         lctl set_param llite.*.xattr_cache 1
16730
16731         # 6.1) linkea update on rename
16732         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16733
16734         # get parents by fid
16735         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16736         # foo1 should no longer be returned in parent list
16737         echo "$parent" | grep -F "$FID1" &&
16738                 error "$FID1 should no longer be in parent list"
16739         # the new path should appear
16740         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16741                 error "$FID2/$tfile.moved is not in parent list"
16742
16743         # 6.2) linkea update on unlink
16744         rm -f $DIR/$tdir/foo2/link
16745         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16746         # foo2/link should no longer be returned in parent list
16747         echo "$parent" | grep -F "$FID2/link" &&
16748                 error "$FID2/link should no longer be in parent list"
16749         true
16750
16751         rm -f $DIR/f
16752         restore_lustre_params < $save
16753         rm -f $save
16754 }
16755 run_test 154f "get parent fids by reading link ea"
16756
16757 test_154g()
16758 {
16759         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16760            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16761                 skip "Need MDS version at least 2.6.92"
16762
16763         mkdir_on_mdt0 $DIR/$tdir
16764         llapi_fid_test -d $DIR/$tdir
16765 }
16766 run_test 154g "various llapi FID tests"
16767
16768 test_154h()
16769 {
16770         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16771                 skip "Need client at least version 2.15.55.1"
16772
16773         # Create an empty file
16774         touch $DIR/$tfile
16775
16776         # Get FID (interactive mode) and save under $TMP/$tfile.log
16777         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16778                 path2fid $DIR/$tfile
16779         EOF
16780
16781         fid=$(cat $TMP/$tfile.log)
16782         # $fid should not be empty
16783         [[ ! -z $fid ]] || error "FID is empty"
16784         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16785 }
16786 run_test 154h "Verify interactive path2fid"
16787
16788 test_155_small_load() {
16789     local temp=$TMP/$tfile
16790     local file=$DIR/$tfile
16791
16792     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16793         error "dd of=$temp bs=6096 count=1 failed"
16794     cp $temp $file
16795     cancel_lru_locks $OSC
16796     cmp $temp $file || error "$temp $file differ"
16797
16798     $TRUNCATE $temp 6000
16799     $TRUNCATE $file 6000
16800     cmp $temp $file || error "$temp $file differ (truncate1)"
16801
16802     echo "12345" >>$temp
16803     echo "12345" >>$file
16804     cmp $temp $file || error "$temp $file differ (append1)"
16805
16806     echo "12345" >>$temp
16807     echo "12345" >>$file
16808     cmp $temp $file || error "$temp $file differ (append2)"
16809
16810     rm -f $temp $file
16811     true
16812 }
16813
16814 test_155_big_load() {
16815         remote_ost_nodsh && skip "remote OST with nodsh"
16816
16817         local temp=$TMP/$tfile
16818         local file=$DIR/$tfile
16819
16820         free_min_max
16821         local cache_size=$(do_facet ost$((MAXI+1)) \
16822                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16823
16824         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16825         # pre-set value
16826         if [ -z "$cache_size" ]; then
16827                 cache_size=256
16828         fi
16829         local large_file_size=$((cache_size * 2))
16830
16831         echo "OSS cache size: $cache_size KB"
16832         echo "Large file size: $large_file_size KB"
16833
16834         [ $MAXV -le $large_file_size ] &&
16835                 skip_env "max available OST size needs > $large_file_size KB"
16836
16837         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16838
16839         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16840                 error "dd of=$temp bs=$large_file_size count=1k failed"
16841         cp $temp $file
16842         ls -lh $temp $file
16843         cancel_lru_locks osc
16844         cmp $temp $file || error "$temp $file differ"
16845
16846         rm -f $temp $file
16847         true
16848 }
16849
16850 save_writethrough() {
16851         local facets=$(get_facets OST)
16852
16853         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16854 }
16855
16856 test_155a() {
16857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16858
16859         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16860
16861         save_writethrough $p
16862
16863         set_cache read on
16864         set_cache writethrough on
16865         test_155_small_load
16866         restore_lustre_params < $p
16867         rm -f $p
16868 }
16869 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16870
16871 test_155b() {
16872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16873
16874         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16875
16876         save_writethrough $p
16877
16878         set_cache read on
16879         set_cache writethrough off
16880         test_155_small_load
16881         restore_lustre_params < $p
16882         rm -f $p
16883 }
16884 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16885
16886 test_155c() {
16887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16888
16889         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16890
16891         save_writethrough $p
16892
16893         set_cache read off
16894         set_cache writethrough on
16895         test_155_small_load
16896         restore_lustre_params < $p
16897         rm -f $p
16898 }
16899 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16900
16901 test_155d() {
16902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16903
16904         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16905
16906         save_writethrough $p
16907
16908         set_cache read off
16909         set_cache writethrough off
16910         test_155_small_load
16911         restore_lustre_params < $p
16912         rm -f $p
16913 }
16914 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16915
16916 test_155e() {
16917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16918
16919         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16920
16921         save_writethrough $p
16922
16923         set_cache read on
16924         set_cache writethrough on
16925         test_155_big_load
16926         restore_lustre_params < $p
16927         rm -f $p
16928 }
16929 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16930
16931 test_155f() {
16932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16933
16934         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16935
16936         save_writethrough $p
16937
16938         set_cache read on
16939         set_cache writethrough off
16940         test_155_big_load
16941         restore_lustre_params < $p
16942         rm -f $p
16943 }
16944 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16945
16946 test_155g() {
16947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16948
16949         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16950
16951         save_writethrough $p
16952
16953         set_cache read off
16954         set_cache writethrough on
16955         test_155_big_load
16956         restore_lustre_params < $p
16957         rm -f $p
16958 }
16959 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16960
16961 test_155h() {
16962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16963
16964         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16965
16966         save_writethrough $p
16967
16968         set_cache read off
16969         set_cache writethrough off
16970         test_155_big_load
16971         restore_lustre_params < $p
16972         rm -f $p
16973 }
16974 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16975
16976 test_156() {
16977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16978         remote_ost_nodsh && skip "remote OST with nodsh"
16979         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16980                 skip "stats not implemented on old servers"
16981         [ "$ost1_FSTYPE" = "zfs" ] &&
16982                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16983         (( CLIENT_VERSION == OST1_VERSION )) ||
16984                 skip "LU-13081: no interop testing for OSS cache"
16985
16986         local CPAGES=3
16987         local BEFORE
16988         local AFTER
16989         local file="$DIR/$tfile"
16990         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16991
16992         save_writethrough $p
16993         roc_hit_init
16994
16995         log "Turn on read and write cache"
16996         set_cache read on
16997         set_cache writethrough on
16998
16999         log "Write data and read it back."
17000         log "Read should be satisfied from the cache."
17001         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17002         BEFORE=$(roc_hit)
17003         cancel_lru_locks osc
17004         cat $file >/dev/null
17005         AFTER=$(roc_hit)
17006         if ! let "AFTER - BEFORE == CPAGES"; then
17007                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17008         else
17009                 log "cache hits: before: $BEFORE, after: $AFTER"
17010         fi
17011
17012         log "Read again; it should be satisfied from the cache."
17013         BEFORE=$AFTER
17014         cancel_lru_locks osc
17015         cat $file >/dev/null
17016         AFTER=$(roc_hit)
17017         if ! let "AFTER - BEFORE == CPAGES"; then
17018                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17019         else
17020                 log "cache hits:: before: $BEFORE, after: $AFTER"
17021         fi
17022
17023         log "Turn off the read cache and turn on the write cache"
17024         set_cache read off
17025         set_cache writethrough on
17026
17027         log "Read again; it should be satisfied from the cache."
17028         BEFORE=$(roc_hit)
17029         cancel_lru_locks osc
17030         cat $file >/dev/null
17031         AFTER=$(roc_hit)
17032         if ! let "AFTER - BEFORE == CPAGES"; then
17033                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17034         else
17035                 log "cache hits:: before: $BEFORE, after: $AFTER"
17036         fi
17037
17038         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17039                 # > 2.12.56 uses pagecache if cached
17040                 log "Read again; it should not be satisfied from the cache."
17041                 BEFORE=$AFTER
17042                 cancel_lru_locks osc
17043                 cat $file >/dev/null
17044                 AFTER=$(roc_hit)
17045                 if ! let "AFTER - BEFORE == 0"; then
17046                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17047                 else
17048                         log "cache hits:: before: $BEFORE, after: $AFTER"
17049                 fi
17050         fi
17051
17052         log "Write data and read it back."
17053         log "Read should be satisfied from the cache."
17054         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17055         BEFORE=$(roc_hit)
17056         cancel_lru_locks osc
17057         cat $file >/dev/null
17058         AFTER=$(roc_hit)
17059         if ! let "AFTER - BEFORE == CPAGES"; then
17060                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17061         else
17062                 log "cache hits:: before: $BEFORE, after: $AFTER"
17063         fi
17064
17065         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17066                 # > 2.12.56 uses pagecache if cached
17067                 log "Read again; it should not be satisfied from the cache."
17068                 BEFORE=$AFTER
17069                 cancel_lru_locks osc
17070                 cat $file >/dev/null
17071                 AFTER=$(roc_hit)
17072                 if ! let "AFTER - BEFORE == 0"; then
17073                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17074                 else
17075                         log "cache hits:: before: $BEFORE, after: $AFTER"
17076                 fi
17077         fi
17078
17079         log "Turn off read and write cache"
17080         set_cache read off
17081         set_cache writethrough off
17082
17083         log "Write data and read it back"
17084         log "It should not be satisfied from the cache."
17085         rm -f $file
17086         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17087         cancel_lru_locks osc
17088         BEFORE=$(roc_hit)
17089         cat $file >/dev/null
17090         AFTER=$(roc_hit)
17091         if ! let "AFTER - BEFORE == 0"; then
17092                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17093         else
17094                 log "cache hits:: before: $BEFORE, after: $AFTER"
17095         fi
17096
17097         log "Turn on the read cache and turn off the write cache"
17098         set_cache read on
17099         set_cache writethrough off
17100
17101         log "Write data and read it back"
17102         log "It should not be satisfied from the cache."
17103         rm -f $file
17104         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17105         BEFORE=$(roc_hit)
17106         cancel_lru_locks osc
17107         cat $file >/dev/null
17108         AFTER=$(roc_hit)
17109         if ! let "AFTER - BEFORE == 0"; then
17110                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17111         else
17112                 log "cache hits:: before: $BEFORE, after: $AFTER"
17113         fi
17114
17115         log "Read again; it should be satisfied from the cache."
17116         BEFORE=$(roc_hit)
17117         cancel_lru_locks osc
17118         cat $file >/dev/null
17119         AFTER=$(roc_hit)
17120         if ! let "AFTER - BEFORE == CPAGES"; then
17121                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17122         else
17123                 log "cache hits:: before: $BEFORE, after: $AFTER"
17124         fi
17125
17126         restore_lustre_params < $p
17127         rm -f $p $file
17128 }
17129 run_test 156 "Verification of tunables"
17130
17131 test_160a() {
17132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17133         remote_mds_nodsh && skip "remote MDS with nodsh"
17134         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17135                 skip "Need MDS version at least 2.2.0"
17136
17137         changelog_register || error "changelog_register failed"
17138         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17139         changelog_users $SINGLEMDS | grep -q $cl_user ||
17140                 error "User $cl_user not found in changelog_users"
17141
17142         mkdir_on_mdt0 $DIR/$tdir
17143
17144         # change something
17145         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17146         changelog_clear 0 || error "changelog_clear failed"
17147         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17148         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17149         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17150         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17151         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17152         rm $DIR/$tdir/pics/desktop.jpg
17153
17154         echo "verifying changelog mask"
17155         changelog_chmask "-MKDIR"
17156         changelog_chmask "-CLOSE"
17157
17158         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17159         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17160
17161         changelog_chmask "+MKDIR"
17162         changelog_chmask "+CLOSE"
17163
17164         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17165         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17166
17167         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17168         CLOSES=$(changelog_dump | grep -c "CLOSE")
17169         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17170         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17171
17172         # verify contents
17173         echo "verifying target fid"
17174         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17175         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17176         [ "$fidc" == "$fidf" ] ||
17177                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17178         echo "verifying parent fid"
17179         # The FID returned from the Changelog may be the directory shard on
17180         # a different MDT, and not the FID returned by path2fid on the parent.
17181         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17182         # since this is what will matter when recreating this file in the tree.
17183         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17184         local pathp=$($LFS fid2path $MOUNT "$fidp")
17185         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17186                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17187
17188         echo "getting records for $cl_user"
17189         changelog_users $SINGLEMDS
17190         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17191         local nclr=3
17192         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17193                 error "changelog_clear failed"
17194         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17195         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17196         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17197                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17198
17199         local min0_rec=$(changelog_users $SINGLEMDS |
17200                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17201         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17202                           awk '{ print $1; exit; }')
17203
17204         changelog_dump | tail -n 5
17205         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17206         [ $first_rec == $((min0_rec + 1)) ] ||
17207                 error "first index should be $min0_rec + 1 not $first_rec"
17208
17209         # LU-3446 changelog index reset on MDT restart
17210         local cur_rec1=$(changelog_users $SINGLEMDS |
17211                          awk '/^current.index:/ { print $NF }')
17212         changelog_clear 0 ||
17213                 error "clear all changelog records for $cl_user failed"
17214         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17215         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17216                 error "Fail to start $SINGLEMDS"
17217         local cur_rec2=$(changelog_users $SINGLEMDS |
17218                          awk '/^current.index:/ { print $NF }')
17219         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17220         [ $cur_rec1 == $cur_rec2 ] ||
17221                 error "current index should be $cur_rec1 not $cur_rec2"
17222
17223         echo "verifying users from this test are deregistered"
17224         changelog_deregister || error "changelog_deregister failed"
17225         changelog_users $SINGLEMDS | grep -q $cl_user &&
17226                 error "User '$cl_user' still in changelog_users"
17227
17228         # lctl get_param -n mdd.*.changelog_users
17229         # current_index: 144
17230         # ID    index (idle seconds)
17231         # cl3   144   (2) mask=<list>
17232         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17233                 # this is the normal case where all users were deregistered
17234                 # make sure no new records are added when no users are present
17235                 local last_rec1=$(changelog_users $SINGLEMDS |
17236                                   awk '/^current.index:/ { print $NF }')
17237                 touch $DIR/$tdir/chloe
17238                 local last_rec2=$(changelog_users $SINGLEMDS |
17239                                   awk '/^current.index:/ { print $NF }')
17240                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17241                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17242         else
17243                 # any changelog users must be leftovers from a previous test
17244                 changelog_users $SINGLEMDS
17245                 echo "other changelog users; can't verify off"
17246         fi
17247 }
17248 run_test 160a "changelog sanity"
17249
17250 test_160b() { # LU-3587
17251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17252         remote_mds_nodsh && skip "remote MDS with nodsh"
17253         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17254                 skip "Need MDS version at least 2.2.0"
17255
17256         changelog_register || error "changelog_register failed"
17257         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17258         changelog_users $SINGLEMDS | grep -q $cl_user ||
17259                 error "User '$cl_user' not found in changelog_users"
17260
17261         local longname1=$(str_repeat a 255)
17262         local longname2=$(str_repeat b 255)
17263
17264         cd $DIR
17265         echo "creating very long named file"
17266         touch $longname1 || error "create of '$longname1' failed"
17267         echo "renaming very long named file"
17268         mv $longname1 $longname2
17269
17270         changelog_dump | grep RENME | tail -n 5
17271         rm -f $longname2
17272 }
17273 run_test 160b "Verify that very long rename doesn't crash in changelog"
17274
17275 test_160c() {
17276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17277         remote_mds_nodsh && skip "remote MDS with nodsh"
17278
17279         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17280                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17281                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17282                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17283
17284         local rc=0
17285
17286         # Registration step
17287         changelog_register || error "changelog_register failed"
17288
17289         rm -rf $DIR/$tdir
17290         mkdir -p $DIR/$tdir
17291         $MCREATE $DIR/$tdir/foo_160c
17292         changelog_chmask "-TRUNC"
17293         $TRUNCATE $DIR/$tdir/foo_160c 200
17294         changelog_chmask "+TRUNC"
17295         $TRUNCATE $DIR/$tdir/foo_160c 199
17296         changelog_dump | tail -n 5
17297         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17298         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17299 }
17300 run_test 160c "verify that changelog log catch the truncate event"
17301
17302 test_160d() {
17303         remote_mds_nodsh && skip "remote MDS with nodsh"
17304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17306         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17307                 skip "Need MDS version at least 2.7.60"
17308
17309         # Registration step
17310         changelog_register || error "changelog_register failed"
17311
17312         mkdir -p $DIR/$tdir/migrate_dir
17313         changelog_clear 0 || error "changelog_clear failed"
17314
17315         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17316         changelog_dump | tail -n 5
17317         local migrates=$(changelog_dump | grep -c "MIGRT")
17318         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17319 }
17320 run_test 160d "verify that changelog log catch the migrate event"
17321
17322 test_160e() {
17323         remote_mds_nodsh && skip "remote MDS with nodsh"
17324
17325         # Create a user
17326         changelog_register || error "changelog_register failed"
17327
17328         local MDT0=$(facet_svc $SINGLEMDS)
17329         local rc
17330
17331         # No user (expect fail)
17332         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17333         rc=$?
17334         if [ $rc -eq 0 ]; then
17335                 error "Should fail without user"
17336         elif [ $rc -ne 4 ]; then
17337                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17338         fi
17339
17340         # Delete a future user (expect fail)
17341         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17342         rc=$?
17343         if [ $rc -eq 0 ]; then
17344                 error "Deleted non-existant user cl77"
17345         elif [ $rc -ne 2 ]; then
17346                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17347         fi
17348
17349         # Clear to a bad index (1 billion should be safe)
17350         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17351         rc=$?
17352
17353         if [ $rc -eq 0 ]; then
17354                 error "Successfully cleared to invalid CL index"
17355         elif [ $rc -ne 22 ]; then
17356                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17357         fi
17358 }
17359 run_test 160e "changelog negative testing (should return errors)"
17360
17361 test_160f() {
17362         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17363         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17364                 skip "Need MDS version at least 2.10.56"
17365
17366         local mdts=$(comma_list $(mdts_nodes))
17367
17368         # Create a user
17369         changelog_register || error "first changelog_register failed"
17370         changelog_register || error "second changelog_register failed"
17371         local cl_users
17372         declare -A cl_user1
17373         declare -A cl_user2
17374         local user_rec1
17375         local user_rec2
17376         local i
17377
17378         # generate some changelog records to accumulate on each MDT
17379         # use all_char because created files should be evenly distributed
17380         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17381                 error "test_mkdir $tdir failed"
17382         log "$(date +%s): creating first files"
17383         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17384                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17385                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17386         done
17387
17388         # check changelogs have been generated
17389         local start=$SECONDS
17390         local idle_time=$((MDSCOUNT * 5 + 5))
17391         local nbcl=$(changelog_dump | wc -l)
17392         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17393
17394         for param in "changelog_max_idle_time=$idle_time" \
17395                      "changelog_gc=1" \
17396                      "changelog_min_gc_interval=2" \
17397                      "changelog_min_free_cat_entries=3"; do
17398                 local MDT0=$(facet_svc $SINGLEMDS)
17399                 local var="${param%=*}"
17400                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17401
17402                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17403                 do_nodes $mdts $LCTL set_param mdd.*.$param
17404         done
17405
17406         # force cl_user2 to be idle (1st part), but also cancel the
17407         # cl_user1 records so that it is not evicted later in the test.
17408         local sleep1=$((idle_time / 2))
17409         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17410         sleep $sleep1
17411
17412         # simulate changelog catalog almost full
17413         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17414         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17415
17416         for i in $(seq $MDSCOUNT); do
17417                 cl_users=(${CL_USERS[mds$i]})
17418                 cl_user1[mds$i]="${cl_users[0]}"
17419                 cl_user2[mds$i]="${cl_users[1]}"
17420
17421                 [ -n "${cl_user1[mds$i]}" ] ||
17422                         error "mds$i: no user registered"
17423                 [ -n "${cl_user2[mds$i]}" ] ||
17424                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17425
17426                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17427                 [ -n "$user_rec1" ] ||
17428                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17429                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17430                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17431                 [ -n "$user_rec2" ] ||
17432                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17433                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17434                      "$user_rec1 + 2 == $user_rec2"
17435                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17436                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17437                               "$user_rec1 + 2, but is $user_rec2"
17438                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17439                 [ -n "$user_rec2" ] ||
17440                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17441                 [ $user_rec1 == $user_rec2 ] ||
17442                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17443                               "$user_rec1, but is $user_rec2"
17444         done
17445
17446         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17447         local sleep2=$((idle_time - (SECONDS - start) + 1))
17448         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17449         sleep $sleep2
17450
17451         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17452         # cl_user1 should be OK because it recently processed records.
17453         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17454         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17455                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17456                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17457         done
17458
17459         # ensure gc thread is done
17460         for i in $(mdts_nodes); do
17461                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17462                         error "$i: GC-thread not done"
17463         done
17464
17465         local first_rec
17466         for (( i = 1; i <= MDSCOUNT; i++ )); do
17467                 # check cl_user1 still registered
17468                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17469                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17470                 # check cl_user2 unregistered
17471                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17472                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17473
17474                 # check changelogs are present and starting at $user_rec1 + 1
17475                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17476                 [ -n "$user_rec1" ] ||
17477                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17478                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17479                             awk '{ print $1; exit; }')
17480
17481                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17482                 [ $((user_rec1 + 1)) == $first_rec ] ||
17483                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17484         done
17485 }
17486 run_test 160f "changelog garbage collect (timestamped users)"
17487
17488 test_160g() {
17489         remote_mds_nodsh && skip "remote MDS with nodsh"
17490         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17491                 skip "Need MDS version at least 2.14.55"
17492
17493         local mdts=$(comma_list $(mdts_nodes))
17494
17495         # Create a user
17496         changelog_register || error "first changelog_register failed"
17497         changelog_register || error "second changelog_register failed"
17498         local cl_users
17499         declare -A cl_user1
17500         declare -A cl_user2
17501         local user_rec1
17502         local user_rec2
17503         local i
17504
17505         # generate some changelog records to accumulate on each MDT
17506         # use all_char because created files should be evenly distributed
17507         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17508                 error "test_mkdir $tdir failed"
17509         for ((i = 0; i < MDSCOUNT; i++)); do
17510                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17511                         error "create $DIR/$tdir/d$i.1 failed"
17512         done
17513
17514         # check changelogs have been generated
17515         local nbcl=$(changelog_dump | wc -l)
17516         (( $nbcl > 0 )) || error "no changelogs found"
17517
17518         # reduce the max_idle_indexes value to make sure we exceed it
17519         for param in "changelog_max_idle_indexes=2" \
17520                      "changelog_gc=1" \
17521                      "changelog_min_gc_interval=2"; do
17522                 local MDT0=$(facet_svc $SINGLEMDS)
17523                 local var="${param%=*}"
17524                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17525
17526                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17527                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17528                         error "unable to set mdd.*.$param"
17529         done
17530
17531         local start=$SECONDS
17532         for i in $(seq $MDSCOUNT); do
17533                 cl_users=(${CL_USERS[mds$i]})
17534                 cl_user1[mds$i]="${cl_users[0]}"
17535                 cl_user2[mds$i]="${cl_users[1]}"
17536
17537                 [ -n "${cl_user1[mds$i]}" ] ||
17538                         error "mds$i: user1 is not registered"
17539                 [ -n "${cl_user2[mds$i]}" ] ||
17540                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17541
17542                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17543                 [ -n "$user_rec1" ] ||
17544                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17545                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17546                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17547                 [ -n "$user_rec2" ] ||
17548                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17549                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17550                      "$user_rec1 + 2 == $user_rec2"
17551                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17552                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17553                               "expected $user_rec1 + 2, but is $user_rec2"
17554                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17555                 [ -n "$user_rec2" ] ||
17556                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17557                 [ $user_rec1 == $user_rec2 ] ||
17558                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17559                               "expected $user_rec1, but is $user_rec2"
17560         done
17561
17562         # ensure we are past the previous changelog_min_gc_interval set above
17563         local sleep2=$((start + 2 - SECONDS))
17564         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17565         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17566         # cl_user1 should be OK because it recently processed records.
17567         for ((i = 0; i < MDSCOUNT; i++)); do
17568                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17569                         error "create $DIR/$tdir/d$i.3 failed"
17570         done
17571
17572         # ensure gc thread is done
17573         for i in $(mdts_nodes); do
17574                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17575                         error "$i: GC-thread not done"
17576         done
17577
17578         local first_rec
17579         for (( i = 1; i <= MDSCOUNT; i++ )); do
17580                 # check cl_user1 still registered
17581                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17582                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17583                 # check cl_user2 unregistered
17584                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17585                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17586
17587                 # check changelogs are present and starting at $user_rec1 + 1
17588                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17589                 [ -n "$user_rec1" ] ||
17590                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17591                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17592                             awk '{ print $1; exit; }')
17593
17594                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17595                 [ $((user_rec1 + 1)) == $first_rec ] ||
17596                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17597         done
17598 }
17599 run_test 160g "changelog garbage collect on idle records"
17600
17601 test_160h() {
17602         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17603         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17604                 skip "Need MDS version at least 2.10.56"
17605
17606         local mdts=$(comma_list $(mdts_nodes))
17607
17608         # Create a user
17609         changelog_register || error "first changelog_register failed"
17610         changelog_register || error "second changelog_register failed"
17611         local cl_users
17612         declare -A cl_user1
17613         declare -A cl_user2
17614         local user_rec1
17615         local user_rec2
17616         local i
17617
17618         # generate some changelog records to accumulate on each MDT
17619         # use all_char because created files should be evenly distributed
17620         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17621                 error "test_mkdir $tdir failed"
17622         for ((i = 0; i < MDSCOUNT; i++)); do
17623                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17624                         error "create $DIR/$tdir/d$i.1 failed"
17625         done
17626
17627         # check changelogs have been generated
17628         local nbcl=$(changelog_dump | wc -l)
17629         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17630
17631         for param in "changelog_max_idle_time=10" \
17632                      "changelog_gc=1" \
17633                      "changelog_min_gc_interval=2"; do
17634                 local MDT0=$(facet_svc $SINGLEMDS)
17635                 local var="${param%=*}"
17636                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17637
17638                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17639                 do_nodes $mdts $LCTL set_param mdd.*.$param
17640         done
17641
17642         # force cl_user2 to be idle (1st part)
17643         sleep 9
17644
17645         for i in $(seq $MDSCOUNT); do
17646                 cl_users=(${CL_USERS[mds$i]})
17647                 cl_user1[mds$i]="${cl_users[0]}"
17648                 cl_user2[mds$i]="${cl_users[1]}"
17649
17650                 [ -n "${cl_user1[mds$i]}" ] ||
17651                         error "mds$i: no user registered"
17652                 [ -n "${cl_user2[mds$i]}" ] ||
17653                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17654
17655                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17656                 [ -n "$user_rec1" ] ||
17657                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17658                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17659                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17660                 [ -n "$user_rec2" ] ||
17661                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17662                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17663                      "$user_rec1 + 2 == $user_rec2"
17664                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17665                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17666                               "$user_rec1 + 2, but is $user_rec2"
17667                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17668                 [ -n "$user_rec2" ] ||
17669                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17670                 [ $user_rec1 == $user_rec2 ] ||
17671                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17672                               "$user_rec1, but is $user_rec2"
17673         done
17674
17675         # force cl_user2 to be idle (2nd part) and to reach
17676         # changelog_max_idle_time
17677         sleep 2
17678
17679         # force each GC-thread start and block then
17680         # one per MDT/MDD, set fail_val accordingly
17681         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17682         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17683
17684         # generate more changelogs to trigger fail_loc
17685         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17686                 error "create $DIR/$tdir/${tfile}bis failed"
17687
17688         # stop MDT to stop GC-thread, should be done in back-ground as it will
17689         # block waiting for the thread to be released and exit
17690         declare -A stop_pids
17691         for i in $(seq $MDSCOUNT); do
17692                 stop mds$i &
17693                 stop_pids[mds$i]=$!
17694         done
17695
17696         for i in $(mdts_nodes); do
17697                 local facet
17698                 local nb=0
17699                 local facets=$(facets_up_on_host $i)
17700
17701                 for facet in ${facets//,/ }; do
17702                         if [[ $facet == mds* ]]; then
17703                                 nb=$((nb + 1))
17704                         fi
17705                 done
17706                 # ensure each MDS's gc threads are still present and all in "R"
17707                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17708                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17709                         error "$i: expected $nb GC-thread"
17710                 wait_update $i \
17711                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17712                         "R" 20 ||
17713                         error "$i: GC-thread not found in R-state"
17714                 # check umounts of each MDT on MDS have reached kthread_stop()
17715                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17716                         error "$i: expected $nb umount"
17717                 wait_update $i \
17718                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17719                         error "$i: umount not found in D-state"
17720         done
17721
17722         # release all GC-threads
17723         do_nodes $mdts $LCTL set_param fail_loc=0
17724
17725         # wait for MDT stop to complete
17726         for i in $(seq $MDSCOUNT); do
17727                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17728         done
17729
17730         # XXX
17731         # may try to check if any orphan changelog records are present
17732         # via ldiskfs/zfs and llog_reader...
17733
17734         # re-start/mount MDTs
17735         for i in $(seq $MDSCOUNT); do
17736                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17737                         error "Fail to start mds$i"
17738         done
17739
17740         local first_rec
17741         for i in $(seq $MDSCOUNT); do
17742                 # check cl_user1 still registered
17743                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17744                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17745                 # check cl_user2 unregistered
17746                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17747                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17748
17749                 # check changelogs are present and starting at $user_rec1 + 1
17750                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17751                 [ -n "$user_rec1" ] ||
17752                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17753                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17754                             awk '{ print $1; exit; }')
17755
17756                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17757                 [ $((user_rec1 + 1)) == $first_rec ] ||
17758                         error "mds$i: first index should be $user_rec1 + 1, " \
17759                               "but is $first_rec"
17760         done
17761 }
17762 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17763               "during mount"
17764
17765 test_160i() {
17766
17767         local mdts=$(comma_list $(mdts_nodes))
17768
17769         changelog_register || error "first changelog_register failed"
17770
17771         # generate some changelog records to accumulate on each MDT
17772         # use all_char because created files should be evenly distributed
17773         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17774                 error "test_mkdir $tdir failed"
17775         for ((i = 0; i < MDSCOUNT; i++)); do
17776                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17777                         error "create $DIR/$tdir/d$i.1 failed"
17778         done
17779
17780         # check changelogs have been generated
17781         local nbcl=$(changelog_dump | wc -l)
17782         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17783
17784         # simulate race between register and unregister
17785         # XXX as fail_loc is set per-MDS, with DNE configs the race
17786         # simulation will only occur for one MDT per MDS and for the
17787         # others the normal race scenario will take place
17788         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17789         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17790         do_nodes $mdts $LCTL set_param fail_val=1
17791
17792         # unregister 1st user
17793         changelog_deregister &
17794         local pid1=$!
17795         # wait some time for deregister work to reach race rdv
17796         sleep 2
17797         # register 2nd user
17798         changelog_register || error "2nd user register failed"
17799
17800         wait $pid1 || error "1st user deregister failed"
17801
17802         local i
17803         local last_rec
17804         declare -A LAST_REC
17805         for i in $(seq $MDSCOUNT); do
17806                 if changelog_users mds$i | grep "^cl"; then
17807                         # make sure new records are added with one user present
17808                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17809                                           awk '/^current.index:/ { print $NF }')
17810                 else
17811                         error "mds$i has no user registered"
17812                 fi
17813         done
17814
17815         # generate more changelog records to accumulate on each MDT
17816         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17817                 error "create $DIR/$tdir/${tfile}bis failed"
17818
17819         for i in $(seq $MDSCOUNT); do
17820                 last_rec=$(changelog_users $SINGLEMDS |
17821                            awk '/^current.index:/ { print $NF }')
17822                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17823                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17824                         error "changelogs are off on mds$i"
17825         done
17826 }
17827 run_test 160i "changelog user register/unregister race"
17828
17829 test_160j() {
17830         remote_mds_nodsh && skip "remote MDS with nodsh"
17831         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17832                 skip "Need MDS version at least 2.12.56"
17833
17834         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17835         stack_trap "umount $MOUNT2" EXIT
17836
17837         changelog_register || error "first changelog_register failed"
17838         stack_trap "changelog_deregister" EXIT
17839
17840         # generate some changelog
17841         # use all_char because created files should be evenly distributed
17842         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17843                 error "mkdir $tdir failed"
17844         for ((i = 0; i < MDSCOUNT; i++)); do
17845                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17846                         error "create $DIR/$tdir/d$i.1 failed"
17847         done
17848
17849         # open the changelog device
17850         exec 3>/dev/changelog-$FSNAME-MDT0000
17851         stack_trap "exec 3>&-" EXIT
17852         exec 4</dev/changelog-$FSNAME-MDT0000
17853         stack_trap "exec 4<&-" EXIT
17854
17855         # umount the first lustre mount
17856         umount $MOUNT
17857         stack_trap "mount_client $MOUNT" EXIT
17858
17859         # read changelog, which may or may not fail, but should not crash
17860         cat <&4 >/dev/null
17861
17862         # clear changelog
17863         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17864         changelog_users $SINGLEMDS | grep -q $cl_user ||
17865                 error "User $cl_user not found in changelog_users"
17866
17867         printf 'clear:'$cl_user':0' >&3
17868 }
17869 run_test 160j "client can be umounted while its chanangelog is being used"
17870
17871 test_160k() {
17872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17873         remote_mds_nodsh && skip "remote MDS with nodsh"
17874
17875         mkdir -p $DIR/$tdir/1/1
17876
17877         changelog_register || error "changelog_register failed"
17878         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17879
17880         changelog_users $SINGLEMDS | grep -q $cl_user ||
17881                 error "User '$cl_user' not found in changelog_users"
17882 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17883         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17884         rmdir $DIR/$tdir/1/1 & sleep 1
17885         mkdir $DIR/$tdir/2
17886         touch $DIR/$tdir/2/2
17887         rm -rf $DIR/$tdir/2
17888
17889         wait
17890         sleep 4
17891
17892         changelog_dump | grep rmdir || error "rmdir not recorded"
17893 }
17894 run_test 160k "Verify that changelog records are not lost"
17895
17896 # Verifies that a file passed as a parameter has recently had an operation
17897 # performed on it that has generated an MTIME changelog which contains the
17898 # correct parent FID. As files might reside on a different MDT from the
17899 # parent directory in DNE configurations, the FIDs are translated to paths
17900 # before being compared, which should be identical
17901 compare_mtime_changelog() {
17902         local file="${1}"
17903         local mdtidx
17904         local mtime
17905         local cl_fid
17906         local pdir
17907         local dir
17908
17909         mdtidx=$($LFS getstripe --mdt-index $file)
17910         mdtidx=$(printf "%04x" $mdtidx)
17911
17912         # Obtain the parent FID from the MTIME changelog
17913         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17914         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17915
17916         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17917         [ -z "$cl_fid" ] && error "parent FID not present"
17918
17919         # Verify that the path for the parent FID is the same as the path for
17920         # the test directory
17921         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17922
17923         dir=$(dirname $1)
17924
17925         [[ "${pdir%/}" == "$dir" ]] ||
17926                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17927 }
17928
17929 test_160l() {
17930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17931
17932         remote_mds_nodsh && skip "remote MDS with nodsh"
17933         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17934                 skip "Need MDS version at least 2.13.55"
17935
17936         local cl_user
17937
17938         changelog_register || error "changelog_register failed"
17939         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17940
17941         changelog_users $SINGLEMDS | grep -q $cl_user ||
17942                 error "User '$cl_user' not found in changelog_users"
17943
17944         # Clear some types so that MTIME changelogs are generated
17945         changelog_chmask "-CREAT"
17946         changelog_chmask "-CLOSE"
17947
17948         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17949
17950         # Test CL_MTIME during setattr
17951         touch $DIR/$tdir/$tfile
17952         compare_mtime_changelog $DIR/$tdir/$tfile
17953
17954         # Test CL_MTIME during close
17955         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17956         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17957 }
17958 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17959
17960 test_160m() {
17961         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17962         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17963                 skip "Need MDS version at least 2.14.51"
17964         local cl_users
17965         local cl_user1
17966         local cl_user2
17967         local pid1
17968
17969         # Create a user
17970         changelog_register || error "first changelog_register failed"
17971         changelog_register || error "second changelog_register failed"
17972
17973         cl_users=(${CL_USERS[mds1]})
17974         cl_user1="${cl_users[0]}"
17975         cl_user2="${cl_users[1]}"
17976         # generate some changelog records to accumulate on MDT0
17977         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17978         createmany -m $DIR/$tdir/$tfile 50 ||
17979                 error "create $DIR/$tdir/$tfile failed"
17980         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17981         rm -f $DIR/$tdir
17982
17983         # check changelogs have been generated
17984         local nbcl=$(changelog_dump | wc -l)
17985         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17986
17987 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17988         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17989
17990         __changelog_clear mds1 $cl_user1 +10
17991         __changelog_clear mds1 $cl_user2 0 &
17992         pid1=$!
17993         sleep 2
17994         __changelog_clear mds1 $cl_user1 0 ||
17995                 error "fail to cancel record for $cl_user1"
17996         wait $pid1
17997         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17998 }
17999 run_test 160m "Changelog clear race"
18000
18001 test_160n() {
18002         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18003         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18004                 skip "Need MDS version at least 2.14.51"
18005         local cl_users
18006         local cl_user1
18007         local cl_user2
18008         local pid1
18009         local first_rec
18010         local last_rec=0
18011
18012         # Create a user
18013         changelog_register || error "first changelog_register failed"
18014
18015         cl_users=(${CL_USERS[mds1]})
18016         cl_user1="${cl_users[0]}"
18017
18018         # generate some changelog records to accumulate on MDT0
18019         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18020         first_rec=$(changelog_users $SINGLEMDS |
18021                         awk '/^current.index:/ { print $NF }')
18022         while (( last_rec < (( first_rec + 65000)) )); do
18023                 createmany -m $DIR/$tdir/$tfile 10000 ||
18024                         error "create $DIR/$tdir/$tfile failed"
18025
18026                 for i in $(seq 0 10000); do
18027                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18028                                 > /dev/null
18029                 done
18030
18031                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18032                         error "unlinkmany failed unlink"
18033                 last_rec=$(changelog_users $SINGLEMDS |
18034                         awk '/^current.index:/ { print $NF }')
18035                 echo last record $last_rec
18036                 (( last_rec == 0 )) && error "no changelog found"
18037         done
18038
18039 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18040         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18041
18042         __changelog_clear mds1 $cl_user1 0 &
18043         pid1=$!
18044         sleep 2
18045         __changelog_clear mds1 $cl_user1 0 ||
18046                 error "fail to cancel record for $cl_user1"
18047         wait $pid1
18048         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18049 }
18050 run_test 160n "Changelog destroy race"
18051
18052 test_160o() {
18053         local mdt="$(facet_svc $SINGLEMDS)"
18054
18055         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18056         remote_mds_nodsh && skip "remote MDS with nodsh"
18057         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18058                 skip "Need MDS version at least 2.14.52"
18059
18060         changelog_register --user test_160o -m unlnk+close+open ||
18061                 error "changelog_register failed"
18062
18063         do_facet $SINGLEMDS $LCTL --device $mdt \
18064                                 changelog_register -u "Tt3_-#" &&
18065                 error "bad symbols in name should fail"
18066
18067         do_facet $SINGLEMDS $LCTL --device $mdt \
18068                                 changelog_register -u test_160o &&
18069                 error "the same name registration should fail"
18070
18071         do_facet $SINGLEMDS $LCTL --device $mdt \
18072                         changelog_register -u test_160toolongname &&
18073                 error "too long name registration should fail"
18074
18075         changelog_chmask "MARK+HSM"
18076         lctl get_param mdd.*.changelog*mask
18077         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18078         changelog_users $SINGLEMDS | grep -q $cl_user ||
18079                 error "User $cl_user not found in changelog_users"
18080         #verify username
18081         echo $cl_user | grep -q test_160o ||
18082                 error "User $cl_user has no specific name 'test160o'"
18083
18084         # change something
18085         changelog_clear 0 || error "changelog_clear failed"
18086         # generate some changelog records to accumulate on MDT0
18087         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18088         touch $DIR/$tdir/$tfile                 # open 1
18089
18090         OPENS=$(changelog_dump | grep -c "OPEN")
18091         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18092
18093         # must be no MKDIR it wasn't set as user mask
18094         MKDIR=$(changelog_dump | grep -c "MKDIR")
18095         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18096
18097         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18098                                 mdd.$mdt.changelog_current_mask -n)
18099         # register maskless user
18100         changelog_register || error "changelog_register failed"
18101         # effective mask should be not changed because it is not minimal
18102         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18103                                 mdd.$mdt.changelog_current_mask -n)
18104         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18105         # set server mask to minimal value
18106         changelog_chmask "MARK"
18107         # check effective mask again, should be treated as DEFMASK now
18108         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18109                                 mdd.$mdt.changelog_current_mask -n)
18110         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18111
18112         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18113                 # set server mask back to some value
18114                 changelog_chmask "CLOSE,UNLNK"
18115                 # check effective mask again, should not remain as DEFMASK
18116                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18117                                 mdd.$mdt.changelog_current_mask -n)
18118                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18119         fi
18120
18121         do_facet $SINGLEMDS $LCTL --device $mdt \
18122                                 changelog_deregister -u test_160o ||
18123                 error "cannot deregister by name"
18124 }
18125 run_test 160o "changelog user name and mask"
18126
18127 test_160p() {
18128         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18129         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18130                 skip "Need MDS version at least 2.14.51"
18131         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18132         local cl_users
18133         local cl_user1
18134         local entry_count
18135
18136         # Create a user
18137         changelog_register || error "first changelog_register failed"
18138
18139         cl_users=(${CL_USERS[mds1]})
18140         cl_user1="${cl_users[0]}"
18141
18142         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18143         createmany -m $DIR/$tdir/$tfile 50 ||
18144                 error "create $DIR/$tdir/$tfile failed"
18145         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18146         rm -rf $DIR/$tdir
18147
18148         # check changelogs have been generated
18149         entry_count=$(changelog_dump | wc -l)
18150         ((entry_count != 0)) || error "no changelog entries found"
18151
18152         # remove changelog_users and check that orphan entries are removed
18153         stop mds1
18154         local dev=$(mdsdevname 1)
18155         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18156         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18157         entry_count=$(changelog_dump | wc -l)
18158         ((entry_count == 0)) ||
18159                 error "found $entry_count changelog entries, expected none"
18160 }
18161 run_test 160p "Changelog orphan cleanup with no users"
18162
18163 test_160q() {
18164         local mdt="$(facet_svc $SINGLEMDS)"
18165         local clu
18166
18167         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18168         remote_mds_nodsh && skip "remote MDS with nodsh"
18169         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18170                 skip "Need MDS version at least 2.14.54"
18171
18172         # set server mask to minimal value like server init does
18173         changelog_chmask "MARK"
18174         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18175                 error "changelog_register failed"
18176         # check effective mask again, should be treated as DEFMASK now
18177         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18178                                 mdd.$mdt.changelog_current_mask -n)
18179         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18180                 error "changelog_deregister failed"
18181         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18182 }
18183 run_test 160q "changelog effective mask is DEFMASK if not set"
18184
18185 test_160s() {
18186         remote_mds_nodsh && skip "remote MDS with nodsh"
18187         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18188                 skip "Need MDS version at least 2.14.55"
18189
18190         local mdts=$(comma_list $(mdts_nodes))
18191
18192         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18193         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18194                                        fail_val=$((24 * 3600 * 10))
18195
18196         # Create a user which is 10 days old
18197         changelog_register || error "first changelog_register failed"
18198         local cl_users
18199         declare -A cl_user1
18200         local i
18201
18202         # generate some changelog records to accumulate on each MDT
18203         # use all_char because created files should be evenly distributed
18204         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18205                 error "test_mkdir $tdir failed"
18206         for ((i = 0; i < MDSCOUNT; i++)); do
18207                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18208                         error "create $DIR/$tdir/d$i.1 failed"
18209         done
18210
18211         # check changelogs have been generated
18212         local nbcl=$(changelog_dump | wc -l)
18213         (( nbcl > 0 )) || error "no changelogs found"
18214
18215         # reduce the max_idle_indexes value to make sure we exceed it
18216         for param in "changelog_max_idle_indexes=2097446912" \
18217                      "changelog_max_idle_time=2592000" \
18218                      "changelog_gc=1" \
18219                      "changelog_min_gc_interval=2"; do
18220                 local MDT0=$(facet_svc $SINGLEMDS)
18221                 local var="${param%=*}"
18222                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18223
18224                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18225                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18226                         error "unable to set mdd.*.$param"
18227         done
18228
18229         local start=$SECONDS
18230         for i in $(seq $MDSCOUNT); do
18231                 cl_users=(${CL_USERS[mds$i]})
18232                 cl_user1[mds$i]="${cl_users[0]}"
18233
18234                 [[ -n "${cl_user1[mds$i]}" ]] ||
18235                         error "mds$i: no user registered"
18236         done
18237
18238         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18239         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18240
18241         # ensure we are past the previous changelog_min_gc_interval set above
18242         local sleep2=$((start + 2 - SECONDS))
18243         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18244
18245         # Generate one more changelog to trigger GC
18246         for ((i = 0; i < MDSCOUNT; i++)); do
18247                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18248                         error "create $DIR/$tdir/d$i.3 failed"
18249         done
18250
18251         # ensure gc thread is done
18252         for node in $(mdts_nodes); do
18253                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18254                         error "$node: GC-thread not done"
18255         done
18256
18257         do_nodes $mdts $LCTL set_param fail_loc=0
18258
18259         for (( i = 1; i <= MDSCOUNT; i++ )); do
18260                 # check cl_user1 is purged
18261                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18262                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18263         done
18264         return 0
18265 }
18266 run_test 160s "changelog garbage collect on idle records * time"
18267
18268 test_160t() {
18269         remote_mds_nodsh && skip "remote MDS with nodsh"
18270         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18271                 skip "Need MDS version at least 2.15.50"
18272
18273         local MDT0=$(facet_svc $SINGLEMDS)
18274         local cl_users
18275         local cl_user1
18276         local cl_user2
18277         local start
18278
18279         changelog_register --user user1 -m all ||
18280                 error "user1 failed to register"
18281
18282         mkdir_on_mdt0 $DIR/$tdir
18283         # create default overstripe to maximize changelog size
18284         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18285         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18286         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18287
18288         # user2 consumes less records so less space
18289         changelog_register --user user2 || error "user2 failed to register"
18290         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18291         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18292
18293         # check changelogs have been generated
18294         local nbcl=$(changelog_dump | wc -l)
18295         (( nbcl > 0 )) || error "no changelogs found"
18296
18297         # reduce the changelog_min_gc_interval to force check
18298         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18299                 local var="${param%=*}"
18300                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18301
18302                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18303                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18304                         error "unable to set mdd.*.$param"
18305         done
18306
18307         start=$SECONDS
18308         cl_users=(${CL_USERS[mds1]})
18309         cl_user1="${cl_users[0]}"
18310         cl_user2="${cl_users[1]}"
18311
18312         [[ -n $cl_user1 ]] ||
18313                 error "mds1: user #1 isn't registered"
18314         [[ -n $cl_user2 ]] ||
18315                 error "mds1: user #2 isn't registered"
18316
18317         # ensure we are past the previous changelog_min_gc_interval set above
18318         local sleep2=$((start + 2 - SECONDS))
18319         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18320
18321         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18322         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18323                         fail_val=$(((llog_size1 + llog_size2) / 2))
18324
18325         # Generate more changelog to trigger GC
18326         createmany -o $DIR/$tdir/u3_ 4 ||
18327                 error "create failed for more files"
18328
18329         # ensure gc thread is done
18330         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18331                 error "mds1: GC-thread not done"
18332
18333         do_facet mds1 $LCTL set_param fail_loc=0
18334
18335         # check cl_user1 is purged
18336         changelog_users mds1 | grep -q "$cl_user1" &&
18337                 error "User $cl_user1 is registered"
18338         # check cl_user2 is not purged
18339         changelog_users mds1 | grep -q "$cl_user2" ||
18340                 error "User $cl_user2 is not registered"
18341 }
18342 run_test 160t "changelog garbage collect on lack of space"
18343
18344 test_161a() {
18345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18346
18347         test_mkdir -c1 $DIR/$tdir
18348         cp /etc/hosts $DIR/$tdir/$tfile
18349         test_mkdir -c1 $DIR/$tdir/foo1
18350         test_mkdir -c1 $DIR/$tdir/foo2
18351         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18352         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18353         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18354         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18355         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18356         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18357                 $LFS fid2path $DIR $FID
18358                 error "bad link ea"
18359         fi
18360         # middle
18361         rm $DIR/$tdir/foo2/zachary
18362         # last
18363         rm $DIR/$tdir/foo2/thor
18364         # first
18365         rm $DIR/$tdir/$tfile
18366         # rename
18367         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18368         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18369                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18370         rm $DIR/$tdir/foo2/maggie
18371
18372         # overflow the EA
18373         local longname=$tfile.avg_len_is_thirty_two_
18374         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18375                 error_noexit 'failed to unlink many hardlinks'" EXIT
18376         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18377                 error "failed to hardlink many files"
18378         links=$($LFS fid2path $DIR $FID | wc -l)
18379         echo -n "${links}/1000 links in link EA"
18380         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18381 }
18382 run_test 161a "link ea sanity"
18383
18384 test_161b() {
18385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18386         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18387
18388         local MDTIDX=1
18389         local remote_dir=$DIR/$tdir/remote_dir
18390
18391         mkdir -p $DIR/$tdir
18392         $LFS mkdir -i $MDTIDX $remote_dir ||
18393                 error "create remote directory failed"
18394
18395         cp /etc/hosts $remote_dir/$tfile
18396         mkdir -p $remote_dir/foo1
18397         mkdir -p $remote_dir/foo2
18398         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18399         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18400         ln $remote_dir/$tfile $remote_dir/foo1/luna
18401         ln $remote_dir/$tfile $remote_dir/foo2/thor
18402
18403         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18404                      tr -d ']')
18405         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18406                 $LFS fid2path $DIR $FID
18407                 error "bad link ea"
18408         fi
18409         # middle
18410         rm $remote_dir/foo2/zachary
18411         # last
18412         rm $remote_dir/foo2/thor
18413         # first
18414         rm $remote_dir/$tfile
18415         # rename
18416         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18417         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18418         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18419                 $LFS fid2path $DIR $FID
18420                 error "bad link rename"
18421         fi
18422         rm $remote_dir/foo2/maggie
18423
18424         # overflow the EA
18425         local longname=filename_avg_len_is_thirty_two_
18426         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18427                 error "failed to hardlink many files"
18428         links=$($LFS fid2path $DIR $FID | wc -l)
18429         echo -n "${links}/1000 links in link EA"
18430         [[ ${links} -gt 60 ]] ||
18431                 error "expected at least 60 links in link EA"
18432         unlinkmany $remote_dir/foo2/$longname 1000 ||
18433         error "failed to unlink many hardlinks"
18434 }
18435 run_test 161b "link ea sanity under remote directory"
18436
18437 test_161c() {
18438         remote_mds_nodsh && skip "remote MDS with nodsh"
18439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18440         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18441                 skip "Need MDS version at least 2.1.5"
18442
18443         # define CLF_RENAME_LAST 0x0001
18444         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18445         changelog_register || error "changelog_register failed"
18446
18447         rm -rf $DIR/$tdir
18448         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18449         touch $DIR/$tdir/foo_161c
18450         touch $DIR/$tdir/bar_161c
18451         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18452         changelog_dump | grep RENME | tail -n 5
18453         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18454         changelog_clear 0 || error "changelog_clear failed"
18455         if [ x$flags != "x0x1" ]; then
18456                 error "flag $flags is not 0x1"
18457         fi
18458
18459         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18460         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18461         touch $DIR/$tdir/foo_161c
18462         touch $DIR/$tdir/bar_161c
18463         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18464         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18465         changelog_dump | grep RENME | tail -n 5
18466         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18467         changelog_clear 0 || error "changelog_clear failed"
18468         if [ x$flags != "x0x0" ]; then
18469                 error "flag $flags is not 0x0"
18470         fi
18471         echo "rename overwrite a target having nlink > 1," \
18472                 "changelog record has flags of $flags"
18473
18474         # rename doesn't overwrite a target (changelog flag 0x0)
18475         touch $DIR/$tdir/foo_161c
18476         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18477         changelog_dump | grep RENME | tail -n 5
18478         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18479         changelog_clear 0 || error "changelog_clear failed"
18480         if [ x$flags != "x0x0" ]; then
18481                 error "flag $flags is not 0x0"
18482         fi
18483         echo "rename doesn't overwrite a target," \
18484                 "changelog record has flags of $flags"
18485
18486         # define CLF_UNLINK_LAST 0x0001
18487         # unlink a file having nlink = 1 (changelog flag 0x1)
18488         rm -f $DIR/$tdir/foo2_161c
18489         changelog_dump | grep UNLNK | tail -n 5
18490         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18491         changelog_clear 0 || error "changelog_clear failed"
18492         if [ x$flags != "x0x1" ]; then
18493                 error "flag $flags is not 0x1"
18494         fi
18495         echo "unlink a file having nlink = 1," \
18496                 "changelog record has flags of $flags"
18497
18498         # unlink a file having nlink > 1 (changelog flag 0x0)
18499         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18500         rm -f $DIR/$tdir/foobar_161c
18501         changelog_dump | grep UNLNK | tail -n 5
18502         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18503         changelog_clear 0 || error "changelog_clear failed"
18504         if [ x$flags != "x0x0" ]; then
18505                 error "flag $flags is not 0x0"
18506         fi
18507         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18508 }
18509 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18510
18511 test_161d() {
18512         remote_mds_nodsh && skip "remote MDS with nodsh"
18513         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18514
18515         local pid
18516         local fid
18517
18518         changelog_register || error "changelog_register failed"
18519
18520         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18521         # interfer with $MOUNT/.lustre/fid/ access
18522         mkdir $DIR/$tdir
18523         [[ $? -eq 0 ]] || error "mkdir failed"
18524
18525         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18526         $LCTL set_param fail_loc=0x8000140c
18527         # 5s pause
18528         $LCTL set_param fail_val=5
18529
18530         # create file
18531         echo foofoo > $DIR/$tdir/$tfile &
18532         pid=$!
18533
18534         # wait for create to be delayed
18535         sleep 2
18536
18537         ps -p $pid
18538         [[ $? -eq 0 ]] || error "create should be blocked"
18539
18540         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18541         stack_trap "rm -f $tempfile"
18542         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18543         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18544         # some delay may occur during ChangeLog publishing and file read just
18545         # above, that could allow file write to happen finally
18546         [[ -s $tempfile ]] && echo "file should be empty"
18547
18548         $LCTL set_param fail_loc=0
18549
18550         wait $pid
18551         [[ $? -eq 0 ]] || error "create failed"
18552 }
18553 run_test 161d "create with concurrent .lustre/fid access"
18554
18555 check_path() {
18556         local expected="$1"
18557         shift
18558         local fid="$2"
18559
18560         local path
18561         path=$($LFS fid2path "$@")
18562         local rc=$?
18563
18564         if [ $rc -ne 0 ]; then
18565                 error "path looked up of '$expected' failed: rc=$rc"
18566         elif [ "$path" != "$expected" ]; then
18567                 error "path looked up '$path' instead of '$expected'"
18568         else
18569                 echo "FID '$fid' resolves to path '$path' as expected"
18570         fi
18571 }
18572
18573 test_162a() { # was test_162
18574         test_mkdir -p -c1 $DIR/$tdir/d2
18575         touch $DIR/$tdir/d2/$tfile
18576         touch $DIR/$tdir/d2/x1
18577         touch $DIR/$tdir/d2/x2
18578         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18579         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18580         # regular file
18581         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18582         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18583
18584         # softlink
18585         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18586         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18587         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18588
18589         # softlink to wrong file
18590         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18591         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18592         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18593
18594         # hardlink
18595         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18596         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18597         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18598         # fid2path dir/fsname should both work
18599         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18600         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18601
18602         # hardlink count: check that there are 2 links
18603         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18604         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18605
18606         # hardlink indexing: remove the first link
18607         rm $DIR/$tdir/d2/p/q/r/hlink
18608         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18609 }
18610 run_test 162a "path lookup sanity"
18611
18612 test_162b() {
18613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18614         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18615
18616         mkdir $DIR/$tdir
18617         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18618                                 error "create striped dir failed"
18619
18620         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18621                                         tail -n 1 | awk '{print $2}')
18622         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18623
18624         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18625         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18626
18627         # regular file
18628         for ((i=0;i<5;i++)); do
18629                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18630                         error "get fid for f$i failed"
18631                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18632
18633                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18634                         error "get fid for d$i failed"
18635                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18636         done
18637
18638         return 0
18639 }
18640 run_test 162b "striped directory path lookup sanity"
18641
18642 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18643 test_162c() {
18644         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18645                 skip "Need MDS version at least 2.7.51"
18646
18647         local lpath=$tdir.local
18648         local rpath=$tdir.remote
18649
18650         test_mkdir $DIR/$lpath
18651         test_mkdir $DIR/$rpath
18652
18653         for ((i = 0; i <= 101; i++)); do
18654                 lpath="$lpath/$i"
18655                 mkdir $DIR/$lpath
18656                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18657                         error "get fid for local directory $DIR/$lpath failed"
18658                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18659
18660                 rpath="$rpath/$i"
18661                 test_mkdir $DIR/$rpath
18662                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18663                         error "get fid for remote directory $DIR/$rpath failed"
18664                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18665         done
18666
18667         return 0
18668 }
18669 run_test 162c "fid2path works with paths 100 or more directories deep"
18670
18671 oalr_event_count() {
18672         local event="${1}"
18673         local trace="${2}"
18674
18675         awk -v name="${FSNAME}-OST0000" \
18676             -v event="${event}" \
18677             '$1 == "TRACE" && $2 == event && $3 == name' \
18678             "${trace}" |
18679         wc -l
18680 }
18681
18682 oalr_expect_event_count() {
18683         local event="${1}"
18684         local trace="${2}"
18685         local expect="${3}"
18686         local count
18687
18688         count=$(oalr_event_count "${event}" "${trace}")
18689         if ((count == expect)); then
18690                 return 0
18691         fi
18692
18693         error_noexit "${event} event count was '${count}', expected ${expect}"
18694         cat "${trace}" >&2
18695         exit 1
18696 }
18697
18698 cleanup_165() {
18699         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18700         stop ost1
18701         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18702 }
18703
18704 setup_165() {
18705         sync # Flush previous IOs so we can count log entries.
18706         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18707         stack_trap cleanup_165 EXIT
18708 }
18709
18710 test_165a() {
18711         local trace="/tmp/${tfile}.trace"
18712         local rc
18713         local count
18714
18715         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18716                 skip "OFD access log unsupported"
18717
18718         setup_165
18719         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18720         sleep 5
18721
18722         do_facet ost1 ofd_access_log_reader --list
18723         stop ost1
18724
18725         do_facet ost1 killall -TERM ofd_access_log_reader
18726         wait
18727         rc=$?
18728
18729         if ((rc != 0)); then
18730                 error "ofd_access_log_reader exited with rc = '${rc}'"
18731         fi
18732
18733         # Parse trace file for discovery events:
18734         oalr_expect_event_count alr_log_add "${trace}" 1
18735         oalr_expect_event_count alr_log_eof "${trace}" 1
18736         oalr_expect_event_count alr_log_free "${trace}" 1
18737 }
18738 run_test 165a "ofd access log discovery"
18739
18740 test_165b() {
18741         local trace="/tmp/${tfile}.trace"
18742         local file="${DIR}/${tfile}"
18743         local pfid1
18744         local pfid2
18745         local -a entry
18746         local rc
18747         local count
18748         local size
18749         local flags
18750
18751         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18752                 skip "OFD access log unsupported"
18753
18754         setup_165
18755         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18756         sleep 5
18757
18758         do_facet ost1 ofd_access_log_reader --list
18759
18760         lfs setstripe -c 1 -i 0 "${file}"
18761         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18762                 error "cannot create '${file}'"
18763
18764         sleep 5
18765         do_facet ost1 killall -TERM ofd_access_log_reader
18766         wait
18767         rc=$?
18768
18769         if ((rc != 0)); then
18770                 error "ofd_access_log_reader exited with rc = '${rc}'"
18771         fi
18772
18773         oalr_expect_event_count alr_log_entry "${trace}" 1
18774
18775         pfid1=$($LFS path2fid "${file}")
18776
18777         # 1     2             3   4    5     6   7    8    9     10
18778         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18779         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18780
18781         echo "entry = '${entry[*]}'" >&2
18782
18783         pfid2=${entry[4]}
18784         if [[ "${pfid1}" != "${pfid2}" ]]; then
18785                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18786         fi
18787
18788         size=${entry[8]}
18789         if ((size != 1048576)); then
18790                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18791         fi
18792
18793         flags=${entry[10]}
18794         if [[ "${flags}" != "w" ]]; then
18795                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18796         fi
18797
18798         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18799         sleep 5
18800
18801         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18802                 error "cannot read '${file}'"
18803         sleep 5
18804
18805         do_facet ost1 killall -TERM ofd_access_log_reader
18806         wait
18807         rc=$?
18808
18809         if ((rc != 0)); then
18810                 error "ofd_access_log_reader exited with rc = '${rc}'"
18811         fi
18812
18813         oalr_expect_event_count alr_log_entry "${trace}" 1
18814
18815         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18816         echo "entry = '${entry[*]}'" >&2
18817
18818         pfid2=${entry[4]}
18819         if [[ "${pfid1}" != "${pfid2}" ]]; then
18820                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18821         fi
18822
18823         size=${entry[8]}
18824         if ((size != 524288)); then
18825                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18826         fi
18827
18828         flags=${entry[10]}
18829         if [[ "${flags}" != "r" ]]; then
18830                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18831         fi
18832 }
18833 run_test 165b "ofd access log entries are produced and consumed"
18834
18835 test_165c() {
18836         local trace="/tmp/${tfile}.trace"
18837         local file="${DIR}/${tdir}/${tfile}"
18838
18839         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18840                 skip "OFD access log unsupported"
18841
18842         test_mkdir "${DIR}/${tdir}"
18843
18844         setup_165
18845         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18846         sleep 5
18847
18848         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18849
18850         # 4096 / 64 = 64. Create twice as many entries.
18851         for ((i = 0; i < 128; i++)); do
18852                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18853                         error "cannot create file"
18854         done
18855
18856         sync
18857
18858         do_facet ost1 killall -TERM ofd_access_log_reader
18859         wait
18860         rc=$?
18861         if ((rc != 0)); then
18862                 error "ofd_access_log_reader exited with rc = '${rc}'"
18863         fi
18864
18865         unlinkmany  "${file}-%d" 128
18866 }
18867 run_test 165c "full ofd access logs do not block IOs"
18868
18869 oal_get_read_count() {
18870         local stats="$1"
18871
18872         # STATS lustre-OST0001 alr_read_count 1
18873
18874         do_facet ost1 cat "${stats}" |
18875         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18876              END { print count; }'
18877 }
18878
18879 oal_expect_read_count() {
18880         local stats="$1"
18881         local count
18882         local expect="$2"
18883
18884         # Ask ofd_access_log_reader to write stats.
18885         do_facet ost1 killall -USR1 ofd_access_log_reader
18886
18887         # Allow some time for things to happen.
18888         sleep 1
18889
18890         count=$(oal_get_read_count "${stats}")
18891         if ((count == expect)); then
18892                 return 0
18893         fi
18894
18895         error_noexit "bad read count, got ${count}, expected ${expect}"
18896         do_facet ost1 cat "${stats}" >&2
18897         exit 1
18898 }
18899
18900 test_165d() {
18901         local stats="/tmp/${tfile}.stats"
18902         local file="${DIR}/${tdir}/${tfile}"
18903         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18904
18905         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18906                 skip "OFD access log unsupported"
18907
18908         test_mkdir "${DIR}/${tdir}"
18909
18910         setup_165
18911         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18912         sleep 5
18913
18914         lfs setstripe -c 1 -i 0 "${file}"
18915
18916         do_facet ost1 lctl set_param "${param}=rw"
18917         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18918                 error "cannot create '${file}'"
18919         oal_expect_read_count "${stats}" 1
18920
18921         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18922                 error "cannot read '${file}'"
18923         oal_expect_read_count "${stats}" 2
18924
18925         do_facet ost1 lctl set_param "${param}=r"
18926         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18927                 error "cannot create '${file}'"
18928         oal_expect_read_count "${stats}" 2
18929
18930         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18931                 error "cannot read '${file}'"
18932         oal_expect_read_count "${stats}" 3
18933
18934         do_facet ost1 lctl set_param "${param}=w"
18935         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18936                 error "cannot create '${file}'"
18937         oal_expect_read_count "${stats}" 4
18938
18939         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18940                 error "cannot read '${file}'"
18941         oal_expect_read_count "${stats}" 4
18942
18943         do_facet ost1 lctl set_param "${param}=0"
18944         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18945                 error "cannot create '${file}'"
18946         oal_expect_read_count "${stats}" 4
18947
18948         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18949                 error "cannot read '${file}'"
18950         oal_expect_read_count "${stats}" 4
18951
18952         do_facet ost1 killall -TERM ofd_access_log_reader
18953         wait
18954         rc=$?
18955         if ((rc != 0)); then
18956                 error "ofd_access_log_reader exited with rc = '${rc}'"
18957         fi
18958 }
18959 run_test 165d "ofd_access_log mask works"
18960
18961 test_165e() {
18962         local stats="/tmp/${tfile}.stats"
18963         local file0="${DIR}/${tdir}-0/${tfile}"
18964         local file1="${DIR}/${tdir}-1/${tfile}"
18965
18966         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18967                 skip "OFD access log unsupported"
18968
18969         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18970
18971         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18972         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18973
18974         lfs setstripe -c 1 -i 0 "${file0}"
18975         lfs setstripe -c 1 -i 0 "${file1}"
18976
18977         setup_165
18978         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18979         sleep 5
18980
18981         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18982                 error "cannot create '${file0}'"
18983         sync
18984         oal_expect_read_count "${stats}" 0
18985
18986         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18987                 error "cannot create '${file1}'"
18988         sync
18989         oal_expect_read_count "${stats}" 1
18990
18991         do_facet ost1 killall -TERM ofd_access_log_reader
18992         wait
18993         rc=$?
18994         if ((rc != 0)); then
18995                 error "ofd_access_log_reader exited with rc = '${rc}'"
18996         fi
18997 }
18998 run_test 165e "ofd_access_log MDT index filter works"
18999
19000 test_165f() {
19001         local trace="/tmp/${tfile}.trace"
19002         local rc
19003         local count
19004
19005         setup_165
19006         do_facet ost1 timeout 60 ofd_access_log_reader \
19007                 --exit-on-close --debug=- --trace=- > "${trace}" &
19008         sleep 5
19009         stop ost1
19010
19011         wait
19012         rc=$?
19013
19014         if ((rc != 0)); then
19015                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19016                 cat "${trace}"
19017                 exit 1
19018         fi
19019 }
19020 run_test 165f "ofd_access_log_reader --exit-on-close works"
19021
19022 test_169() {
19023         # do directio so as not to populate the page cache
19024         log "creating a 10 Mb file"
19025         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19026                 error "multiop failed while creating a file"
19027         log "starting reads"
19028         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19029         log "truncating the file"
19030         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19031                 error "multiop failed while truncating the file"
19032         log "killing dd"
19033         kill %+ || true # reads might have finished
19034         echo "wait until dd is finished"
19035         wait
19036         log "removing the temporary file"
19037         rm -rf $DIR/$tfile || error "tmp file removal failed"
19038 }
19039 run_test 169 "parallel read and truncate should not deadlock"
19040
19041 test_170() {
19042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19043
19044         $LCTL clear     # bug 18514
19045         $LCTL debug_daemon start $TMP/${tfile}_log_good
19046         touch $DIR/$tfile
19047         $LCTL debug_daemon stop
19048         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19049                 error "sed failed to read log_good"
19050
19051         $LCTL debug_daemon start $TMP/${tfile}_log_good
19052         rm -rf $DIR/$tfile
19053         $LCTL debug_daemon stop
19054
19055         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19056                error "lctl df log_bad failed"
19057
19058         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19059         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19060
19061         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19062         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19063
19064         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19065                 error "bad_line good_line1 good_line2 are empty"
19066
19067         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19068         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19069         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19070
19071         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19072         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19073         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19074
19075         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19076                 error "bad_line_new good_line_new are empty"
19077
19078         local expected_good=$((good_line1 + good_line2*2))
19079
19080         rm -f $TMP/${tfile}*
19081         # LU-231, short malformed line may not be counted into bad lines
19082         if [ $bad_line -ne $bad_line_new ] &&
19083                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19084                 error "expected $bad_line bad lines, but got $bad_line_new"
19085                 return 1
19086         fi
19087
19088         if [ $expected_good -ne $good_line_new ]; then
19089                 error "expected $expected_good good lines, but got $good_line_new"
19090                 return 2
19091         fi
19092         true
19093 }
19094 run_test 170 "test lctl df to handle corrupted log ====================="
19095
19096 test_171() { # bug20592
19097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19098
19099         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19100         $LCTL set_param fail_loc=0x50e
19101         $LCTL set_param fail_val=3000
19102         multiop_bg_pause $DIR/$tfile O_s || true
19103         local MULTIPID=$!
19104         kill -USR1 $MULTIPID
19105         # cause log dump
19106         sleep 3
19107         wait $MULTIPID
19108         if dmesg | grep "recursive fault"; then
19109                 error "caught a recursive fault"
19110         fi
19111         $LCTL set_param fail_loc=0
19112         true
19113 }
19114 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19115
19116 test_172() {
19117
19118         #define OBD_FAIL_OBD_CLEANUP  0x60e
19119         $LCTL set_param fail_loc=0x60e
19120         umount $MOUNT || error "umount $MOUNT failed"
19121         stack_trap "mount_client $MOUNT"
19122
19123         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19124                 error "no client OBDs are remained"
19125
19126         $LCTL dl | while read devno state type name foo; do
19127                 case $type in
19128                 lov|osc|lmv|mdc)
19129                         $LCTL --device $name cleanup
19130                         $LCTL --device $name detach
19131                         ;;
19132                 *)
19133                         # skip server devices
19134                         ;;
19135                 esac
19136         done
19137
19138         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19139                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19140                 error "some client OBDs are still remained"
19141         fi
19142
19143 }
19144 run_test 172 "manual device removal with lctl cleanup/detach ======"
19145
19146 # it would be good to share it with obdfilter-survey/iokit-libecho code
19147 setup_obdecho_osc () {
19148         local rc=0
19149         local ost_nid=$1
19150         local obdfilter_name=$2
19151         echo "Creating new osc for $obdfilter_name on $ost_nid"
19152         # make sure we can find loopback nid
19153         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19154
19155         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19156                            ${obdfilter_name}_osc_UUID || rc=2; }
19157         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19158                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19159         return $rc
19160 }
19161
19162 cleanup_obdecho_osc () {
19163         local obdfilter_name=$1
19164         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19165         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19166         return 0
19167 }
19168
19169 obdecho_test() {
19170         local OBD=$1
19171         local node=$2
19172         local pages=${3:-64}
19173         local rc=0
19174         local id
19175
19176         local count=10
19177         local obd_size=$(get_obd_size $node $OBD)
19178         local page_size=$(get_page_size $node)
19179         if [[ -n "$obd_size" ]]; then
19180                 local new_count=$((obd_size / (pages * page_size / 1024)))
19181                 [[ $new_count -ge $count ]] || count=$new_count
19182         fi
19183
19184         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19185         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19186                            rc=2; }
19187         if [ $rc -eq 0 ]; then
19188             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19189             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19190         fi
19191         echo "New object id is $id"
19192         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19193                            rc=4; }
19194         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19195                            "test_brw $count w v $pages $id" || rc=4; }
19196         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19197                            rc=4; }
19198         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19199                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19200         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19201                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19202         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19203         return $rc
19204 }
19205
19206 test_180a() {
19207         skip "obdecho on osc is no longer supported"
19208 }
19209 run_test 180a "test obdecho on osc"
19210
19211 test_180b() {
19212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19213         remote_ost_nodsh && skip "remote OST with nodsh"
19214
19215         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19216                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19217                 error "failed to load module obdecho"
19218
19219         local target=$(do_facet ost1 $LCTL dl |
19220                        awk '/obdfilter/ { print $4; exit; }')
19221
19222         if [ -n "$target" ]; then
19223                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19224         else
19225                 do_facet ost1 $LCTL dl
19226                 error "there is no obdfilter target on ost1"
19227         fi
19228 }
19229 run_test 180b "test obdecho directly on obdfilter"
19230
19231 test_180c() { # LU-2598
19232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19233         remote_ost_nodsh && skip "remote OST with nodsh"
19234         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19235                 skip "Need MDS version at least 2.4.0"
19236
19237         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19238                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19239                 error "failed to load module obdecho"
19240
19241         local target=$(do_facet ost1 $LCTL dl |
19242                        awk '/obdfilter/ { print $4; exit; }')
19243
19244         if [ -n "$target" ]; then
19245                 local pages=16384 # 64MB bulk I/O RPC size
19246
19247                 obdecho_test "$target" ost1 "$pages" ||
19248                         error "obdecho_test with pages=$pages failed with $?"
19249         else
19250                 do_facet ost1 $LCTL dl
19251                 error "there is no obdfilter target on ost1"
19252         fi
19253 }
19254 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19255
19256 test_181() { # bug 22177
19257         test_mkdir $DIR/$tdir
19258         # create enough files to index the directory
19259         createmany -o $DIR/$tdir/foobar 4000
19260         # print attributes for debug purpose
19261         lsattr -d .
19262         # open dir
19263         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19264         MULTIPID=$!
19265         # remove the files & current working dir
19266         unlinkmany $DIR/$tdir/foobar 4000
19267         rmdir $DIR/$tdir
19268         kill -USR1 $MULTIPID
19269         wait $MULTIPID
19270         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19271         return 0
19272 }
19273 run_test 181 "Test open-unlinked dir ========================"
19274
19275 test_182a() {
19276         local fcount=1000
19277         local tcount=10
19278
19279         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19280
19281         $LCTL set_param mdc.*.rpc_stats=clear
19282
19283         for (( i = 0; i < $tcount; i++ )) ; do
19284                 mkdir $DIR/$tdir/$i
19285         done
19286
19287         for (( i = 0; i < $tcount; i++ )) ; do
19288                 createmany -o $DIR/$tdir/$i/f- $fcount &
19289         done
19290         wait
19291
19292         for (( i = 0; i < $tcount; i++ )) ; do
19293                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19294         done
19295         wait
19296
19297         $LCTL get_param mdc.*.rpc_stats
19298
19299         rm -rf $DIR/$tdir
19300 }
19301 run_test 182a "Test parallel modify metadata operations from mdc"
19302
19303 test_182b() {
19304         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19305         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19306         local dcount=1000
19307         local tcount=10
19308         local stime
19309         local etime
19310         local delta
19311
19312         do_facet mds1 $LCTL list_param \
19313                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19314                 skip "MDS lacks parallel RPC handling"
19315
19316         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19317
19318         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19319                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19320
19321         stime=$(date +%s)
19322         createmany -i 0 -d $DIR/$tdir/t- $tcount
19323
19324         for (( i = 0; i < $tcount; i++ )) ; do
19325                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19326         done
19327         wait
19328         etime=$(date +%s)
19329         delta=$((etime - stime))
19330         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19331
19332         stime=$(date +%s)
19333         for (( i = 0; i < $tcount; i++ )) ; do
19334                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19335         done
19336         wait
19337         etime=$(date +%s)
19338         delta=$((etime - stime))
19339         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19340
19341         rm -rf $DIR/$tdir
19342
19343         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19344
19345         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19346
19347         stime=$(date +%s)
19348         createmany -i 0 -d $DIR/$tdir/t- $tcount
19349
19350         for (( i = 0; i < $tcount; i++ )) ; do
19351                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19352         done
19353         wait
19354         etime=$(date +%s)
19355         delta=$((etime - stime))
19356         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19357
19358         stime=$(date +%s)
19359         for (( i = 0; i < $tcount; i++ )) ; do
19360                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19361         done
19362         wait
19363         etime=$(date +%s)
19364         delta=$((etime - stime))
19365         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19366
19367         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19368 }
19369 run_test 182b "Test parallel modify metadata operations from osp"
19370
19371 test_183() { # LU-2275
19372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19373         remote_mds_nodsh && skip "remote MDS with nodsh"
19374         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19375                 skip "Need MDS version at least 2.3.56"
19376
19377         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19378         echo aaa > $DIR/$tdir/$tfile
19379
19380 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19381         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19382
19383         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19384         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19385
19386         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19387
19388         # Flush negative dentry cache
19389         touch $DIR/$tdir/$tfile
19390
19391         # We are not checking for any leaked references here, they'll
19392         # become evident next time we do cleanup with module unload.
19393         rm -rf $DIR/$tdir
19394 }
19395 run_test 183 "No crash or request leak in case of strange dispositions ========"
19396
19397 # test suite 184 is for LU-2016, LU-2017
19398 test_184a() {
19399         check_swap_layouts_support
19400
19401         dir0=$DIR/$tdir/$testnum
19402         test_mkdir -p -c1 $dir0
19403         ref1=/etc/passwd
19404         ref2=/etc/group
19405         file1=$dir0/f1
19406         file2=$dir0/f2
19407         $LFS setstripe -c1 $file1
19408         cp $ref1 $file1
19409         $LFS setstripe -c2 $file2
19410         cp $ref2 $file2
19411         gen1=$($LFS getstripe -g $file1)
19412         gen2=$($LFS getstripe -g $file2)
19413
19414         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19415         gen=$($LFS getstripe -g $file1)
19416         [[ $gen1 != $gen ]] ||
19417                 error "Layout generation on $file1 does not change"
19418         gen=$($LFS getstripe -g $file2)
19419         [[ $gen2 != $gen ]] ||
19420                 error "Layout generation on $file2 does not change"
19421
19422         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19423         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19424
19425         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19426 }
19427 run_test 184a "Basic layout swap"
19428
19429 test_184b() {
19430         check_swap_layouts_support
19431
19432         dir0=$DIR/$tdir/$testnum
19433         mkdir -p $dir0 || error "creating dir $dir0"
19434         file1=$dir0/f1
19435         file2=$dir0/f2
19436         file3=$dir0/f3
19437         dir1=$dir0/d1
19438         dir2=$dir0/d2
19439         mkdir $dir1 $dir2
19440         $LFS setstripe -c1 $file1
19441         $LFS setstripe -c2 $file2
19442         $LFS setstripe -c1 $file3
19443         chown $RUNAS_ID $file3
19444         gen1=$($LFS getstripe -g $file1)
19445         gen2=$($LFS getstripe -g $file2)
19446
19447         $LFS swap_layouts $dir1 $dir2 &&
19448                 error "swap of directories layouts should fail"
19449         $LFS swap_layouts $dir1 $file1 &&
19450                 error "swap of directory and file layouts should fail"
19451         $RUNAS $LFS swap_layouts $file1 $file2 &&
19452                 error "swap of file we cannot write should fail"
19453         $LFS swap_layouts $file1 $file3 &&
19454                 error "swap of file with different owner should fail"
19455         /bin/true # to clear error code
19456 }
19457 run_test 184b "Forbidden layout swap (will generate errors)"
19458
19459 test_184c() {
19460         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19461         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19462         check_swap_layouts_support
19463         check_swap_layout_no_dom $DIR
19464
19465         local dir0=$DIR/$tdir/$testnum
19466         mkdir -p $dir0 || error "creating dir $dir0"
19467
19468         local ref1=$dir0/ref1
19469         local ref2=$dir0/ref2
19470         local file1=$dir0/file1
19471         local file2=$dir0/file2
19472         # create a file large enough for the concurrent test
19473         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19474         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19475         echo "ref file size: ref1($(stat -c %s $ref1))," \
19476              "ref2($(stat -c %s $ref2))"
19477
19478         cp $ref2 $file2
19479         dd if=$ref1 of=$file1 bs=16k &
19480         local DD_PID=$!
19481
19482         # Make sure dd starts to copy file, but wait at most 5 seconds
19483         local loops=0
19484         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19485
19486         $LFS swap_layouts $file1 $file2
19487         local rc=$?
19488         wait $DD_PID
19489         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19490         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19491
19492         # how many bytes copied before swapping layout
19493         local copied=$(stat -c %s $file2)
19494         local remaining=$(stat -c %s $ref1)
19495         remaining=$((remaining - copied))
19496         echo "Copied $copied bytes before swapping layout..."
19497
19498         cmp -n $copied $file1 $ref2 | grep differ &&
19499                 error "Content mismatch [0, $copied) of ref2 and file1"
19500         cmp -n $copied $file2 $ref1 ||
19501                 error "Content mismatch [0, $copied) of ref1 and file2"
19502         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19503                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19504
19505         # clean up
19506         rm -f $ref1 $ref2 $file1 $file2
19507 }
19508 run_test 184c "Concurrent write and layout swap"
19509
19510 test_184d() {
19511         check_swap_layouts_support
19512         check_swap_layout_no_dom $DIR
19513         [ -z "$(which getfattr 2>/dev/null)" ] &&
19514                 skip_env "no getfattr command"
19515
19516         local file1=$DIR/$tdir/$tfile-1
19517         local file2=$DIR/$tdir/$tfile-2
19518         local file3=$DIR/$tdir/$tfile-3
19519         local lovea1
19520         local lovea2
19521
19522         mkdir -p $DIR/$tdir
19523         touch $file1 || error "create $file1 failed"
19524         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19525                 error "create $file2 failed"
19526         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19527                 error "create $file3 failed"
19528         lovea1=$(get_layout_param $file1)
19529
19530         $LFS swap_layouts $file2 $file3 ||
19531                 error "swap $file2 $file3 layouts failed"
19532         $LFS swap_layouts $file1 $file2 ||
19533                 error "swap $file1 $file2 layouts failed"
19534
19535         lovea2=$(get_layout_param $file2)
19536         echo "$lovea1"
19537         echo "$lovea2"
19538         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19539
19540         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19541         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19542 }
19543 run_test 184d "allow stripeless layouts swap"
19544
19545 test_184e() {
19546         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19547                 skip "Need MDS version at least 2.6.94"
19548         check_swap_layouts_support
19549         check_swap_layout_no_dom $DIR
19550         [ -z "$(which getfattr 2>/dev/null)" ] &&
19551                 skip_env "no getfattr command"
19552
19553         local file1=$DIR/$tdir/$tfile-1
19554         local file2=$DIR/$tdir/$tfile-2
19555         local file3=$DIR/$tdir/$tfile-3
19556         local lovea
19557
19558         mkdir -p $DIR/$tdir
19559         touch $file1 || error "create $file1 failed"
19560         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19561                 error "create $file2 failed"
19562         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19563                 error "create $file3 failed"
19564
19565         $LFS swap_layouts $file1 $file2 ||
19566                 error "swap $file1 $file2 layouts failed"
19567
19568         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19569         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19570
19571         echo 123 > $file1 || error "Should be able to write into $file1"
19572
19573         $LFS swap_layouts $file1 $file3 ||
19574                 error "swap $file1 $file3 layouts failed"
19575
19576         echo 123 > $file1 || error "Should be able to write into $file1"
19577
19578         rm -rf $file1 $file2 $file3
19579 }
19580 run_test 184e "Recreate layout after stripeless layout swaps"
19581
19582 test_184f() {
19583         # Create a file with name longer than sizeof(struct stat) ==
19584         # 144 to see if we can get chars from the file name to appear
19585         # in the returned striping. Note that 'f' == 0x66.
19586         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19587
19588         mkdir -p $DIR/$tdir
19589         mcreate $DIR/$tdir/$file
19590         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19591                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19592         fi
19593 }
19594 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19595
19596 test_185() { # LU-2441
19597         # LU-3553 - no volatile file support in old servers
19598         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19599                 skip "Need MDS version at least 2.3.60"
19600
19601         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19602         touch $DIR/$tdir/spoo
19603         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19604         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19605                 error "cannot create/write a volatile file"
19606         [ "$FILESET" == "" ] &&
19607         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19608                 error "FID is still valid after close"
19609
19610         multiop_bg_pause $DIR/$tdir Vw4096_c
19611         local multi_pid=$!
19612
19613         local OLD_IFS=$IFS
19614         IFS=":"
19615         local fidv=($fid)
19616         IFS=$OLD_IFS
19617         # assume that the next FID for this client is sequential, since stdout
19618         # is unfortunately eaten by multiop_bg_pause
19619         local n=$((${fidv[1]} + 1))
19620         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19621         if [ "$FILESET" == "" ]; then
19622                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19623                         error "FID is missing before close"
19624         fi
19625         kill -USR1 $multi_pid
19626         # 1 second delay, so if mtime change we will see it
19627         sleep 1
19628         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19629         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19630 }
19631 run_test 185 "Volatile file support"
19632
19633 function create_check_volatile() {
19634         local idx=$1
19635         local tgt
19636
19637         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19638         local PID=$!
19639         sleep 1
19640         local FID=$(cat /tmp/${tfile}.fid)
19641         [ "$FID" == "" ] && error "can't get FID for volatile"
19642         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19643         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19644         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19645         kill -USR1 $PID
19646         wait
19647         sleep 1
19648         cancel_lru_locks mdc # flush opencache
19649         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19650         return 0
19651 }
19652
19653 test_185a(){
19654         # LU-12516 - volatile creation via .lustre
19655         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19656                 skip "Need MDS version at least 2.3.55"
19657
19658         create_check_volatile 0
19659         [ $MDSCOUNT -lt 2 ] && return 0
19660
19661         # DNE case
19662         create_check_volatile 1
19663
19664         return 0
19665 }
19666 run_test 185a "Volatile file creation in .lustre/fid/"
19667
19668 test_187a() {
19669         remote_mds_nodsh && skip "remote MDS with nodsh"
19670         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19671                 skip "Need MDS version at least 2.3.0"
19672
19673         local dir0=$DIR/$tdir/$testnum
19674         mkdir -p $dir0 || error "creating dir $dir0"
19675
19676         local file=$dir0/file1
19677         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19678         stack_trap "rm -f $file"
19679         local dv1=$($LFS data_version $file)
19680         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19681         local dv2=$($LFS data_version $file)
19682         [[ $dv1 != $dv2 ]] ||
19683                 error "data version did not change on write $dv1 == $dv2"
19684 }
19685 run_test 187a "Test data version change"
19686
19687 test_187b() {
19688         remote_mds_nodsh && skip "remote MDS with nodsh"
19689         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19690                 skip "Need MDS version at least 2.3.0"
19691
19692         local dir0=$DIR/$tdir/$testnum
19693         mkdir -p $dir0 || error "creating dir $dir0"
19694
19695         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19696         [[ ${DV[0]} != ${DV[1]} ]] ||
19697                 error "data version did not change on write"\
19698                       " ${DV[0]} == ${DV[1]}"
19699
19700         # clean up
19701         rm -f $file1
19702 }
19703 run_test 187b "Test data version change on volatile file"
19704
19705 test_200() {
19706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19707         remote_mgs_nodsh && skip "remote MGS with nodsh"
19708         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19709
19710         local POOL=${POOL:-cea1}
19711         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19712         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19713         # Pool OST targets
19714         local first_ost=0
19715         local last_ost=$(($OSTCOUNT - 1))
19716         local ost_step=2
19717         local ost_list=$(seq $first_ost $ost_step $last_ost)
19718         local ost_range="$first_ost $last_ost $ost_step"
19719         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19720         local file_dir=$POOL_ROOT/file_tst
19721         local subdir=$test_path/subdir
19722         local rc=0
19723
19724         while : ; do
19725                 # former test_200a test_200b
19726                 pool_add $POOL                          || { rc=$? ; break; }
19727                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19728                 # former test_200c test_200d
19729                 mkdir -p $test_path
19730                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19731                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19732                 mkdir -p $subdir
19733                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19734                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19735                                                         || { rc=$? ; break; }
19736                 # former test_200e test_200f
19737                 local files=$((OSTCOUNT*3))
19738                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19739                                                         || { rc=$? ; break; }
19740                 pool_create_files $POOL $file_dir $files "$ost_list" \
19741                                                         || { rc=$? ; break; }
19742                 # former test_200g test_200h
19743                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19744                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19745
19746                 # former test_201a test_201b test_201c
19747                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19748
19749                 local f=$test_path/$tfile
19750                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19751                 pool_remove $POOL $f                    || { rc=$? ; break; }
19752                 break
19753         done
19754
19755         destroy_test_pools
19756
19757         return $rc
19758 }
19759 run_test 200 "OST pools"
19760
19761 # usage: default_attr <count | size | offset>
19762 default_attr() {
19763         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19764 }
19765
19766 # usage: check_default_stripe_attr
19767 check_default_stripe_attr() {
19768         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19769         case $1 in
19770         --stripe-count|-c)
19771                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19772         --stripe-size|-S)
19773                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19774         --stripe-index|-i)
19775                 EXPECTED=-1;;
19776         *)
19777                 error "unknown getstripe attr '$1'"
19778         esac
19779
19780         [ $ACTUAL == $EXPECTED ] ||
19781                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19782 }
19783
19784 test_204a() {
19785         test_mkdir $DIR/$tdir
19786         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19787
19788         check_default_stripe_attr --stripe-count
19789         check_default_stripe_attr --stripe-size
19790         check_default_stripe_attr --stripe-index
19791 }
19792 run_test 204a "Print default stripe attributes"
19793
19794 test_204b() {
19795         test_mkdir $DIR/$tdir
19796         $LFS setstripe --stripe-count 1 $DIR/$tdir
19797
19798         check_default_stripe_attr --stripe-size
19799         check_default_stripe_attr --stripe-index
19800 }
19801 run_test 204b "Print default stripe size and offset"
19802
19803 test_204c() {
19804         test_mkdir $DIR/$tdir
19805         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19806
19807         check_default_stripe_attr --stripe-count
19808         check_default_stripe_attr --stripe-index
19809 }
19810 run_test 204c "Print default stripe count and offset"
19811
19812 test_204d() {
19813         test_mkdir $DIR/$tdir
19814         $LFS setstripe --stripe-index 0 $DIR/$tdir
19815
19816         check_default_stripe_attr --stripe-count
19817         check_default_stripe_attr --stripe-size
19818 }
19819 run_test 204d "Print default stripe count and size"
19820
19821 test_204e() {
19822         test_mkdir $DIR/$tdir
19823         $LFS setstripe -d $DIR/$tdir
19824
19825         # LU-16904 check if root is set as PFL layout
19826         local numcomp=$($LFS getstripe --component-count $MOUNT)
19827
19828         if [[ $numcomp -gt 0 ]]; then
19829                 check_default_stripe_attr --stripe-count
19830         else
19831                 check_default_stripe_attr --stripe-count --raw
19832         fi
19833         check_default_stripe_attr --stripe-size --raw
19834         check_default_stripe_attr --stripe-index --raw
19835 }
19836 run_test 204e "Print raw stripe attributes"
19837
19838 test_204f() {
19839         test_mkdir $DIR/$tdir
19840         $LFS setstripe --stripe-count 1 $DIR/$tdir
19841
19842         check_default_stripe_attr --stripe-size --raw
19843         check_default_stripe_attr --stripe-index --raw
19844 }
19845 run_test 204f "Print raw stripe size and offset"
19846
19847 test_204g() {
19848         test_mkdir $DIR/$tdir
19849         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19850
19851         check_default_stripe_attr --stripe-count --raw
19852         check_default_stripe_attr --stripe-index --raw
19853 }
19854 run_test 204g "Print raw stripe count and offset"
19855
19856 test_204h() {
19857         test_mkdir $DIR/$tdir
19858         $LFS setstripe --stripe-index 0 $DIR/$tdir
19859
19860         check_default_stripe_attr --stripe-count --raw
19861         check_default_stripe_attr --stripe-size --raw
19862 }
19863 run_test 204h "Print raw stripe count and size"
19864
19865 # Figure out which job scheduler is being used, if any,
19866 # or use a fake one
19867 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19868         JOBENV=SLURM_JOB_ID
19869 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19870         JOBENV=LSB_JOBID
19871 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19872         JOBENV=PBS_JOBID
19873 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19874         JOBENV=LOADL_STEP_ID
19875 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19876         JOBENV=JOB_ID
19877 else
19878         $LCTL list_param jobid_name > /dev/null 2>&1
19879         if [ $? -eq 0 ]; then
19880                 JOBENV=nodelocal
19881         else
19882                 JOBENV=FAKE_JOBID
19883         fi
19884 fi
19885 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19886
19887 verify_jobstats() {
19888         local cmd=($1)
19889         shift
19890         local facets="$@"
19891
19892 # we don't really need to clear the stats for this test to work, since each
19893 # command has a unique jobid, but it makes debugging easier if needed.
19894 #       for facet in $facets; do
19895 #               local dev=$(convert_facet2label $facet)
19896 #               # clear old jobstats
19897 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19898 #       done
19899
19900         # use a new JobID for each test, or we might see an old one
19901         [ "$JOBENV" = "FAKE_JOBID" ] &&
19902                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19903
19904         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19905
19906         [ "$JOBENV" = "nodelocal" ] && {
19907                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19908                 $LCTL set_param jobid_name=$FAKE_JOBID
19909                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19910         }
19911
19912         log "Test: ${cmd[*]}"
19913         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19914
19915         if [ $JOBENV = "FAKE_JOBID" ]; then
19916                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19917         else
19918                 ${cmd[*]}
19919         fi
19920
19921         # all files are created on OST0000
19922         for facet in $facets; do
19923                 local stats="*.$(convert_facet2label $facet).job_stats"
19924
19925                 # strip out libtool wrappers for in-tree executables
19926                 if (( $(do_facet $facet lctl get_param $stats |
19927                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19928                         do_facet $facet lctl get_param $stats
19929                         error "No jobstats for $JOBVAL found on $facet::$stats"
19930                 fi
19931         done
19932 }
19933
19934 jobstats_set() {
19935         local new_jobenv=$1
19936
19937         set_persistent_param_and_check client "jobid_var" \
19938                 "$FSNAME.sys.jobid_var" $new_jobenv
19939 }
19940
19941 test_205a() { # Job stats
19942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19943         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19944                 skip "Need MDS version with at least 2.7.1"
19945         remote_mgs_nodsh && skip "remote MGS with nodsh"
19946         remote_mds_nodsh && skip "remote MDS with nodsh"
19947         remote_ost_nodsh && skip "remote OST with nodsh"
19948         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19949                 skip "Server doesn't support jobstats"
19950         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19951
19952         local old_jobenv=$($LCTL get_param -n jobid_var)
19953         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19954         stack_trap "jobstats_set $old_jobenv" EXIT
19955
19956         changelog_register
19957
19958         local old_jobid_name=$($LCTL get_param jobid_name)
19959         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19960
19961         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19962                                 mdt.*.job_cleanup_interval | head -n 1)
19963         local new_interval=5
19964         do_facet $SINGLEMDS \
19965                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19966         stack_trap "do_facet $SINGLEMDS \
19967                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19968         local start=$SECONDS
19969
19970         local cmd
19971         # mkdir
19972         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19973         verify_jobstats "$cmd" "$SINGLEMDS"
19974         # rmdir
19975         cmd="rmdir $DIR/$tdir"
19976         verify_jobstats "$cmd" "$SINGLEMDS"
19977         # mkdir on secondary MDT
19978         if [ $MDSCOUNT -gt 1 ]; then
19979                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19980                 verify_jobstats "$cmd" "mds2"
19981         fi
19982         # mknod
19983         cmd="mknod $DIR/$tfile c 1 3"
19984         verify_jobstats "$cmd" "$SINGLEMDS"
19985         # unlink
19986         cmd="rm -f $DIR/$tfile"
19987         verify_jobstats "$cmd" "$SINGLEMDS"
19988         # create all files on OST0000 so verify_jobstats can find OST stats
19989         # open & close
19990         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19991         verify_jobstats "$cmd" "$SINGLEMDS"
19992         # setattr
19993         cmd="touch $DIR/$tfile"
19994         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19995         # write
19996         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19997         verify_jobstats "$cmd" "ost1"
19998         # read
19999         cancel_lru_locks osc
20000         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20001         verify_jobstats "$cmd" "ost1"
20002         # truncate
20003         cmd="$TRUNCATE $DIR/$tfile 0"
20004         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20005         # rename
20006         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20007         verify_jobstats "$cmd" "$SINGLEMDS"
20008         # jobstats expiry - sleep until old stats should be expired
20009         local left=$((new_interval + 5 - (SECONDS - start)))
20010         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20011                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20012                         "0" $left
20013         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20014         verify_jobstats "$cmd" "$SINGLEMDS"
20015         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20016             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20017
20018         # Ensure that jobid are present in changelog (if supported by MDS)
20019         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20020                 changelog_dump | tail -10
20021                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20022                 [ $jobids -eq 9 ] ||
20023                         error "Wrong changelog jobid count $jobids != 9"
20024
20025                 # LU-5862
20026                 JOBENV="disable"
20027                 jobstats_set $JOBENV
20028                 touch $DIR/$tfile
20029                 changelog_dump | grep $tfile
20030                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20031                 [ $jobids -eq 0 ] ||
20032                         error "Unexpected jobids when jobid_var=$JOBENV"
20033         fi
20034
20035         # test '%j' access to environment variable - if supported
20036         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20037                 JOBENV="JOBCOMPLEX"
20038                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20039
20040                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20041         fi
20042
20043         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20044                 JOBENV="JOBCOMPLEX"
20045                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20046
20047                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20048         fi
20049
20050         # test '%j' access to per-session jobid - if supported
20051         if lctl list_param jobid_this_session > /dev/null 2>&1
20052         then
20053                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20054                 lctl set_param jobid_this_session=$USER
20055
20056                 JOBENV="JOBCOMPLEX"
20057                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20058
20059                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20060         fi
20061 }
20062 run_test 205a "Verify job stats"
20063
20064 # LU-13117, LU-13597, LU-16599
20065 test_205b() {
20066         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20067                 skip "Need MDS version at least 2.13.54.91"
20068
20069         local job_stats="mdt.*.job_stats"
20070         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20071
20072         do_facet mds1 $LCTL set_param $job_stats=clear
20073
20074         # Setting jobid_var to USER might not be supported
20075         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20076         $LCTL set_param jobid_var=USER || true
20077         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20078         $LCTL set_param jobid_name="%j.%e.%u"
20079
20080         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20081         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20082                 { do_facet mds1 $LCTL get_param $job_stats;
20083                   error "Unexpected jobid found"; }
20084         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20085                 { do_facet mds1 $LCTL get_param $job_stats;
20086                   error "wrong job_stats format found"; }
20087
20088         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20089                 echo "MDS does not yet escape jobid" && return 0
20090
20091         mkdir_on_mdt0 $DIR/$tdir
20092         $LCTL set_param jobid_var=TEST205b
20093         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20094         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20095                       awk '/has\\x20sp/ {print $3}')
20096         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20097                   error "jobid not escaped"; }
20098
20099         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20100                 # need to run such a command on mds1:
20101                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20102                 #
20103                 # there might be multiple MDTs on single mds server, so need to
20104                 # specifiy MDT0000. Or the command will fail due to other MDTs
20105                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20106                         error "cannot clear escaped jobid in job_stats";
20107         else
20108                 echo "MDS does not support clearing escaped jobid"
20109         fi
20110 }
20111 run_test 205b "Verify job stats jobid and output format"
20112
20113 # LU-13733
20114 test_205c() {
20115         $LCTL set_param llite.*.stats=0
20116         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20117         $LCTL get_param llite.*.stats
20118         $LCTL get_param llite.*.stats | grep \
20119                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20120                         error "wrong client stats format found"
20121 }
20122 run_test 205c "Verify client stats format"
20123
20124 test_205d() {
20125         local file=$DIR/$tdir/$tfile
20126
20127         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20128                 skip "need lustre >= 2.15.53 for lljobstat"
20129         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20130                 skip "need lustre >= 2.15.53 for lljobstat"
20131         verify_yaml_available || skip_env "YAML verification not installed"
20132
20133         test_mkdir -i 0 $DIR/$tdir
20134         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20135         stack_trap "rm -rf $DIR/$tdir"
20136
20137         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20138                 error "failed to write data to $file"
20139         mv $file $file.2
20140
20141         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20142         echo -n 'verify rename_stats...'
20143         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20144                 verify_yaml || error "rename_stats is not valid YAML"
20145         echo " OK"
20146
20147         echo -n 'verify mdt job_stats...'
20148         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20149                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20150         echo " OK"
20151
20152         echo -n 'verify ost job_stats...'
20153         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20154                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20155         echo " OK"
20156 }
20157 run_test 205d "verify the format of some stats files"
20158
20159 test_205e() {
20160         local ops_comma
20161         local file=$DIR/$tdir/$tfile
20162         local -a cli_params
20163
20164         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20165                 skip "need lustre >= 2.15.53 for lljobstat"
20166         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20167                 skip "need lustre >= 2.15.53 for lljobstat"
20168         verify_yaml_available || skip_env "YAML verification not installed"
20169
20170         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20171         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20172         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20173
20174         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20175         stack_trap "rm -rf $DIR/$tdir"
20176
20177         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20178                 error "failed to create $file on ost1"
20179         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20180                 error "failed to write data to $file"
20181
20182         do_facet mds1 "$LCTL get_param *.*.job_stats"
20183         do_facet ost1 "$LCTL get_param *.*.job_stats"
20184
20185         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20186         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20187                 error "The output of lljobstat is not an valid YAML"
20188
20189         # verify that job dd.0 does exist and has some ops on ost1
20190         # typically this line is like:
20191         # - 205e.dd.0:            {ops: 20, ...}
20192         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20193                     awk '$2=="205e.dd.0:" {print $4}')
20194
20195         (( ${ops_comma%,} >= 10 )) ||
20196                 error "cannot find job 205e.dd.0 with ops >= 10"
20197 }
20198 run_test 205e "verify the output of lljobstat"
20199
20200 test_205f() {
20201         verify_yaml_available || skip_env "YAML verification not installed"
20202
20203         # check both qos_ost_weights and qos_mdt_weights
20204         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20205         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20206                 error "qos_ost_weights is not valid YAML"
20207 }
20208 run_test 205f "verify qos_ost_weights YAML format "
20209
20210 __test_205_jobstats_dump() {
20211         local -a pids
20212         local nbr_instance=$1
20213
20214         while true; do
20215                 if (( ${#pids[@]} >= nbr_instance )); then
20216                         wait ${pids[@]}
20217                         pids=()
20218                 fi
20219
20220                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20221                 pids+=( $! )
20222         done
20223 }
20224
20225 __test_205_cleanup() {
20226         kill $@
20227         # Clear all job entries
20228         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20229 }
20230
20231 test_205g() {
20232         local -a mds1_params
20233         local -a cli_params
20234         local pids
20235         local interval=5
20236
20237         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20238         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20239         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20240
20241         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20242         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20243         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20244
20245         # start jobs loop
20246         export TEST205G_ID=205g
20247         stack_trap "unset TEST205G_ID" EXIT
20248         while true; do
20249                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20250         done & pids="$! "
20251
20252         __test_205_jobstats_dump 4 & pids+="$! "
20253         stack_trap "__test_205_cleanup $pids" EXIT INT
20254
20255         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20256 }
20257 run_test 205g "stress test for job_stats procfile"
20258
20259 test_205h() {
20260         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20261                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20262         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20263
20264         local dir=$DIR/$tdir
20265         local f=$dir/$tfile
20266         local f2=$dir/$tfile-2
20267         local f3=$dir/$tfile-3
20268         local subdir=$DIR/dir
20269         local val
20270
20271         local mdts=$(comma_list $(mdts_nodes))
20272         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20273         local client_saved=$($LCTL get_param -n jobid_var)
20274
20275         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20276         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20277
20278         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20279                 error "failed to set job_xattr parameter to user.job"
20280         $LCTL set_param jobid_var=procname.uid ||
20281                 error "failed to set jobid_var parameter"
20282
20283         test_mkdir $dir
20284
20285         touch $f
20286         val=$(getfattr -n user.job $f | grep user.job)
20287         [[ $val = user.job=\"touch.0\" ]] ||
20288                 error "expected user.job=\"touch.0\", got '$val'"
20289
20290         mkdir $subdir
20291         val=$(getfattr -n user.job $subdir | grep user.job)
20292         [[ $val = user.job=\"mkdir.0\" ]] ||
20293                 error "expected user.job=\"mkdir.0\", got '$val'"
20294
20295         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20296                 error "failed to set job_xattr parameter to NONE"
20297
20298         touch $f2
20299         val=$(getfattr -d $f2)
20300         [[ -z $val ]] ||
20301                 error "expected no user xattr, got '$val'"
20302
20303         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20304                 error "failed to set job_xattr parameter to trusted.job"
20305
20306         touch $f3
20307         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20308         [[ $val = trusted.job=\"touch.0\" ]] ||
20309                 error "expected trusted.job=\"touch.0\", got '$val'"
20310 }
20311 run_test 205h "check jobid xattr is stored correctly"
20312
20313 test_205i() {
20314         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20315                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20316
20317         local mdts=$(comma_list $(mdts_nodes))
20318         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20319
20320         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20321
20322         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20323                 error "failed to set mdt.*.job_xattr to user.1234567"
20324
20325         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20326                 error "failed to reject too long job_xattr name"
20327
20328         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20329                 error "failed to reject job_xattr name in bad format"
20330
20331         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20332                 error "failed to reject job_xattr name with invalid character"
20333
20334         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20335                         xargs $LCTL set_param" &&
20336                 error "failed to reject job_xattr name with non-ascii character"
20337
20338         return 0
20339 }
20340 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20341
20342 # LU-1480, LU-1773 and LU-1657
20343 test_206() {
20344         mkdir -p $DIR/$tdir
20345         $LFS setstripe -c -1 $DIR/$tdir
20346 #define OBD_FAIL_LOV_INIT 0x1403
20347         $LCTL set_param fail_loc=0xa0001403
20348         $LCTL set_param fail_val=1
20349         touch $DIR/$tdir/$tfile || true
20350 }
20351 run_test 206 "fail lov_init_raid0() doesn't lbug"
20352
20353 test_207a() {
20354         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20355         local fsz=`stat -c %s $DIR/$tfile`
20356         cancel_lru_locks mdc
20357
20358         # do not return layout in getattr intent
20359 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20360         $LCTL set_param fail_loc=0x170
20361         local sz=`stat -c %s $DIR/$tfile`
20362
20363         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20364
20365         rm -rf $DIR/$tfile
20366 }
20367 run_test 207a "can refresh layout at glimpse"
20368
20369 test_207b() {
20370         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20371         local cksum=`md5sum $DIR/$tfile`
20372         local fsz=`stat -c %s $DIR/$tfile`
20373         cancel_lru_locks mdc
20374         cancel_lru_locks osc
20375
20376         # do not return layout in getattr intent
20377 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20378         $LCTL set_param fail_loc=0x171
20379
20380         # it will refresh layout after the file is opened but before read issues
20381         echo checksum is "$cksum"
20382         echo "$cksum" |md5sum -c --quiet || error "file differs"
20383
20384         rm -rf $DIR/$tfile
20385 }
20386 run_test 207b "can refresh layout at open"
20387
20388 test_208() {
20389         # FIXME: in this test suite, only RD lease is used. This is okay
20390         # for now as only exclusive open is supported. After generic lease
20391         # is done, this test suite should be revised. - Jinshan
20392
20393         remote_mds_nodsh && skip "remote MDS with nodsh"
20394         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20395                 skip "Need MDS version at least 2.4.52"
20396
20397         echo "==== test 1: verify get lease work"
20398         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20399
20400         echo "==== test 2: verify lease can be broken by upcoming open"
20401         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20402         local PID=$!
20403         sleep 2
20404
20405         $MULTIOP $DIR/$tfile oO_RDWR:c
20406         kill -USR1 $PID && wait $PID || error "break lease error"
20407
20408         echo "==== test 3: verify lease can't be granted if an open already exists"
20409         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20410         local PID=$!
20411         sleep 2
20412
20413         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20414         kill -USR1 $PID && wait $PID || error "open file error"
20415
20416         echo "==== test 4: lease can sustain over recovery"
20417         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20418         PID=$!
20419         sleep 2
20420
20421         fail mds1
20422
20423         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20424
20425         echo "==== test 5: lease broken can't be regained by replay"
20426         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20427         PID=$!
20428         sleep 2
20429
20430         # open file to break lease and then recovery
20431         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20432         fail mds1
20433
20434         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20435
20436         rm -f $DIR/$tfile
20437 }
20438 run_test 208 "Exclusive open"
20439
20440 test_209() {
20441         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20442                 skip_env "must have disp_stripe"
20443
20444         touch $DIR/$tfile
20445         sync; sleep 5; sync;
20446
20447         echo 3 > /proc/sys/vm/drop_caches
20448         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20449                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20450         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20451
20452         # open/close 500 times
20453         for i in $(seq 500); do
20454                 cat $DIR/$tfile
20455         done
20456
20457         echo 3 > /proc/sys/vm/drop_caches
20458         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20459                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20460         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20461
20462         echo "before: $req_before, after: $req_after"
20463         [ $((req_after - req_before)) -ge 300 ] &&
20464                 error "open/close requests are not freed"
20465         return 0
20466 }
20467 run_test 209 "read-only open/close requests should be freed promptly"
20468
20469 test_210() {
20470         local pid
20471
20472         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20473         pid=$!
20474         sleep 1
20475
20476         $LFS getstripe $DIR/$tfile
20477         kill -USR1 $pid
20478         wait $pid || error "multiop failed"
20479
20480         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20481         pid=$!
20482         sleep 1
20483
20484         $LFS getstripe $DIR/$tfile
20485         kill -USR1 $pid
20486         wait $pid || error "multiop failed"
20487 }
20488 run_test 210 "lfs getstripe does not break leases"
20489
20490 function test_211() {
20491         local PID
20492         local id
20493         local rc
20494
20495         stack_trap "rm -f $DIR/$tfile" EXIT
20496         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20497                 error "can't create file"
20498         $LFS mirror extend -N $DIR/$tfile ||
20499                 error "can't create a replica"
20500         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20501         $LFS getstripe $DIR/$tfile
20502         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20503         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20504
20505         $MULTIOP $DIR/$tfile OeW_E+eUc &
20506         PID=$!
20507         sleep 0.3
20508
20509         id=$($LFS getstripe $DIR/$tfile |
20510                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20511         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20512                 error "removed last in-sync replica?"
20513
20514         kill -USR1 $PID
20515         wait $PID
20516         (( $? == 0 )) || error "failed split broke the lease"
20517 }
20518 run_test 211 "failed mirror split doesn't break write lease"
20519
20520 test_212() {
20521         size=`date +%s`
20522         size=$((size % 8192 + 1))
20523         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20524         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20525         rm -f $DIR/f212 $DIR/f212.xyz
20526 }
20527 run_test 212 "Sendfile test ============================================"
20528
20529 test_213() {
20530         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20531         cancel_lru_locks osc
20532         lctl set_param fail_loc=0x8000040f
20533         # generate a read lock
20534         cat $DIR/$tfile > /dev/null
20535         # write to the file, it will try to cancel the above read lock.
20536         cat /etc/hosts >> $DIR/$tfile
20537 }
20538 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20539
20540 test_214() { # for bug 20133
20541         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20542         for (( i=0; i < 340; i++ )) ; do
20543                 touch $DIR/$tdir/d214c/a$i
20544         done
20545
20546         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20547         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20548         ls $DIR/d214c || error "ls $DIR/d214c failed"
20549         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20550         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20551 }
20552 run_test 214 "hash-indexed directory test - bug 20133"
20553
20554 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20555 create_lnet_proc_files() {
20556         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20557 }
20558
20559 # counterpart of create_lnet_proc_files
20560 remove_lnet_proc_files() {
20561         rm -f $TMP/lnet_$1.sys
20562 }
20563
20564 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20565 # 3rd arg as regexp for body
20566 check_lnet_proc_stats() {
20567         local l=$(cat "$TMP/lnet_$1" |wc -l)
20568         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20569
20570         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20571 }
20572
20573 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20574 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20575 # optional and can be regexp for 2nd line (lnet.routes case)
20576 check_lnet_proc_entry() {
20577         local blp=2          # blp stands for 'position of 1st line of body'
20578         [ -z "$5" ] || blp=3 # lnet.routes case
20579
20580         local l=$(cat "$TMP/lnet_$1" |wc -l)
20581         # subtracting one from $blp because the body can be empty
20582         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20583
20584         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20585                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20586
20587         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20588                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20589
20590         # bail out if any unexpected line happened
20591         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20592         [ "$?" != 0 ] || error "$2 misformatted"
20593 }
20594
20595 test_215() { # for bugs 18102, 21079, 21517
20596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20597
20598         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20599         local P='[1-9][0-9]*'           # positive numeric
20600         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20601         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20602         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20603         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20604
20605         local L1 # regexp for 1st line
20606         local L2 # regexp for 2nd line (optional)
20607         local BR # regexp for the rest (body)
20608
20609         # lnet.stats should look as 11 space-separated non-negative numerics
20610         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20611         create_lnet_proc_files "stats"
20612         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20613         remove_lnet_proc_files "stats"
20614
20615         # lnet.routes should look like this:
20616         # Routing disabled/enabled
20617         # net hops priority state router
20618         # where net is a string like tcp0, hops > 0, priority >= 0,
20619         # state is up/down,
20620         # router is a string like 192.168.1.1@tcp2
20621         L1="^Routing (disabled|enabled)$"
20622         L2="^net +hops +priority +state +router$"
20623         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20624         create_lnet_proc_files "routes"
20625         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20626         remove_lnet_proc_files "routes"
20627
20628         # lnet.routers should look like this:
20629         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20630         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20631         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20632         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20633         L1="^ref +rtr_ref +alive +router$"
20634         BR="^$P +$P +(up|down) +$NID$"
20635         create_lnet_proc_files "routers"
20636         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20637         remove_lnet_proc_files "routers"
20638
20639         # lnet.peers should look like this:
20640         # nid refs state last max rtr min tx min queue
20641         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20642         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20643         # numeric (0 or >0 or <0), queue >= 0.
20644         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20645         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20646         create_lnet_proc_files "peers"
20647         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20648         remove_lnet_proc_files "peers"
20649
20650         # lnet.buffers  should look like this:
20651         # pages count credits min
20652         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20653         L1="^pages +count +credits +min$"
20654         BR="^ +$N +$N +$I +$I$"
20655         create_lnet_proc_files "buffers"
20656         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20657         remove_lnet_proc_files "buffers"
20658
20659         # lnet.nis should look like this:
20660         # nid status alive refs peer rtr max tx min
20661         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20662         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20663         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20664         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20665         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20666         create_lnet_proc_files "nis"
20667         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20668         remove_lnet_proc_files "nis"
20669
20670         # can we successfully write to lnet.stats?
20671         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20672 }
20673 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20674
20675 test_216() { # bug 20317
20676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20677         remote_ost_nodsh && skip "remote OST with nodsh"
20678
20679         local node
20680         local facets=$(get_facets OST)
20681         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20682
20683         save_lustre_params client "osc.*.contention_seconds" > $p
20684         save_lustre_params $facets \
20685                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20686         save_lustre_params $facets \
20687                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20688         save_lustre_params $facets \
20689                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20690         clear_stats osc.*.osc_stats
20691
20692         # agressive lockless i/o settings
20693         do_nodes $(comma_list $(osts_nodes)) \
20694                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20695                         ldlm.namespaces.filter-*.contended_locks=0 \
20696                         ldlm.namespaces.filter-*.contention_seconds=60"
20697         lctl set_param -n osc.*.contention_seconds=60
20698
20699         $DIRECTIO write $DIR/$tfile 0 10 4096
20700         $CHECKSTAT -s 40960 $DIR/$tfile
20701
20702         # disable lockless i/o
20703         do_nodes $(comma_list $(osts_nodes)) \
20704                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20705                         ldlm.namespaces.filter-*.contended_locks=32 \
20706                         ldlm.namespaces.filter-*.contention_seconds=0"
20707         lctl set_param -n osc.*.contention_seconds=0
20708         clear_stats osc.*.osc_stats
20709
20710         dd if=/dev/zero of=$DIR/$tfile count=0
20711         $CHECKSTAT -s 0 $DIR/$tfile
20712
20713         restore_lustre_params <$p
20714         rm -f $p
20715         rm $DIR/$tfile
20716 }
20717 run_test 216 "check lockless direct write updates file size and kms correctly"
20718
20719 test_217() { # bug 22430
20720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20721
20722         local node
20723
20724         for node in $(nodes_list); do
20725                 local nid=$(host_nids_address $node $NETTYPE)
20726                 local node_ip=$(do_node $node getent ahostsv4 $node |
20727                                 awk '{ print $1; exit; }')
20728
20729                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20730                 # if hostname matches any NID, use hostname for better testing
20731                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20732                         echo "lctl ping node $node@$NETTYPE"
20733                         lctl ping $node@$NETTYPE
20734                 else # otherwise, at least test 'lctl ping' is working
20735                         echo "lctl ping nid $(h2nettype $nid)"
20736                         lctl ping $(h2nettype $nid)
20737                         echo "skipping $node (no hyphen detected)"
20738                 fi
20739         done
20740 }
20741 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20742
20743 test_218() {
20744         # do directio so as not to populate the page cache
20745         log "creating a 10 Mb file"
20746         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20747                 error "multiop failed while creating a file"
20748         log "starting reads"
20749         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20750         log "truncating the file"
20751         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20752                 error "multiop failed while truncating the file"
20753         log "killing dd"
20754         kill %+ || true # reads might have finished
20755         echo "wait until dd is finished"
20756         wait
20757         log "removing the temporary file"
20758         rm -rf $DIR/$tfile || error "tmp file removal failed"
20759 }
20760 run_test 218 "parallel read and truncate should not deadlock"
20761
20762 test_219() {
20763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20764
20765         # write one partial page
20766         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20767         # set no grant so vvp_io_commit_write will do sync write
20768         $LCTL set_param fail_loc=0x411
20769         # write a full page at the end of file
20770         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20771
20772         $LCTL set_param fail_loc=0
20773         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20774         $LCTL set_param fail_loc=0x411
20775         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20776
20777         # LU-4201
20778         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20779         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20780 }
20781 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20782
20783 test_220() { #LU-325
20784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20785         remote_ost_nodsh && skip "remote OST with nodsh"
20786         remote_mds_nodsh && skip "remote MDS with nodsh"
20787         remote_mgs_nodsh && skip "remote MGS with nodsh"
20788
20789         local OSTIDX=0
20790
20791         # create on MDT0000 so the last_id and next_id are correct
20792         mkdir_on_mdt0 $DIR/$tdir
20793         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20794         OST=${OST%_UUID}
20795
20796         # on the mdt's osc
20797         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20798         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20799                         osp.$mdtosc_proc1.prealloc_last_id)
20800         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20801                         osp.$mdtosc_proc1.prealloc_next_id)
20802
20803         $LFS df -i
20804
20805         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20806         #define OBD_FAIL_OST_ENOINO              0x229
20807         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20808         create_pool $FSNAME.$TESTNAME || return 1
20809         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20810
20811         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20812
20813         MDSOBJS=$((last_id - next_id))
20814         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20815
20816         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20817         echo "OST still has $count kbytes free"
20818
20819         echo "create $MDSOBJS files @next_id..."
20820         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20821
20822         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20823                         osp.$mdtosc_proc1.prealloc_last_id)
20824         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20825                         osp.$mdtosc_proc1.prealloc_next_id)
20826
20827         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20828         $LFS df -i
20829
20830         echo "cleanup..."
20831
20832         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20833         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20834
20835         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20836                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20837         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20838                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20839         echo "unlink $MDSOBJS files @$next_id..."
20840         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20841 }
20842 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20843
20844 test_221() {
20845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20846
20847         dd if=`which date` of=$MOUNT/date oflag=sync
20848         chmod +x $MOUNT/date
20849
20850         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20851         $LCTL set_param fail_loc=0x80001401
20852
20853         $MOUNT/date > /dev/null
20854         rm -f $MOUNT/date
20855 }
20856 run_test 221 "make sure fault and truncate race to not cause OOM"
20857
20858 test_222a () {
20859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20860
20861         rm -rf $DIR/$tdir
20862         test_mkdir $DIR/$tdir
20863         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20864         createmany -o $DIR/$tdir/$tfile 10
20865         cancel_lru_locks mdc
20866         cancel_lru_locks osc
20867         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20868         $LCTL set_param fail_loc=0x31a
20869         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20870         $LCTL set_param fail_loc=0
20871         rm -r $DIR/$tdir
20872 }
20873 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20874
20875 test_222b () {
20876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20877
20878         rm -rf $DIR/$tdir
20879         test_mkdir $DIR/$tdir
20880         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20881         createmany -o $DIR/$tdir/$tfile 10
20882         cancel_lru_locks mdc
20883         cancel_lru_locks osc
20884         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20885         $LCTL set_param fail_loc=0x31a
20886         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20887         $LCTL set_param fail_loc=0
20888 }
20889 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20890
20891 test_223 () {
20892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20893
20894         rm -rf $DIR/$tdir
20895         test_mkdir $DIR/$tdir
20896         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20897         createmany -o $DIR/$tdir/$tfile 10
20898         cancel_lru_locks mdc
20899         cancel_lru_locks osc
20900         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20901         $LCTL set_param fail_loc=0x31b
20902         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20903         $LCTL set_param fail_loc=0
20904         rm -r $DIR/$tdir
20905 }
20906 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20907
20908 test_224a() { # LU-1039, MRP-303
20909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20910         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20911         $LCTL set_param fail_loc=0x508
20912         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20913         $LCTL set_param fail_loc=0
20914         df $DIR
20915 }
20916 run_test 224a "Don't panic on bulk IO failure"
20917
20918 test_224bd_sub() { # LU-1039, MRP-303
20919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20920         local timeout=$1
20921
20922         shift
20923         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20924
20925         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20926
20927         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20928         cancel_lru_locks osc
20929         set_checksums 0
20930         stack_trap "set_checksums $ORIG_CSUM" EXIT
20931         local at_max_saved=0
20932
20933         # adaptive timeouts may prevent seeing the issue
20934         if at_is_enabled; then
20935                 at_max_saved=$(at_max_get mds)
20936                 at_max_set 0 mds client
20937                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20938         fi
20939
20940         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20941         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20942         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20943
20944         do_facet ost1 $LCTL set_param fail_loc=0
20945         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20946         df $DIR
20947 }
20948
20949 test_224b() {
20950         test_224bd_sub 3 error "dd failed"
20951 }
20952 run_test 224b "Don't panic on bulk IO failure"
20953
20954 test_224c() { # LU-6441
20955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20956         remote_mds_nodsh && skip "remote MDS with nodsh"
20957
20958         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20959         save_writethrough $p
20960         set_cache writethrough on
20961
20962         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20963         local at_max=$($LCTL get_param -n at_max)
20964         local timeout=$($LCTL get_param -n timeout)
20965         local test_at="at_max"
20966         local param_at="$FSNAME.sys.at_max"
20967         local test_timeout="timeout"
20968         local param_timeout="$FSNAME.sys.timeout"
20969
20970         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20971
20972         set_persistent_param_and_check client "$test_at" "$param_at" 0
20973         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20974
20975         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20976         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20977         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20978         stack_trap "rm -f $DIR/$tfile"
20979         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20980         sync
20981         do_facet ost1 "$LCTL set_param fail_loc=0"
20982
20983         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20984         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20985                 $timeout
20986
20987         $LCTL set_param -n $pages_per_rpc
20988         restore_lustre_params < $p
20989         rm -f $p
20990 }
20991 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20992
20993 test_224d() { # LU-11169
20994         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20995 }
20996 run_test 224d "Don't corrupt data on bulk IO timeout"
20997
20998 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20999 test_225a () {
21000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21001         if [ -z ${MDSSURVEY} ]; then
21002                 skip_env "mds-survey not found"
21003         fi
21004         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21005                 skip "Need MDS version at least 2.2.51"
21006
21007         local mds=$(facet_host $SINGLEMDS)
21008         local target=$(do_nodes $mds 'lctl dl' |
21009                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21010
21011         local cmd1="file_count=1000 thrhi=4"
21012         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21013         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21014         local cmd="$cmd1 $cmd2 $cmd3"
21015
21016         rm -f ${TMP}/mds_survey*
21017         echo + $cmd
21018         eval $cmd || error "mds-survey with zero-stripe failed"
21019         cat ${TMP}/mds_survey*
21020         rm -f ${TMP}/mds_survey*
21021 }
21022 run_test 225a "Metadata survey sanity with zero-stripe"
21023
21024 test_225b () {
21025         if [ -z ${MDSSURVEY} ]; then
21026                 skip_env "mds-survey not found"
21027         fi
21028         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21029                 skip "Need MDS version at least 2.2.51"
21030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21031         remote_mds_nodsh && skip "remote MDS with nodsh"
21032         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21033                 skip_env "Need to mount OST to test"
21034         fi
21035
21036         local mds=$(facet_host $SINGLEMDS)
21037         local target=$(do_nodes $mds 'lctl dl' |
21038                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21039
21040         local cmd1="file_count=1000 thrhi=4"
21041         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21042         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21043         local cmd="$cmd1 $cmd2 $cmd3"
21044
21045         rm -f ${TMP}/mds_survey*
21046         echo + $cmd
21047         eval $cmd || error "mds-survey with stripe_count failed"
21048         cat ${TMP}/mds_survey*
21049         rm -f ${TMP}/mds_survey*
21050 }
21051 run_test 225b "Metadata survey sanity with stripe_count = 1"
21052
21053 mcreate_path2fid () {
21054         local mode=$1
21055         local major=$2
21056         local minor=$3
21057         local name=$4
21058         local desc=$5
21059         local path=$DIR/$tdir/$name
21060         local fid
21061         local rc
21062         local fid_path
21063
21064         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21065                 error "cannot create $desc"
21066
21067         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21068         rc=$?
21069         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21070
21071         fid_path=$($LFS fid2path $MOUNT $fid)
21072         rc=$?
21073         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21074
21075         [ "$path" == "$fid_path" ] ||
21076                 error "fid2path returned $fid_path, expected $path"
21077
21078         echo "pass with $path and $fid"
21079 }
21080
21081 test_226a () {
21082         rm -rf $DIR/$tdir
21083         mkdir -p $DIR/$tdir
21084
21085         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21086         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21087         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21088         mcreate_path2fid 0040666 0 0 dir "directory"
21089         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21090         mcreate_path2fid 0100666 0 0 file "regular file"
21091         mcreate_path2fid 0120666 0 0 link "symbolic link"
21092         mcreate_path2fid 0140666 0 0 sock "socket"
21093 }
21094 run_test 226a "call path2fid and fid2path on files of all type"
21095
21096 test_226b () {
21097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21098
21099         local MDTIDX=1
21100
21101         rm -rf $DIR/$tdir
21102         mkdir -p $DIR/$tdir
21103         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21104                 error "create remote directory failed"
21105         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21106         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21107                                 "character special file (null)"
21108         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21109                                 "character special file (no device)"
21110         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21111         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21112                                 "block special file (loop)"
21113         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21114         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21115         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21116 }
21117 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21118
21119 test_226c () {
21120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21121         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21122                 skip "Need MDS version at least 2.13.55"
21123
21124         local submnt=/mnt/submnt
21125         local srcfile=/etc/passwd
21126         local dstfile=$submnt/passwd
21127         local path
21128         local fid
21129
21130         rm -rf $DIR/$tdir
21131         rm -rf $submnt
21132         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21133                 error "create remote directory failed"
21134         mkdir -p $submnt || error "create $submnt failed"
21135         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21136                 error "mount $submnt failed"
21137         stack_trap "umount $submnt" EXIT
21138
21139         cp $srcfile $dstfile
21140         fid=$($LFS path2fid $dstfile)
21141         path=$($LFS fid2path $submnt "$fid")
21142         [ "$path" = "$dstfile" ] ||
21143                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21144 }
21145 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21146
21147 test_226d () {
21148         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21149                 skip "Need client at least version 2.15.57"
21150
21151         # Define First test dataset
21152         local testdirs_01=$DIR/$tdir
21153         local testdata_01=$testdirs_01/${tdir}_01
21154         local testresult_01=${tdir}_01
21155         # Define Second test dataset
21156         local testdirs_02=$DIR/$tdir/$tdir
21157         local testdata_02=$testdirs_02/${tdir}_02
21158         local testresult_02=${tdir}_02
21159         # Define third test dataset (top level)
21160         local testdata_03=$DIR/${tdir}_03
21161         local testresult_03=${tdir}_03
21162
21163         # Create first test dataset
21164         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21165         touch $testdata_01 || error "cannot create file $testdata_01"
21166
21167         # Create second test dataset
21168         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21169         touch $testdata_02 || error "cannot create file $testdata_02"
21170
21171         # Create third test dataset
21172         touch $testdata_03 || error "cannot create file $testdata_03"
21173
21174         local fid01=$($LFS getstripe -F "$testdata_01") ||
21175                 error "getstripe failed on $testdata_01"
21176         local fid02=$($LFS getstripe -F "$testdata_02") ||
21177                 error "getstripe failed on $testdata_01"
21178         local fid03=$($LFS getstripe -F "$testdata_03") ||
21179                 error "getstripe failed on $testdata_03"
21180
21181         # Verify only -n option
21182         local out1=$($LFS fid2path -n $DIR $fid01) ||
21183                 error "fid2path failed on $fid01"
21184         local out2=$($LFS fid2path -n $DIR $fid02) ||
21185                 error "fid2path failed on $fid02"
21186         local out3=$($LFS fid2path -n $DIR $fid03) ||
21187                 error "fid2path failed on $fid03"
21188
21189         [[ "$out1" == "$testresult_01" ]] ||
21190                 error "fid2path failed: Expected $testresult_01 got $out1"
21191         [[ "$out2" == "$testresult_02" ]] ||
21192                 error "fid2path failed: Expected $testresult_02 got $out2"
21193         [[ "$out3" == "$testresult_03" ]] ||
21194                 error "fid2path failed: Expected $testresult_03 got $out3"
21195
21196         # Verify with option -fn together
21197         out1=$($LFS fid2path -fn $DIR $fid01) ||
21198                 error "fid2path -fn failed on $fid01"
21199         out2=$($LFS fid2path -fn $DIR $fid02) ||
21200                 error "fid2path -fn failed on $fid02"
21201         out3=$($LFS fid2path -fn $DIR $fid03) ||
21202                 error "fid2path -fn failed on $fid03"
21203
21204         local tmpout=$(echo $out1 | cut -d" " -f2)
21205         [[ "$tmpout" == "$testresult_01" ]] ||
21206                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21207
21208         tmpout=$(echo $out2 | cut -d" " -f2)
21209         [[ "$tmpout" == "$testresult_02" ]] ||
21210                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21211
21212         tmpout=$(echo $out3 | cut -d" " -f2)
21213         [[ "$tmpout" == "$testresult_03" ]] ||
21214                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21215 }
21216 run_test 226d "verify fid2path with -n and -fn option"
21217
21218 test_226e () {
21219         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21220                 skip "Need client at least version 2.15.56"
21221
21222         # Define filename with 'newline' and a space
21223         local testfile="Test"$'\n'"file 01"
21224         # Define link name with multiple 'newline' and a space
21225         local linkfile="Link"$'\n'"file "$'\n'"01"
21226         # Remove prior hard link
21227         rm -f $DIR/"$linkfile"
21228
21229         # Create file
21230         touch $DIR/"$testfile"
21231         # Create link
21232         ln $DIR/"$testfile" $DIR/"$linkfile"
21233
21234         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21235                 error "getstripe failed on $DIR/$testfile"
21236
21237         # Call with -0 option
21238         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21239                 echo "FILE:" | grep -c "FILE:")
21240
21241         # With -0 option the output should be exactly 2 lines.
21242         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21243 }
21244 run_test 226e "Verify path2fid -0 option with newline and space"
21245
21246 # LU-1299 Executing or running ldd on a truncated executable does not
21247 # cause an out-of-memory condition.
21248 test_227() {
21249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21250         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21251
21252         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21253         chmod +x $MOUNT/date
21254
21255         $MOUNT/date > /dev/null
21256         ldd $MOUNT/date > /dev/null
21257         rm -f $MOUNT/date
21258 }
21259 run_test 227 "running truncated executable does not cause OOM"
21260
21261 # LU-1512 try to reuse idle OI blocks
21262 test_228a() {
21263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21264         remote_mds_nodsh && skip "remote MDS with nodsh"
21265         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21266
21267         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21268         local myDIR=$DIR/$tdir
21269
21270         mkdir -p $myDIR
21271         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21272         $LCTL set_param fail_loc=0x80001002
21273         createmany -o $myDIR/t- 10000
21274         $LCTL set_param fail_loc=0
21275         # The guard is current the largest FID holder
21276         touch $myDIR/guard
21277         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21278                     tr -d '[')
21279         local IDX=$(($SEQ % 64))
21280
21281         do_facet $SINGLEMDS sync
21282         # Make sure journal flushed.
21283         sleep 6
21284         local blk1=$(do_facet $SINGLEMDS \
21285                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21286                      grep Blockcount | awk '{print $4}')
21287
21288         # Remove old files, some OI blocks will become idle.
21289         unlinkmany $myDIR/t- 10000
21290         # Create new files, idle OI blocks should be reused.
21291         createmany -o $myDIR/t- 2000
21292         do_facet $SINGLEMDS sync
21293         # Make sure journal flushed.
21294         sleep 6
21295         local blk2=$(do_facet $SINGLEMDS \
21296                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21297                      grep Blockcount | awk '{print $4}')
21298
21299         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21300 }
21301 run_test 228a "try to reuse idle OI blocks"
21302
21303 test_228b() {
21304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21305         remote_mds_nodsh && skip "remote MDS with nodsh"
21306         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21307
21308         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21309         local myDIR=$DIR/$tdir
21310
21311         mkdir -p $myDIR
21312         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21313         $LCTL set_param fail_loc=0x80001002
21314         createmany -o $myDIR/t- 10000
21315         $LCTL set_param fail_loc=0
21316         # The guard is current the largest FID holder
21317         touch $myDIR/guard
21318         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21319                     tr -d '[')
21320         local IDX=$(($SEQ % 64))
21321
21322         do_facet $SINGLEMDS sync
21323         # Make sure journal flushed.
21324         sleep 6
21325         local blk1=$(do_facet $SINGLEMDS \
21326                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21327                      grep Blockcount | awk '{print $4}')
21328
21329         # Remove old files, some OI blocks will become idle.
21330         unlinkmany $myDIR/t- 10000
21331
21332         # stop the MDT
21333         stop $SINGLEMDS || error "Fail to stop MDT."
21334         # remount the MDT
21335         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21336                 error "Fail to start MDT."
21337
21338         client_up || error "Fail to df."
21339         # Create new files, idle OI blocks should be reused.
21340         createmany -o $myDIR/t- 2000
21341         do_facet $SINGLEMDS sync
21342         # Make sure journal flushed.
21343         sleep 6
21344         local blk2=$(do_facet $SINGLEMDS \
21345                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21346                      grep Blockcount | awk '{print $4}')
21347
21348         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21349 }
21350 run_test 228b "idle OI blocks can be reused after MDT restart"
21351
21352 #LU-1881
21353 test_228c() {
21354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21355         remote_mds_nodsh && skip "remote MDS with nodsh"
21356         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21357
21358         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21359         local myDIR=$DIR/$tdir
21360
21361         mkdir -p $myDIR
21362         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21363         $LCTL set_param fail_loc=0x80001002
21364         # 20000 files can guarantee there are index nodes in the OI file
21365         createmany -o $myDIR/t- 20000
21366         $LCTL set_param fail_loc=0
21367         # The guard is current the largest FID holder
21368         touch $myDIR/guard
21369         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21370                     tr -d '[')
21371         local IDX=$(($SEQ % 64))
21372
21373         do_facet $SINGLEMDS sync
21374         # Make sure journal flushed.
21375         sleep 6
21376         local blk1=$(do_facet $SINGLEMDS \
21377                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21378                      grep Blockcount | awk '{print $4}')
21379
21380         # Remove old files, some OI blocks will become idle.
21381         unlinkmany $myDIR/t- 20000
21382         rm -f $myDIR/guard
21383         # The OI file should become empty now
21384
21385         # Create new files, idle OI blocks should be reused.
21386         createmany -o $myDIR/t- 2000
21387         do_facet $SINGLEMDS sync
21388         # Make sure journal flushed.
21389         sleep 6
21390         local blk2=$(do_facet $SINGLEMDS \
21391                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21392                      grep Blockcount | awk '{print $4}')
21393
21394         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21395 }
21396 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21397
21398 test_229() { # LU-2482, LU-3448
21399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21400         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21401         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21402                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21403
21404         rm -f $DIR/$tfile
21405
21406         # Create a file with a released layout and stripe count 2.
21407         $MULTIOP $DIR/$tfile H2c ||
21408                 error "failed to create file with released layout"
21409
21410         $LFS getstripe -v $DIR/$tfile
21411
21412         local pattern=$($LFS getstripe -L $DIR/$tfile)
21413         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21414
21415         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21416                 error "getstripe"
21417         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21418         stat $DIR/$tfile || error "failed to stat released file"
21419
21420         chown $RUNAS_ID $DIR/$tfile ||
21421                 error "chown $RUNAS_ID $DIR/$tfile failed"
21422
21423         chgrp $RUNAS_ID $DIR/$tfile ||
21424                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21425
21426         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21427         rm $DIR/$tfile || error "failed to remove released file"
21428 }
21429 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21430
21431 test_230a() {
21432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21433         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21434         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21435                 skip "Need MDS version at least 2.11.52"
21436
21437         local MDTIDX=1
21438
21439         test_mkdir $DIR/$tdir
21440         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21441         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21442         [ $mdt_idx -ne 0 ] &&
21443                 error "create local directory on wrong MDT $mdt_idx"
21444
21445         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21446                         error "create remote directory failed"
21447         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21448         [ $mdt_idx -ne $MDTIDX ] &&
21449                 error "create remote directory on wrong MDT $mdt_idx"
21450
21451         createmany -o $DIR/$tdir/test_230/t- 10 ||
21452                 error "create files on remote directory failed"
21453         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21454         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21455         rm -r $DIR/$tdir || error "unlink remote directory failed"
21456 }
21457 run_test 230a "Create remote directory and files under the remote directory"
21458
21459 test_230b() {
21460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21462         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21463                 skip "Need MDS version at least 2.11.52"
21464
21465         local MDTIDX=1
21466         local mdt_index
21467         local i
21468         local file
21469         local pid
21470         local stripe_count
21471         local migrate_dir=$DIR/$tdir/migrate_dir
21472         local other_dir=$DIR/$tdir/other_dir
21473
21474         test_mkdir $DIR/$tdir
21475         test_mkdir -i0 -c1 $migrate_dir
21476         test_mkdir -i0 -c1 $other_dir
21477         for ((i=0; i<10; i++)); do
21478                 mkdir -p $migrate_dir/dir_${i}
21479                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21480                         error "create files under remote dir failed $i"
21481         done
21482
21483         cp /etc/passwd $migrate_dir/$tfile
21484         cp /etc/passwd $other_dir/$tfile
21485         chattr +SAD $migrate_dir
21486         chattr +SAD $migrate_dir/$tfile
21487
21488         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21489         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21490         local old_dir_mode=$(stat -c%f $migrate_dir)
21491         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21492
21493         mkdir -p $migrate_dir/dir_default_stripe2
21494         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21495         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21496
21497         mkdir -p $other_dir
21498         ln $migrate_dir/$tfile $other_dir/luna
21499         ln $migrate_dir/$tfile $migrate_dir/sofia
21500         ln $other_dir/$tfile $migrate_dir/david
21501         ln -s $migrate_dir/$tfile $other_dir/zachary
21502         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21503         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21504
21505         local len
21506         local lnktgt
21507
21508         # inline symlink
21509         for len in 58 59 60; do
21510                 lnktgt=$(str_repeat 'l' $len)
21511                 touch $migrate_dir/$lnktgt
21512                 ln -s $lnktgt $migrate_dir/${len}char_ln
21513         done
21514
21515         # PATH_MAX
21516         for len in 4094 4095; do
21517                 lnktgt=$(str_repeat 'l' $len)
21518                 ln -s $lnktgt $migrate_dir/${len}char_ln
21519         done
21520
21521         # NAME_MAX
21522         for len in 254 255; do
21523                 touch $migrate_dir/$(str_repeat 'l' $len)
21524         done
21525
21526         $LFS migrate -m $MDTIDX $migrate_dir ||
21527                 error "fails on migrating remote dir to MDT1"
21528
21529         echo "migratate to MDT1, then checking.."
21530         for ((i = 0; i < 10; i++)); do
21531                 for file in $(find $migrate_dir/dir_${i}); do
21532                         mdt_index=$($LFS getstripe -m $file)
21533                         # broken symlink getstripe will fail
21534                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21535                                 error "$file is not on MDT${MDTIDX}"
21536                 done
21537         done
21538
21539         # the multiple link file should still in MDT0
21540         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21541         [ $mdt_index == 0 ] ||
21542                 error "$file is not on MDT${MDTIDX}"
21543
21544         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21545         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21546                 error " expect $old_dir_flag get $new_dir_flag"
21547
21548         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21549         [ "$old_file_flag" = "$new_file_flag" ] ||
21550                 error " expect $old_file_flag get $new_file_flag"
21551
21552         local new_dir_mode=$(stat -c%f $migrate_dir)
21553         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21554                 error "expect mode $old_dir_mode get $new_dir_mode"
21555
21556         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21557         [ "$old_file_mode" = "$new_file_mode" ] ||
21558                 error "expect mode $old_file_mode get $new_file_mode"
21559
21560         diff /etc/passwd $migrate_dir/$tfile ||
21561                 error "$tfile different after migration"
21562
21563         diff /etc/passwd $other_dir/luna ||
21564                 error "luna different after migration"
21565
21566         diff /etc/passwd $migrate_dir/sofia ||
21567                 error "sofia different after migration"
21568
21569         diff /etc/passwd $migrate_dir/david ||
21570                 error "david different after migration"
21571
21572         diff /etc/passwd $other_dir/zachary ||
21573                 error "zachary different after migration"
21574
21575         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21576                 error "${tfile}_ln different after migration"
21577
21578         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21579                 error "${tfile}_ln_other different after migration"
21580
21581         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21582         [ $stripe_count = 2 ] ||
21583                 error "dir strpe_count $d != 2 after migration."
21584
21585         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21586         [ $stripe_count = 2 ] ||
21587                 error "file strpe_count $d != 2 after migration."
21588
21589         #migrate back to MDT0
21590         MDTIDX=0
21591
21592         $LFS migrate -m $MDTIDX $migrate_dir ||
21593                 error "fails on migrating remote dir to MDT0"
21594
21595         echo "migrate back to MDT0, checking.."
21596         for file in $(find $migrate_dir); do
21597                 mdt_index=$($LFS getstripe -m $file)
21598                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21599                         error "$file is not on MDT${MDTIDX}"
21600         done
21601
21602         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21603         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21604                 error " expect $old_dir_flag get $new_dir_flag"
21605
21606         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21607         [ "$old_file_flag" = "$new_file_flag" ] ||
21608                 error " expect $old_file_flag get $new_file_flag"
21609
21610         local new_dir_mode=$(stat -c%f $migrate_dir)
21611         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21612                 error "expect mode $old_dir_mode get $new_dir_mode"
21613
21614         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21615         [ "$old_file_mode" = "$new_file_mode" ] ||
21616                 error "expect mode $old_file_mode get $new_file_mode"
21617
21618         diff /etc/passwd ${migrate_dir}/$tfile ||
21619                 error "$tfile different after migration"
21620
21621         diff /etc/passwd ${other_dir}/luna ||
21622                 error "luna different after migration"
21623
21624         diff /etc/passwd ${migrate_dir}/sofia ||
21625                 error "sofia different after migration"
21626
21627         diff /etc/passwd ${other_dir}/zachary ||
21628                 error "zachary different after migration"
21629
21630         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21631                 error "${tfile}_ln different after migration"
21632
21633         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21634                 error "${tfile}_ln_other different after migration"
21635
21636         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21637         [ $stripe_count = 2 ] ||
21638                 error "dir strpe_count $d != 2 after migration."
21639
21640         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21641         [ $stripe_count = 2 ] ||
21642                 error "file strpe_count $d != 2 after migration."
21643
21644         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21645 }
21646 run_test 230b "migrate directory"
21647
21648 test_230c() {
21649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21650         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21651         remote_mds_nodsh && skip "remote MDS with nodsh"
21652         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21653                 skip "Need MDS version at least 2.11.52"
21654
21655         local MDTIDX=1
21656         local total=3
21657         local mdt_index
21658         local file
21659         local migrate_dir=$DIR/$tdir/migrate_dir
21660
21661         #If migrating directory fails in the middle, all entries of
21662         #the directory is still accessiable.
21663         test_mkdir $DIR/$tdir
21664         test_mkdir -i0 -c1 $migrate_dir
21665         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21666         stat $migrate_dir
21667         createmany -o $migrate_dir/f $total ||
21668                 error "create files under ${migrate_dir} failed"
21669
21670         # fail after migrating top dir, and this will fail only once, so the
21671         # first sub file migration will fail (currently f3), others succeed.
21672         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21673         do_facet mds1 lctl set_param fail_loc=0x1801
21674         local t=$(ls $migrate_dir | wc -l)
21675         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21676                 error "migrate should fail"
21677         local u=$(ls $migrate_dir | wc -l)
21678         [ "$u" == "$t" ] || error "$u != $t during migration"
21679
21680         # add new dir/file should succeed
21681         mkdir $migrate_dir/dir ||
21682                 error "mkdir failed under migrating directory"
21683         touch $migrate_dir/file ||
21684                 error "create file failed under migrating directory"
21685
21686         # add file with existing name should fail
21687         for file in $migrate_dir/f*; do
21688                 stat $file > /dev/null || error "stat $file failed"
21689                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21690                         error "open(O_CREAT|O_EXCL) $file should fail"
21691                 $MULTIOP $file m && error "create $file should fail"
21692                 touch $DIR/$tdir/remote_dir/$tfile ||
21693                         error "touch $tfile failed"
21694                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21695                         error "link $file should fail"
21696                 mdt_index=$($LFS getstripe -m $file)
21697                 if [ $mdt_index == 0 ]; then
21698                         # file failed to migrate is not allowed to rename to
21699                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21700                                 error "rename to $file should fail"
21701                 else
21702                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21703                                 error "rename to $file failed"
21704                 fi
21705                 echo hello >> $file || error "write $file failed"
21706         done
21707
21708         # resume migration with different options should fail
21709         $LFS migrate -m 0 $migrate_dir &&
21710                 error "migrate -m 0 $migrate_dir should fail"
21711
21712         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21713                 error "migrate -c 2 $migrate_dir should fail"
21714
21715         # resume migration should succeed
21716         $LFS migrate -m $MDTIDX $migrate_dir ||
21717                 error "migrate $migrate_dir failed"
21718
21719         echo "Finish migration, then checking.."
21720         for file in $(find $migrate_dir); do
21721                 mdt_index=$($LFS getstripe -m $file)
21722                 [ $mdt_index == $MDTIDX ] ||
21723                         error "$file is not on MDT${MDTIDX}"
21724         done
21725
21726         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21727 }
21728 run_test 230c "check directory accessiblity if migration failed"
21729
21730 test_230d() {
21731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21732         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21733         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21734                 skip "Need MDS version at least 2.11.52"
21735         # LU-11235
21736         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21737
21738         local migrate_dir=$DIR/$tdir/migrate_dir
21739         local old_index
21740         local new_index
21741         local old_count
21742         local new_count
21743         local new_hash
21744         local mdt_index
21745         local i
21746         local j
21747
21748         old_index=$((RANDOM % MDSCOUNT))
21749         old_count=$((MDSCOUNT - old_index))
21750         new_index=$((RANDOM % MDSCOUNT))
21751         new_count=$((MDSCOUNT - new_index))
21752         new_hash=1 # for all_char
21753
21754         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21755         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21756
21757         test_mkdir $DIR/$tdir
21758         test_mkdir -i $old_index -c $old_count $migrate_dir
21759
21760         for ((i=0; i<100; i++)); do
21761                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21762                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21763                         error "create files under remote dir failed $i"
21764         done
21765
21766         echo -n "Migrate from MDT$old_index "
21767         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21768         echo -n "to MDT$new_index"
21769         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21770         echo
21771
21772         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21773         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21774                 error "migrate remote dir error"
21775
21776         echo "Finish migration, then checking.."
21777         for file in $(find $migrate_dir -maxdepth 1); do
21778                 mdt_index=$($LFS getstripe -m $file)
21779                 if [ $mdt_index -lt $new_index ] ||
21780                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21781                         error "$file is on MDT$mdt_index"
21782                 fi
21783         done
21784
21785         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21786 }
21787 run_test 230d "check migrate big directory"
21788
21789 test_230e() {
21790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21792         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21793                 skip "Need MDS version at least 2.11.52"
21794
21795         local i
21796         local j
21797         local a_fid
21798         local b_fid
21799
21800         mkdir_on_mdt0 $DIR/$tdir
21801         mkdir $DIR/$tdir/migrate_dir
21802         mkdir $DIR/$tdir/other_dir
21803         touch $DIR/$tdir/migrate_dir/a
21804         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21805         ls $DIR/$tdir/other_dir
21806
21807         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21808                 error "migrate dir fails"
21809
21810         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21811         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21812
21813         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21814         [ $mdt_index == 0 ] || error "a is not on MDT0"
21815
21816         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21817                 error "migrate dir fails"
21818
21819         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21820         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21821
21822         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21823         [ $mdt_index == 1 ] || error "a is not on MDT1"
21824
21825         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21826         [ $mdt_index == 1 ] || error "b is not on MDT1"
21827
21828         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21829         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21830
21831         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21832
21833         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21834 }
21835 run_test 230e "migrate mulitple local link files"
21836
21837 test_230f() {
21838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21840         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21841                 skip "Need MDS version at least 2.11.52"
21842
21843         local a_fid
21844         local ln_fid
21845
21846         mkdir -p $DIR/$tdir
21847         mkdir $DIR/$tdir/migrate_dir
21848         $LFS mkdir -i1 $DIR/$tdir/other_dir
21849         touch $DIR/$tdir/migrate_dir/a
21850         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21851         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21852         ls $DIR/$tdir/other_dir
21853
21854         # a should be migrated to MDT1, since no other links on MDT0
21855         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21856                 error "#1 migrate dir fails"
21857         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21858         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21859         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21860         [ $mdt_index == 1 ] || error "a is not on MDT1"
21861
21862         # a should stay on MDT1, because it is a mulitple link file
21863         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21864                 error "#2 migrate dir fails"
21865         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21866         [ $mdt_index == 1 ] || error "a is not on MDT1"
21867
21868         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21869                 error "#3 migrate dir fails"
21870
21871         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21872         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21873         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21874
21875         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21876         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21877
21878         # a should be migrated to MDT0, since no other links on MDT1
21879         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21880                 error "#4 migrate dir fails"
21881         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21882         [ $mdt_index == 0 ] || error "a is not on MDT0"
21883
21884         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21885 }
21886 run_test 230f "migrate mulitple remote link files"
21887
21888 test_230g() {
21889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21891         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21892                 skip "Need MDS version at least 2.11.52"
21893
21894         mkdir -p $DIR/$tdir/migrate_dir
21895
21896         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21897                 error "migrating dir to non-exist MDT succeeds"
21898         true
21899 }
21900 run_test 230g "migrate dir to non-exist MDT"
21901
21902 test_230h() {
21903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21904         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21905         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21906                 skip "Need MDS version at least 2.11.52"
21907
21908         local mdt_index
21909
21910         mkdir -p $DIR/$tdir/migrate_dir
21911
21912         $LFS migrate -m1 $DIR &&
21913                 error "migrating mountpoint1 should fail"
21914
21915         $LFS migrate -m1 $DIR/$tdir/.. &&
21916                 error "migrating mountpoint2 should fail"
21917
21918         # same as mv
21919         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21920                 error "migrating $tdir/migrate_dir/.. should fail"
21921
21922         true
21923 }
21924 run_test 230h "migrate .. and root"
21925
21926 test_230i() {
21927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21929         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21930                 skip "Need MDS version at least 2.11.52"
21931
21932         mkdir -p $DIR/$tdir/migrate_dir
21933
21934         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21935                 error "migration fails with a tailing slash"
21936
21937         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21938                 error "migration fails with two tailing slashes"
21939 }
21940 run_test 230i "lfs migrate -m tolerates trailing slashes"
21941
21942 test_230j() {
21943         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21944         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21945                 skip "Need MDS version at least 2.11.52"
21946
21947         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21948         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21949                 error "create $tfile failed"
21950         cat /etc/passwd > $DIR/$tdir/$tfile
21951
21952         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21953
21954         cmp /etc/passwd $DIR/$tdir/$tfile ||
21955                 error "DoM file mismatch after migration"
21956 }
21957 run_test 230j "DoM file data not changed after dir migration"
21958
21959 test_230k() {
21960         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21961         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21962                 skip "Need MDS version at least 2.11.56"
21963
21964         local total=20
21965         local files_on_starting_mdt=0
21966
21967         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21968         $LFS getdirstripe $DIR/$tdir
21969         for i in $(seq $total); do
21970                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21971                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21972                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21973         done
21974
21975         echo "$files_on_starting_mdt files on MDT0"
21976
21977         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21978         $LFS getdirstripe $DIR/$tdir
21979
21980         files_on_starting_mdt=0
21981         for i in $(seq $total); do
21982                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21983                         error "file $tfile.$i mismatch after migration"
21984                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21985                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21986         done
21987
21988         echo "$files_on_starting_mdt files on MDT1 after migration"
21989         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21990
21991         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21992         $LFS getdirstripe $DIR/$tdir
21993
21994         files_on_starting_mdt=0
21995         for i in $(seq $total); do
21996                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21997                         error "file $tfile.$i mismatch after 2nd migration"
21998                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21999                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22000         done
22001
22002         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22003         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22004
22005         true
22006 }
22007 run_test 230k "file data not changed after dir migration"
22008
22009 test_230l() {
22010         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22011         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22012                 skip "Need MDS version at least 2.11.56"
22013
22014         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22015         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22016                 error "create files under remote dir failed $i"
22017         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22018 }
22019 run_test 230l "readdir between MDTs won't crash"
22020
22021 test_230m() {
22022         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22023         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22024                 skip "Need MDS version at least 2.11.56"
22025
22026         local MDTIDX=1
22027         local mig_dir=$DIR/$tdir/migrate_dir
22028         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22029         local shortstr="b"
22030         local val
22031
22032         echo "Creating files and dirs with xattrs"
22033         test_mkdir $DIR/$tdir
22034         test_mkdir -i0 -c1 $mig_dir
22035         mkdir $mig_dir/dir
22036         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22037                 error "cannot set xattr attr1 on dir"
22038         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22039                 error "cannot set xattr attr2 on dir"
22040         touch $mig_dir/dir/f0
22041         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22042                 error "cannot set xattr attr1 on file"
22043         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22044                 error "cannot set xattr attr2 on file"
22045         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22046         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22047         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22048         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22049         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22050         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22051         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22052         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22053         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22054
22055         echo "Migrating to MDT1"
22056         $LFS migrate -m $MDTIDX $mig_dir ||
22057                 error "fails on migrating dir to MDT1"
22058
22059         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22060         echo "Checking xattrs"
22061         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22062         [ "$val" = $longstr ] ||
22063                 error "expecting xattr1 $longstr on dir, found $val"
22064         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22065         [ "$val" = $shortstr ] ||
22066                 error "expecting xattr2 $shortstr on dir, found $val"
22067         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22068         [ "$val" = $longstr ] ||
22069                 error "expecting xattr1 $longstr on file, found $val"
22070         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22071         [ "$val" = $shortstr ] ||
22072                 error "expecting xattr2 $shortstr on file, found $val"
22073 }
22074 run_test 230m "xattrs not changed after dir migration"
22075
22076 test_230n() {
22077         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22078         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22079                 skip "Need MDS version at least 2.13.53"
22080
22081         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22082         cat /etc/hosts > $DIR/$tdir/$tfile
22083         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22084         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22085
22086         cmp /etc/hosts $DIR/$tdir/$tfile ||
22087                 error "File data mismatch after migration"
22088 }
22089 run_test 230n "Dir migration with mirrored file"
22090
22091 test_230o() {
22092         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22093         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22094                 skip "Need MDS version at least 2.13.52"
22095
22096         local mdts=$(comma_list $(mdts_nodes))
22097         local timeout=100
22098         local restripe_status
22099         local delta
22100         local i
22101
22102         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22103
22104         # in case "crush" hash type is not set
22105         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22106
22107         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22108                            mdt.*MDT0000.enable_dir_restripe)
22109         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22110         stack_trap "do_nodes $mdts $LCTL set_param \
22111                     mdt.*.enable_dir_restripe=$restripe_status"
22112
22113         mkdir $DIR/$tdir
22114         createmany -m $DIR/$tdir/f 100 ||
22115                 error "create files under remote dir failed $i"
22116         createmany -d $DIR/$tdir/d 100 ||
22117                 error "create dirs under remote dir failed $i"
22118
22119         for i in $(seq 2 $MDSCOUNT); do
22120                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22121                 $LFS setdirstripe -c $i $DIR/$tdir ||
22122                         error "split -c $i $tdir failed"
22123                 wait_update $HOSTNAME \
22124                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22125                         error "dir split not finished"
22126                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22127                         awk '/migrate/ {sum += $2} END { print sum }')
22128                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22129                 # delta is around total_files/stripe_count
22130                 (( $delta < 200 / (i - 1) + 4 )) ||
22131                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22132         done
22133 }
22134 run_test 230o "dir split"
22135
22136 test_230p() {
22137         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22138         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22139                 skip "Need MDS version at least 2.13.52"
22140
22141         local mdts=$(comma_list $(mdts_nodes))
22142         local timeout=100
22143         local restripe_status
22144         local delta
22145         local c
22146
22147         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22148
22149         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22150
22151         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22152                            mdt.*MDT0000.enable_dir_restripe)
22153         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22154         stack_trap "do_nodes $mdts $LCTL set_param \
22155                     mdt.*.enable_dir_restripe=$restripe_status"
22156
22157         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22158         createmany -m $DIR/$tdir/f 100 ||
22159                 error "create files under remote dir failed"
22160         createmany -d $DIR/$tdir/d 100 ||
22161                 error "create dirs under remote dir failed"
22162
22163         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22164                 local mdt_hash="crush"
22165
22166                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22167                 $LFS setdirstripe -c $c $DIR/$tdir ||
22168                         error "split -c $c $tdir failed"
22169                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22170                         mdt_hash="$mdt_hash,fixed"
22171                 elif [ $c -eq 1 ]; then
22172                         mdt_hash="none"
22173                 fi
22174                 wait_update $HOSTNAME \
22175                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22176                         error "dir merge not finished"
22177                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22178                         awk '/migrate/ {sum += $2} END { print sum }')
22179                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22180                 # delta is around total_files/stripe_count
22181                 (( delta < 200 / c + 4 )) ||
22182                         error "$delta files migrated >= $((200 / c + 4))"
22183         done
22184 }
22185 run_test 230p "dir merge"
22186
22187 test_230q() {
22188         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22189         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22190                 skip "Need MDS version at least 2.13.52"
22191
22192         local mdts=$(comma_list $(mdts_nodes))
22193         local saved_threshold=$(do_facet mds1 \
22194                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22195         local saved_delta=$(do_facet mds1 \
22196                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22197         local threshold=100
22198         local delta=2
22199         local total=0
22200         local stripe_count=0
22201         local stripe_index
22202         local nr_files
22203         local create
22204
22205         # test with fewer files on ZFS
22206         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22207
22208         stack_trap "do_nodes $mdts $LCTL set_param \
22209                     mdt.*.dir_split_count=$saved_threshold"
22210         stack_trap "do_nodes $mdts $LCTL set_param \
22211                     mdt.*.dir_split_delta=$saved_delta"
22212         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22213         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22214         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22215         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22216         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22217         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22218
22219         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22220         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22221
22222         create=$((threshold * 3 / 2))
22223         while [ $stripe_count -lt $MDSCOUNT ]; do
22224                 createmany -m $DIR/$tdir/f $total $create ||
22225                         error "create sub files failed"
22226                 stat $DIR/$tdir > /dev/null
22227                 total=$((total + create))
22228                 stripe_count=$((stripe_count + delta))
22229                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22230
22231                 wait_update $HOSTNAME \
22232                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22233                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22234
22235                 wait_update $HOSTNAME \
22236                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22237                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22238
22239                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22240                 echo "$nr_files/$total files on MDT$stripe_index after split"
22241                 # allow 10% margin of imbalance with crush hash
22242                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22243                         error "$nr_files files on MDT$stripe_index after split"
22244
22245                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22246                 [ $nr_files -eq $total ] ||
22247                         error "total sub files $nr_files != $total"
22248         done
22249
22250         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22251
22252         echo "fixed layout directory won't auto split"
22253         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22254         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22255                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22256         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22257                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22258 }
22259 run_test 230q "dir auto split"
22260
22261 test_230r() {
22262         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22263         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22264         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22265                 skip "Need MDS version at least 2.13.54"
22266
22267         # maximum amount of local locks:
22268         # parent striped dir - 2 locks
22269         # new stripe in parent to migrate to - 1 lock
22270         # source and target - 2 locks
22271         # Total 5 locks for regular file
22272         mkdir -p $DIR/$tdir
22273         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22274         touch $DIR/$tdir/dir1/eee
22275
22276         # create 4 hardlink for 4 more locks
22277         # Total: 9 locks > RS_MAX_LOCKS (8)
22278         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22279         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22280         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22281         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22282         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22283         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22284         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22285         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22286
22287         cancel_lru_locks mdc
22288
22289         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22290                 error "migrate dir fails"
22291
22292         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22293 }
22294 run_test 230r "migrate with too many local locks"
22295
22296 test_230s() {
22297         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22298                 skip "Need MDS version at least 2.14.52"
22299
22300         local mdts=$(comma_list $(mdts_nodes))
22301         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22302                                 mdt.*MDT0000.enable_dir_restripe)
22303
22304         stack_trap "do_nodes $mdts $LCTL set_param \
22305                     mdt.*.enable_dir_restripe=$restripe_status"
22306
22307         local st
22308         for st in 0 1; do
22309                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22310                 test_mkdir $DIR/$tdir
22311                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22312                         error "$LFS mkdir should return EEXIST if target exists"
22313                 rmdir $DIR/$tdir
22314         done
22315 }
22316 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22317
22318 test_230t()
22319 {
22320         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22321         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22322                 skip "Need MDS version at least 2.14.50"
22323
22324         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22325         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22326         $LFS project -p 1 -s $DIR/$tdir ||
22327                 error "set $tdir project id failed"
22328         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22329                 error "set subdir project id failed"
22330         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22331 }
22332 run_test 230t "migrate directory with project ID set"
22333
22334 test_230u()
22335 {
22336         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22337         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22338                 skip "Need MDS version at least 2.14.53"
22339
22340         local count
22341
22342         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22343         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22344         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22345         for i in $(seq 0 $((MDSCOUNT - 1))); do
22346                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22347                 echo "$count dirs migrated to MDT$i"
22348         done
22349         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22350         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22351 }
22352 run_test 230u "migrate directory by QOS"
22353
22354 test_230v()
22355 {
22356         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22357         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22358                 skip "Need MDS version at least 2.14.53"
22359
22360         local count
22361
22362         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22363         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22364         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22365         for i in $(seq 0 $((MDSCOUNT - 1))); do
22366                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22367                 echo "$count subdirs migrated to MDT$i"
22368                 (( i == 3 )) && (( count > 0 )) &&
22369                         error "subdir shouldn't be migrated to MDT3"
22370         done
22371         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22372         (( count == 3 )) || error "dirs migrated to $count MDTs"
22373 }
22374 run_test 230v "subdir migrated to the MDT where its parent is located"
22375
22376 test_230w() {
22377         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22378         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22379                 skip "Need MDS version at least 2.15.0"
22380
22381         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22382         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22383         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22384
22385         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22386                 error "migrate failed"
22387
22388         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22389                 error "$tdir stripe count mismatch"
22390
22391         for i in $(seq 0 9); do
22392                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22393                         error "d$i is striped"
22394         done
22395 }
22396 run_test 230w "non-recursive mode dir migration"
22397
22398 test_230x() {
22399         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22400         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22401                 skip "Need MDS version at least 2.15.0"
22402
22403         mkdir -p $DIR/$tdir || error "mkdir failed"
22404         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22405
22406         local mdt_name=$(mdtname_from_index 0)
22407         local low=$(do_facet mds2 $LCTL get_param -n \
22408                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22409         local high=$(do_facet mds2 $LCTL get_param -n \
22410                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22411         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22412         local maxage=$(do_facet mds2 $LCTL get_param -n \
22413                 osp.*$mdt_name-osp-MDT0001.maxage)
22414
22415         stack_trap "do_facet mds2 $LCTL set_param -n \
22416                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22417                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22418         stack_trap "do_facet mds2 $LCTL set_param -n \
22419                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22420
22421         do_facet mds2 $LCTL set_param -n \
22422                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22423         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22424         sleep 4
22425         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22426                 error "migrate $tdir should fail"
22427
22428         do_facet mds2 $LCTL set_param -n \
22429                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22430         do_facet mds2 $LCTL set_param -n \
22431                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22432         sleep 4
22433         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22434                 error "migrate failed"
22435         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22436                 error "$tdir stripe count mismatch"
22437 }
22438 run_test 230x "dir migration check space"
22439
22440 test_230y() {
22441         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22442         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22443                 skip "Need MDS version at least 2.15.55.45"
22444
22445         local pid
22446
22447         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22448         $LFS getdirstripe $DIR/$tdir
22449         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22450         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22451         pid=$!
22452         sleep 1
22453
22454         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22455         do_facet mds2 lctl set_param fail_loc=0x1802
22456
22457         wait $pid
22458         do_facet mds2 lctl set_param fail_loc=0
22459         $LFS getdirstripe $DIR/$tdir
22460         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22461         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22462 }
22463 run_test 230y "unlink dir with bad hash type"
22464
22465 test_230z() {
22466         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22467         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22468                 skip "Need MDS version at least 2.15.55.45"
22469
22470         local pid
22471
22472         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22473         $LFS getdirstripe $DIR/$tdir
22474         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22475         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22476         pid=$!
22477         sleep 1
22478
22479         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22480         do_facet mds2 lctl set_param fail_loc=0x1802
22481
22482         wait $pid
22483         do_facet mds2 lctl set_param fail_loc=0
22484         $LFS getdirstripe $DIR/$tdir
22485
22486         # resume migration
22487         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22488                 error "resume migration failed"
22489         $LFS getdirstripe $DIR/$tdir
22490         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22491                 error "migration is not finished"
22492 }
22493 run_test 230z "resume dir migration with bad hash type"
22494
22495 test_231a()
22496 {
22497         # For simplicity this test assumes that max_pages_per_rpc
22498         # is the same across all OSCs
22499         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22500         local bulk_size=$((max_pages * PAGE_SIZE))
22501         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22502                                        head -n 1)
22503
22504         mkdir -p $DIR/$tdir
22505         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22506                 error "failed to set stripe with -S ${brw_size}M option"
22507         stack_trap "rm -rf $DIR/$tdir"
22508
22509         # clear the OSC stats
22510         $LCTL set_param osc.*.stats=0 &>/dev/null
22511         stop_writeback
22512
22513         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22515                 oflag=direct &>/dev/null || error "dd failed"
22516
22517         sync; sleep 1; sync # just to be safe
22518         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22519         if [ x$nrpcs != "x1" ]; then
22520                 $LCTL get_param osc.*.stats
22521                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22522         fi
22523
22524         start_writeback
22525         # Drop the OSC cache, otherwise we will read from it
22526         cancel_lru_locks osc
22527
22528         # clear the OSC stats
22529         $LCTL set_param osc.*.stats=0 &>/dev/null
22530
22531         # Client reads $bulk_size.
22532         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22533                 iflag=direct &>/dev/null || error "dd failed"
22534
22535         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22536         if [ x$nrpcs != "x1" ]; then
22537                 $LCTL get_param osc.*.stats
22538                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22539         fi
22540 }
22541 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22542
22543 test_231b() {
22544         mkdir -p $DIR/$tdir
22545         stack_trap "rm -rf $DIR/$tdir"
22546         local i
22547         for i in {0..1023}; do
22548                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22549                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22550                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22551         done
22552         sync
22553 }
22554 run_test 231b "must not assert on fully utilized OST request buffer"
22555
22556 test_232a() {
22557         mkdir -p $DIR/$tdir
22558         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22559
22560         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22561         do_facet ost1 $LCTL set_param fail_loc=0x31c
22562
22563         # ignore dd failure
22564         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22565         stack_trap "rm -f $DIR/$tdir/$tfile"
22566
22567         do_facet ost1 $LCTL set_param fail_loc=0
22568         umount_client $MOUNT || error "umount failed"
22569         mount_client $MOUNT || error "mount failed"
22570         stop ost1 || error "cannot stop ost1"
22571         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22572 }
22573 run_test 232a "failed lock should not block umount"
22574
22575 test_232b() {
22576         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22577                 skip "Need MDS version at least 2.10.58"
22578
22579         mkdir -p $DIR/$tdir
22580         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22582         stack_trap "rm -f $DIR/$tdir/$tfile"
22583         sync
22584         cancel_lru_locks osc
22585
22586         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22587         do_facet ost1 $LCTL set_param fail_loc=0x31c
22588
22589         # ignore failure
22590         $LFS data_version $DIR/$tdir/$tfile || true
22591
22592         do_facet ost1 $LCTL set_param fail_loc=0
22593         umount_client $MOUNT || error "umount failed"
22594         mount_client $MOUNT || error "mount failed"
22595         stop ost1 || error "cannot stop ost1"
22596         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22597 }
22598 run_test 232b "failed data version lock should not block umount"
22599
22600 test_233a() {
22601         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22602                 skip "Need MDS version at least 2.3.64"
22603         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22604
22605         local fid=$($LFS path2fid $MOUNT)
22606
22607         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22608                 error "cannot access $MOUNT using its FID '$fid'"
22609 }
22610 run_test 233a "checking that OBF of the FS root succeeds"
22611
22612 test_233b() {
22613         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22614                 skip "Need MDS version at least 2.5.90"
22615         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22616
22617         local fid=$($LFS path2fid $MOUNT/.lustre)
22618
22619         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22620                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22621
22622         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22623         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22624                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22625 }
22626 run_test 233b "checking that OBF of the FS .lustre succeeds"
22627
22628 test_234() {
22629         local p="$TMP/sanityN-$TESTNAME.parameters"
22630         save_lustre_params client "llite.*.xattr_cache" > $p
22631         lctl set_param llite.*.xattr_cache 1 ||
22632                 skip_env "xattr cache is not supported"
22633
22634         mkdir -p $DIR/$tdir || error "mkdir failed"
22635         touch $DIR/$tdir/$tfile || error "touch failed"
22636         # OBD_FAIL_LLITE_XATTR_ENOMEM
22637         $LCTL set_param fail_loc=0x1405
22638         getfattr -n user.attr $DIR/$tdir/$tfile &&
22639                 error "getfattr should have failed with ENOMEM"
22640         $LCTL set_param fail_loc=0x0
22641         rm -rf $DIR/$tdir
22642
22643         restore_lustre_params < $p
22644         rm -f $p
22645 }
22646 run_test 234 "xattr cache should not crash on ENOMEM"
22647
22648 test_235() {
22649         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22650                 skip "Need MDS version at least 2.4.52"
22651
22652         flock_deadlock $DIR/$tfile
22653         local RC=$?
22654         case $RC in
22655                 0)
22656                 ;;
22657                 124) error "process hangs on a deadlock"
22658                 ;;
22659                 *) error "error executing flock_deadlock $DIR/$tfile"
22660                 ;;
22661         esac
22662 }
22663 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22664
22665 #LU-2935
22666 test_236() {
22667         check_swap_layouts_support
22668
22669         local ref1=/etc/passwd
22670         local ref2=/etc/group
22671         local file1=$DIR/$tdir/f1
22672         local file2=$DIR/$tdir/f2
22673
22674         test_mkdir -c1 $DIR/$tdir
22675         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22676         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22677         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22678         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22679         local fd=$(free_fd)
22680         local cmd="exec $fd<>$file2"
22681         eval $cmd
22682         rm $file2
22683         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22684                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22685         cmd="exec $fd>&-"
22686         eval $cmd
22687         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22688
22689         #cleanup
22690         rm -rf $DIR/$tdir
22691 }
22692 run_test 236 "Layout swap on open unlinked file"
22693
22694 # LU-4659 linkea consistency
22695 test_238() {
22696         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22697                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22698                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22699                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22700
22701         touch $DIR/$tfile
22702         ln $DIR/$tfile $DIR/$tfile.lnk
22703         touch $DIR/$tfile.new
22704         mv $DIR/$tfile.new $DIR/$tfile
22705         local fid1=$($LFS path2fid $DIR/$tfile)
22706         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22707         local path1=$($LFS fid2path $FSNAME "$fid1")
22708         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22709         local path2=$($LFS fid2path $FSNAME "$fid2")
22710         [ $tfile.lnk == $path2 ] ||
22711                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22712         rm -f $DIR/$tfile*
22713 }
22714 run_test 238 "Verify linkea consistency"
22715
22716 test_239A() { # was test_239
22717         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22718                 skip "Need MDS version at least 2.5.60"
22719
22720         local list=$(comma_list $(mdts_nodes))
22721
22722         mkdir -p $DIR/$tdir
22723         createmany -o $DIR/$tdir/f- 5000
22724         unlinkmany $DIR/$tdir/f- 5000
22725         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22726                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22727         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22728                         osp.*MDT*.sync_in_flight" | calc_sum)
22729         [ "$changes" -eq 0 ] || error "$changes not synced"
22730 }
22731 run_test 239A "osp_sync test"
22732
22733 test_239a() { #LU-5297
22734         remote_mds_nodsh && skip "remote MDS with nodsh"
22735
22736         touch $DIR/$tfile
22737         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22738         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22739         chgrp $RUNAS_GID $DIR/$tfile
22740         wait_delete_completed
22741 }
22742 run_test 239a "process invalid osp sync record correctly"
22743
22744 test_239b() { #LU-5297
22745         remote_mds_nodsh && skip "remote MDS with nodsh"
22746
22747         touch $DIR/$tfile1
22748         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22749         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22750         chgrp $RUNAS_GID $DIR/$tfile1
22751         wait_delete_completed
22752         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22753         touch $DIR/$tfile2
22754         chgrp $RUNAS_GID $DIR/$tfile2
22755         wait_delete_completed
22756 }
22757 run_test 239b "process osp sync record with ENOMEM error correctly"
22758
22759 test_240() {
22760         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22761         remote_mds_nodsh && skip "remote MDS with nodsh"
22762
22763         mkdir -p $DIR/$tdir
22764
22765         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22766                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22767         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22768                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22769
22770         umount_client $MOUNT || error "umount failed"
22771         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22772         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22773         mount_client $MOUNT || error "failed to mount client"
22774
22775         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22776         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22777 }
22778 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22779
22780 test_241_bio() {
22781         local count=$1
22782         local bsize=$2
22783
22784         for LOOP in $(seq $count); do
22785                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22786                 cancel_lru_locks $OSC || true
22787         done
22788 }
22789
22790 test_241_dio() {
22791         local count=$1
22792         local bsize=$2
22793
22794         for LOOP in $(seq $1); do
22795                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22796                         2>/dev/null
22797         done
22798 }
22799
22800 test_241a() { # was test_241
22801         local bsize=$PAGE_SIZE
22802
22803         (( bsize < 40960 )) && bsize=40960
22804         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22805         ls -la $DIR/$tfile
22806         cancel_lru_locks $OSC
22807         test_241_bio 1000 $bsize &
22808         PID=$!
22809         test_241_dio 1000 $bsize
22810         wait $PID
22811 }
22812 run_test 241a "bio vs dio"
22813
22814 test_241b() {
22815         local bsize=$PAGE_SIZE
22816
22817         (( bsize < 40960 )) && bsize=40960
22818         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22819         ls -la $DIR/$tfile
22820         test_241_dio 1000 $bsize &
22821         PID=$!
22822         test_241_dio 1000 $bsize
22823         wait $PID
22824 }
22825 run_test 241b "dio vs dio"
22826
22827 test_242() {
22828         remote_mds_nodsh && skip "remote MDS with nodsh"
22829
22830         mkdir_on_mdt0 $DIR/$tdir
22831         touch $DIR/$tdir/$tfile
22832
22833         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22834         do_facet mds1 lctl set_param fail_loc=0x105
22835         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22836
22837         do_facet mds1 lctl set_param fail_loc=0
22838         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22839 }
22840 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22841
22842 test_243()
22843 {
22844         test_mkdir $DIR/$tdir
22845         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22846 }
22847 run_test 243 "various group lock tests"
22848
22849 test_244a()
22850 {
22851         test_mkdir $DIR/$tdir
22852         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22853         sendfile_grouplock $DIR/$tdir/$tfile || \
22854                 error "sendfile+grouplock failed"
22855         rm -rf $DIR/$tdir
22856 }
22857 run_test 244a "sendfile with group lock tests"
22858
22859 test_244b()
22860 {
22861         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22862
22863         local threads=50
22864         local size=$((1024*1024))
22865
22866         test_mkdir $DIR/$tdir
22867         for i in $(seq 1 $threads); do
22868                 local file=$DIR/$tdir/file_$((i / 10))
22869                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22870                 local pids[$i]=$!
22871         done
22872         for i in $(seq 1 $threads); do
22873                 wait ${pids[$i]}
22874         done
22875 }
22876 run_test 244b "multi-threaded write with group lock"
22877
22878 test_245a() {
22879         local flagname="multi_mod_rpcs"
22880         local connect_data_name="max_mod_rpcs"
22881         local out
22882
22883         # check if multiple modify RPCs flag is set
22884         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22885                 grep "connect_flags:")
22886         echo "$out"
22887
22888         echo "$out" | grep -qw $flagname
22889         if [ $? -ne 0 ]; then
22890                 echo "connect flag $flagname is not set"
22891                 return
22892         fi
22893
22894         # check if multiple modify RPCs data is set
22895         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22896         echo "$out"
22897
22898         echo "$out" | grep -qw $connect_data_name ||
22899                 error "import should have connect data $connect_data_name"
22900 }
22901 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22902
22903 test_245b() {
22904         local flagname="multi_mod_rpcs"
22905         local connect_data_name="max_mod_rpcs"
22906         local out
22907
22908         remote_mds_nodsh && skip "remote MDS with nodsh"
22909         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22910
22911         # check if multiple modify RPCs flag is set
22912         out=$(do_facet mds1 \
22913               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22914               grep "connect_flags:")
22915         echo "$out"
22916
22917         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22918
22919         # check if multiple modify RPCs data is set
22920         out=$(do_facet mds1 \
22921               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22922
22923         [[ "$out" =~ $connect_data_name ]] ||
22924                 {
22925                         echo "$out"
22926                         error "missing connect data $connect_data_name"
22927                 }
22928 }
22929 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22930
22931 cleanup_247() {
22932         local submount=$1
22933
22934         trap 0
22935         umount_client $submount
22936         rmdir $submount
22937 }
22938
22939 test_247a() {
22940         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22941                 grep -q subtree ||
22942                 skip_env "Fileset feature is not supported"
22943
22944         local submount=${MOUNT}_$tdir
22945
22946         mkdir $MOUNT/$tdir
22947         mkdir -p $submount || error "mkdir $submount failed"
22948         FILESET="$FILESET/$tdir" mount_client $submount ||
22949                 error "mount $submount failed"
22950         trap "cleanup_247 $submount" EXIT
22951         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22952         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22953                 error "read $MOUNT/$tdir/$tfile failed"
22954         cleanup_247 $submount
22955 }
22956 run_test 247a "mount subdir as fileset"
22957
22958 test_247b() {
22959         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22960                 skip_env "Fileset feature is not supported"
22961
22962         local submount=${MOUNT}_$tdir
22963
22964         rm -rf $MOUNT/$tdir
22965         mkdir -p $submount || error "mkdir $submount failed"
22966         SKIP_FILESET=1
22967         FILESET="$FILESET/$tdir" mount_client $submount &&
22968                 error "mount $submount should fail"
22969         rmdir $submount
22970 }
22971 run_test 247b "mount subdir that dose not exist"
22972
22973 test_247c() {
22974         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22975                 skip_env "Fileset feature is not supported"
22976
22977         local submount=${MOUNT}_$tdir
22978
22979         mkdir -p $MOUNT/$tdir/dir1
22980         mkdir -p $submount || error "mkdir $submount failed"
22981         trap "cleanup_247 $submount" EXIT
22982         FILESET="$FILESET/$tdir" mount_client $submount ||
22983                 error "mount $submount failed"
22984         local fid=$($LFS path2fid $MOUNT/)
22985         $LFS fid2path $submount $fid && error "fid2path should fail"
22986         cleanup_247 $submount
22987 }
22988 run_test 247c "running fid2path outside subdirectory root"
22989
22990 test_247d() {
22991         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22992                 skip "Fileset feature is not supported"
22993
22994         local submount=${MOUNT}_$tdir
22995
22996         mkdir -p $MOUNT/$tdir/dir1
22997         mkdir -p $submount || error "mkdir $submount failed"
22998         FILESET="$FILESET/$tdir" mount_client $submount ||
22999                 error "mount $submount failed"
23000         trap "cleanup_247 $submount" EXIT
23001
23002         local td=$submount/dir1
23003         local fid=$($LFS path2fid $td)
23004         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23005
23006         # check that we get the same pathname back
23007         local rootpath
23008         local found
23009         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23010                 echo "$rootpath $fid"
23011                 found=$($LFS fid2path $rootpath "$fid")
23012                 [ -n "$found" ] || error "fid2path should succeed"
23013                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23014         done
23015         # check wrong root path format
23016         rootpath=$submount"_wrong"
23017         found=$($LFS fid2path $rootpath "$fid")
23018         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23019
23020         cleanup_247 $submount
23021 }
23022 run_test 247d "running fid2path inside subdirectory root"
23023
23024 # LU-8037
23025 test_247e() {
23026         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23027                 grep -q subtree ||
23028                 skip "Fileset feature is not supported"
23029
23030         local submount=${MOUNT}_$tdir
23031
23032         mkdir $MOUNT/$tdir
23033         mkdir -p $submount || error "mkdir $submount failed"
23034         FILESET="$FILESET/.." mount_client $submount &&
23035                 error "mount $submount should fail"
23036         rmdir $submount
23037 }
23038 run_test 247e "mount .. as fileset"
23039
23040 test_247f() {
23041         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23042         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23043                 skip "Need at least version 2.14.50.162"
23044         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23045                 skip "Fileset feature is not supported"
23046
23047         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23048         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23049                 error "mkdir remote failed"
23050         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23051                 error "mkdir remote/subdir failed"
23052         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23053                 error "mkdir striped failed"
23054         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23055
23056         local submount=${MOUNT}_$tdir
23057
23058         mkdir -p $submount || error "mkdir $submount failed"
23059         stack_trap "rmdir $submount"
23060
23061         local dir
23062         local fileset=$FILESET
23063         local mdts=$(comma_list $(mdts_nodes))
23064
23065         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23066         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23067                 $tdir/striped/subdir $tdir/striped/.; do
23068                 FILESET="$fileset/$dir" mount_client $submount ||
23069                         error "mount $dir failed"
23070                 umount_client $submount
23071         done
23072 }
23073 run_test 247f "mount striped or remote directory as fileset"
23074
23075 test_subdir_mount_lock()
23076 {
23077         local testdir=$1
23078         local submount=${MOUNT}_$(basename $testdir)
23079
23080         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23081
23082         mkdir -p $submount || error "mkdir $submount failed"
23083         stack_trap "rmdir $submount"
23084
23085         FILESET="$fileset/$testdir" mount_client $submount ||
23086                 error "mount $FILESET failed"
23087         stack_trap "umount $submount"
23088
23089         local mdts=$(comma_list $(mdts_nodes))
23090
23091         local nrpcs
23092
23093         stat $submount > /dev/null || error "stat $submount failed"
23094         cancel_lru_locks $MDC
23095         stat $submount > /dev/null || error "stat $submount failed"
23096         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23097         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23098         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23099         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23100                 awk '/getattr/ {sum += $2} END {print sum}')
23101
23102         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23103 }
23104
23105 test_247g() {
23106         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23107
23108         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23109                 error "mkdir $tdir failed"
23110         test_subdir_mount_lock $tdir
23111 }
23112 run_test 247g "striped directory submount revalidate ROOT from cache"
23113
23114 test_247h() {
23115         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23116         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23117                 skip "Need MDS version at least 2.15.51"
23118
23119         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23120         test_subdir_mount_lock $tdir
23121         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23122         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23123                 error "mkdir $tdir.1 failed"
23124         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23125 }
23126 run_test 247h "remote directory submount revalidate ROOT from cache"
23127
23128 test_248a() {
23129         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23130         [ -z "$fast_read_sav" ] && skip "no fast read support"
23131
23132         # create a large file for fast read verification
23133         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23134
23135         # make sure the file is created correctly
23136         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23137                 { rm -f $DIR/$tfile; skip "file creation error"; }
23138
23139         echo "Test 1: verify that fast read is 4 times faster on cache read"
23140
23141         # small read with fast read enabled
23142         $LCTL set_param -n llite.*.fast_read=1
23143         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23144                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23145                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23146         # small read with fast read disabled
23147         $LCTL set_param -n llite.*.fast_read=0
23148         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23149                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23150                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23151
23152         # verify that fast read is 4 times faster for cache read
23153         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23154                 error_not_in_vm "fast read was not 4 times faster: " \
23155                            "$t_fast vs $t_slow"
23156
23157         echo "Test 2: verify the performance between big and small read"
23158         $LCTL set_param -n llite.*.fast_read=1
23159
23160         # 1k non-cache read
23161         cancel_lru_locks osc
23162         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23163                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23164                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23165
23166         # 1M non-cache read
23167         cancel_lru_locks osc
23168         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23169                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23170                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23171
23172         # verify that big IO is not 4 times faster than small IO
23173         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23174                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23175
23176         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23177         rm -f $DIR/$tfile
23178 }
23179 run_test 248a "fast read verification"
23180
23181 test_248b() {
23182         # Default short_io_bytes=16384, try both smaller and larger sizes.
23183         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23184         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23185         echo "bs=53248 count=113 normal buffered write"
23186         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23187                 error "dd of initial data file failed"
23188         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23189
23190         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23191         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23192                 error "dd with sync normal writes failed"
23193         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23194
23195         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23196         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23197                 error "dd with sync small writes failed"
23198         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23199
23200         cancel_lru_locks osc
23201
23202         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23203         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23204         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23205         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23206                 iflag=direct || error "dd with O_DIRECT small read failed"
23207         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23208         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23209                 error "compare $TMP/$tfile.1 failed"
23210
23211         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23212         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23213
23214         # just to see what the maximum tunable value is, and test parsing
23215         echo "test invalid parameter 2MB"
23216         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23217                 error "too-large short_io_bytes allowed"
23218         echo "test maximum parameter 512KB"
23219         # if we can set a larger short_io_bytes, run test regardless of version
23220         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23221                 # older clients may not allow setting it this large, that's OK
23222                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23223                         skip "Need at least client version 2.13.50"
23224                 error "medium short_io_bytes failed"
23225         fi
23226         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23227         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23228
23229         echo "test large parameter 64KB"
23230         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23231         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23232
23233         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23234         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23235                 error "dd with sync large writes failed"
23236         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23237
23238         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23239         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23240         num=$((113 * 4096 / PAGE_SIZE))
23241         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23242         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23243                 error "dd with O_DIRECT large writes failed"
23244         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23245                 error "compare $DIR/$tfile.3 failed"
23246
23247         cancel_lru_locks osc
23248
23249         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23250         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23251                 error "dd with O_DIRECT large read failed"
23252         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23253                 error "compare $TMP/$tfile.2 failed"
23254
23255         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23256         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23257                 error "dd with O_DIRECT large read failed"
23258         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23259                 error "compare $TMP/$tfile.3 failed"
23260 }
23261 run_test 248b "test short_io read and write for both small and large sizes"
23262
23263 test_249() { # LU-7890
23264         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23265                 skip "Need at least version 2.8.54"
23266
23267         rm -f $DIR/$tfile
23268         $LFS setstripe -c 1 $DIR/$tfile
23269         # Offset 2T == 4k * 512M
23270         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23271                 error "dd to 2T offset failed"
23272 }
23273 run_test 249 "Write above 2T file size"
23274
23275 test_250() {
23276         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23277          && skip "no 16TB file size limit on ZFS"
23278
23279         $LFS setstripe -c 1 $DIR/$tfile
23280         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23281         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23282         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23283         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23284                 conv=notrunc,fsync && error "append succeeded"
23285         return 0
23286 }
23287 run_test 250 "Write above 16T limit"
23288
23289 test_251() {
23290         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23291
23292         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23293         #Skip once - writing the first stripe will succeed
23294         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23295         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23296                 error "short write happened"
23297
23298         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23299         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23300                 error "short read happened"
23301
23302         rm -f $DIR/$tfile
23303 }
23304 run_test 251 "Handling short read and write correctly"
23305
23306 test_252() {
23307         remote_mds_nodsh && skip "remote MDS with nodsh"
23308         remote_ost_nodsh && skip "remote OST with nodsh"
23309         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23310                 skip_env "ldiskfs only test"
23311         fi
23312
23313         local tgt
23314         local dev
23315         local out
23316         local uuid
23317         local num
23318         local gen
23319
23320         # check lr_reader on OST0000
23321         tgt=ost1
23322         dev=$(facet_device $tgt)
23323         out=$(do_facet $tgt $LR_READER $dev)
23324         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23325         echo "$out"
23326         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23327         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23328                 error "Invalid uuid returned by $LR_READER on target $tgt"
23329         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23330
23331         # check lr_reader -c on MDT0000
23332         tgt=mds1
23333         dev=$(facet_device $tgt)
23334         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23335                 skip "$LR_READER does not support additional options"
23336         fi
23337         out=$(do_facet $tgt $LR_READER -c $dev)
23338         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23339         echo "$out"
23340         num=$(echo "$out" | grep -c "mdtlov")
23341         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23342                 error "Invalid number of mdtlov clients returned by $LR_READER"
23343         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23344
23345         # check lr_reader -cr on MDT0000
23346         out=$(do_facet $tgt $LR_READER -cr $dev)
23347         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23348         echo "$out"
23349         echo "$out" | grep -q "^reply_data:$" ||
23350                 error "$LR_READER should have returned 'reply_data' section"
23351         num=$(echo "$out" | grep -c "client_generation")
23352         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23353 }
23354 run_test 252 "check lr_reader tool"
23355
23356 test_253() {
23357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23358         remote_mds_nodsh && skip "remote MDS with nodsh"
23359         remote_mgs_nodsh && skip "remote MGS with nodsh"
23360
23361         local ostidx=0
23362         local rc=0
23363         local ost_name=$(ostname_from_index $ostidx)
23364
23365         # on the mdt's osc
23366         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23367         do_facet $SINGLEMDS $LCTL get_param -n \
23368                 osp.$mdtosc_proc1.reserved_mb_high ||
23369                 skip  "remote MDS does not support reserved_mb_high"
23370
23371         rm -rf $DIR/$tdir
23372         wait_mds_ost_sync
23373         wait_delete_completed
23374         mkdir $DIR/$tdir
23375         stack_trap "rm -rf $DIR/$tdir"
23376
23377         pool_add $TESTNAME || error "Pool creation failed"
23378         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23379
23380         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23381                 error "Setstripe failed"
23382
23383         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23384
23385         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23386                     grep "watermarks")
23387         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23388
23389         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23390                         osp.$mdtosc_proc1.prealloc_status)
23391         echo "prealloc_status $oa_status"
23392
23393         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23394                 error "File creation should fail"
23395
23396         #object allocation was stopped, but we still able to append files
23397         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23398                 oflag=append || error "Append failed"
23399
23400         rm -f $DIR/$tdir/$tfile.0
23401
23402         # For this test, we want to delete the files we created to go out of
23403         # space but leave the watermark, so we remain nearly out of space
23404         ost_watermarks_enospc_delete_files $tfile $ostidx
23405
23406         wait_delete_completed
23407
23408         sleep_maxage
23409
23410         for i in $(seq 10 12); do
23411                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23412                         2>/dev/null || error "File creation failed after rm"
23413         done
23414
23415         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23416                         osp.$mdtosc_proc1.prealloc_status)
23417         echo "prealloc_status $oa_status"
23418
23419         if (( oa_status != 0 )); then
23420                 error "Object allocation still disable after rm"
23421         fi
23422 }
23423 run_test 253 "Check object allocation limit"
23424
23425 test_254() {
23426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23427         remote_mds_nodsh && skip "remote MDS with nodsh"
23428
23429         local mdt=$(facet_svc $SINGLEMDS)
23430
23431         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23432                 skip "MDS does not support changelog_size"
23433
23434         local cl_user
23435
23436         changelog_register || error "changelog_register failed"
23437
23438         changelog_clear 0 || error "changelog_clear failed"
23439
23440         local size1=$(do_facet $SINGLEMDS \
23441                       $LCTL get_param -n mdd.$mdt.changelog_size)
23442         echo "Changelog size $size1"
23443
23444         rm -rf $DIR/$tdir
23445         $LFS mkdir -i 0 $DIR/$tdir
23446         # change something
23447         mkdir -p $DIR/$tdir/pics/2008/zachy
23448         touch $DIR/$tdir/pics/2008/zachy/timestamp
23449         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23450         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23451         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23452         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23453         rm $DIR/$tdir/pics/desktop.jpg
23454
23455         local size2=$(do_facet $SINGLEMDS \
23456                       $LCTL get_param -n mdd.$mdt.changelog_size)
23457         echo "Changelog size after work $size2"
23458
23459         (( $size2 > $size1 )) ||
23460                 error "new Changelog size=$size2 less than old size=$size1"
23461 }
23462 run_test 254 "Check changelog size"
23463
23464 ladvise_no_type()
23465 {
23466         local type=$1
23467         local file=$2
23468
23469         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23470                 awk -F: '{print $2}' | grep $type > /dev/null
23471         if [ $? -ne 0 ]; then
23472                 return 0
23473         fi
23474         return 1
23475 }
23476
23477 ladvise_no_ioctl()
23478 {
23479         local file=$1
23480
23481         lfs ladvise -a willread $file > /dev/null 2>&1
23482         if [ $? -eq 0 ]; then
23483                 return 1
23484         fi
23485
23486         lfs ladvise -a willread $file 2>&1 |
23487                 grep "Inappropriate ioctl for device" > /dev/null
23488         if [ $? -eq 0 ]; then
23489                 return 0
23490         fi
23491         return 1
23492 }
23493
23494 percent() {
23495         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23496 }
23497
23498 # run a random read IO workload
23499 # usage: random_read_iops <filename> <filesize> <iosize>
23500 random_read_iops() {
23501         local file=$1
23502         local fsize=$2
23503         local iosize=${3:-4096}
23504
23505         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23506                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23507 }
23508
23509 drop_file_oss_cache() {
23510         local file="$1"
23511         local nodes="$2"
23512
23513         $LFS ladvise -a dontneed $file 2>/dev/null ||
23514                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23515 }
23516
23517 ladvise_willread_performance()
23518 {
23519         local repeat=10
23520         local average_origin=0
23521         local average_cache=0
23522         local average_ladvise=0
23523
23524         for ((i = 1; i <= $repeat; i++)); do
23525                 echo "Iter $i/$repeat: reading without willread hint"
23526                 cancel_lru_locks osc
23527                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23528                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23529                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23530                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23531
23532                 cancel_lru_locks osc
23533                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23534                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23535                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23536
23537                 cancel_lru_locks osc
23538                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23539                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23540                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23541                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23542                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23543         done
23544         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23545         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23546         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23547
23548         speedup_cache=$(percent $average_cache $average_origin)
23549         speedup_ladvise=$(percent $average_ladvise $average_origin)
23550
23551         echo "Average uncached read: $average_origin"
23552         echo "Average speedup with OSS cached read: " \
23553                 "$average_cache = +$speedup_cache%"
23554         echo "Average speedup with ladvise willread: " \
23555                 "$average_ladvise = +$speedup_ladvise%"
23556
23557         local lowest_speedup=20
23558         if (( ${average_cache%.*} < $lowest_speedup )); then
23559                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23560                      " got $average_cache%. Skipping ladvise willread check."
23561                 return 0
23562         fi
23563
23564         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23565         # it is still good to run until then to exercise 'ladvise willread'
23566         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23567                 [ "$ost1_FSTYPE" = "zfs" ] &&
23568                 echo "osd-zfs does not support dontneed or drop_caches" &&
23569                 return 0
23570
23571         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23572         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23573                 error_not_in_vm "Speedup with willread is less than " \
23574                         "$lowest_speedup%, got $average_ladvise%"
23575 }
23576
23577 test_255a() {
23578         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23579                 skip "lustre < 2.8.54 does not support ladvise "
23580         remote_ost_nodsh && skip "remote OST with nodsh"
23581
23582         stack_trap "rm -f $DIR/$tfile"
23583         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23584
23585         ladvise_no_type willread $DIR/$tfile &&
23586                 skip "willread ladvise is not supported"
23587
23588         ladvise_no_ioctl $DIR/$tfile &&
23589                 skip "ladvise ioctl is not supported"
23590
23591         local size_mb=100
23592         local size=$((size_mb * 1048576))
23593         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23594                 error "dd to $DIR/$tfile failed"
23595
23596         lfs ladvise -a willread $DIR/$tfile ||
23597                 error "Ladvise failed with no range argument"
23598
23599         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23600                 error "Ladvise failed with no -l or -e argument"
23601
23602         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23603                 error "Ladvise failed with only -e argument"
23604
23605         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23606                 error "Ladvise failed with only -l argument"
23607
23608         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23609                 error "End offset should not be smaller than start offset"
23610
23611         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23612                 error "End offset should not be equal to start offset"
23613
23614         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23615                 error "Ladvise failed with overflowing -s argument"
23616
23617         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23618                 error "Ladvise failed with overflowing -e argument"
23619
23620         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23621                 error "Ladvise failed with overflowing -l argument"
23622
23623         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23624                 error "Ladvise succeeded with conflicting -l and -e arguments"
23625
23626         echo "Synchronous ladvise should wait"
23627         local delay=8
23628 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23629         do_nodes $(comma_list $(osts_nodes)) \
23630                 $LCTL set_param fail_val=$delay fail_loc=0x237
23631         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23632                 $LCTL set_param fail_loc=0"
23633
23634         local start_ts=$SECONDS
23635         lfs ladvise -a willread $DIR/$tfile ||
23636                 error "Ladvise failed with no range argument"
23637         local end_ts=$SECONDS
23638         local inteval_ts=$((end_ts - start_ts))
23639
23640         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23641                 error "Synchronous advice didn't wait reply"
23642         fi
23643
23644         echo "Asynchronous ladvise shouldn't wait"
23645         local start_ts=$SECONDS
23646         lfs ladvise -a willread -b $DIR/$tfile ||
23647                 error "Ladvise failed with no range argument"
23648         local end_ts=$SECONDS
23649         local inteval_ts=$((end_ts - start_ts))
23650
23651         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23652                 error "Asynchronous advice blocked"
23653         fi
23654
23655         ladvise_willread_performance
23656 }
23657 run_test 255a "check 'lfs ladvise -a willread'"
23658
23659 facet_meminfo() {
23660         local facet=$1
23661         local info=$2
23662
23663         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23664 }
23665
23666 test_255b() {
23667         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23668                 skip "lustre < 2.8.54 does not support ladvise "
23669         remote_ost_nodsh && skip "remote OST with nodsh"
23670
23671         stack_trap "rm -f $DIR/$tfile"
23672         lfs setstripe -c 1 -i 0 $DIR/$tfile
23673
23674         ladvise_no_type dontneed $DIR/$tfile &&
23675                 skip "dontneed ladvise is not supported"
23676
23677         ladvise_no_ioctl $DIR/$tfile &&
23678                 skip "ladvise ioctl is not supported"
23679
23680         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23681                 [ "$ost1_FSTYPE" = "zfs" ] &&
23682                 skip "zfs-osd does not support 'ladvise dontneed'"
23683
23684         local size_mb=100
23685         local size=$((size_mb * 1048576))
23686         # In order to prevent disturbance of other processes, only check 3/4
23687         # of the memory usage
23688         local kibibytes=$((size_mb * 1024 * 3 / 4))
23689
23690         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23691                 error "dd to $DIR/$tfile failed"
23692
23693         #force write to complete before dropping OST cache & checking memory
23694         sync
23695
23696         local total=$(facet_meminfo ost1 MemTotal)
23697         echo "Total memory: $total KiB"
23698
23699         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23700         local before_read=$(facet_meminfo ost1 Cached)
23701         echo "Cache used before read: $before_read KiB"
23702
23703         lfs ladvise -a willread $DIR/$tfile ||
23704                 error "Ladvise willread failed"
23705         local after_read=$(facet_meminfo ost1 Cached)
23706         echo "Cache used after read: $after_read KiB"
23707
23708         lfs ladvise -a dontneed $DIR/$tfile ||
23709                 error "Ladvise dontneed again failed"
23710         local no_read=$(facet_meminfo ost1 Cached)
23711         echo "Cache used after dontneed ladvise: $no_read KiB"
23712
23713         if [ $total -lt $((before_read + kibibytes)) ]; then
23714                 echo "Memory is too small, abort checking"
23715                 return 0
23716         fi
23717
23718         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23719                 error "Ladvise willread should use more memory" \
23720                         "than $kibibytes KiB"
23721         fi
23722
23723         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23724                 error "Ladvise dontneed should release more memory" \
23725                         "than $kibibytes KiB"
23726         fi
23727 }
23728 run_test 255b "check 'lfs ladvise -a dontneed'"
23729
23730 test_255c() {
23731         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23732                 skip "lustre < 2.10.50 does not support lockahead"
23733
23734         local ost1_imp=$(get_osc_import_name client ost1)
23735         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23736                          cut -d'.' -f2)
23737         local count
23738         local new_count
23739         local difference
23740         local i
23741         local rc
23742
23743         test_mkdir -p $DIR/$tdir
23744         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23745
23746         #test 10 returns only success/failure
23747         i=10
23748         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23749         rc=$?
23750         if [ $rc -eq 255 ]; then
23751                 error "Ladvise test${i} failed, ${rc}"
23752         fi
23753
23754         #test 11 counts lock enqueue requests, all others count new locks
23755         i=11
23756         count=$(do_facet ost1 \
23757                 $LCTL get_param -n ost.OSS.ost.stats)
23758         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23759
23760         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23761         rc=$?
23762         if [ $rc -eq 255 ]; then
23763                 error "Ladvise test${i} failed, ${rc}"
23764         fi
23765
23766         new_count=$(do_facet ost1 \
23767                 $LCTL get_param -n ost.OSS.ost.stats)
23768         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23769                    awk '{ print $2 }')
23770
23771         difference="$((new_count - count))"
23772         if [ $difference -ne $rc ]; then
23773                 error "Ladvise test${i}, bad enqueue count, returned " \
23774                       "${rc}, actual ${difference}"
23775         fi
23776
23777         for i in $(seq 12 21); do
23778                 # If we do not do this, we run the risk of having too many
23779                 # locks and starting lock cancellation while we are checking
23780                 # lock counts.
23781                 cancel_lru_locks osc
23782
23783                 count=$($LCTL get_param -n \
23784                        ldlm.namespaces.$imp_name.lock_unused_count)
23785
23786                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23787                 rc=$?
23788                 if [ $rc -eq 255 ]; then
23789                         error "Ladvise test ${i} failed, ${rc}"
23790                 fi
23791
23792                 new_count=$($LCTL get_param -n \
23793                        ldlm.namespaces.$imp_name.lock_unused_count)
23794                 difference="$((new_count - count))"
23795
23796                 # Test 15 output is divided by 100 to map down to valid return
23797                 if [ $i -eq 15 ]; then
23798                         rc="$((rc * 100))"
23799                 fi
23800
23801                 if [ $difference -ne $rc ]; then
23802                         error "Ladvise test ${i}, bad lock count, returned " \
23803                               "${rc}, actual ${difference}"
23804                 fi
23805         done
23806
23807         #test 22 returns only success/failure
23808         i=22
23809         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23810         rc=$?
23811         if [ $rc -eq 255 ]; then
23812                 error "Ladvise test${i} failed, ${rc}"
23813         fi
23814 }
23815 run_test 255c "suite of ladvise lockahead tests"
23816
23817 test_256() {
23818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23819         remote_mds_nodsh && skip "remote MDS with nodsh"
23820         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23821         changelog_users $SINGLEMDS | grep "^cl" &&
23822                 skip "active changelog user"
23823
23824         local cl_user
23825         local cat_sl
23826         local mdt_dev
23827
23828         mdt_dev=$(facet_device $SINGLEMDS)
23829         echo $mdt_dev
23830
23831         changelog_register || error "changelog_register failed"
23832
23833         rm -rf $DIR/$tdir
23834         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23835
23836         changelog_clear 0 || error "changelog_clear failed"
23837
23838         # change something
23839         touch $DIR/$tdir/{1..10}
23840
23841         # stop the MDT
23842         stop $SINGLEMDS || error "Fail to stop MDT"
23843
23844         # remount the MDT
23845         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23846                 error "Fail to start MDT"
23847
23848         #after mount new plainllog is used
23849         touch $DIR/$tdir/{11..19}
23850         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23851         stack_trap "rm -f $tmpfile"
23852         cat_sl=$(do_facet $SINGLEMDS "sync; \
23853                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23854                  llog_reader $tmpfile | grep -c type=1064553b")
23855         do_facet $SINGLEMDS llog_reader $tmpfile
23856
23857         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23858
23859         changelog_clear 0 || error "changelog_clear failed"
23860
23861         cat_sl=$(do_facet $SINGLEMDS "sync; \
23862                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23863                  llog_reader $tmpfile | grep -c type=1064553b")
23864
23865         if (( cat_sl == 2 )); then
23866                 error "Empty plain llog was not deleted from changelog catalog"
23867         elif (( cat_sl != 1 )); then
23868                 error "Active plain llog shouldn't be deleted from catalog"
23869         fi
23870 }
23871 run_test 256 "Check llog delete for empty and not full state"
23872
23873 test_257() {
23874         remote_mds_nodsh && skip "remote MDS with nodsh"
23875         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23876                 skip "Need MDS version at least 2.8.55"
23877
23878         test_mkdir $DIR/$tdir
23879
23880         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23881                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23882         stat $DIR/$tdir
23883
23884 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23885         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23886         local facet=mds$((mdtidx + 1))
23887         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23888         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23889
23890         stop $facet || error "stop MDS failed"
23891         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23892                 error "start MDS fail"
23893         wait_recovery_complete $facet
23894 }
23895 run_test 257 "xattr locks are not lost"
23896
23897 # Verify we take the i_mutex when security requires it
23898 test_258a() {
23899 #define OBD_FAIL_IMUTEX_SEC 0x141c
23900         $LCTL set_param fail_loc=0x141c
23901         touch $DIR/$tfile
23902         chmod u+s $DIR/$tfile
23903         chmod a+rwx $DIR/$tfile
23904         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23905         RC=$?
23906         if [ $RC -ne 0 ]; then
23907                 error "error, failed to take i_mutex, rc=$?"
23908         fi
23909         rm -f $DIR/$tfile
23910 }
23911 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23912
23913 # Verify we do NOT take the i_mutex in the normal case
23914 test_258b() {
23915 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23916         $LCTL set_param fail_loc=0x141d
23917         touch $DIR/$tfile
23918         chmod a+rwx $DIR
23919         chmod a+rw $DIR/$tfile
23920         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23921         RC=$?
23922         if [ $RC -ne 0 ]; then
23923                 error "error, took i_mutex unnecessarily, rc=$?"
23924         fi
23925         rm -f $DIR/$tfile
23926
23927 }
23928 run_test 258b "verify i_mutex security behavior"
23929
23930 test_259() {
23931         local file=$DIR/$tfile
23932         local before
23933         local after
23934
23935         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23936
23937         stack_trap "rm -f $file" EXIT
23938
23939         wait_delete_completed
23940         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23941         echo "before: $before"
23942
23943         $LFS setstripe -i 0 -c 1 $file
23944         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23945         sync_all_data
23946         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23947         echo "after write: $after"
23948
23949 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23950         do_facet ost1 $LCTL set_param fail_loc=0x2301
23951         $TRUNCATE $file 0
23952         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23953         echo "after truncate: $after"
23954
23955         stop ost1
23956         do_facet ost1 $LCTL set_param fail_loc=0
23957         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23958         sleep 2
23959         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23960         echo "after restart: $after"
23961         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23962                 error "missing truncate?"
23963
23964         return 0
23965 }
23966 run_test 259 "crash at delayed truncate"
23967
23968 test_260() {
23969 #define OBD_FAIL_MDC_CLOSE               0x806
23970         $LCTL set_param fail_loc=0x80000806
23971         touch $DIR/$tfile
23972
23973 }
23974 run_test 260 "Check mdc_close fail"
23975
23976 ### Data-on-MDT sanity tests ###
23977 test_270a() {
23978         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23979                 skip "Need MDS version at least 2.10.55 for DoM"
23980
23981         # create DoM file
23982         local dom=$DIR/$tdir/dom_file
23983         local tmp=$DIR/$tdir/tmp_file
23984
23985         mkdir_on_mdt0 $DIR/$tdir
23986
23987         # basic checks for DoM component creation
23988         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23989                 error "Can set MDT layout to non-first entry"
23990
23991         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23992                 error "Can define multiple entries as MDT layout"
23993
23994         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23995
23996         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23997         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23998         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23999
24000         local mdtidx=$($LFS getstripe -m $dom)
24001         local mdtname=MDT$(printf %04x $mdtidx)
24002         local facet=mds$((mdtidx + 1))
24003         local space_check=1
24004
24005         # Skip free space checks with ZFS
24006         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24007
24008         # write
24009         sync
24010         local size_tmp=$((65536 * 3))
24011         local mdtfree1=$(do_facet $facet \
24012                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24013
24014         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24015         # check also direct IO along write
24016         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24017         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24018         sync
24019         cmp $tmp $dom || error "file data is different"
24020         [ $(stat -c%s $dom) == $size_tmp ] ||
24021                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24022         if [ $space_check == 1 ]; then
24023                 local mdtfree2=$(do_facet $facet \
24024                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24025
24026                 # increase in usage from by $size_tmp
24027                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24028                         error "MDT free space wrong after write: " \
24029                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24030         fi
24031
24032         # truncate
24033         local size_dom=10000
24034
24035         $TRUNCATE $dom $size_dom
24036         [ $(stat -c%s $dom) == $size_dom ] ||
24037                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24038         if [ $space_check == 1 ]; then
24039                 mdtfree1=$(do_facet $facet \
24040                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24041                 # decrease in usage from $size_tmp to new $size_dom
24042                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24043                   $(((size_tmp - size_dom) / 1024)) ] ||
24044                         error "MDT free space is wrong after truncate: " \
24045                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24046         fi
24047
24048         # append
24049         cat $tmp >> $dom
24050         sync
24051         size_dom=$((size_dom + size_tmp))
24052         [ $(stat -c%s $dom) == $size_dom ] ||
24053                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24054         if [ $space_check == 1 ]; then
24055                 mdtfree2=$(do_facet $facet \
24056                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24057                 # increase in usage by $size_tmp from previous
24058                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24059                         error "MDT free space is wrong after append: " \
24060                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24061         fi
24062
24063         # delete
24064         rm $dom
24065         if [ $space_check == 1 ]; then
24066                 mdtfree1=$(do_facet $facet \
24067                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24068                 # decrease in usage by $size_dom from previous
24069                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24070                         error "MDT free space is wrong after removal: " \
24071                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24072         fi
24073
24074         # combined striping
24075         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24076                 error "Can't create DoM + OST striping"
24077
24078         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24079         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24080         # check also direct IO along write
24081         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24082         sync
24083         cmp $tmp $dom || error "file data is different"
24084         [ $(stat -c%s $dom) == $size_tmp ] ||
24085                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24086         rm $dom $tmp
24087
24088         return 0
24089 }
24090 run_test 270a "DoM: basic functionality tests"
24091
24092 test_270b() {
24093         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24094                 skip "Need MDS version at least 2.10.55"
24095
24096         local dom=$DIR/$tdir/dom_file
24097         local max_size=1048576
24098
24099         mkdir -p $DIR/$tdir
24100         $LFS setstripe -E $max_size -L mdt $dom
24101
24102         # truncate over the limit
24103         $TRUNCATE $dom $(($max_size + 1)) &&
24104                 error "successful truncate over the maximum size"
24105         # write over the limit
24106         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24107                 error "successful write over the maximum size"
24108         # append over the limit
24109         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24110         echo "12345" >> $dom && error "successful append over the maximum size"
24111         rm $dom
24112
24113         return 0
24114 }
24115 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24116
24117 test_270c() {
24118         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24119                 skip "Need MDS version at least 2.10.55"
24120
24121         mkdir -p $DIR/$tdir
24122         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24123
24124         # check files inherit DoM EA
24125         touch $DIR/$tdir/first
24126         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24127                 error "bad pattern"
24128         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24129                 error "bad stripe count"
24130         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24131                 error "bad stripe size"
24132
24133         # check directory inherits DoM EA and uses it as default
24134         mkdir $DIR/$tdir/subdir
24135         touch $DIR/$tdir/subdir/second
24136         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24137                 error "bad pattern in sub-directory"
24138         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24139                 error "bad stripe count in sub-directory"
24140         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24141                 error "bad stripe size in sub-directory"
24142         return 0
24143 }
24144 run_test 270c "DoM: DoM EA inheritance tests"
24145
24146 test_270d() {
24147         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24148                 skip "Need MDS version at least 2.10.55"
24149
24150         mkdir -p $DIR/$tdir
24151         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24152
24153         # inherit default DoM striping
24154         mkdir $DIR/$tdir/subdir
24155         touch $DIR/$tdir/subdir/f1
24156
24157         # change default directory striping
24158         $LFS setstripe -c 1 $DIR/$tdir/subdir
24159         touch $DIR/$tdir/subdir/f2
24160         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24161                 error "wrong default striping in file 2"
24162         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24163                 error "bad pattern in file 2"
24164         return 0
24165 }
24166 run_test 270d "DoM: change striping from DoM to RAID0"
24167
24168 test_270e() {
24169         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24170                 skip "Need MDS version at least 2.10.55"
24171
24172         mkdir -p $DIR/$tdir/dom
24173         mkdir -p $DIR/$tdir/norm
24174         DOMFILES=20
24175         NORMFILES=10
24176         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24177         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24178
24179         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24180         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24181
24182         # find DoM files by layout
24183         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24184         [ $NUM -eq  $DOMFILES ] ||
24185                 error "lfs find -L: found $NUM, expected $DOMFILES"
24186         echo "Test 1: lfs find 20 DOM files by layout: OK"
24187
24188         # there should be 1 dir with default DOM striping
24189         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24190         [ $NUM -eq  1 ] ||
24191                 error "lfs find -L: found $NUM, expected 1 dir"
24192         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24193
24194         # find DoM files by stripe size
24195         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24196         [ $NUM -eq  $DOMFILES ] ||
24197                 error "lfs find -S: found $NUM, expected $DOMFILES"
24198         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24199
24200         # find files by stripe offset except DoM files
24201         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24202         [ $NUM -eq  $NORMFILES ] ||
24203                 error "lfs find -i: found $NUM, expected $NORMFILES"
24204         echo "Test 5: lfs find no DOM files by stripe index: OK"
24205         return 0
24206 }
24207 run_test 270e "DoM: lfs find with DoM files test"
24208
24209 test_270f() {
24210         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24211                 skip "Need MDS version at least 2.10.55"
24212
24213         local mdtname=${FSNAME}-MDT0000-mdtlov
24214         local dom=$DIR/$tdir/dom_file
24215         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24216                                                 lod.$mdtname.dom_stripesize)
24217         local dom_limit=131072
24218
24219         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24220         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24221                                                 lod.$mdtname.dom_stripesize)
24222         [ ${dom_limit} -eq ${dom_current} ] ||
24223                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24224
24225         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24226         $LFS setstripe -d $DIR/$tdir
24227         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24228                 error "Can't set directory default striping"
24229
24230         # exceed maximum stripe size
24231         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24232                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24233         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24234                 error "Able to create DoM component size more than LOD limit"
24235
24236         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24237         dom_current=$(do_facet mds1 $LCTL get_param -n \
24238                                                 lod.$mdtname.dom_stripesize)
24239         [ 0 -eq ${dom_current} ] ||
24240                 error "Can't set zero DoM stripe limit"
24241         rm $dom
24242
24243         # attempt to create DoM file on server with disabled DoM should
24244         # remove DoM entry from layout and be succeed
24245         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24246                 error "Can't create DoM file (DoM is disabled)"
24247         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24248                 error "File has DoM component while DoM is disabled"
24249         rm $dom
24250
24251         # attempt to create DoM file with only DoM stripe should return error
24252         $LFS setstripe -E $dom_limit -L mdt $dom &&
24253                 error "Able to create DoM-only file while DoM is disabled"
24254
24255         # too low values to be aligned with smallest stripe size 64K
24256         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24257         dom_current=$(do_facet mds1 $LCTL get_param -n \
24258                                                 lod.$mdtname.dom_stripesize)
24259         [ 30000 -eq ${dom_current} ] &&
24260                 error "Can set too small DoM stripe limit"
24261
24262         # 64K is a minimal stripe size in Lustre, expect limit of that size
24263         [ 65536 -eq ${dom_current} ] ||
24264                 error "Limit is not set to 64K but ${dom_current}"
24265
24266         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24267         dom_current=$(do_facet mds1 $LCTL get_param -n \
24268                                                 lod.$mdtname.dom_stripesize)
24269         echo $dom_current
24270         [ 2147483648 -eq ${dom_current} ] &&
24271                 error "Can set too large DoM stripe limit"
24272
24273         do_facet mds1 $LCTL set_param -n \
24274                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24275         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24276                 error "Can't create DoM component size after limit change"
24277         do_facet mds1 $LCTL set_param -n \
24278                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24279         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24280                 error "Can't create DoM file after limit decrease"
24281         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24282                 error "Can create big DoM component after limit decrease"
24283         touch ${dom}_def ||
24284                 error "Can't create file with old default layout"
24285
24286         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24287         return 0
24288 }
24289 run_test 270f "DoM: maximum DoM stripe size checks"
24290
24291 test_270g() {
24292         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24293                 skip "Need MDS version at least 2.13.52"
24294         local dom=$DIR/$tdir/$tfile
24295
24296         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24297         local lodname=${FSNAME}-MDT0000-mdtlov
24298
24299         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24300         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24301         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24302         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24303
24304         local dom_limit=1024
24305         local dom_threshold="50%"
24306
24307         $LFS setstripe -d $DIR/$tdir
24308         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24309                 error "Can't set directory default striping"
24310
24311         do_facet mds1 $LCTL set_param -n \
24312                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24313         # set 0 threshold and create DOM file to change tunable stripesize
24314         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24315         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24316                 error "Failed to create $dom file"
24317         # now tunable dom_cur_stripesize should reach maximum
24318         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24319                                         lod.${lodname}.dom_stripesize_cur_kb)
24320         [[ $dom_current == $dom_limit ]] ||
24321                 error "Current DOM stripesize is not maximum"
24322         rm $dom
24323
24324         # set threshold for further tests
24325         do_facet mds1 $LCTL set_param -n \
24326                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24327         echo "DOM threshold is $dom_threshold free space"
24328         local dom_def
24329         local dom_set
24330         # Spoof bfree to exceed threshold
24331         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24332         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24333         for spfree in 40 20 0 15 30 55; do
24334                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24335                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24336                         error "Failed to create $dom file"
24337                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24338                                         lod.${lodname}.dom_stripesize_cur_kb)
24339                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24340                 [[ $dom_def != $dom_current ]] ||
24341                         error "Default stripe size was not changed"
24342                 if (( spfree > 0 )) ; then
24343                         dom_set=$($LFS getstripe -S $dom)
24344                         (( dom_set == dom_def * 1024 )) ||
24345                                 error "DOM component size is still old"
24346                 else
24347                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24348                                 error "DoM component is set with no free space"
24349                 fi
24350                 rm $dom
24351                 dom_current=$dom_def
24352         done
24353 }
24354 run_test 270g "DoM: default DoM stripe size depends on free space"
24355
24356 test_270h() {
24357         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24358                 skip "Need MDS version at least 2.13.53"
24359
24360         local mdtname=${FSNAME}-MDT0000-mdtlov
24361         local dom=$DIR/$tdir/$tfile
24362         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24363
24364         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24365         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24366
24367         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24368         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24369                 error "can't create OST file"
24370         # mirrored file with DOM entry in the second mirror
24371         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24372                 error "can't create mirror with DoM component"
24373
24374         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24375
24376         # DOM component in the middle and has other enries in the same mirror,
24377         # should succeed but lost DoM component
24378         $LFS setstripe --copy=${dom}_1 $dom ||
24379                 error "Can't create file from OST|DOM mirror layout"
24380         # check new file has no DoM layout after all
24381         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24382                 error "File has DoM component while DoM is disabled"
24383 }
24384 run_test 270h "DoM: DoM stripe removal when disabled on server"
24385
24386 test_270i() {
24387         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24388                 skip "Need MDS version at least 2.14.54"
24389
24390         mkdir $DIR/$tdir
24391         # DoM with plain layout
24392         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24393                 error "default plain layout with DoM must fail"
24394         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24395                 error "setstripe plain file layout with DoM must fail"
24396         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24397                 error "default DoM layout with bad striping must fail"
24398         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24399                 error "setstripe to DoM layout with bad striping must fail"
24400         return 0
24401 }
24402 run_test 270i "DoM: setting invalid DoM striping should fail"
24403
24404 test_270j() {
24405         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24406                 skip "Need MDS version at least 2.15.55.203"
24407
24408         local dom=$DIR/$tdir/$tfile
24409         local odv
24410         local ndv
24411
24412         mkdir -p $DIR/$tdir
24413
24414         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24415
24416         odv=$($LFS data_version $dom)
24417         chmod 666 $dom
24418         mv $dom ${dom}_moved
24419         link ${dom}_moved $dom
24420         setfattr -n user.attrx -v "some_attr" $dom
24421         ndv=$($LFS data_version $dom)
24422         (( $ndv == $odv )) ||
24423                 error "data version was changed by metadata operations"
24424
24425         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24426                 error "failed to write data into $dom"
24427         cancel_lru_locks mdc
24428         ndv=$($LFS data_version $dom)
24429         (( $ndv != $odv )) ||
24430                 error "data version wasn't changed on write"
24431
24432         odv=$ndv
24433         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24434         ndv=$($LFS data_version $dom)
24435         (( $ndv != $odv )) ||
24436                 error "data version wasn't changed on truncate down"
24437
24438         odv=$ndv
24439         $TRUNCATE $dom 25000
24440         ndv=$($LFS data_version $dom)
24441         (( $ndv != $odv )) ||
24442                 error "data version wasn't changed on truncate up"
24443
24444         # check also fallocate for ldiskfs
24445         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24446                 odv=$ndv
24447                 fallocate -l 1048576 $dom
24448                 ndv=$($LFS data_version $dom)
24449                 (( $ndv != $odv )) ||
24450                         error "data version wasn't changed on fallocate"
24451
24452                 odv=$ndv
24453                 fallocate -p --offset 4096 -l 4096 $dom
24454                 ndv=$($LFS data_version $dom)
24455                 (( $ndv != $odv )) ||
24456                         error "data version wasn't changed on fallocate punch"
24457         fi
24458 }
24459 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24460
24461 test_271a() {
24462         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24463                 skip "Need MDS version at least 2.10.55"
24464
24465         local dom=$DIR/$tdir/dom
24466
24467         mkdir -p $DIR/$tdir
24468
24469         $LFS setstripe -E 1024K -L mdt $dom
24470
24471         lctl set_param -n mdc.*.stats=clear
24472         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24473         cat $dom > /dev/null
24474         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24475         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24476         ls $dom
24477         rm -f $dom
24478 }
24479 run_test 271a "DoM: data is cached for read after write"
24480
24481 test_271b() {
24482         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24483                 skip "Need MDS version at least 2.10.55"
24484
24485         local dom=$DIR/$tdir/dom
24486
24487         mkdir -p $DIR/$tdir
24488
24489         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24490
24491         lctl set_param -n mdc.*.stats=clear
24492         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24493         cancel_lru_locks mdc
24494         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24495         # second stat to check size is cached on client
24496         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24497         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24498         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24499         rm -f $dom
24500 }
24501 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24502
24503 test_271ba() {
24504         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24505                 skip "Need MDS version at least 2.10.55"
24506
24507         local dom=$DIR/$tdir/dom
24508
24509         mkdir -p $DIR/$tdir
24510
24511         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24512
24513         lctl set_param -n mdc.*.stats=clear
24514         lctl set_param -n osc.*.stats=clear
24515         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24516         cancel_lru_locks mdc
24517         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24518         # second stat to check size is cached on client
24519         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24520         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24521         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24522         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24523         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24524         rm -f $dom
24525 }
24526 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24527
24528
24529 get_mdc_stats() {
24530         local mdtidx=$1
24531         local param=$2
24532         local mdt=MDT$(printf %04x $mdtidx)
24533
24534         if [ -z $param ]; then
24535                 lctl get_param -n mdc.*$mdt*.stats
24536         else
24537                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24538         fi
24539 }
24540
24541 test_271c() {
24542         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24543                 skip "Need MDS version at least 2.10.55"
24544
24545         local dom=$DIR/$tdir/dom
24546
24547         mkdir -p $DIR/$tdir
24548
24549         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24550
24551         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24552         local facet=mds$((mdtidx + 1))
24553
24554         cancel_lru_locks mdc
24555         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24556         createmany -o $dom 1000
24557         lctl set_param -n mdc.*.stats=clear
24558         smalliomany -w $dom 1000 200
24559         get_mdc_stats $mdtidx
24560         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24561         # Each file has 1 open, 1 IO enqueues, total 2000
24562         # but now we have also +1 getxattr for security.capability, total 3000
24563         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24564         unlinkmany $dom 1000
24565
24566         cancel_lru_locks mdc
24567         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24568         createmany -o $dom 1000
24569         lctl set_param -n mdc.*.stats=clear
24570         smalliomany -w $dom 1000 200
24571         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24572         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24573         # for OPEN and IO lock.
24574         [ $((enq - enq_2)) -ge 1000 ] ||
24575                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24576         unlinkmany $dom 1000
24577         return 0
24578 }
24579 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24580
24581 cleanup_271def_tests() {
24582         trap 0
24583         rm -f $1
24584 }
24585
24586 test_271d() {
24587         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24588                 skip "Need MDS version at least 2.10.57"
24589
24590         local dom=$DIR/$tdir/dom
24591         local tmp=$TMP/$tfile
24592         trap "cleanup_271def_tests $tmp" EXIT
24593
24594         mkdir -p $DIR/$tdir
24595
24596         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24597
24598         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24599
24600         cancel_lru_locks mdc
24601         dd if=/dev/urandom of=$tmp bs=1000 count=1
24602         dd if=$tmp of=$dom bs=1000 count=1
24603         cancel_lru_locks mdc
24604
24605         cat /etc/hosts >> $tmp
24606         lctl set_param -n mdc.*.stats=clear
24607
24608         # append data to the same file it should update local page
24609         echo "Append to the same page"
24610         cat /etc/hosts >> $dom
24611         local num=$(get_mdc_stats $mdtidx ost_read)
24612         local ra=$(get_mdc_stats $mdtidx req_active)
24613         local rw=$(get_mdc_stats $mdtidx req_waittime)
24614
24615         [ -z $num ] || error "$num READ RPC occured"
24616         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24617         echo "... DONE"
24618
24619         # compare content
24620         cmp $tmp $dom || error "file miscompare"
24621
24622         cancel_lru_locks mdc
24623         lctl set_param -n mdc.*.stats=clear
24624
24625         echo "Open and read file"
24626         cat $dom > /dev/null
24627         local num=$(get_mdc_stats $mdtidx ost_read)
24628         local ra=$(get_mdc_stats $mdtidx req_active)
24629         local rw=$(get_mdc_stats $mdtidx req_waittime)
24630
24631         [ -z $num ] || error "$num READ RPC occured"
24632         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24633         echo "... DONE"
24634
24635         # compare content
24636         cmp $tmp $dom || error "file miscompare"
24637
24638         return 0
24639 }
24640 run_test 271d "DoM: read on open (1K file in reply buffer)"
24641
24642 test_271f() {
24643         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24644                 skip "Need MDS version at least 2.10.57"
24645
24646         local dom=$DIR/$tdir/dom
24647         local tmp=$TMP/$tfile
24648         trap "cleanup_271def_tests $tmp" EXIT
24649
24650         mkdir -p $DIR/$tdir
24651
24652         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24653
24654         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24655
24656         cancel_lru_locks mdc
24657         dd if=/dev/urandom of=$tmp bs=265000 count=1
24658         dd if=$tmp of=$dom bs=265000 count=1
24659         cancel_lru_locks mdc
24660         cat /etc/hosts >> $tmp
24661         lctl set_param -n mdc.*.stats=clear
24662
24663         echo "Append to the same page"
24664         cat /etc/hosts >> $dom
24665         local num=$(get_mdc_stats $mdtidx ost_read)
24666         local ra=$(get_mdc_stats $mdtidx req_active)
24667         local rw=$(get_mdc_stats $mdtidx req_waittime)
24668
24669         [ -z $num ] || error "$num READ RPC occured"
24670         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24671         echo "... DONE"
24672
24673         # compare content
24674         cmp $tmp $dom || error "file miscompare"
24675
24676         cancel_lru_locks mdc
24677         lctl set_param -n mdc.*.stats=clear
24678
24679         echo "Open and read file"
24680         cat $dom > /dev/null
24681         local num=$(get_mdc_stats $mdtidx ost_read)
24682         local ra=$(get_mdc_stats $mdtidx req_active)
24683         local rw=$(get_mdc_stats $mdtidx req_waittime)
24684
24685         [ -z $num ] && num=0
24686         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24687         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24688         echo "... DONE"
24689
24690         # compare content
24691         cmp $tmp $dom || error "file miscompare"
24692
24693         return 0
24694 }
24695 run_test 271f "DoM: read on open (200K file and read tail)"
24696
24697 test_271g() {
24698         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24699                 skip "Skipping due to old client or server version"
24700
24701         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24702         # to get layout
24703         $CHECKSTAT -t file $DIR1/$tfile
24704
24705         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24706         MULTIOP_PID=$!
24707         sleep 1
24708         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24709         $LCTL set_param fail_loc=0x80000314
24710         rm $DIR1/$tfile || error "Unlink fails"
24711         RC=$?
24712         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24713         [ $RC -eq 0 ] || error "Failed write to stale object"
24714 }
24715 run_test 271g "Discard DoM data vs client flush race"
24716
24717 test_272a() {
24718         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24719                 skip "Need MDS version at least 2.11.50"
24720
24721         local dom=$DIR/$tdir/dom
24722         mkdir -p $DIR/$tdir
24723
24724         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24725         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24726                 error "failed to write data into $dom"
24727         local old_md5=$(md5sum $dom)
24728
24729         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24730                 error "failed to migrate to the same DoM component"
24731
24732         local new_md5=$(md5sum $dom)
24733
24734         [ "$old_md5" == "$new_md5" ] ||
24735                 error "md5sum differ: $old_md5, $new_md5"
24736
24737         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24738                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24739 }
24740 run_test 272a "DoM migration: new layout with the same DOM component"
24741
24742 test_272b() {
24743         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24744                 skip "Need MDS version at least 2.11.50"
24745
24746         local dom=$DIR/$tdir/dom
24747         mkdir -p $DIR/$tdir
24748         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24749         stack_trap "rm -rf $DIR/$tdir"
24750
24751         local mdtidx=$($LFS getstripe -m $dom)
24752         local mdtname=MDT$(printf %04x $mdtidx)
24753         local facet=mds$((mdtidx + 1))
24754
24755         local mdtfree1=$(do_facet $facet \
24756                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24757         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24758                 error "failed to write data into $dom"
24759         local old_md5=$(md5sum $dom)
24760         cancel_lru_locks mdc
24761         local mdtfree1=$(do_facet $facet \
24762                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24763
24764         $LFS migrate -c2 $dom ||
24765                 error "failed to migrate to the new composite layout"
24766         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24767                 error "MDT stripe was not removed"
24768         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24769                 error "$dir1 shouldn't have DATAVER EA"
24770
24771         cancel_lru_locks mdc
24772         local new_md5=$(md5sum $dom)
24773         [ "$old_md5" == "$new_md5" ] ||
24774                 error "$old_md5 != $new_md5"
24775
24776         # Skip free space checks with ZFS
24777         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24778                 local mdtfree2=$(do_facet $facet \
24779                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24780                 [ $mdtfree2 -gt $mdtfree1 ] ||
24781                         error "MDT space is not freed after migration"
24782         fi
24783         return 0
24784 }
24785 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24786
24787 test_272c() {
24788         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24789                 skip "Need MDS version at least 2.11.50"
24790
24791         local dom=$DIR/$tdir/$tfile
24792         mkdir -p $DIR/$tdir
24793         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24794         stack_trap "rm -rf $DIR/$tdir"
24795
24796         local mdtidx=$($LFS getstripe -m $dom)
24797         local mdtname=MDT$(printf %04x $mdtidx)
24798         local facet=mds$((mdtidx + 1))
24799
24800         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24801                 error "failed to write data into $dom"
24802         local old_md5=$(md5sum $dom)
24803         cancel_lru_locks mdc
24804         local mdtfree1=$(do_facet $facet \
24805                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24806
24807         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24808                 error "failed to migrate to the new composite layout"
24809         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24810                 error "MDT stripe was not removed"
24811
24812         cancel_lru_locks mdc
24813         local new_md5=$(md5sum $dom)
24814         [ "$old_md5" == "$new_md5" ] ||
24815                 error "$old_md5 != $new_md5"
24816
24817         # Skip free space checks with ZFS
24818         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24819                 local mdtfree2=$(do_facet $facet \
24820                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24821                 [ $mdtfree2 -gt $mdtfree1 ] ||
24822                         error "MDS space is not freed after migration"
24823         fi
24824         return 0
24825 }
24826 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24827
24828 test_272d() {
24829         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24830                 skip "Need MDS version at least 2.12.55"
24831
24832         local dom=$DIR/$tdir/$tfile
24833         mkdir -p $DIR/$tdir
24834         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24835
24836         local mdtidx=$($LFS getstripe -m $dom)
24837         local mdtname=MDT$(printf %04x $mdtidx)
24838         local facet=mds$((mdtidx + 1))
24839
24840         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24841                 error "failed to write data into $dom"
24842         local old_md5=$(md5sum $dom)
24843         cancel_lru_locks mdc
24844         local mdtfree1=$(do_facet $facet \
24845                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24846
24847         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24848                 error "failed mirroring to the new composite layout"
24849         $LFS mirror resync $dom ||
24850                 error "failed mirror resync"
24851         $LFS mirror split --mirror-id 1 -d $dom ||
24852                 error "failed mirror split"
24853
24854         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24855                 error "MDT stripe was not removed"
24856
24857         cancel_lru_locks mdc
24858         local new_md5=$(md5sum $dom)
24859         [ "$old_md5" == "$new_md5" ] ||
24860                 error "$old_md5 != $new_md5"
24861
24862         # Skip free space checks with ZFS
24863         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24864                 local mdtfree2=$(do_facet $facet \
24865                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24866                 [ $mdtfree2 -gt $mdtfree1 ] ||
24867                         error "MDS space is not freed after DOM mirror deletion"
24868         fi
24869         return 0
24870 }
24871 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24872
24873 test_272e() {
24874         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24875                 skip "Need MDS version at least 2.12.55"
24876
24877         local dom=$DIR/$tdir/$tfile
24878         mkdir -p $DIR/$tdir
24879         $LFS setstripe -c 2 $dom
24880
24881         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24882                 error "failed to write data into $dom"
24883         local old_md5=$(md5sum $dom)
24884         cancel_lru_locks
24885
24886         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24887                 error "failed mirroring to the DOM layout"
24888         $LFS mirror resync $dom ||
24889                 error "failed mirror resync"
24890         $LFS mirror split --mirror-id 1 -d $dom ||
24891                 error "failed mirror split"
24892
24893         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24894                 error "MDT stripe wasn't set"
24895
24896         cancel_lru_locks
24897         local new_md5=$(md5sum $dom)
24898         [ "$old_md5" == "$new_md5" ] ||
24899                 error "$old_md5 != $new_md5"
24900
24901         return 0
24902 }
24903 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24904
24905 test_272f() {
24906         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24907                 skip "Need MDS version at least 2.12.55"
24908
24909         local dom=$DIR/$tdir/$tfile
24910         mkdir -p $DIR/$tdir
24911         $LFS setstripe -c 2 $dom
24912
24913         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24914                 error "failed to write data into $dom"
24915         local old_md5=$(md5sum $dom)
24916         cancel_lru_locks
24917
24918         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24919                 error "failed migrating to the DOM file"
24920
24921         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24922                 error "MDT stripe wasn't set"
24923
24924         cancel_lru_locks
24925         local new_md5=$(md5sum $dom)
24926         [ "$old_md5" != "$new_md5" ] &&
24927                 error "$old_md5 != $new_md5"
24928
24929         return 0
24930 }
24931 run_test 272f "DoM migration: OST-striped file to DOM file"
24932
24933 test_273a() {
24934         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24935                 skip "Need MDS version at least 2.11.50"
24936
24937         # Layout swap cannot be done if either file has DOM component,
24938         # this will never be supported, migration should be used instead
24939
24940         local dom=$DIR/$tdir/$tfile
24941         mkdir -p $DIR/$tdir
24942
24943         $LFS setstripe -c2 ${dom}_plain
24944         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24945         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24946                 error "can swap layout with DoM component"
24947         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24948                 error "can swap layout with DoM component"
24949
24950         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24951         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24952                 error "can swap layout with DoM component"
24953         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24954                 error "can swap layout with DoM component"
24955         return 0
24956 }
24957 run_test 273a "DoM: layout swapping should fail with DOM"
24958
24959 test_273b() {
24960         mkdir -p $DIR/$tdir
24961         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24962
24963 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24964         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24965
24966         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24967 }
24968 run_test 273b "DoM: race writeback and object destroy"
24969
24970 test_273c() {
24971         mkdir -p $DIR/$tdir
24972         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24973
24974         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24975         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24976
24977         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24978 }
24979 run_test 273c "race writeback and object destroy"
24980
24981 test_275() {
24982         remote_ost_nodsh && skip "remote OST with nodsh"
24983         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24984                 skip "Need OST version >= 2.10.57"
24985
24986         local file=$DIR/$tfile
24987         local oss
24988
24989         oss=$(comma_list $(osts_nodes))
24990
24991         dd if=/dev/urandom of=$file bs=1M count=2 ||
24992                 error "failed to create a file"
24993         stack_trap "rm -f $file"
24994         cancel_lru_locks osc
24995
24996         #lock 1
24997         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24998                 error "failed to read a file"
24999
25000 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25001         $LCTL set_param fail_loc=0x8000031f
25002
25003         cancel_lru_locks osc &
25004         sleep 1
25005
25006 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25007         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25008         #IO takes another lock, but matches the PENDING one
25009         #and places it to the IO RPC
25010         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25011                 error "failed to read a file with PENDING lock"
25012 }
25013 run_test 275 "Read on a canceled duplicate lock"
25014
25015 test_276() {
25016         remote_ost_nodsh && skip "remote OST with nodsh"
25017         local pid
25018
25019         do_facet ost1 "(while true; do \
25020                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25021                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25022         pid=$!
25023
25024         for LOOP in $(seq 20); do
25025                 stop ost1
25026                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25027         done
25028         kill -9 $pid
25029         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25030                 rm $TMP/sanity_276_pid"
25031 }
25032 run_test 276 "Race between mount and obd_statfs"
25033
25034 test_277() {
25035         $LCTL set_param ldlm.namespaces.*.lru_size=0
25036         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25037         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25038                           awk '/^used_mb/ { print $2 }')
25039         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25040         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25041                 oflag=direct conv=notrunc
25042         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25043                     awk '/^used_mb/ { print $2 }')
25044         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25045 }
25046 run_test 277 "Direct IO shall drop page cache"
25047
25048 test_278() {
25049         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25050         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25051         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25052                 skip "needs the same host for mdt1 mdt2" && return
25053
25054         local pid1
25055         local pid2
25056
25057 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25058         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25059         stop mds2 &
25060         pid2=$!
25061
25062         stop mds1
25063
25064         echo "Starting MDTs"
25065         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25066         wait $pid2
25067 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25068 #will return NULL
25069         do_facet mds2 $LCTL set_param fail_loc=0
25070
25071         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25072         wait_recovery_complete mds2
25073 }
25074 run_test 278 "Race starting MDS between MDTs stop/start"
25075
25076 test_280() {
25077         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25078                 skip "Need MGS version at least 2.13.52"
25079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25080         combined_mgs_mds || skip "needs combined MGS/MDT"
25081
25082         umount_client $MOUNT
25083 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25084         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25085
25086         mount_client $MOUNT &
25087         sleep 1
25088         stop mgs || error "stop mgs failed"
25089         #for a race mgs would crash
25090         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25091         # make sure we unmount client before remounting
25092         wait
25093         umount_client $MOUNT
25094         mount_client $MOUNT || error "mount client failed"
25095 }
25096 run_test 280 "Race between MGS umount and client llog processing"
25097
25098 cleanup_test_300() {
25099         trap 0
25100         umask $SAVE_UMASK
25101 }
25102 test_striped_dir() {
25103         local mdt_index=$1
25104         local stripe_count
25105         local stripe_index
25106
25107         mkdir -p $DIR/$tdir
25108
25109         SAVE_UMASK=$(umask)
25110         trap cleanup_test_300 RETURN EXIT
25111
25112         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25113                                                 $DIR/$tdir/striped_dir ||
25114                 error "set striped dir error"
25115
25116         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25117         [ "$mode" = "755" ] || error "expect 755 got $mode"
25118
25119         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25120                 error "getdirstripe failed"
25121         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25122         if [ "$stripe_count" != "2" ]; then
25123                 error "1:stripe_count is $stripe_count, expect 2"
25124         fi
25125         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25126         if [ "$stripe_count" != "2" ]; then
25127                 error "2:stripe_count is $stripe_count, expect 2"
25128         fi
25129
25130         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25131         if [ "$stripe_index" != "$mdt_index" ]; then
25132                 error "stripe_index is $stripe_index, expect $mdt_index"
25133         fi
25134
25135         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25136                 error "nlink error after create striped dir"
25137
25138         mkdir $DIR/$tdir/striped_dir/a
25139         mkdir $DIR/$tdir/striped_dir/b
25140
25141         stat $DIR/$tdir/striped_dir/a ||
25142                 error "create dir under striped dir failed"
25143         stat $DIR/$tdir/striped_dir/b ||
25144                 error "create dir under striped dir failed"
25145
25146         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25147                 error "nlink error after mkdir"
25148
25149         rmdir $DIR/$tdir/striped_dir/a
25150         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25151                 error "nlink error after rmdir"
25152
25153         rmdir $DIR/$tdir/striped_dir/b
25154         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25155                 error "nlink error after rmdir"
25156
25157         chattr +i $DIR/$tdir/striped_dir
25158         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25159                 error "immutable flags not working under striped dir!"
25160         chattr -i $DIR/$tdir/striped_dir
25161
25162         rmdir $DIR/$tdir/striped_dir ||
25163                 error "rmdir striped dir error"
25164
25165         cleanup_test_300
25166
25167         true
25168 }
25169
25170 test_300a() {
25171         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25172                 skip "skipped for lustre < 2.7.0"
25173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25175
25176         test_striped_dir 0 || error "failed on striped dir on MDT0"
25177         test_striped_dir 1 || error "failed on striped dir on MDT0"
25178 }
25179 run_test 300a "basic striped dir sanity test"
25180
25181 test_300b() {
25182         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25183                 skip "skipped for lustre < 2.7.0"
25184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25186
25187         local i
25188         local mtime1
25189         local mtime2
25190         local mtime3
25191
25192         test_mkdir $DIR/$tdir || error "mkdir fail"
25193         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25194                 error "set striped dir error"
25195         for i in {0..9}; do
25196                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25197                 sleep 1
25198                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25199                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25200                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25201                 sleep 1
25202                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25203                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25204                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25205         done
25206         true
25207 }
25208 run_test 300b "check ctime/mtime for striped dir"
25209
25210 test_300c() {
25211         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25212                 skip "skipped for lustre < 2.7.0"
25213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25214         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25215
25216         local file_count
25217
25218         mkdir_on_mdt0 $DIR/$tdir
25219         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25220                 error "set striped dir error"
25221
25222         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25223                 error "chown striped dir failed"
25224
25225         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25226                 error "create 5k files failed"
25227
25228         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25229
25230         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25231
25232         rm -rf $DIR/$tdir
25233 }
25234 run_test 300c "chown && check ls under striped directory"
25235
25236 test_300d() {
25237         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25238                 skip "skipped for lustre < 2.7.0"
25239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25241
25242         local stripe_count
25243         local file
25244
25245         mkdir -p $DIR/$tdir
25246         $LFS setstripe -c 2 $DIR/$tdir
25247
25248         #local striped directory
25249         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25250                 error "set striped dir error"
25251         #look at the directories for debug purposes
25252         ls -l $DIR/$tdir
25253         $LFS getdirstripe $DIR/$tdir
25254         ls -l $DIR/$tdir/striped_dir
25255         $LFS getdirstripe $DIR/$tdir/striped_dir
25256         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25257                 error "create 10 files failed"
25258
25259         #remote striped directory
25260         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25261                 error "set striped dir error"
25262         #look at the directories for debug purposes
25263         ls -l $DIR/$tdir
25264         $LFS getdirstripe $DIR/$tdir
25265         ls -l $DIR/$tdir/remote_striped_dir
25266         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25267         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25268                 error "create 10 files failed"
25269
25270         for file in $(find $DIR/$tdir); do
25271                 stripe_count=$($LFS getstripe -c $file)
25272                 [ $stripe_count -eq 2 ] ||
25273                         error "wrong stripe $stripe_count for $file"
25274         done
25275
25276         rm -rf $DIR/$tdir
25277 }
25278 run_test 300d "check default stripe under striped directory"
25279
25280 test_300e() {
25281         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25282                 skip "Need MDS version at least 2.7.55"
25283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25285
25286         local stripe_count
25287         local file
25288
25289         mkdir -p $DIR/$tdir
25290
25291         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25292                 error "set striped dir error"
25293
25294         touch $DIR/$tdir/striped_dir/a
25295         touch $DIR/$tdir/striped_dir/b
25296         touch $DIR/$tdir/striped_dir/c
25297
25298         mkdir $DIR/$tdir/striped_dir/dir_a
25299         mkdir $DIR/$tdir/striped_dir/dir_b
25300         mkdir $DIR/$tdir/striped_dir/dir_c
25301
25302         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25303                 error "set striped adir under striped dir error"
25304
25305         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25306                 error "set striped bdir under striped dir error"
25307
25308         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25309                 error "set striped cdir under striped dir error"
25310
25311         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25312                 error "rename dir under striped dir fails"
25313
25314         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25315                 error "rename dir under different stripes fails"
25316
25317         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25318                 error "rename file under striped dir should succeed"
25319
25320         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25321                 error "rename dir under striped dir should succeed"
25322
25323         rm -rf $DIR/$tdir
25324 }
25325 run_test 300e "check rename under striped directory"
25326
25327 test_300f() {
25328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25329         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25330         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25331                 skip "Need MDS version at least 2.7.55"
25332
25333         local stripe_count
25334         local file
25335
25336         rm -rf $DIR/$tdir
25337         mkdir -p $DIR/$tdir
25338
25339         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25340                 error "set striped dir error"
25341
25342         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25343                 error "set striped dir error"
25344
25345         touch $DIR/$tdir/striped_dir/a
25346         mkdir $DIR/$tdir/striped_dir/dir_a
25347         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25348                 error "create striped dir under striped dir fails"
25349
25350         touch $DIR/$tdir/striped_dir1/b
25351         mkdir $DIR/$tdir/striped_dir1/dir_b
25352         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25353                 error "create striped dir under striped dir fails"
25354
25355         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25356                 error "rename dir under different striped dir should fail"
25357
25358         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25359                 error "rename striped dir under diff striped dir should fail"
25360
25361         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25362                 error "rename file under diff striped dirs fails"
25363
25364         rm -rf $DIR/$tdir
25365 }
25366 run_test 300f "check rename cross striped directory"
25367
25368 test_300_check_default_striped_dir()
25369 {
25370         local dirname=$1
25371         local default_count=$2
25372         local default_index=$3
25373         local stripe_count
25374         local stripe_index
25375         local dir_stripe_index
25376         local dir
25377
25378         echo "checking $dirname $default_count $default_index"
25379         $LFS setdirstripe -D -c $default_count -i $default_index \
25380                                 -H all_char $DIR/$tdir/$dirname ||
25381                 error "set default stripe on striped dir error"
25382         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25383         [ $stripe_count -eq $default_count ] ||
25384                 error "expect $default_count get $stripe_count for $dirname"
25385
25386         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25387         [ $stripe_index -eq $default_index ] ||
25388                 error "expect $default_index get $stripe_index for $dirname"
25389
25390         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25391                                                 error "create dirs failed"
25392
25393         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25394         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25395         for dir in $(find $DIR/$tdir/$dirname/*); do
25396                 stripe_count=$($LFS getdirstripe -c $dir)
25397                 (( $stripe_count == $default_count )) ||
25398                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25399                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25400                 error "stripe count $default_count != $stripe_count for $dir"
25401
25402                 stripe_index=$($LFS getdirstripe -i $dir)
25403                 [ $default_index -eq -1 ] ||
25404                         [ $stripe_index -eq $default_index ] ||
25405                         error "$stripe_index != $default_index for $dir"
25406
25407                 #check default stripe
25408                 stripe_count=$($LFS getdirstripe -D -c $dir)
25409                 [ $stripe_count -eq $default_count ] ||
25410                 error "default count $default_count != $stripe_count for $dir"
25411
25412                 stripe_index=$($LFS getdirstripe -D -i $dir)
25413                 [ $stripe_index -eq $default_index ] ||
25414                 error "default index $default_index != $stripe_index for $dir"
25415         done
25416         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25417 }
25418
25419 test_300g() {
25420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25421         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25422                 skip "Need MDS version at least 2.7.55"
25423
25424         local dir
25425         local stripe_count
25426         local stripe_index
25427
25428         mkdir_on_mdt0 $DIR/$tdir
25429         mkdir $DIR/$tdir/normal_dir
25430
25431         #Checking when client cache stripe index
25432         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25433         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25434                 error "create striped_dir failed"
25435
25436         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25437                 error "create dir0 fails"
25438         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25439         [ $stripe_index -eq 0 ] ||
25440                 error "dir0 expect index 0 got $stripe_index"
25441
25442         mkdir $DIR/$tdir/striped_dir/dir1 ||
25443                 error "create dir1 fails"
25444         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25445         [ $stripe_index -eq 1 ] ||
25446                 error "dir1 expect index 1 got $stripe_index"
25447
25448         #check default stripe count/stripe index
25449         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25450         test_300_check_default_striped_dir normal_dir 1 0
25451         test_300_check_default_striped_dir normal_dir -1 1
25452         test_300_check_default_striped_dir normal_dir 2 -1
25453
25454         #delete default stripe information
25455         echo "delete default stripeEA"
25456         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25457                 error "set default stripe on striped dir error"
25458
25459         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25460         for dir in $(find $DIR/$tdir/normal_dir/*); do
25461                 stripe_count=$($LFS getdirstripe -c $dir)
25462                 [ $stripe_count -eq 0 ] ||
25463                         error "expect 1 get $stripe_count for $dir"
25464         done
25465 }
25466 run_test 300g "check default striped directory for normal directory"
25467
25468 test_300h() {
25469         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25470         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25471                 skip "Need MDS version at least 2.7.55"
25472
25473         local dir
25474         local stripe_count
25475
25476         mkdir $DIR/$tdir
25477         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25478                 error "set striped dir error"
25479
25480         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25481         test_300_check_default_striped_dir striped_dir 1 0
25482         test_300_check_default_striped_dir striped_dir -1 1
25483         test_300_check_default_striped_dir striped_dir 2 -1
25484
25485         #delete default stripe information
25486         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25487                 error "set default stripe on striped dir error"
25488
25489         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25490         for dir in $(find $DIR/$tdir/striped_dir/*); do
25491                 stripe_count=$($LFS getdirstripe -c $dir)
25492                 [ $stripe_count -eq 0 ] ||
25493                         error "expect 1 get $stripe_count for $dir"
25494         done
25495 }
25496 run_test 300h "check default striped directory for striped directory"
25497
25498 test_300i() {
25499         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25500         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25501         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25502                 skip "Need MDS version at least 2.7.55"
25503
25504         local stripe_count
25505         local file
25506
25507         mkdir $DIR/$tdir
25508
25509         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25510                 error "set striped dir error"
25511
25512         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25513                 error "create files under striped dir failed"
25514
25515         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25516                 error "set striped hashdir error"
25517
25518         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25519                 error "create dir0 under hash dir failed"
25520         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25521                 error "create dir1 under hash dir failed"
25522         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25523                 error "create dir2 under hash dir failed"
25524
25525         # unfortunately, we need to umount to clear dir layout cache for now
25526         # once we fully implement dir layout, we can drop this
25527         umount_client $MOUNT || error "umount failed"
25528         mount_client $MOUNT || error "mount failed"
25529
25530         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25531         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25532         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25533
25534         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25535                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25536                         error "create crush2 dir $tdir/hashdir/d3 failed"
25537                 $LFS find -H crush2 $DIR/$tdir/hashdir
25538                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25539                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25540
25541                 # mkdir with an invalid hash type (hash=fail_val) from client
25542                 # should be replaced on MDS with a valid (default) hash type
25543                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25544                 $LCTL set_param fail_loc=0x1901 fail_val=99
25545                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25546
25547                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25548                 local expect=$(do_facet mds1 \
25549                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25550                 [[ $hash == $expect ]] ||
25551                         error "d99 hash '$hash' != expected hash '$expect'"
25552         fi
25553
25554         #set the stripe to be unknown hash type on read
25555         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25556         $LCTL set_param fail_loc=0x1901 fail_val=99
25557         for ((i = 0; i < 10; i++)); do
25558                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25559                         error "stat f-$i failed"
25560                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25561         done
25562
25563         touch $DIR/$tdir/striped_dir/f0 &&
25564                 error "create under striped dir with unknown hash should fail"
25565
25566         $LCTL set_param fail_loc=0
25567
25568         umount_client $MOUNT || error "umount failed"
25569         mount_client $MOUNT || error "mount failed"
25570
25571         return 0
25572 }
25573 run_test 300i "client handle unknown hash type striped directory"
25574
25575 test_300j() {
25576         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25578         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25579                 skip "Need MDS version at least 2.7.55"
25580
25581         local stripe_count
25582         local file
25583
25584         mkdir $DIR/$tdir
25585
25586         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25587         $LCTL set_param fail_loc=0x1702
25588         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25589                 error "set striped dir error"
25590
25591         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25592                 error "create files under striped dir failed"
25593
25594         $LCTL set_param fail_loc=0
25595
25596         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25597
25598         return 0
25599 }
25600 run_test 300j "test large update record"
25601
25602 test_300k() {
25603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25605         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25606                 skip "Need MDS version at least 2.7.55"
25607
25608         # this test needs a huge transaction
25609         local kb
25610         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25611              osd*.$FSNAME-MDT0000.kbytestotal")
25612         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25613
25614         local stripe_count
25615         local file
25616
25617         mkdir $DIR/$tdir
25618
25619         #define OBD_FAIL_LARGE_STRIPE   0x1703
25620         $LCTL set_param fail_loc=0x1703
25621         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25622                 error "set striped dir error"
25623         $LCTL set_param fail_loc=0
25624
25625         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25626                 error "getstripeddir fails"
25627         rm -rf $DIR/$tdir/striped_dir ||
25628                 error "unlink striped dir fails"
25629
25630         return 0
25631 }
25632 run_test 300k "test large striped directory"
25633
25634 test_300l() {
25635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25636         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25637         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25638                 skip "Need MDS version at least 2.7.55"
25639
25640         local stripe_index
25641
25642         test_mkdir -p $DIR/$tdir/striped_dir
25643         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25644                         error "chown $RUNAS_ID failed"
25645         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25646                 error "set default striped dir failed"
25647
25648         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25649         $LCTL set_param fail_loc=0x80000158
25650         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25651
25652         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25653         [ $stripe_index -eq 1 ] ||
25654                 error "expect 1 get $stripe_index for $dir"
25655 }
25656 run_test 300l "non-root user to create dir under striped dir with stale layout"
25657
25658 test_300m() {
25659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25660         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25661         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25662                 skip "Need MDS version at least 2.7.55"
25663
25664         mkdir -p $DIR/$tdir/striped_dir
25665         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25666                 error "set default stripes dir error"
25667
25668         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25669
25670         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25671         [ $stripe_count -eq 0 ] ||
25672                         error "expect 0 get $stripe_count for a"
25673
25674         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25675                 error "set default stripes dir error"
25676
25677         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25678
25679         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25680         [ $stripe_count -eq 0 ] ||
25681                         error "expect 0 get $stripe_count for b"
25682
25683         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25684                 error "set default stripes dir error"
25685
25686         mkdir $DIR/$tdir/striped_dir/c &&
25687                 error "default stripe_index is invalid, mkdir c should fails"
25688
25689         rm -rf $DIR/$tdir || error "rmdir fails"
25690 }
25691 run_test 300m "setstriped directory on single MDT FS"
25692
25693 cleanup_300n() {
25694         local list=$(comma_list $(mdts_nodes))
25695
25696         trap 0
25697         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25698 }
25699
25700 test_300n() {
25701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25703         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25704                 skip "Need MDS version at least 2.7.55"
25705         remote_mds_nodsh && skip "remote MDS with nodsh"
25706
25707         local stripe_index
25708         local list=$(comma_list $(mdts_nodes))
25709
25710         trap cleanup_300n RETURN EXIT
25711         mkdir -p $DIR/$tdir
25712         chmod 777 $DIR/$tdir
25713         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25714                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25715                 error "create striped dir succeeds with gid=0"
25716
25717         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25718         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25719                 error "create striped dir fails with gid=-1"
25720
25721         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25722         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25723                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25724                 error "set default striped dir succeeds with gid=0"
25725
25726
25727         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25728         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25729                 error "set default striped dir fails with gid=-1"
25730
25731
25732         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25733         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25734                                         error "create test_dir fails"
25735         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25736                                         error "create test_dir1 fails"
25737         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25738                                         error "create test_dir2 fails"
25739         cleanup_300n
25740 }
25741 run_test 300n "non-root user to create dir under striped dir with default EA"
25742
25743 test_300o() {
25744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25745         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25746         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25747                 skip "Need MDS version at least 2.7.55"
25748
25749         local numfree1
25750         local numfree2
25751
25752         mkdir -p $DIR/$tdir
25753
25754         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25755         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25756         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25757                 skip "not enough free inodes $numfree1 $numfree2"
25758         fi
25759
25760         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25761         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25762         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25763                 skip "not enough free space $numfree1 $numfree2"
25764         fi
25765
25766         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25767                 error "setdirstripe fails"
25768
25769         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25770                 error "create dirs fails"
25771
25772         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25773         ls $DIR/$tdir/striped_dir > /dev/null ||
25774                 error "ls striped dir fails"
25775         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25776                 error "unlink big striped dir fails"
25777 }
25778 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25779
25780 test_300p() {
25781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25782         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25783         remote_mds_nodsh && skip "remote MDS with nodsh"
25784
25785         mkdir_on_mdt0 $DIR/$tdir
25786
25787         #define OBD_FAIL_OUT_ENOSPC     0x1704
25788         do_facet mds2 lctl set_param fail_loc=0x80001704
25789         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25790                  && error "create striped directory should fail"
25791
25792         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25793
25794         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25795         true
25796 }
25797 run_test 300p "create striped directory without space"
25798
25799 test_300q() {
25800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25801         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25802
25803         local fd=$(free_fd)
25804         local cmd="exec $fd<$tdir"
25805         cd $DIR
25806         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25807         eval $cmd
25808         cmd="exec $fd<&-"
25809         trap "eval $cmd" EXIT
25810         cd $tdir || error "cd $tdir fails"
25811         rmdir  ../$tdir || error "rmdir $tdir fails"
25812         mkdir local_dir && error "create dir succeeds"
25813         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25814         eval $cmd
25815         return 0
25816 }
25817 run_test 300q "create remote directory under orphan directory"
25818
25819 test_300r() {
25820         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25821                 skip "Need MDS version at least 2.7.55" && return
25822         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25823
25824         mkdir $DIR/$tdir
25825
25826         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25827                 error "set striped dir error"
25828
25829         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25830                 error "getstripeddir fails"
25831
25832         local stripe_count
25833         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25834                       awk '/lmv_stripe_count:/ { print $2 }')
25835
25836         [ $MDSCOUNT -ne $stripe_count ] &&
25837                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25838
25839         rm -rf $DIR/$tdir/striped_dir ||
25840                 error "unlink striped dir fails"
25841 }
25842 run_test 300r "test -1 striped directory"
25843
25844 test_300s_helper() {
25845         local count=$1
25846
25847         local stripe_dir=$DIR/$tdir/striped_dir.$count
25848
25849         $LFS mkdir -c $count $stripe_dir ||
25850                 error "lfs mkdir -c error"
25851
25852         $LFS getdirstripe $stripe_dir ||
25853                 error "lfs getdirstripe fails"
25854
25855         local stripe_count
25856         stripe_count=$($LFS getdirstripe $stripe_dir |
25857                       awk '/lmv_stripe_count:/ { print $2 }')
25858
25859         [ $count -ne $stripe_count ] &&
25860                 error_noexit "bad stripe count $stripe_count expected $count"
25861
25862         local dupe_stripes
25863         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25864                 awk '/0x/ {count[$1] += 1}; END {
25865                         for (idx in count) {
25866                                 if (count[idx]>1) {
25867                                         print "index " idx " count " count[idx]
25868                                 }
25869                         }
25870                 }')
25871
25872         if [[ -n "$dupe_stripes" ]] ; then
25873                 lfs getdirstripe $stripe_dir
25874                 error_noexit "Dupe MDT above: $dupe_stripes "
25875         fi
25876
25877         rm -rf $stripe_dir ||
25878                 error_noexit "unlink $stripe_dir fails"
25879 }
25880
25881 test_300s() {
25882         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25883                 skip "Need MDS version at least 2.7.55" && return
25884         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25885
25886         mkdir $DIR/$tdir
25887         for count in $(seq 2 $MDSCOUNT); do
25888                 test_300s_helper $count
25889         done
25890 }
25891 run_test 300s "test lfs mkdir -c without -i"
25892
25893 test_300t() {
25894         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25895                 skip "need MDS 2.14.55 or later"
25896         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25897
25898         local testdir="$DIR/$tdir/striped_dir"
25899         local dir1=$testdir/dir1
25900         local dir2=$testdir/dir2
25901
25902         mkdir -p $testdir
25903
25904         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25905                 error "failed to set default stripe count for $testdir"
25906
25907         mkdir $dir1
25908         local stripe_count=$($LFS getdirstripe -c $dir1)
25909
25910         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25911
25912         local max_count=$((MDSCOUNT - 1))
25913         local mdts=$(comma_list $(mdts_nodes))
25914
25915         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25916         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25917
25918         mkdir $dir2
25919         stripe_count=$($LFS getdirstripe -c $dir2)
25920
25921         (( $stripe_count == $max_count )) || error "wrong stripe count"
25922 }
25923 run_test 300t "test max_mdt_stripecount"
25924
25925 prepare_remote_file() {
25926         mkdir $DIR/$tdir/src_dir ||
25927                 error "create remote source failed"
25928
25929         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25930                  error "cp to remote source failed"
25931         touch $DIR/$tdir/src_dir/a
25932
25933         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25934                 error "create remote target dir failed"
25935
25936         touch $DIR/$tdir/tgt_dir/b
25937
25938         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25939                 error "rename dir cross MDT failed!"
25940
25941         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25942                 error "src_child still exists after rename"
25943
25944         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25945                 error "missing file(a) after rename"
25946
25947         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25948                 error "diff after rename"
25949 }
25950
25951 test_310a() {
25952         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25954
25955         local remote_file=$DIR/$tdir/tgt_dir/b
25956
25957         mkdir -p $DIR/$tdir
25958
25959         prepare_remote_file || error "prepare remote file failed"
25960
25961         #open-unlink file
25962         $OPENUNLINK $remote_file $remote_file ||
25963                 error "openunlink $remote_file failed"
25964         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25965 }
25966 run_test 310a "open unlink remote file"
25967
25968 test_310b() {
25969         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25971
25972         local remote_file=$DIR/$tdir/tgt_dir/b
25973
25974         mkdir -p $DIR/$tdir
25975
25976         prepare_remote_file || error "prepare remote file failed"
25977
25978         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25979         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25980         $CHECKSTAT -t file $remote_file || error "check file failed"
25981 }
25982 run_test 310b "unlink remote file with multiple links while open"
25983
25984 test_310c() {
25985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25986         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25987
25988         local remote_file=$DIR/$tdir/tgt_dir/b
25989
25990         mkdir -p $DIR/$tdir
25991
25992         prepare_remote_file || error "prepare remote file failed"
25993
25994         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25995         multiop_bg_pause $remote_file O_uc ||
25996                         error "mulitop failed for remote file"
25997         MULTIPID=$!
25998         $MULTIOP $DIR/$tfile Ouc
25999         kill -USR1 $MULTIPID
26000         wait $MULTIPID
26001 }
26002 run_test 310c "open-unlink remote file with multiple links"
26003
26004 #LU-4825
26005 test_311() {
26006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26007         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26008         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26009                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26010         remote_mds_nodsh && skip "remote MDS with nodsh"
26011
26012         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26013         local mdts=$(comma_list $(mdts_nodes))
26014
26015         mkdir -p $DIR/$tdir
26016         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26017         createmany -o $DIR/$tdir/$tfile. 1000
26018
26019         # statfs data is not real time, let's just calculate it
26020         old_iused=$((old_iused + 1000))
26021
26022         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26023                         osp.*OST0000*MDT0000.create_count")
26024         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26025                                 osp.*OST0000*MDT0000.max_create_count")
26026         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26027
26028         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26029         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26030         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26031
26032         unlinkmany $DIR/$tdir/$tfile. 1000
26033
26034         do_nodes $mdts "$LCTL set_param -n \
26035                         osp.*OST0000*.max_create_count=$max_count"
26036         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26037                 do_nodes $mdts "$LCTL set_param -n \
26038                                 osp.*OST0000*.create_count=$count"
26039         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26040                         grep "=0" && error "create_count is zero"
26041
26042         local new_iused
26043         for i in $(seq 120); do
26044                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26045                 # system may be too busy to destroy all objs in time, use
26046                 # a somewhat small value to not fail autotest
26047                 [ $((old_iused - new_iused)) -gt 400 ] && break
26048                 sleep 1
26049         done
26050
26051         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26052         [ $((old_iused - new_iused)) -gt 400 ] ||
26053                 error "objs not destroyed after unlink"
26054 }
26055 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26056
26057 zfs_get_objid()
26058 {
26059         local ost=$1
26060         local tf=$2
26061         local fid=($($LFS getstripe $tf | grep 0x))
26062         local seq=${fid[3]#0x}
26063         local objid=${fid[1]}
26064
26065         local vdevdir=$(dirname $(facet_vdevice $ost))
26066         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26067         local zfs_zapid=$(do_facet $ost $cmd |
26068                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26069                           awk '/Object/{getline; print $1}')
26070         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26071                           awk "/$objid = /"'{printf $3}')
26072
26073         echo $zfs_objid
26074 }
26075
26076 zfs_object_blksz() {
26077         local ost=$1
26078         local objid=$2
26079
26080         local vdevdir=$(dirname $(facet_vdevice $ost))
26081         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26082         local blksz=$(do_facet $ost $cmd $objid |
26083                       awk '/dblk/{getline; printf $4}')
26084
26085         case "${blksz: -1}" in
26086                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26087                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26088                 *) ;;
26089         esac
26090
26091         echo $blksz
26092 }
26093
26094 test_312() { # LU-4856
26095         remote_ost_nodsh && skip "remote OST with nodsh"
26096         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26097
26098         local max_blksz=$(do_facet ost1 \
26099                           $ZFS get -p recordsize $(facet_device ost1) |
26100                           awk '!/VALUE/{print $3}')
26101         local tf=$DIR/$tfile
26102
26103         $LFS setstripe -c1 $tf
26104         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26105
26106         # Get ZFS object id
26107         local zfs_objid=$(zfs_get_objid $facet $tf)
26108         # block size change by sequential overwrite
26109         local bs
26110
26111         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26112                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26113
26114                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26115                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26116         done
26117         rm -f $tf
26118
26119         $LFS setstripe -c1 $tf
26120         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26121
26122         # block size change by sequential append write
26123         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26124         zfs_objid=$(zfs_get_objid $facet $tf)
26125         local count
26126
26127         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26128                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26129                         oflag=sync conv=notrunc
26130
26131                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26132                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26133                         error "blksz error, actual $blksz, " \
26134                                 "expected: 2 * $count * $PAGE_SIZE"
26135         done
26136         rm -f $tf
26137
26138         # random write
26139         $LFS setstripe -c1 $tf
26140         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26141         zfs_objid=$(zfs_get_objid $facet $tf)
26142
26143         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26144         blksz=$(zfs_object_blksz $facet $zfs_objid)
26145         (( blksz == PAGE_SIZE )) ||
26146                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26147
26148         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26149         blksz=$(zfs_object_blksz $facet $zfs_objid)
26150         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26151
26152         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26153         blksz=$(zfs_object_blksz $facet $zfs_objid)
26154         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26155 }
26156 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26157
26158 test_313() {
26159         remote_ost_nodsh && skip "remote OST with nodsh"
26160
26161         local file=$DIR/$tfile
26162
26163         rm -f $file
26164         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26165
26166         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26167         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26168         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26169                 error "write should failed"
26170         do_facet ost1 "$LCTL set_param fail_loc=0"
26171         rm -f $file
26172 }
26173 run_test 313 "io should fail after last_rcvd update fail"
26174
26175 test_314() {
26176         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26177
26178         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26179         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26180         rm -f $DIR/$tfile
26181         wait_delete_completed
26182         do_facet ost1 "$LCTL set_param fail_loc=0"
26183 }
26184 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26185
26186 test_315() { # LU-618
26187         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26188
26189         local file=$DIR/$tfile
26190         rm -f $file
26191
26192         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26193                 error "multiop file write failed"
26194         $MULTIOP $file oO_RDONLY:r4063232_c &
26195         PID=$!
26196
26197         sleep 2
26198
26199         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26200         kill -USR1 $PID
26201
26202         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26203         rm -f $file
26204 }
26205 run_test 315 "read should be accounted"
26206
26207 test_316() {
26208         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26209         large_xattr_enabled || skip "ea_inode feature disabled"
26210
26211         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26212         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26213         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26214         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26215
26216         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26217 }
26218 run_test 316 "lfs migrate of file with large_xattr enabled"
26219
26220 test_317() {
26221         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26222                 skip "Need MDS version at least 2.11.53"
26223         if [ "$ost1_FSTYPE" == "zfs" ]; then
26224                 skip "LU-10370: no implementation for ZFS"
26225         fi
26226
26227         local trunc_sz
26228         local grant_blk_size
26229
26230         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26231                         awk '/grant_block_size:/ { print $2; exit; }')
26232         #
26233         # Create File of size 5M. Truncate it to below size's and verify
26234         # blocks count.
26235         #
26236         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26237                 error "Create file $DIR/$tfile failed"
26238         stack_trap "rm -f $DIR/$tfile" EXIT
26239
26240         for trunc_sz in 2097152 4097 4000 509 0; do
26241                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26242                         error "truncate $tfile to $trunc_sz failed"
26243                 local sz=$(stat --format=%s $DIR/$tfile)
26244                 local blk=$(stat --format=%b $DIR/$tfile)
26245                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26246                                      grant_blk_size) * 8))
26247
26248                 if [[ $blk -ne $trunc_blk ]]; then
26249                         $(which stat) $DIR/$tfile
26250                         error "Expected Block $trunc_blk got $blk for $tfile"
26251                 fi
26252
26253                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26254                         error "Expected Size $trunc_sz got $sz for $tfile"
26255         done
26256
26257         #
26258         # sparse file test
26259         # Create file with a hole and write actual 65536 bytes which aligned
26260         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26261         #
26262         local bs=65536
26263         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26264                 error "Create file : $DIR/$tfile"
26265
26266         #
26267         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26268         # blocks. The block count must drop to 8.
26269         #
26270         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26271                 ((bs - grant_blk_size) + 1)))
26272         $TRUNCATE $DIR/$tfile $trunc_sz ||
26273                 error "truncate $tfile to $trunc_sz failed"
26274
26275         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26276         sz=$(stat --format=%s $DIR/$tfile)
26277         blk=$(stat --format=%b $DIR/$tfile)
26278
26279         if [[ $blk -ne $trunc_bsz ]]; then
26280                 $(which stat) $DIR/$tfile
26281                 error "Expected Block $trunc_bsz got $blk for $tfile"
26282         fi
26283
26284         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26285                 error "Expected Size $trunc_sz got $sz for $tfile"
26286 }
26287 run_test 317 "Verify blocks get correctly update after truncate"
26288
26289 test_318() {
26290         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26291         local old_max_active=$($LCTL get_param -n \
26292                             ${llite_name}.max_read_ahead_async_active \
26293                             2>/dev/null)
26294
26295         $LCTL set_param llite.*.max_read_ahead_async_active=256
26296         local max_active=$($LCTL get_param -n \
26297                            ${llite_name}.max_read_ahead_async_active \
26298                            2>/dev/null)
26299         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26300
26301         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26302                 error "set max_read_ahead_async_active should succeed"
26303
26304         $LCTL set_param llite.*.max_read_ahead_async_active=512
26305         max_active=$($LCTL get_param -n \
26306                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26307         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26308
26309         # restore @max_active
26310         [ $old_max_active -ne 0 ] && $LCTL set_param \
26311                 llite.*.max_read_ahead_async_active=$old_max_active
26312
26313         local old_threshold=$($LCTL get_param -n \
26314                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26315         local max_per_file_mb=$($LCTL get_param -n \
26316                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26317
26318         local invalid=$(($max_per_file_mb + 1))
26319         $LCTL set_param \
26320                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26321                         && error "set $invalid should fail"
26322
26323         local valid=$(($invalid - 1))
26324         $LCTL set_param \
26325                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26326                         error "set $valid should succeed"
26327         local threshold=$($LCTL get_param -n \
26328                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26329         [ $threshold -eq $valid ] || error \
26330                 "expect threshold $valid got $threshold"
26331         $LCTL set_param \
26332                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26333 }
26334 run_test 318 "Verify async readahead tunables"
26335
26336 test_319() {
26337         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26338
26339         local before=$(date +%s)
26340         local evict
26341         local mdir=$DIR/$tdir
26342         local file=$mdir/xxx
26343
26344         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26345         touch $file
26346
26347 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26348         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26349         $LFS migrate -m1 $mdir &
26350
26351         sleep 1
26352         dd if=$file of=/dev/null
26353         wait
26354         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26355           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26356
26357         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26358 }
26359 run_test 319 "lost lease lock on migrate error"
26360
26361 test_398a() { # LU-4198
26362         local ost1_imp=$(get_osc_import_name client ost1)
26363         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26364                          cut -d'.' -f2)
26365
26366         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26367         stack_trap "rm -f $DIR/$tfile"
26368         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26369
26370         # request a new lock on client
26371         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26372
26373         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26374         local lock_count=$($LCTL get_param -n \
26375                            ldlm.namespaces.$imp_name.lru_size)
26376         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26377
26378         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26379
26380         # no lock cached, should use lockless DIO and not enqueue new lock
26381         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26382         lock_count=$($LCTL get_param -n \
26383                      ldlm.namespaces.$imp_name.lru_size)
26384         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26385
26386         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26387
26388         # no lock cached, should use locked DIO append
26389         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26390                 conv=notrunc || error "DIO append failed"
26391         lock_count=$($LCTL get_param -n \
26392                      ldlm.namespaces.$imp_name.lru_size)
26393         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26394 }
26395 run_test 398a "direct IO should cancel lock otherwise lockless"
26396
26397 test_398b() { # LU-4198
26398         local before=$(date +%s)
26399         local njobs=4
26400         local size=48
26401
26402         which fio || skip_env "no fio installed"
26403         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26404         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26405
26406         # Single page, multiple pages, stripe size, 4*stripe size
26407         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26408                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26409                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26410                         --numjobs=$njobs --fallocate=none \
26411                         --iodepth=16 --allow_file_create=0 \
26412                         --size=$((size/njobs))M \
26413                         --filename=$DIR/$tfile &
26414                 bg_pid=$!
26415
26416                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26417                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26418                         --numjobs=$njobs --fallocate=none \
26419                         --iodepth=16 --allow_file_create=0 \
26420                         --size=$((size/njobs))M \
26421                         --filename=$DIR/$tfile || true
26422                 wait $bg_pid
26423         done
26424
26425         evict=$(do_facet client $LCTL get_param \
26426                 osc.$FSNAME-OST*-osc-*/state |
26427             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26428
26429         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26430                 (do_facet client $LCTL get_param \
26431                         osc.$FSNAME-OST*-osc-*/state;
26432                     error "eviction happened: $evict before:$before")
26433
26434         rm -f $DIR/$tfile
26435 }
26436 run_test 398b "DIO and buffer IO race"
26437
26438 test_398c() { # LU-4198
26439         local ost1_imp=$(get_osc_import_name client ost1)
26440         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26441                          cut -d'.' -f2)
26442
26443         which fio || skip_env "no fio installed"
26444
26445         saved_debug=$($LCTL get_param -n debug)
26446         $LCTL set_param debug=0
26447
26448         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26449         ((size /= 1024)) # by megabytes
26450         ((size /= 2)) # write half of the OST at most
26451         [ $size -gt 40 ] && size=40 #reduce test time anyway
26452
26453         $LFS setstripe -c 1 $DIR/$tfile
26454
26455         # it seems like ldiskfs reserves more space than necessary if the
26456         # writing blocks are not mapped, so it extends the file firstly
26457         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26458         cancel_lru_locks osc
26459
26460         # clear and verify rpc_stats later
26461         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26462
26463         local njobs=4
26464         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26465         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26466                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26467                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26468                 --filename=$DIR/$tfile
26469         [ $? -eq 0 ] || error "fio write error"
26470
26471         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26472                 error "Locks were requested while doing AIO"
26473
26474         # get the percentage of 1-page I/O
26475         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26476                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26477                 awk '{print $7}')
26478         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26479
26480         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26481         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26482                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26483                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26484                 --filename=$DIR/$tfile
26485         [ $? -eq 0 ] || error "fio mixed read write error"
26486
26487         echo "AIO with large block size ${size}M"
26488         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26489                 --numjobs=1 --fallocate=none --ioengine=libaio \
26490                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26491                 --filename=$DIR/$tfile
26492         [ $? -eq 0 ] || error "fio large block size failed"
26493
26494         rm -f $DIR/$tfile
26495         $LCTL set_param debug="$saved_debug"
26496 }
26497 run_test 398c "run fio to test AIO"
26498
26499 test_398d() { #  LU-13846
26500         which aiocp || skip_env "no aiocp installed"
26501         local aio_file=$DIR/$tfile.aio
26502
26503         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26504
26505         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26506         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26507         stack_trap "rm -f $DIR/$tfile $aio_file"
26508
26509         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26510
26511         # make sure we don't crash and fail properly
26512         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26513                 error "aio not aligned with PAGE SIZE should fail"
26514
26515         rm -f $DIR/$tfile $aio_file
26516 }
26517 run_test 398d "run aiocp to verify block size > stripe size"
26518
26519 test_398e() {
26520         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26521         touch $DIR/$tfile.new
26522         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26523 }
26524 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26525
26526 test_398f() { #  LU-14687
26527         which aiocp || skip_env "no aiocp installed"
26528         local aio_file=$DIR/$tfile.aio
26529
26530         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26531
26532         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26533         stack_trap "rm -f $DIR/$tfile $aio_file"
26534
26535         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26536         $LCTL set_param fail_loc=0x1418
26537         # make sure we don't crash and fail properly
26538         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26539                 error "aio with page allocation failure succeeded"
26540         $LCTL set_param fail_loc=0
26541         diff $DIR/$tfile $aio_file
26542         [[ $? != 0 ]] || error "no diff after failed aiocp"
26543 }
26544 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26545
26546 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26547 # stripe and i/o size must be > stripe size
26548 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26549 # single RPC in flight.  This test shows async DIO submission is working by
26550 # showing multiple RPCs in flight.
26551 test_398g() { #  LU-13798
26552         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26553
26554         # We need to do some i/o first to acquire enough grant to put our RPCs
26555         # in flight; otherwise a new connection may not have enough grant
26556         # available
26557         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26558                 error "parallel dio failed"
26559         stack_trap "rm -f $DIR/$tfile"
26560
26561         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26562         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26563         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26564         stack_trap "$LCTL set_param -n $pages_per_rpc"
26565
26566         # Recreate file so it's empty
26567         rm -f $DIR/$tfile
26568         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26569         #Pause rpc completion to guarantee we see multiple rpcs in flight
26570         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26571         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26572         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26573
26574         # Clear rpc stats
26575         $LCTL set_param osc.*.rpc_stats=c
26576
26577         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26578                 error "parallel dio failed"
26579         stack_trap "rm -f $DIR/$tfile"
26580
26581         $LCTL get_param osc.*-OST0000-*.rpc_stats
26582         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26583                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26584                 grep "8:" | awk '{print $8}')
26585         # We look at the "8 rpcs in flight" field, and verify A) it is present
26586         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26587         # as expected for an 8M DIO to a file with 1M stripes.
26588         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26589
26590         # Verify turning off parallel dio works as expected
26591         # Clear rpc stats
26592         $LCTL set_param osc.*.rpc_stats=c
26593         $LCTL set_param llite.*.parallel_dio=0
26594         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26595
26596         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26597                 error "dio with parallel dio disabled failed"
26598
26599         # Ideally, we would see only one RPC in flight here, but there is an
26600         # unavoidable race between i/o completion and RPC in flight counting,
26601         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26602         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26603         # So instead we just verify it's always < 8.
26604         $LCTL get_param osc.*-OST0000-*.rpc_stats
26605         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26606                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26607                 grep '^$' -B1 | grep . | awk '{print $1}')
26608         [ $ret != "8:" ] ||
26609                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26610 }
26611 run_test 398g "verify parallel dio async RPC submission"
26612
26613 test_398h() { #  LU-13798
26614         local dio_file=$DIR/$tfile.dio
26615
26616         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26617
26618         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26619         stack_trap "rm -f $DIR/$tfile $dio_file"
26620
26621         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26622                 error "parallel dio failed"
26623         diff $DIR/$tfile $dio_file
26624         [[ $? == 0 ]] || error "file diff after aiocp"
26625 }
26626 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26627
26628 test_398i() { #  LU-13798
26629         local dio_file=$DIR/$tfile.dio
26630
26631         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26632
26633         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26634         stack_trap "rm -f $DIR/$tfile $dio_file"
26635
26636         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26637         $LCTL set_param fail_loc=0x1418
26638         # make sure we don't crash and fail properly
26639         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26640                 error "parallel dio page allocation failure succeeded"
26641         diff $DIR/$tfile $dio_file
26642         [[ $? != 0 ]] || error "no diff after failed aiocp"
26643 }
26644 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26645
26646 test_398j() { #  LU-13798
26647         # Stripe size > RPC size but less than i/o size tests split across
26648         # stripes and RPCs for individual i/o op
26649         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26650
26651         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26652         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26653         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26654         stack_trap "$LCTL set_param -n $pages_per_rpc"
26655
26656         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26657                 error "parallel dio write failed"
26658         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26659
26660         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26661                 error "parallel dio read failed"
26662         diff $DIR/$tfile $DIR/$tfile.2
26663         [[ $? == 0 ]] || error "file diff after parallel dio read"
26664 }
26665 run_test 398j "test parallel dio where stripe size > rpc_size"
26666
26667 test_398k() { #  LU-13798
26668         wait_delete_completed
26669         wait_mds_ost_sync
26670
26671         # 4 stripe file; we will cause out of space on OST0
26672         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26673
26674         # Fill OST0 (if it's not too large)
26675         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26676                    head -n1)
26677         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26678                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26679         fi
26680         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26681         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26682                 error "dd should fill OST0"
26683         stack_trap "rm -f $DIR/$tfile.1"
26684
26685         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26686         err=$?
26687
26688         ls -la $DIR/$tfile
26689         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26690                 error "file is not 0 bytes in size"
26691
26692         # dd above should not succeed, but don't error until here so we can
26693         # get debug info above
26694         [[ $err != 0 ]] ||
26695                 error "parallel dio write with enospc succeeded"
26696         stack_trap "rm -f $DIR/$tfile"
26697 }
26698 run_test 398k "test enospc on first stripe"
26699
26700 test_398l() { #  LU-13798
26701         wait_delete_completed
26702         wait_mds_ost_sync
26703
26704         # 4 stripe file; we will cause out of space on OST0
26705         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26706         # happens on the second i/o chunk we issue
26707         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26708
26709         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26710         stack_trap "rm -f $DIR/$tfile"
26711
26712         # Fill OST0 (if it's not too large)
26713         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26714                    head -n1)
26715         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26716                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26717         fi
26718         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26719         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26720                 error "dd should fill OST0"
26721         stack_trap "rm -f $DIR/$tfile.1"
26722
26723         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26724         err=$?
26725         stack_trap "rm -f $DIR/$tfile.2"
26726
26727         # Check that short write completed as expected
26728         ls -la $DIR/$tfile.2
26729         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26730                 error "file is not 1M in size"
26731
26732         # dd above should not succeed, but don't error until here so we can
26733         # get debug info above
26734         [[ $err != 0 ]] ||
26735                 error "parallel dio write with enospc succeeded"
26736
26737         # Truncate source file to same length as output file and diff them
26738         $TRUNCATE $DIR/$tfile 1048576
26739         diff $DIR/$tfile $DIR/$tfile.2
26740         [[ $? == 0 ]] || error "data incorrect after short write"
26741 }
26742 run_test 398l "test enospc on intermediate stripe/RPC"
26743
26744 test_398m() { #  LU-13798
26745         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26746
26747         # Set up failure on OST0, the first stripe:
26748         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26749         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26750         # OST0 is on ost1, OST1 is on ost2.
26751         # So this fail_val specifies OST0
26752         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26753         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26754
26755         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26756                 error "parallel dio write with failure on first stripe succeeded"
26757         stack_trap "rm -f $DIR/$tfile"
26758         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26759
26760         # Place data in file for read
26761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26762                 error "parallel dio write failed"
26763
26764         # Fail read on OST0, first stripe
26765         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26766         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26767         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26768                 error "parallel dio read with error on first stripe succeeded"
26769         rm -f $DIR/$tfile.2
26770         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26771
26772         # Switch to testing on OST1, second stripe
26773         # Clear file contents, maintain striping
26774         echo > $DIR/$tfile
26775         # Set up failure on OST1, second stripe:
26776         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26777         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26778
26779         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26780                 error "parallel dio write with failure on second stripe succeeded"
26781         stack_trap "rm -f $DIR/$tfile"
26782         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26783
26784         # Place data in file for read
26785         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26786                 error "parallel dio write failed"
26787
26788         # Fail read on OST1, second stripe
26789         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26790         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26791         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26792                 error "parallel dio read with error on second stripe succeeded"
26793         rm -f $DIR/$tfile.2
26794         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26795 }
26796 run_test 398m "test RPC failures with parallel dio"
26797
26798 # Parallel submission of DIO should not cause problems for append, but it's
26799 # important to verify.
26800 test_398n() { #  LU-13798
26801         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26802
26803         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26804                 error "dd to create source file failed"
26805         stack_trap "rm -f $DIR/$tfile"
26806
26807         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26808                 error "parallel dio write with failure on second stripe succeeded"
26809         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26810         diff $DIR/$tfile $DIR/$tfile.1
26811         [[ $? == 0 ]] || error "data incorrect after append"
26812
26813 }
26814 run_test 398n "test append with parallel DIO"
26815
26816 test_398o() {
26817         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26818 }
26819 run_test 398o "right kms with DIO"
26820
26821 test_398p()
26822 {
26823         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26824         which aiocp || skip_env "no aiocp installed"
26825
26826         local stripe_size=$((1024 * 1024)) #1 MiB
26827         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26828         local file_size=$((25 * stripe_size))
26829
26830         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26831         stack_trap "rm -f $DIR/$tfile*"
26832         # Just a bit bigger than the largest size in the test set below
26833         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26834                 error "buffered i/o to create file failed"
26835
26836         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26837                 $((stripe_size * 4)); do
26838
26839                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26840
26841                 echo "bs: $bs, file_size $file_size"
26842                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26843                         $DIR/$tfile.1 $DIR/$tfile.2 &
26844                 pid_dio1=$!
26845                 # Buffered I/O with similar but not the same block size
26846                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26847                         conv=notrunc &
26848                 pid_bio2=$!
26849                 wait $pid_dio1
26850                 rc1=$?
26851                 wait $pid_bio2
26852                 rc2=$?
26853                 if (( rc1 != 0 )); then
26854                         error "aio copy 1 w/bsize $bs failed: $rc1"
26855                 fi
26856                 if (( rc2 != 0 )); then
26857                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26858                 fi
26859
26860                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26861                         error "size incorrect"
26862                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26863                         error "files differ, bsize $bs"
26864                 rm -f $DIR/$tfile.2
26865         done
26866 }
26867 run_test 398p "race aio with buffered i/o"
26868
26869 test_398q()
26870 {
26871         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26872
26873         local stripe_size=$((1024 * 1024)) #1 MiB
26874         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26875         local file_size=$((25 * stripe_size))
26876
26877         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26878         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26879
26880         # Just a bit bigger than the largest size in the test set below
26881         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26882                 error "buffered i/o to create file failed"
26883
26884         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26885                 $((stripe_size * 4)); do
26886
26887                 echo "bs: $bs, file_size $file_size"
26888                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26889                         conv=notrunc oflag=direct iflag=direct &
26890                 pid_dio1=$!
26891                 # Buffered I/O with similar but not the same block size
26892                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26893                         conv=notrunc &
26894                 pid_bio2=$!
26895                 wait $pid_dio1
26896                 rc1=$?
26897                 wait $pid_bio2
26898                 rc2=$?
26899                 if (( rc1 != 0 )); then
26900                         error "dio copy 1 w/bsize $bs failed: $rc1"
26901                 fi
26902                 if (( rc2 != 0 )); then
26903                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26904                 fi
26905
26906                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26907                         error "size incorrect"
26908                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26909                         error "files differ, bsize $bs"
26910         done
26911
26912         rm -f $DIR/$tfile*
26913 }
26914 run_test 398q "race dio with buffered i/o"
26915
26916 test_fake_rw() {
26917         local read_write=$1
26918         if [ "$read_write" = "write" ]; then
26919                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26920         elif [ "$read_write" = "read" ]; then
26921                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26922         else
26923                 error "argument error"
26924         fi
26925
26926         # turn off debug for performance testing
26927         local saved_debug=$($LCTL get_param -n debug)
26928         $LCTL set_param debug=0
26929
26930         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26931
26932         # get ost1 size - $FSNAME-OST0000
26933         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26934         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26935         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26936
26937         if [ "$read_write" = "read" ]; then
26938                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26939         fi
26940
26941         local start_time=$(date +%s.%N)
26942         $dd_cmd bs=1M count=$blocks oflag=sync ||
26943                 error "real dd $read_write error"
26944         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26945
26946         if [ "$read_write" = "write" ]; then
26947                 rm -f $DIR/$tfile
26948         fi
26949
26950         # define OBD_FAIL_OST_FAKE_RW           0x238
26951         do_facet ost1 $LCTL set_param fail_loc=0x238
26952
26953         local start_time=$(date +%s.%N)
26954         $dd_cmd bs=1M count=$blocks oflag=sync ||
26955                 error "fake dd $read_write error"
26956         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26957
26958         if [ "$read_write" = "write" ]; then
26959                 # verify file size
26960                 cancel_lru_locks osc
26961                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26962                         error "$tfile size not $blocks MB"
26963         fi
26964         do_facet ost1 $LCTL set_param fail_loc=0
26965
26966         echo "fake $read_write $duration_fake vs. normal $read_write" \
26967                 "$duration in seconds"
26968         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26969                 error_not_in_vm "fake write is slower"
26970
26971         $LCTL set_param -n debug="$saved_debug"
26972         rm -f $DIR/$tfile
26973 }
26974 test_399a() { # LU-7655 for OST fake write
26975         remote_ost_nodsh && skip "remote OST with nodsh"
26976
26977         test_fake_rw write
26978 }
26979 run_test 399a "fake write should not be slower than normal write"
26980
26981 test_399b() { # LU-8726 for OST fake read
26982         remote_ost_nodsh && skip "remote OST with nodsh"
26983         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26984                 skip_env "ldiskfs only test"
26985         fi
26986
26987         test_fake_rw read
26988 }
26989 run_test 399b "fake read should not be slower than normal read"
26990
26991 test_400a() { # LU-1606, was conf-sanity test_74
26992         if ! which $CC > /dev/null 2>&1; then
26993                 skip_env "$CC is not installed"
26994         fi
26995
26996         local extra_flags=''
26997         local out=$TMP/$tfile
26998         local prefix=/usr/include/lustre
26999         local prog
27000
27001         # Oleg removes .c files in his test rig so test if any c files exist
27002         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27003                 skip_env "Needed .c test files are missing"
27004
27005         if ! [[ -d $prefix ]]; then
27006                 # Assume we're running in tree and fixup the include path.
27007                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27008                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27009                 extra_flags+=" -L$LUSTRE/utils/.libs"
27010         fi
27011
27012         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27013                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27014                         error "client api broken"
27015         done
27016         rm -f $out
27017 }
27018 run_test 400a "Lustre client api program can compile and link"
27019
27020 test_400b() { # LU-1606, LU-5011
27021         local header
27022         local out=$TMP/$tfile
27023         local prefix=/usr/include/linux/lustre
27024
27025         # We use a hard coded prefix so that this test will not fail
27026         # when run in tree. There are headers in lustre/include/lustre/
27027         # that are not packaged (like lustre_idl.h) and have more
27028         # complicated include dependencies (like config.h and lnet/types.h).
27029         # Since this test about correct packaging we just skip them when
27030         # they don't exist (see below) rather than try to fixup cppflags.
27031
27032         if ! which $CC > /dev/null 2>&1; then
27033                 skip_env "$CC is not installed"
27034         fi
27035
27036         for header in $prefix/*.h; do
27037                 if ! [[ -f "$header" ]]; then
27038                         continue
27039                 fi
27040
27041                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27042                         continue # lustre_ioctl.h is internal header
27043                 fi
27044
27045                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27046                         error "cannot compile '$header'"
27047         done
27048         rm -f $out
27049 }
27050 run_test 400b "packaged headers can be compiled"
27051
27052 test_401a() { #LU-7437
27053         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27054         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27055
27056         #count the number of parameters by "list_param -R"
27057         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27058         #count the number of parameters by listing proc files
27059         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27060         echo "proc_dirs='$proc_dirs'"
27061         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27062         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27063                       sort -u | wc -l)
27064
27065         [ $params -eq $procs ] ||
27066                 error "found $params parameters vs. $procs proc files"
27067
27068         # test the list_param -D option only returns directories
27069         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27070         #count the number of parameters by listing proc directories
27071         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27072                 sort -u | wc -l)
27073
27074         [ $params -eq $procs ] ||
27075                 error "found $params parameters vs. $procs proc files"
27076 }
27077 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27078
27079 test_401b() {
27080         # jobid_var may not allow arbitrary values, so use jobid_name
27081         # if available
27082         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27083                 local testname=jobid_name tmp='testing%p'
27084         else
27085                 local testname=jobid_var tmp=testing
27086         fi
27087
27088         local save=$($LCTL get_param -n $testname)
27089
27090         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27091                 error "no error returned when setting bad parameters"
27092
27093         local jobid_new=$($LCTL get_param -n foe $testname baz)
27094         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27095
27096         $LCTL set_param -n fog=bam $testname=$save bat=fog
27097         local jobid_old=$($LCTL get_param -n foe $testname bag)
27098         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27099 }
27100 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27101
27102 test_401c() {
27103         # jobid_var may not allow arbitrary values, so use jobid_name
27104         # if available
27105         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27106                 local testname=jobid_name
27107         else
27108                 local testname=jobid_var
27109         fi
27110
27111         local jobid_var_old=$($LCTL get_param -n $testname)
27112         local jobid_var_new
27113
27114         $LCTL set_param $testname= &&
27115                 error "no error returned for 'set_param a='"
27116
27117         jobid_var_new=$($LCTL get_param -n $testname)
27118         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27119                 error "$testname was changed by setting without value"
27120
27121         $LCTL set_param $testname &&
27122                 error "no error returned for 'set_param a'"
27123
27124         jobid_var_new=$($LCTL get_param -n $testname)
27125         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27126                 error "$testname was changed by setting without value"
27127 }
27128 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27129
27130 test_401d() {
27131         # jobid_var may not allow arbitrary values, so use jobid_name
27132         # if available
27133         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27134                 local testname=jobid_name new_value='foo=bar%p'
27135         else
27136                 local testname=jobid_var new_valuie=foo=bar
27137         fi
27138
27139         local jobid_var_old=$($LCTL get_param -n $testname)
27140         local jobid_var_new
27141
27142         $LCTL set_param $testname=$new_value ||
27143                 error "'set_param a=b' did not accept a value containing '='"
27144
27145         jobid_var_new=$($LCTL get_param -n $testname)
27146         [[ "$jobid_var_new" == "$new_value" ]] ||
27147                 error "'set_param a=b' failed on a value containing '='"
27148
27149         # Reset the $testname to test the other format
27150         $LCTL set_param $testname=$jobid_var_old
27151         jobid_var_new=$($LCTL get_param -n $testname)
27152         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27153                 error "failed to reset $testname"
27154
27155         $LCTL set_param $testname $new_value ||
27156                 error "'set_param a b' did not accept a value containing '='"
27157
27158         jobid_var_new=$($LCTL get_param -n $testname)
27159         [[ "$jobid_var_new" == "$new_value" ]] ||
27160                 error "'set_param a b' failed on a value containing '='"
27161
27162         $LCTL set_param $testname $jobid_var_old
27163         jobid_var_new=$($LCTL get_param -n $testname)
27164         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27165                 error "failed to reset $testname"
27166 }
27167 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27168
27169 test_401e() { # LU-14779
27170         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27171                 error "lctl list_param MGC* failed"
27172         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27173         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27174                 error "lctl get_param lru_size failed"
27175 }
27176 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27177
27178 test_402() {
27179         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27180         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27181                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27182         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27183                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27184                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27185         remote_mds_nodsh && skip "remote MDS with nodsh"
27186
27187         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27188 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27189         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27190         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27191                 echo "Touch failed - OK"
27192 }
27193 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27194
27195 test_403() {
27196         local file1=$DIR/$tfile.1
27197         local file2=$DIR/$tfile.2
27198         local tfile=$TMP/$tfile
27199
27200         rm -f $file1 $file2 $tfile
27201
27202         touch $file1
27203         ln $file1 $file2
27204
27205         # 30 sec OBD_TIMEOUT in ll_getattr()
27206         # right before populating st_nlink
27207         $LCTL set_param fail_loc=0x80001409
27208         stat -c %h $file1 > $tfile &
27209
27210         # create an alias, drop all locks and reclaim the dentry
27211         < $file2
27212         cancel_lru_locks mdc
27213         cancel_lru_locks osc
27214         sysctl -w vm.drop_caches=2
27215
27216         wait
27217
27218         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27219
27220         rm -f $tfile $file1 $file2
27221 }
27222 run_test 403 "i_nlink should not drop to zero due to aliasing"
27223
27224 test_404() { # LU-6601
27225         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27226                 skip "Need server version newer than 2.8.52"
27227         remote_mds_nodsh && skip "remote MDS with nodsh"
27228
27229         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27230                 awk '/osp .*-osc-MDT/ { print $4}')
27231
27232         local osp
27233         for osp in $mosps; do
27234                 echo "Deactivate: " $osp
27235                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27236                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27237                         awk -vp=$osp '$4 == p { print $2 }')
27238                 [ $stat = IN ] || {
27239                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27240                         error "deactivate error"
27241                 }
27242                 echo "Activate: " $osp
27243                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27244                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27245                         awk -vp=$osp '$4 == p { print $2 }')
27246                 [ $stat = UP ] || {
27247                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27248                         error "activate error"
27249                 }
27250         done
27251 }
27252 run_test 404 "validate manual {de}activated works properly for OSPs"
27253
27254 test_405() {
27255         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27256         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27257                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27258                         skip "Layout swap lock is not supported"
27259
27260         check_swap_layouts_support
27261         check_swap_layout_no_dom $DIR
27262
27263         test_mkdir $DIR/$tdir
27264         swap_lock_test -d $DIR/$tdir ||
27265                 error "One layout swap locked test failed"
27266 }
27267 run_test 405 "Various layout swap lock tests"
27268
27269 test_406() {
27270         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27271         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27272         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27274         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27275                 skip "Need MDS version at least 2.8.50"
27276
27277         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27278         local test_pool=$TESTNAME
27279
27280         pool_add $test_pool || error "pool_add failed"
27281         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27282                 error "pool_add_targets failed"
27283
27284         save_layout_restore_at_exit $MOUNT
27285
27286         # parent set default stripe count only, child will stripe from both
27287         # parent and fs default
27288         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27289                 error "setstripe $MOUNT failed"
27290         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27291         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27292         for i in $(seq 10); do
27293                 local f=$DIR/$tdir/$tfile.$i
27294                 touch $f || error "touch failed"
27295                 local count=$($LFS getstripe -c $f)
27296                 [ $count -eq $OSTCOUNT ] ||
27297                         error "$f stripe count $count != $OSTCOUNT"
27298                 local offset=$($LFS getstripe -i $f)
27299                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27300                 local size=$($LFS getstripe -S $f)
27301                 [ $size -eq $((def_stripe_size * 2)) ] ||
27302                         error "$f stripe size $size != $((def_stripe_size * 2))"
27303                 local pool=$($LFS getstripe -p $f)
27304                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27305         done
27306
27307         # change fs default striping, delete parent default striping, now child
27308         # will stripe from new fs default striping only
27309         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27310                 error "change $MOUNT default stripe failed"
27311         $LFS setstripe -c 0 $DIR/$tdir ||
27312                 error "delete $tdir default stripe failed"
27313         for i in $(seq 11 20); do
27314                 local f=$DIR/$tdir/$tfile.$i
27315                 touch $f || error "touch $f failed"
27316                 local count=$($LFS getstripe -c $f)
27317                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27318                 local offset=$($LFS getstripe -i $f)
27319                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27320                 local size=$($LFS getstripe -S $f)
27321                 [ $size -eq $def_stripe_size ] ||
27322                         error "$f stripe size $size != $def_stripe_size"
27323                 local pool=$($LFS getstripe -p $f)
27324                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27325         done
27326
27327         unlinkmany $DIR/$tdir/$tfile. 1 20
27328
27329         local f=$DIR/$tdir/$tfile
27330         pool_remove_all_targets $test_pool $f
27331         pool_remove $test_pool $f
27332 }
27333 run_test 406 "DNE support fs default striping"
27334
27335 test_407() {
27336         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27337         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27338                 skip "Need MDS version at least 2.8.55"
27339         remote_mds_nodsh && skip "remote MDS with nodsh"
27340
27341         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27342                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27343         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27344                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27345         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27346
27347         #define OBD_FAIL_DT_TXN_STOP    0x2019
27348         for idx in $(seq $MDSCOUNT); do
27349                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27350         done
27351         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27352         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27353                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27354         true
27355 }
27356 run_test 407 "transaction fail should cause operation fail"
27357
27358 test_408() {
27359         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27360
27361         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27362         lctl set_param fail_loc=0x8000040a
27363         # let ll_prepare_partial_page() fail
27364         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27365
27366         rm -f $DIR/$tfile
27367
27368         # create at least 100 unused inodes so that
27369         # shrink_icache_memory(0) should not return 0
27370         touch $DIR/$tfile-{0..100}
27371         rm -f $DIR/$tfile-{0..100}
27372         sync
27373
27374         echo 2 > /proc/sys/vm/drop_caches
27375 }
27376 run_test 408 "drop_caches should not hang due to page leaks"
27377
27378 test_409()
27379 {
27380         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27381
27382         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27383         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27384         touch $DIR/$tdir/guard || error "(2) Fail to create"
27385
27386         local PREFIX=$(str_repeat 'A' 128)
27387         echo "Create 1K hard links start at $(date)"
27388         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27389                 error "(3) Fail to hard link"
27390
27391         echo "Links count should be right although linkEA overflow"
27392         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27393         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27394         [ $linkcount -eq 1001 ] ||
27395                 error "(5) Unexpected hard links count: $linkcount"
27396
27397         echo "List all links start at $(date)"
27398         ls -l $DIR/$tdir/foo > /dev/null ||
27399                 error "(6) Fail to list $DIR/$tdir/foo"
27400
27401         echo "Unlink hard links start at $(date)"
27402         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27403                 error "(7) Fail to unlink"
27404         echo "Unlink hard links finished at $(date)"
27405 }
27406 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27407
27408 test_410()
27409 {
27410         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27411                 skip "Need client version at least 2.9.59"
27412         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27413                 skip "Need MODULES build"
27414
27415         # Create a file, and stat it from the kernel
27416         local testfile=$DIR/$tfile
27417         touch $testfile
27418
27419         local run_id=$RANDOM
27420         local my_ino=$(stat --format "%i" $testfile)
27421
27422         # Try to insert the module. This will always fail as the
27423         # module is designed to not be inserted.
27424         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27425             &> /dev/null
27426
27427         # Anything but success is a test failure
27428         dmesg | grep -q \
27429             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27430             error "no inode match"
27431 }
27432 run_test 410 "Test inode number returned from kernel thread"
27433
27434 cleanup_test411_cgroup() {
27435         trap 0
27436         rmdir "$1"
27437 }
27438
27439 test_411() {
27440         local cg_basedir=/sys/fs/cgroup/memory
27441         # LU-9966
27442         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27443                 skip "no setup for cgroup"
27444
27445         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27446                 error "test file creation failed"
27447         cancel_lru_locks osc
27448
27449         # Create a very small memory cgroup to force a slab allocation error
27450         local cgdir=$cg_basedir/osc_slab_alloc
27451         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27452         trap "cleanup_test411_cgroup $cgdir" EXIT
27453         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27454         echo 1M > $cgdir/memory.limit_in_bytes
27455
27456         # Should not LBUG, just be killed by oom-killer
27457         # dd will return 0 even allocation failure in some environment.
27458         # So don't check return value
27459         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27460         cleanup_test411_cgroup $cgdir
27461
27462         return 0
27463 }
27464 run_test 411 "Slab allocation error with cgroup does not LBUG"
27465
27466 test_412() {
27467         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27468         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27469                 skip "Need server version at least 2.10.55"
27470
27471         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27472                 error "mkdir failed"
27473         $LFS getdirstripe $DIR/$tdir
27474         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27475         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27476                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27477         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27478         [ $stripe_count -eq 2 ] ||
27479                 error "expect 2 get $stripe_count"
27480
27481         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27482
27483         local index
27484         local index2
27485
27486         # subdirs should be on the same MDT as parent
27487         for i in $(seq 0 $((MDSCOUNT - 1))); do
27488                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27489                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27490                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27491                 (( index == i )) || error "mdt$i/sub on MDT$index"
27492         done
27493
27494         # stripe offset -1, ditto
27495         for i in {1..10}; do
27496                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27497                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27498                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27499                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27500                 (( index == index2 )) ||
27501                         error "qos$i on MDT$index, sub on MDT$index2"
27502         done
27503
27504         local testdir=$DIR/$tdir/inherit
27505
27506         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27507         # inherit 2 levels
27508         for i in 1 2; do
27509                 testdir=$testdir/s$i
27510                 mkdir $testdir || error "mkdir $testdir failed"
27511                 index=$($LFS getstripe -m $testdir)
27512                 (( index == 1 )) ||
27513                         error "$testdir on MDT$index"
27514         done
27515
27516         # not inherit any more
27517         testdir=$testdir/s3
27518         mkdir $testdir || error "mkdir $testdir failed"
27519         getfattr -d -m dmv $testdir | grep dmv &&
27520                 error "default LMV set on $testdir" || true
27521 }
27522 run_test 412 "mkdir on specific MDTs"
27523
27524 TEST413_COUNT=${TEST413_COUNT:-200}
27525
27526 #
27527 # set_maxage() is used by test_413 only.
27528 # This is a helper function to set maxage. Does not return any value.
27529 # Input: maxage to set
27530 #
27531 set_maxage() {
27532         local lmv_qos_maxage
27533         local lod_qos_maxage
27534         local new_maxage=$1
27535
27536         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27537         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27538         stack_trap "$LCTL set_param \
27539                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27540         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27541                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27542         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27543                 lod.*.mdt_qos_maxage=$new_maxage
27544         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27545                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27546 }
27547
27548 generate_uneven_mdts() {
27549         local threshold=$1
27550         local ffree
27551         local bavail
27552         local max
27553         local min
27554         local max_index
27555         local min_index
27556         local tmp
27557         local i
27558
27559         echo
27560         echo "Check for uneven MDTs: "
27561
27562         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27563         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27564         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27565
27566         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27567         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27568         max_index=0
27569         min_index=0
27570         for ((i = 1; i < ${#ffree[@]}; i++)); do
27571                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27572                 if [ $tmp -gt $max ]; then
27573                         max=$tmp
27574                         max_index=$i
27575                 fi
27576                 if [ $tmp -lt $min ]; then
27577                         min=$tmp
27578                         min_index=$i
27579                 fi
27580         done
27581
27582         (( min > 0 )) || skip "low space on MDT$min_index"
27583         (( ${ffree[min_index]} > 0 )) ||
27584                 skip "no free files on MDT$min_index"
27585         (( ${ffree[min_index]} < 10000000 )) ||
27586                 skip "too many free files on MDT$min_index"
27587
27588         # Check if we need to generate uneven MDTs
27589         local diff=$(((max - min) * 100 / min))
27590         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27591         local testdir # individual folder within $testdirp
27592         local start
27593         local cmd
27594
27595         # fallocate is faster to consume space on MDT, if available
27596         if check_fallocate_supported mds$((min_index + 1)); then
27597                 cmd="fallocate -l 128K "
27598         else
27599                 cmd="dd if=/dev/zero bs=128K count=1 of="
27600         fi
27601
27602         echo "using cmd $cmd"
27603         for (( i = 0; diff < threshold; i++ )); do
27604                 testdir=${testdirp}/$i
27605                 [ -d $testdir ] && continue
27606
27607                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27608
27609                 mkdir -p $testdirp
27610                 # generate uneven MDTs, create till $threshold% diff
27611                 echo -n "weight diff=$diff% must be > $threshold% ..."
27612                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27613                 $LFS mkdir -i $min_index $testdir ||
27614                         error "mkdir $testdir failed"
27615                 $LFS setstripe -E 1M -L mdt $testdir ||
27616                         error "setstripe $testdir failed"
27617                 start=$SECONDS
27618                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27619                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27620                 done
27621                 sync; sleep 1; sync
27622
27623                 # wait for QOS to update
27624                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27625
27626                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27627                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27628                 max=$(((${ffree[max_index]} >> 8) *
27629                         (${bavail[max_index]} * bsize >> 16)))
27630                 min=$(((${ffree[min_index]} >> 8) *
27631                         (${bavail[min_index]} * bsize >> 16)))
27632                 (( min > 0 )) || skip "low space on MDT$min_index"
27633                 diff=$(((max - min) * 100 / min))
27634         done
27635
27636         echo "MDT filesfree available: ${ffree[*]}"
27637         echo "MDT blocks available: ${bavail[*]}"
27638         echo "weight diff=$diff%"
27639 }
27640
27641 test_qos_mkdir() {
27642         local mkdir_cmd=$1
27643         local stripe_count=$2
27644         local mdts=$(comma_list $(mdts_nodes))
27645
27646         local testdir
27647         local lmv_qos_prio_free
27648         local lmv_qos_threshold_rr
27649         local lod_qos_prio_free
27650         local lod_qos_threshold_rr
27651         local total
27652         local count
27653         local i
27654
27655         # @total is total directories created if it's testing plain
27656         # directories, otherwise it's total stripe object count for
27657         # striped directories test.
27658         # remote/striped directory unlinking is slow on zfs and may
27659         # timeout, test with fewer directories
27660         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27661
27662         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27663         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27664         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27665                 head -n1)
27666         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27667         stack_trap "$LCTL set_param \
27668                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27669         stack_trap "$LCTL set_param \
27670                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27671
27672         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27673                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27674         lod_qos_prio_free=${lod_qos_prio_free%%%}
27675         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27676                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27677         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27678         stack_trap "do_nodes $mdts $LCTL set_param \
27679                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27680         stack_trap "do_nodes $mdts $LCTL set_param \
27681                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27682
27683         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27684         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27685
27686         testdir=$DIR/$tdir-s$stripe_count/rr
27687
27688         local stripe_index=$($LFS getstripe -m $testdir)
27689         local test_mkdir_rr=true
27690
27691         getfattr -d -m dmv -e hex $testdir | grep dmv
27692         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27693                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27694                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27695                         test_mkdir_rr=false
27696         fi
27697
27698         echo
27699         $test_mkdir_rr &&
27700                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27701                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27702
27703         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27704         for (( i = 0; i < total / stripe_count; i++ )); do
27705                 eval $mkdir_cmd $testdir/subdir$i ||
27706                         error "$mkdir_cmd subdir$i failed"
27707         done
27708
27709         for (( i = 0; i < $MDSCOUNT; i++ )); do
27710                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27711                 echo "$count directories created on MDT$i"
27712                 if $test_mkdir_rr; then
27713                         (( count == total / stripe_count / MDSCOUNT )) ||
27714                                 error "subdirs are not evenly distributed"
27715                 elif (( i == stripe_index )); then
27716                         (( count == total / stripe_count )) ||
27717                                 error "$count subdirs created on MDT$i"
27718                 else
27719                         (( count == 0 )) ||
27720                                 error "$count subdirs created on MDT$i"
27721                 fi
27722
27723                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27724                         count=$($LFS getdirstripe $testdir/* |
27725                                 grep -c -P "^\s+$i\t")
27726                         echo "$count stripes created on MDT$i"
27727                         # deviation should < 5% of average
27728                         delta=$((count - total / MDSCOUNT))
27729                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27730                                 error "stripes are not evenly distributed"
27731                 fi
27732         done
27733
27734         echo
27735         echo "Check for uneven MDTs: "
27736
27737         local ffree
27738         local bavail
27739         local max
27740         local min
27741         local max_index
27742         local min_index
27743         local tmp
27744
27745         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27746         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27747         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27748
27749         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27750         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27751         max_index=0
27752         min_index=0
27753         for ((i = 1; i < ${#ffree[@]}; i++)); do
27754                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27755                 if [ $tmp -gt $max ]; then
27756                         max=$tmp
27757                         max_index=$i
27758                 fi
27759                 if [ $tmp -lt $min ]; then
27760                         min=$tmp
27761                         min_index=$i
27762                 fi
27763         done
27764         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27765
27766         (( min > 0 )) || skip "low space on MDT$min_index"
27767         (( ${ffree[min_index]} < 10000000 )) ||
27768                 skip "too many free files on MDT$min_index"
27769
27770         generate_uneven_mdts 120
27771
27772         echo "MDT filesfree available: ${ffree[*]}"
27773         echo "MDT blocks available: ${bavail[*]}"
27774         echo "weight diff=$(((max - min) * 100 / min))%"
27775         echo
27776         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27777
27778         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27779         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27780         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27781         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27782         # decrease statfs age, so that it can be updated in time
27783         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27784         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27785
27786         sleep 1
27787
27788         testdir=$DIR/$tdir-s$stripe_count/qos
27789
27790         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27791         for (( i = 0; i < total / stripe_count; i++ )); do
27792                 eval $mkdir_cmd $testdir/subdir$i ||
27793                         error "$mkdir_cmd subdir$i failed"
27794         done
27795
27796         max=0
27797         for (( i = 0; i < $MDSCOUNT; i++ )); do
27798                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27799                 (( count > max )) && max=$count
27800                 echo "$count directories created on MDT$i : curmax=$max"
27801         done
27802
27803         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27804
27805         # D-value should > 10% of average
27806         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27807                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27808
27809         # ditto for stripes
27810         if (( stripe_count > 1 )); then
27811                 max=0
27812                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27813                         count=$($LFS getdirstripe $testdir/* |
27814                                 grep -c -P "^\s+$i\t")
27815                         (( count > max )) && max=$count
27816                         echo "$count stripes created on MDT$i"
27817                 done
27818
27819                 min=$($LFS getdirstripe $testdir/* |
27820                         grep -c -P "^\s+$min_index\t")
27821                 (( max - min > total / MDSCOUNT / 10 )) ||
27822                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27823         fi
27824 }
27825
27826 most_full_mdt() {
27827         local ffree
27828         local bavail
27829         local bsize
27830         local min
27831         local min_index
27832         local tmp
27833
27834         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27835         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27836         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27837
27838         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27839         min_index=0
27840         for ((i = 1; i < ${#ffree[@]}; i++)); do
27841                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27842                 (( tmp < min )) && min=$tmp && min_index=$i
27843         done
27844
27845         echo -n $min_index
27846 }
27847
27848 test_413a() {
27849         [ $MDSCOUNT -lt 2 ] &&
27850                 skip "We need at least 2 MDTs for this test"
27851
27852         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27853                 skip "Need server version at least 2.12.52"
27854
27855         local stripe_max=$((MDSCOUNT - 1))
27856         local stripe_count
27857
27858         # let caller set maxage for latest result
27859         set_maxage 1
27860
27861         # fill MDT unevenly
27862         generate_uneven_mdts 120
27863
27864         # test 4-stripe directory at most, otherwise it's too slow
27865         # We are being very defensive. Although Autotest uses 4 MDTs.
27866         # We make sure stripe_max does not go over 4.
27867         (( stripe_max > 4 )) && stripe_max=4
27868         # unlinking striped directory is slow on zfs, and may timeout, only test
27869         # plain directory
27870         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27871         for stripe_count in $(seq 1 $stripe_max); do
27872                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27873                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27874                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27875                         error "mkdir failed"
27876                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27877         done
27878 }
27879 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27880
27881 test_413b() {
27882         [ $MDSCOUNT -lt 2 ] &&
27883                 skip "We need at least 2 MDTs for this test"
27884
27885         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27886                 skip "Need server version at least 2.12.52"
27887
27888         local stripe_max=$((MDSCOUNT - 1))
27889         local testdir
27890         local stripe_count
27891
27892         # let caller set maxage for latest result
27893         set_maxage 1
27894
27895         # fill MDT unevenly
27896         generate_uneven_mdts 120
27897
27898         # test 4-stripe directory at most, otherwise it's too slow
27899         # We are being very defensive. Although Autotest uses 4 MDTs.
27900         # We make sure stripe_max does not go over 4.
27901         (( stripe_max > 4 )) && stripe_max=4
27902         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27903         for stripe_count in $(seq 1 $stripe_max); do
27904                 testdir=$DIR/$tdir-s$stripe_count
27905                 mkdir $testdir || error "mkdir $testdir failed"
27906                 mkdir $testdir/rr || error "mkdir rr failed"
27907                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27908                         error "mkdir qos failed"
27909                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27910                         $testdir/rr || error "setdirstripe rr failed"
27911                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27912                         error "setdirstripe failed"
27913                 test_qos_mkdir "mkdir" $stripe_count
27914         done
27915 }
27916 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27917
27918 test_413c() {
27919         (( $MDSCOUNT >= 2 )) ||
27920                 skip "We need at least 2 MDTs for this test"
27921
27922         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27923                 skip "Need server version at least 2.14.51"
27924
27925         local testdir
27926         local inherit
27927         local inherit_rr
27928         local lmv_qos_maxage
27929         local lod_qos_maxage
27930
27931         # let caller set maxage for latest result
27932         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27933         $LCTL set_param lmv.*.qos_maxage=1
27934         stack_trap "$LCTL set_param \
27935                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27936         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27937                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27938         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27939                 lod.*.mdt_qos_maxage=1
27940         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27941                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27942
27943         # fill MDT unevenly
27944         generate_uneven_mdts 120
27945
27946         testdir=$DIR/${tdir}-s1
27947         mkdir $testdir || error "mkdir $testdir failed"
27948         mkdir $testdir/rr || error "mkdir rr failed"
27949         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27950         # default max_inherit is -1, default max_inherit_rr is 0
27951         $LFS setdirstripe -D -c 1 $testdir/rr ||
27952                 error "setdirstripe rr failed"
27953         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27954                 error "setdirstripe qos failed"
27955         test_qos_mkdir "mkdir" 1
27956
27957         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27958         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27959         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27960         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27961         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27962
27963         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27964         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27965         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27966         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27967         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27968         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27969         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27970                 error "level2 shouldn't have default LMV" || true
27971 }
27972 run_test 413c "mkdir with default LMV max inherit rr"
27973
27974 test_413d() {
27975         (( MDSCOUNT >= 2 )) ||
27976                 skip "We need at least 2 MDTs for this test"
27977
27978         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27979                 skip "Need server version at least 2.14.51"
27980
27981         local lmv_qos_threshold_rr
27982
27983         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27984                 head -n1)
27985         stack_trap "$LCTL set_param \
27986                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27987
27988         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27989         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27990         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27991                 error "$tdir shouldn't have default LMV"
27992         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27993                 error "mkdir sub failed"
27994
27995         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27996
27997         (( count == 100 )) || error "$count subdirs on MDT0"
27998 }
27999 run_test 413d "inherit ROOT default LMV"
28000
28001 test_413e() {
28002         (( MDSCOUNT >= 2 )) ||
28003                 skip "We need at least 2 MDTs for this test"
28004         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28005                 skip "Need server version at least 2.14.55"
28006
28007         local testdir=$DIR/$tdir
28008         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28009         local max_inherit
28010         local sub_max_inherit
28011
28012         mkdir -p $testdir || error "failed to create $testdir"
28013
28014         # set default max-inherit to -1 if stripe count is 0 or 1
28015         $LFS setdirstripe -D -c 1 $testdir ||
28016                 error "failed to set default LMV"
28017         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28018         (( max_inherit == -1 )) ||
28019                 error "wrong max_inherit value $max_inherit"
28020
28021         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28022         $LFS setdirstripe -D -c -1 $testdir ||
28023                 error "failed to set default LMV"
28024         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28025         (( max_inherit > 0 )) ||
28026                 error "wrong max_inherit value $max_inherit"
28027
28028         # and the subdir will decrease the max_inherit by 1
28029         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28030         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28031         (( sub_max_inherit == max_inherit - 1)) ||
28032                 error "wrong max-inherit of subdir $sub_max_inherit"
28033
28034         # check specified --max-inherit and warning message
28035         stack_trap "rm -f $tmpfile"
28036         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28037                 error "failed to set default LMV"
28038         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28039         (( max_inherit == -1 )) ||
28040                 error "wrong max_inherit value $max_inherit"
28041
28042         # check the warning messages
28043         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28044                 error "failed to detect warning string"
28045         fi
28046 }
28047 run_test 413e "check default max-inherit value"
28048
28049 test_fs_dmv_inherit()
28050 {
28051         local testdir=$DIR/$tdir
28052
28053         local count
28054         local inherit
28055         local inherit_rr
28056
28057         for i in 1 2; do
28058                 mkdir $testdir || error "mkdir $testdir failed"
28059                 count=$($LFS getdirstripe -D -c $testdir)
28060                 (( count == 1 )) ||
28061                         error "$testdir default LMV count mismatch $count != 1"
28062                 inherit=$($LFS getdirstripe -D -X $testdir)
28063                 (( inherit == 3 - i )) ||
28064                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28065                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28066                 (( inherit_rr == 3 - i )) ||
28067                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28068                 testdir=$testdir/sub
28069         done
28070
28071         mkdir $testdir || error "mkdir $testdir failed"
28072         count=$($LFS getdirstripe -D -c $testdir)
28073         (( count == 0 )) ||
28074                 error "$testdir default LMV count not zero: $count"
28075 }
28076
28077 test_413f() {
28078         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28079
28080         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28081                 skip "Need server version at least 2.14.55"
28082
28083         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28084                 error "dump $DIR default LMV failed"
28085         stack_trap "setfattr --restore=$TMP/dmv.ea"
28086
28087         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28088                 error "set $DIR default LMV failed"
28089
28090         test_fs_dmv_inherit
28091 }
28092 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28093
28094 test_413g() {
28095         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28096
28097         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28098         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28099                 error "dump $DIR default LMV failed"
28100         stack_trap "setfattr --restore=$TMP/dmv.ea"
28101
28102         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28103                 error "set $DIR default LMV failed"
28104
28105         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28106                 error "mount $MOUNT2 failed"
28107         stack_trap "umount_client $MOUNT2"
28108
28109         local saved_DIR=$DIR
28110
28111         export DIR=$MOUNT2
28112
28113         stack_trap "export DIR=$saved_DIR"
28114
28115         # first check filesystem-wide default LMV inheritance
28116         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28117
28118         # then check subdirs are spread to all MDTs
28119         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28120
28121         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28122
28123         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28124 }
28125 run_test 413g "enforce ROOT default LMV on subdir mount"
28126
28127 test_413h() {
28128         (( MDSCOUNT >= 2 )) ||
28129                 skip "We need at least 2 MDTs for this test"
28130
28131         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28132                 skip "Need server version at least 2.15.50.6"
28133
28134         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28135
28136         stack_trap "$LCTL set_param \
28137                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28138         $LCTL set_param lmv.*.qos_maxage=1
28139
28140         local depth=5
28141         local rr_depth=4
28142         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28143         local count=$((MDSCOUNT * 20))
28144
28145         generate_uneven_mdts 50
28146
28147         mkdir -p $dir || error "mkdir $dir failed"
28148         stack_trap "rm -rf $dir"
28149         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28150                 --max-inherit-rr=$rr_depth $dir
28151
28152         for ((d=0; d < depth + 2; d++)); do
28153                 log "dir=$dir:"
28154                 for ((sub=0; sub < count; sub++)); do
28155                         mkdir $dir/d$sub
28156                 done
28157                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28158                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28159                 # subdirs within $rr_depth should be created round-robin
28160                 if (( d < rr_depth )); then
28161                         (( ${num[0]} != count )) ||
28162                                 error "all objects created on MDT ${num[1]}"
28163                 fi
28164
28165                 dir=$dir/d0
28166         done
28167 }
28168 run_test 413h "don't stick to parent for round-robin dirs"
28169
28170 test_413i() {
28171         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28172
28173         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28174                 skip "Need server version at least 2.14.55"
28175
28176         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28177                 error "dump $DIR default LMV failed"
28178         stack_trap "setfattr --restore=$TMP/dmv.ea"
28179
28180         local testdir=$DIR/$tdir
28181         local def_max_rr=1
28182         local def_max=3
28183         local count
28184
28185         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28186                 --max-inherit-rr=$def_max_rr $DIR ||
28187                 error "set $DIR default LMV failed"
28188
28189         for i in $(seq 2 3); do
28190                 def_max=$((def_max - 1))
28191                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28192
28193                 mkdir $testdir
28194                 # RR is decremented and keeps zeroed once exhausted
28195                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28196                 (( count == def_max_rr )) ||
28197                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28198
28199                 # max-inherit is decremented
28200                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28201                 (( count == def_max )) ||
28202                         error_noexit "$testdir: max-inherit $count != $def_max"
28203
28204                 testdir=$testdir/d$i
28205         done
28206
28207         # d3 is the last inherited from ROOT, no inheritance anymore
28208         # i.e. no the default layout anymore
28209         mkdir -p $testdir/d4/d5
28210         count=$($LFS getdirstripe -D --max-inherit $testdir)
28211         (( count == -1 )) ||
28212                 error_noexit "$testdir: max-inherit $count != -1"
28213
28214         local p_count=$($LFS getdirstripe -i $testdir)
28215
28216         for i in $(seq 4 5); do
28217                 testdir=$testdir/d$i
28218
28219                 # the root default layout is not applied once exhausted
28220                 count=$($LFS getdirstripe -i $testdir)
28221                 (( count == p_count )) ||
28222                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28223         done
28224
28225         $LFS setdirstripe -i 0 $DIR/d2
28226         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28227         (( count == -1 )) ||
28228                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28229 }
28230 run_test 413i "check default layout inheritance"
28231
28232 test_413z() {
28233         local pids=""
28234         local subdir
28235         local pid
28236
28237         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28238                 unlinkmany $subdir/f. $TEST413_COUNT &
28239                 pids="$pids $!"
28240         done
28241
28242         for pid in $pids; do
28243                 wait $pid
28244         done
28245
28246         true
28247 }
28248 run_test 413z "413 test cleanup"
28249
28250 test_414() {
28251 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28252         $LCTL set_param fail_loc=0x80000521
28253         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28254         rm -f $DIR/$tfile
28255 }
28256 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28257
28258 test_415() {
28259         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28260         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28261                 skip "Need server version at least 2.11.52"
28262
28263         # LU-11102
28264         local total=500
28265         local max=120
28266
28267         # this test may be slow on ZFS
28268         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28269
28270         # though this test is designed for striped directory, let's test normal
28271         # directory too since lock is always saved as CoS lock.
28272         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28273         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28274         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28275         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28276         wait_delete_completed_mds
28277
28278         # run a loop without concurrent touch to measure rename duration.
28279         # only for test debug/robustness, NOT part of COS functional test.
28280         local start_time=$SECONDS
28281         for ((i = 0; i < total; i++)); do
28282                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28283                         > /dev/null
28284         done
28285         local baseline=$((SECONDS - start_time))
28286         echo "rename $total files without 'touch' took $baseline sec"
28287
28288         (
28289                 while true; do
28290                         touch $DIR/$tdir
28291                 done
28292         ) &
28293         local setattr_pid=$!
28294
28295         # rename files back to original name so unlinkmany works
28296         start_time=$SECONDS
28297         for ((i = 0; i < total; i++)); do
28298                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28299                         > /dev/null
28300         done
28301         local duration=$((SECONDS - start_time))
28302
28303         kill -9 $setattr_pid
28304
28305         echo "rename $total files with 'touch' took $duration sec"
28306         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28307         (( duration <= max )) ||
28308                 error_not_in_vm "rename took $duration > $max sec"
28309 }
28310 run_test 415 "lock revoke is not missing"
28311
28312 test_416() {
28313         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28314                 skip "Need server version at least 2.11.55"
28315
28316         # define OBD_FAIL_OSD_TXN_START    0x19a
28317         do_facet mds1 lctl set_param fail_loc=0x19a
28318
28319         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28320
28321         true
28322 }
28323 run_test 416 "transaction start failure won't cause system hung"
28324
28325 cleanup_417() {
28326         trap 0
28327         do_nodes $(comma_list $(mdts_nodes)) \
28328                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28329         do_nodes $(comma_list $(mdts_nodes)) \
28330                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28331         do_nodes $(comma_list $(mdts_nodes)) \
28332                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28333 }
28334
28335 test_417() {
28336         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28337         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28338                 skip "Need MDS version at least 2.11.56"
28339
28340         trap cleanup_417 RETURN EXIT
28341
28342         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28343         do_nodes $(comma_list $(mdts_nodes)) \
28344                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28345         $LFS migrate -m 0 $DIR/$tdir.1 &&
28346                 error "migrate dir $tdir.1 should fail"
28347
28348         do_nodes $(comma_list $(mdts_nodes)) \
28349                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28350         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28351                 error "create remote dir $tdir.2 should fail"
28352
28353         do_nodes $(comma_list $(mdts_nodes)) \
28354                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28355         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28356                 error "create striped dir $tdir.3 should fail"
28357         true
28358 }
28359 run_test 417 "disable remote dir, striped dir and dir migration"
28360
28361 # Checks that the outputs of df [-i] and lfs df [-i] match
28362 #
28363 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28364 check_lfs_df() {
28365         local dir=$2
28366         local inodes
28367         local df_out
28368         local lfs_df_out
28369         local count
28370         local passed=false
28371
28372         # blocks or inodes
28373         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28374
28375         for count in {1..100}; do
28376                 do_nodes "$CLIENTS" \
28377                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28378                 sync; sleep 0.2
28379
28380                 # read the lines of interest
28381                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28382                         error "df $inodes $dir | tail -n +2 failed"
28383                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28384                         error "lfs df $inodes $dir | grep summary: failed"
28385
28386                 # skip first substrings of each output as they are different
28387                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28388                 # compare the two outputs
28389                 passed=true
28390                 #  skip "available" on MDT until LU-13997 is fixed.
28391                 #for i in {1..5}; do
28392                 for i in 1 2 4 5; do
28393                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28394                 done
28395                 $passed && break
28396         done
28397
28398         if ! $passed; then
28399                 df -P $inodes $dir
28400                 echo
28401                 lfs df $inodes $dir
28402                 error "df and lfs df $1 output mismatch: "      \
28403                       "df ${inodes}: ${df_out[*]}, "            \
28404                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28405         fi
28406 }
28407
28408 test_418() {
28409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28410
28411         local dir=$DIR/$tdir
28412         local numfiles=$((RANDOM % 4096 + 2))
28413         local numblocks=$((RANDOM % 256 + 1))
28414
28415         wait_delete_completed
28416         test_mkdir $dir
28417
28418         # check block output
28419         check_lfs_df blocks $dir
28420         # check inode output
28421         check_lfs_df inodes $dir
28422
28423         # create a single file and retest
28424         echo "Creating a single file and testing"
28425         createmany -o $dir/$tfile- 1 &>/dev/null ||
28426                 error "creating 1 file in $dir failed"
28427         check_lfs_df blocks $dir
28428         check_lfs_df inodes $dir
28429
28430         # create a random number of files
28431         echo "Creating $((numfiles - 1)) files and testing"
28432         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28433                 error "creating $((numfiles - 1)) files in $dir failed"
28434
28435         # write a random number of blocks to the first test file
28436         echo "Writing $numblocks 4K blocks and testing"
28437         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28438                 count=$numblocks &>/dev/null ||
28439                 error "dd to $dir/${tfile}-0 failed"
28440
28441         # retest
28442         check_lfs_df blocks $dir
28443         check_lfs_df inodes $dir
28444
28445         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28446                 error "unlinking $numfiles files in $dir failed"
28447 }
28448 run_test 418 "df and lfs df outputs match"
28449
28450 test_419()
28451 {
28452         local dir=$DIR/$tdir
28453
28454         mkdir -p $dir
28455         touch $dir/file
28456
28457         cancel_lru_locks mdc
28458
28459         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28460         $LCTL set_param fail_loc=0x1410
28461         cat $dir/file
28462         $LCTL set_param fail_loc=0
28463         rm -rf $dir
28464 }
28465 run_test 419 "Verify open file by name doesn't crash kernel"
28466
28467 test_420()
28468 {
28469         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28470                 skip "Need MDS version at least 2.12.53"
28471
28472         local SAVE_UMASK=$(umask)
28473         local dir=$DIR/$tdir
28474         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28475
28476         mkdir -p $dir
28477         umask 0000
28478         mkdir -m03777 $dir/testdir
28479         ls -dn $dir/testdir
28480         # Need to remove trailing '.' when SELinux is enabled
28481         local dirperms=$(ls -dn $dir/testdir |
28482                          awk '{ sub(/\.$/, "", $1); print $1}')
28483         [ $dirperms == "drwxrwsrwt" ] ||
28484                 error "incorrect perms on $dir/testdir"
28485
28486         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28487                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28488         ls -n $dir/testdir/testfile
28489         local fileperms=$(ls -n $dir/testdir/testfile |
28490                           awk '{ sub(/\.$/, "", $1); print $1}')
28491         [ $fileperms == "-rwxr-xr-x" ] ||
28492                 error "incorrect perms on $dir/testdir/testfile"
28493
28494         umask $SAVE_UMASK
28495 }
28496 run_test 420 "clear SGID bit on non-directories for non-members"
28497
28498 test_421a() {
28499         local cnt
28500         local fid1
28501         local fid2
28502
28503         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28504                 skip "Need MDS version at least 2.12.54"
28505
28506         test_mkdir $DIR/$tdir
28507         createmany -o $DIR/$tdir/f 3
28508         cnt=$(ls -1 $DIR/$tdir | wc -l)
28509         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28510
28511         fid1=$(lfs path2fid $DIR/$tdir/f1)
28512         fid2=$(lfs path2fid $DIR/$tdir/f2)
28513         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28514
28515         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28516         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28517
28518         cnt=$(ls -1 $DIR/$tdir | wc -l)
28519         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28520
28521         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28522         createmany -o $DIR/$tdir/f 3
28523         cnt=$(ls -1 $DIR/$tdir | wc -l)
28524         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28525
28526         fid1=$(lfs path2fid $DIR/$tdir/f1)
28527         fid2=$(lfs path2fid $DIR/$tdir/f2)
28528         echo "remove using fsname $FSNAME"
28529         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28530
28531         cnt=$(ls -1 $DIR/$tdir | wc -l)
28532         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28533 }
28534 run_test 421a "simple rm by fid"
28535
28536 test_421b() {
28537         local cnt
28538         local FID1
28539         local FID2
28540
28541         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28542                 skip "Need MDS version at least 2.12.54"
28543
28544         test_mkdir $DIR/$tdir
28545         createmany -o $DIR/$tdir/f 3
28546         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28547         MULTIPID=$!
28548
28549         FID1=$(lfs path2fid $DIR/$tdir/f1)
28550         FID2=$(lfs path2fid $DIR/$tdir/f2)
28551         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28552
28553         kill -USR1 $MULTIPID
28554         wait
28555
28556         cnt=$(ls $DIR/$tdir | wc -l)
28557         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28558 }
28559 run_test 421b "rm by fid on open file"
28560
28561 test_421c() {
28562         local cnt
28563         local FIDS
28564
28565         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28566                 skip "Need MDS version at least 2.12.54"
28567
28568         test_mkdir $DIR/$tdir
28569         createmany -o $DIR/$tdir/f 3
28570         touch $DIR/$tdir/$tfile
28571         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28572         cnt=$(ls -1 $DIR/$tdir | wc -l)
28573         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28574
28575         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28576         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28577
28578         cnt=$(ls $DIR/$tdir | wc -l)
28579         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28580 }
28581 run_test 421c "rm by fid against hardlinked files"
28582
28583 test_421d() {
28584         local cnt
28585         local FIDS
28586
28587         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28588                 skip "Need MDS version at least 2.12.54"
28589
28590         test_mkdir $DIR/$tdir
28591         createmany -o $DIR/$tdir/f 4097
28592         cnt=$(ls -1 $DIR/$tdir | wc -l)
28593         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28594
28595         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28596         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28597
28598         cnt=$(ls $DIR/$tdir | wc -l)
28599         rm -rf $DIR/$tdir
28600         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28601 }
28602 run_test 421d "rmfid en masse"
28603
28604 test_421e() {
28605         local cnt
28606         local FID
28607
28608         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28609         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28610                 skip "Need MDS version at least 2.12.54"
28611
28612         mkdir -p $DIR/$tdir
28613         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28614         createmany -o $DIR/$tdir/striped_dir/f 512
28615         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28616         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28617
28618         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28619                 sed "s/[/][^:]*://g")
28620         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28621
28622         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28623         rm -rf $DIR/$tdir
28624         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28625 }
28626 run_test 421e "rmfid in DNE"
28627
28628 test_421f() {
28629         local cnt
28630         local FID
28631
28632         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28633                 skip "Need MDS version at least 2.12.54"
28634
28635         test_mkdir $DIR/$tdir
28636         touch $DIR/$tdir/f
28637         cnt=$(ls -1 $DIR/$tdir | wc -l)
28638         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28639
28640         FID=$(lfs path2fid $DIR/$tdir/f)
28641         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28642         # rmfid should fail
28643         cnt=$(ls -1 $DIR/$tdir | wc -l)
28644         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28645
28646         chmod a+rw $DIR/$tdir
28647         ls -la $DIR/$tdir
28648         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28649         # rmfid should fail
28650         cnt=$(ls -1 $DIR/$tdir | wc -l)
28651         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28652
28653         rm -f $DIR/$tdir/f
28654         $RUNAS touch $DIR/$tdir/f
28655         FID=$(lfs path2fid $DIR/$tdir/f)
28656         echo "rmfid as root"
28657         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28658         cnt=$(ls -1 $DIR/$tdir | wc -l)
28659         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28660
28661         rm -f $DIR/$tdir/f
28662         $RUNAS touch $DIR/$tdir/f
28663         cnt=$(ls -1 $DIR/$tdir | wc -l)
28664         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28665         FID=$(lfs path2fid $DIR/$tdir/f)
28666         # rmfid w/o user_fid2path mount option should fail
28667         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28668         cnt=$(ls -1 $DIR/$tdir | wc -l)
28669         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28670
28671         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28672         stack_trap "rmdir $tmpdir"
28673         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28674                 error "failed to mount client'"
28675         stack_trap "umount_client $tmpdir"
28676
28677         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28678         # rmfid should succeed
28679         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28680         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28681
28682         # rmfid shouldn't allow to remove files due to dir's permission
28683         chmod a+rwx $tmpdir/$tdir
28684         touch $tmpdir/$tdir/f
28685         ls -la $tmpdir/$tdir
28686         FID=$(lfs path2fid $tmpdir/$tdir/f)
28687         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28688         return 0
28689 }
28690 run_test 421f "rmfid checks permissions"
28691
28692 test_421g() {
28693         local cnt
28694         local FIDS
28695
28696         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28697         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28698                 skip "Need MDS version at least 2.12.54"
28699
28700         mkdir -p $DIR/$tdir
28701         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28702         createmany -o $DIR/$tdir/striped_dir/f 512
28703         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28704         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28705
28706         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28707                 sed "s/[/][^:]*://g")
28708
28709         rm -f $DIR/$tdir/striped_dir/f1*
28710         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28711         removed=$((512 - cnt))
28712
28713         # few files have been just removed, so we expect
28714         # rmfid to fail on their fids
28715         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28716         [ $removed != $errors ] && error "$errors != $removed"
28717
28718         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28719         rm -rf $DIR/$tdir
28720         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28721 }
28722 run_test 421g "rmfid to return errors properly"
28723
28724 test_421h() {
28725         local mount_other
28726         local mount_ret
28727         local rmfid_ret
28728         local old_fid
28729         local fidA
28730         local fidB
28731         local fidC
28732         local fidD
28733
28734         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28735                 skip "Need MDS version at least 2.15.53"
28736
28737         test_mkdir $DIR/$tdir
28738         test_mkdir $DIR/$tdir/subdir
28739         touch $DIR/$tdir/subdir/file0
28740         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28741         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28742         rm -f $DIR/$tdir/subdir/file0
28743         touch $DIR/$tdir/subdir/fileA
28744         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28745         echo File $DIR/$tdir/subdir/fileA FID $fidA
28746         touch $DIR/$tdir/subdir/fileB
28747         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28748         echo File $DIR/$tdir/subdir/fileB FID $fidB
28749         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28750         touch $DIR/$tdir/subdir/fileC
28751         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28752         echo File $DIR/$tdir/subdir/fileC FID $fidC
28753         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28754         touch $DIR/$tdir/fileD
28755         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28756         echo File $DIR/$tdir/fileD FID $fidD
28757
28758         # mount another client mount point with subdirectory mount
28759         export FILESET=/$tdir/subdir
28760         mount_other=${MOUNT}_other
28761         mount_client $mount_other ${MOUNT_OPTS}
28762         mount_ret=$?
28763         export FILESET=""
28764         (( mount_ret == 0 )) || error "mount $mount_other failed"
28765
28766         echo Removing FIDs:
28767         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28768         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28769         rmfid_ret=$?
28770
28771         umount_client $mount_other || error "umount $mount_other failed"
28772
28773         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28774
28775         # fileA should have been deleted
28776         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28777
28778         # fileB should have been deleted
28779         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28780
28781         # fileC should not have been deleted, fid also exists outside of fileset
28782         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28783
28784         # fileD should not have been deleted, it exists outside of fileset
28785         stat $DIR/$tdir/fileD || error "fileD deleted"
28786 }
28787 run_test 421h "rmfid with fileset mount"
28788
28789 test_422() {
28790         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28791         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28792         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28793         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28794         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28795
28796         local amc=$(at_max_get client)
28797         local amo=$(at_max_get mds1)
28798         local timeout=`lctl get_param -n timeout`
28799
28800         at_max_set 0 client
28801         at_max_set 0 mds1
28802
28803 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28804         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28805                         fail_val=$(((2*timeout + 10)*1000))
28806         touch $DIR/$tdir/d3/file &
28807         sleep 2
28808 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28809         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28810                         fail_val=$((2*timeout + 5))
28811         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28812         local pid=$!
28813         sleep 1
28814         kill -9 $pid
28815         sleep $((2 * timeout))
28816         echo kill $pid
28817         kill -9 $pid
28818         lctl mark touch
28819         touch $DIR/$tdir/d2/file3
28820         touch $DIR/$tdir/d2/file4
28821         touch $DIR/$tdir/d2/file5
28822
28823         wait
28824         at_max_set $amc client
28825         at_max_set $amo mds1
28826
28827         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28828         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28829                 error "Watchdog is always throttled"
28830 }
28831 run_test 422 "kill a process with RPC in progress"
28832
28833 stat_test() {
28834     df -h $MOUNT &
28835     df -h $MOUNT &
28836     df -h $MOUNT &
28837     df -h $MOUNT &
28838     df -h $MOUNT &
28839     df -h $MOUNT &
28840 }
28841
28842 test_423() {
28843     local _stats
28844     # ensure statfs cache is expired
28845     sleep 2;
28846
28847     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28848     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28849
28850     return 0
28851 }
28852 run_test 423 "statfs should return a right data"
28853
28854 test_424() {
28855 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28856         $LCTL set_param fail_loc=0x80000522
28857         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28858         rm -f $DIR/$tfile
28859 }
28860 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28861
28862 test_425() {
28863         test_mkdir -c -1 $DIR/$tdir
28864         $LFS setstripe -c -1 $DIR/$tdir
28865
28866         lru_resize_disable "" 100
28867         stack_trap "lru_resize_enable" EXIT
28868
28869         sleep 5
28870
28871         for i in $(seq $((MDSCOUNT * 125))); do
28872                 local t=$DIR/$tdir/$tfile_$i
28873
28874                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28875                         error_noexit "Create file $t"
28876         done
28877         stack_trap "rm -rf $DIR/$tdir" EXIT
28878
28879         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28880                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28881                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28882
28883                 [ $lock_count -le $lru_size ] ||
28884                         error "osc lock count $lock_count > lru size $lru_size"
28885         done
28886
28887         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28888                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28889                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28890
28891                 [ $lock_count -le $lru_size ] ||
28892                         error "mdc lock count $lock_count > lru size $lru_size"
28893         done
28894 }
28895 run_test 425 "lock count should not exceed lru size"
28896
28897 test_426() {
28898         splice-test -r $DIR/$tfile
28899         splice-test -rd $DIR/$tfile
28900         splice-test $DIR/$tfile
28901         splice-test -d $DIR/$tfile
28902 }
28903 run_test 426 "splice test on Lustre"
28904
28905 test_427() {
28906         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28907         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28908                 skip "Need MDS version at least 2.12.4"
28909         local log
28910
28911         mkdir $DIR/$tdir
28912         mkdir $DIR/$tdir/1
28913         mkdir $DIR/$tdir/2
28914         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28915         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28916
28917         $LFS getdirstripe $DIR/$tdir/1/dir
28918
28919         #first setfattr for creating updatelog
28920         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28921
28922 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28923         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28924         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28925         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28926
28927         sleep 2
28928         fail mds2
28929         wait_recovery_complete mds2 $((2*TIMEOUT))
28930
28931         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28932         echo $log | grep "get update log failed" &&
28933                 error "update log corruption is detected" || true
28934 }
28935 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28936
28937 test_428() {
28938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28939         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
28940                               awk '/^max_cached_mb/ { print $2 }')
28941         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
28942
28943         $LCTL set_param -n llite.*.max_cached_mb=64
28944
28945         mkdir $DIR/$tdir
28946         $LFS setstripe -c 1 $DIR/$tdir
28947         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28948         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28949         #test write
28950         for f in $(seq 4); do
28951                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28952         done
28953         wait
28954
28955         cancel_lru_locks osc
28956         # Test read
28957         for f in $(seq 4); do
28958                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28959         done
28960         wait
28961 }
28962 run_test 428 "large block size IO should not hang"
28963
28964 test_429() { # LU-7915 / LU-10948
28965         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28966         local testfile=$DIR/$tfile
28967         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28968         local new_flag=1
28969         local first_rpc
28970         local second_rpc
28971         local third_rpc
28972
28973         $LCTL get_param $ll_opencache_threshold_count ||
28974                 skip "client does not have opencache parameter"
28975
28976         set_opencache $new_flag
28977         stack_trap "restore_opencache"
28978         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28979                 error "enable opencache failed"
28980         touch $testfile
28981         # drop MDC DLM locks
28982         cancel_lru_locks mdc
28983         # clear MDC RPC stats counters
28984         $LCTL set_param $mdc_rpcstats=clear
28985
28986         # According to the current implementation, we need to run 3 times
28987         # open & close file to verify if opencache is enabled correctly.
28988         # 1st, RPCs are sent for lookup/open and open handle is released on
28989         #      close finally.
28990         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28991         #      so open handle won't be released thereafter.
28992         # 3rd, No RPC is sent out.
28993         $MULTIOP $testfile oc || error "multiop failed"
28994         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28995         echo "1st: $first_rpc RPCs in flight"
28996
28997         $MULTIOP $testfile oc || error "multiop failed"
28998         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28999         echo "2nd: $second_rpc RPCs in flight"
29000
29001         $MULTIOP $testfile oc || error "multiop failed"
29002         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29003         echo "3rd: $third_rpc RPCs in flight"
29004
29005         #verify no MDC RPC is sent
29006         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29007 }
29008 run_test 429 "verify if opencache flag on client side does work"
29009
29010 lseek_test_430() {
29011         local offset
29012         local file=$1
29013
29014         # data at [200K, 400K)
29015         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29016                 error "256K->512K dd fails"
29017         # data at [2M, 3M)
29018         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29019                 error "2M->3M dd fails"
29020         # data at [4M, 5M)
29021         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29022                 error "4M->5M dd fails"
29023         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29024         # start at first component hole #1
29025         printf "Seeking hole from 1000 ... "
29026         offset=$(lseek_test -l 1000 $file)
29027         echo $offset
29028         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29029         printf "Seeking data from 1000 ... "
29030         offset=$(lseek_test -d 1000 $file)
29031         echo $offset
29032         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29033
29034         # start at first component data block
29035         printf "Seeking hole from 300000 ... "
29036         offset=$(lseek_test -l 300000 $file)
29037         echo $offset
29038         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29039         printf "Seeking data from 300000 ... "
29040         offset=$(lseek_test -d 300000 $file)
29041         echo $offset
29042         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29043
29044         # start at the first component but beyond end of object size
29045         printf "Seeking hole from 1000000 ... "
29046         offset=$(lseek_test -l 1000000 $file)
29047         echo $offset
29048         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29049         printf "Seeking data from 1000000 ... "
29050         offset=$(lseek_test -d 1000000 $file)
29051         echo $offset
29052         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29053
29054         # start at second component stripe 2 (empty file)
29055         printf "Seeking hole from 1500000 ... "
29056         offset=$(lseek_test -l 1500000 $file)
29057         echo $offset
29058         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29059         printf "Seeking data from 1500000 ... "
29060         offset=$(lseek_test -d 1500000 $file)
29061         echo $offset
29062         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29063
29064         # start at second component stripe 1 (all data)
29065         printf "Seeking hole from 3000000 ... "
29066         offset=$(lseek_test -l 3000000 $file)
29067         echo $offset
29068         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29069         printf "Seeking data from 3000000 ... "
29070         offset=$(lseek_test -d 3000000 $file)
29071         echo $offset
29072         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29073
29074         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29075                 error "2nd dd fails"
29076         echo "Add data block at 640K...1280K"
29077
29078         # start at before new data block, in hole
29079         printf "Seeking hole from 600000 ... "
29080         offset=$(lseek_test -l 600000 $file)
29081         echo $offset
29082         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29083         printf "Seeking data from 600000 ... "
29084         offset=$(lseek_test -d 600000 $file)
29085         echo $offset
29086         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29087
29088         # start at the first component new data block
29089         printf "Seeking hole from 1000000 ... "
29090         offset=$(lseek_test -l 1000000 $file)
29091         echo $offset
29092         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29093         printf "Seeking data from 1000000 ... "
29094         offset=$(lseek_test -d 1000000 $file)
29095         echo $offset
29096         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29097
29098         # start at second component stripe 2, new data
29099         printf "Seeking hole from 1200000 ... "
29100         offset=$(lseek_test -l 1200000 $file)
29101         echo $offset
29102         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29103         printf "Seeking data from 1200000 ... "
29104         offset=$(lseek_test -d 1200000 $file)
29105         echo $offset
29106         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29107
29108         # start beyond file end
29109         printf "Using offset > filesize ... "
29110         lseek_test -l 4000000 $file && error "lseek should fail"
29111         printf "Using offset > filesize ... "
29112         lseek_test -d 4000000 $file && error "lseek should fail"
29113
29114         printf "Done\n\n"
29115 }
29116
29117 test_430a() {
29118         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29119                 skip "MDT does not support SEEK_HOLE"
29120
29121         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29122                 skip "OST does not support SEEK_HOLE"
29123
29124         local file=$DIR/$tdir/$tfile
29125
29126         mkdir -p $DIR/$tdir
29127
29128         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29129         # OST stripe #1 will have continuous data at [1M, 3M)
29130         # OST stripe #2 is empty
29131         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29132         lseek_test_430 $file
29133         rm $file
29134         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29135         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29136         lseek_test_430 $file
29137         rm $file
29138         $LFS setstripe -c2 -S 512K $file
29139         echo "Two stripes, stripe size 512K"
29140         lseek_test_430 $file
29141         rm $file
29142         # FLR with stale mirror
29143         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29144                        -N -c2 -S 1M $file
29145         echo "Mirrored file:"
29146         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29147         echo "Plain 2 stripes 1M"
29148         lseek_test_430 $file
29149         rm $file
29150 }
29151 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29152
29153 test_430b() {
29154         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29155                 skip "OST does not support SEEK_HOLE"
29156
29157         local offset
29158         local file=$DIR/$tdir/$tfile
29159
29160         mkdir -p $DIR/$tdir
29161         # Empty layout lseek should fail
29162         $MCREATE $file
29163         # seek from 0
29164         printf "Seeking hole from 0 ... "
29165         lseek_test -l 0 $file && error "lseek should fail"
29166         printf "Seeking data from 0 ... "
29167         lseek_test -d 0 $file && error "lseek should fail"
29168         rm $file
29169
29170         # 1M-hole file
29171         $LFS setstripe -E 1M -c2 -E eof $file
29172         $TRUNCATE $file 1048576
29173         printf "Seeking hole from 1000000 ... "
29174         offset=$(lseek_test -l 1000000 $file)
29175         echo $offset
29176         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29177         printf "Seeking data from 1000000 ... "
29178         lseek_test -d 1000000 $file && error "lseek should fail"
29179         rm $file
29180
29181         # full component followed by non-inited one
29182         $LFS setstripe -E 1M -c2 -E eof $file
29183         dd if=/dev/urandom of=$file bs=1M count=1
29184         printf "Seeking hole from 1000000 ... "
29185         offset=$(lseek_test -l 1000000 $file)
29186         echo $offset
29187         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29188         printf "Seeking hole from 1048576 ... "
29189         lseek_test -l 1048576 $file && error "lseek should fail"
29190         # init second component and truncate back
29191         echo "123" >> $file
29192         $TRUNCATE $file 1048576
29193         printf "Seeking hole from 1000000 ... "
29194         offset=$(lseek_test -l 1000000 $file)
29195         echo $offset
29196         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29197         printf "Seeking hole from 1048576 ... "
29198         lseek_test -l 1048576 $file && error "lseek should fail"
29199         # boundary checks for big values
29200         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29201         offset=$(lseek_test -d 0 $file.10g)
29202         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29203         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29204         offset=$(lseek_test -d 0 $file.100g)
29205         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29206         return 0
29207 }
29208 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29209
29210 test_430c() {
29211         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29212                 skip "OST does not support SEEK_HOLE"
29213
29214         local file=$DIR/$tdir/$tfile
29215         local start
29216
29217         mkdir -p $DIR/$tdir
29218         stack_trap "rm -f $file $file.tmp"
29219         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29220
29221         # cp version 8.33+ prefers lseek over fiemap
29222         local ver=$(cp --version | awk '{ print $4; exit; }')
29223
29224         echo "cp $ver installed"
29225         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29226                 start=$SECONDS
29227                 time cp -v $file $file.tmp || error "cp $file failed"
29228                 (( SECONDS - start < 5 )) || {
29229                         strace cp $file $file.tmp |&
29230                                 grep -E "open|read|seek|FIEMAP" |
29231                                 grep -A 100 $file
29232                         error "cp: too long runtime $((SECONDS - start))"
29233                 }
29234         else
29235                 echo "cp test skipped due to $ver < 8.33"
29236         fi
29237
29238         # tar version 1.29+ supports SEEK_HOLE/DATA
29239         ver=$(tar --version | awk '{ print $4; exit; }')
29240         echo "tar $ver installed"
29241         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29242                 start=$SECONDS
29243                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29244                 (( SECONDS - start < 5 )) || {
29245                         strace tar cf $file.tmp --sparse $file |&
29246                                 grep -E "open|read|seek|FIEMAP" |
29247                                 grep -A 100 $file
29248                         error "tar: too long runtime $((SECONDS - start))"
29249                 }
29250         else
29251                 echo "tar test skipped due to $ver < 1.29"
29252         fi
29253 }
29254 run_test 430c "lseek: external tools check"
29255
29256 test_431() { # LU-14187
29257         local file=$DIR/$tdir/$tfile
29258
29259         mkdir -p $DIR/$tdir
29260         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29261         dd if=/dev/urandom of=$file bs=4k count=1
29262         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29263         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29264         #define OBD_FAIL_OST_RESTART_IO 0x251
29265         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29266         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29267         cp $file $file.0
29268         cancel_lru_locks
29269         sync_all_data
29270         echo 3 > /proc/sys/vm/drop_caches
29271         diff  $file $file.0 || error "data diff"
29272 }
29273 run_test 431 "Restart transaction for IO"
29274
29275 cleanup_test_432() {
29276         do_facet mgs $LCTL nodemap_activate 0
29277         wait_nm_sync active
29278 }
29279
29280 test_432() {
29281         local tmpdir=$TMP/dir432
29282
29283         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29284                 skip "Need MDS version at least 2.14.52"
29285
29286         stack_trap cleanup_test_432 EXIT
29287         mkdir $DIR/$tdir
29288         mkdir $tmpdir
29289
29290         do_facet mgs $LCTL nodemap_activate 1
29291         wait_nm_sync active
29292         do_facet mgs $LCTL nodemap_modify --name default \
29293                 --property admin --value 1
29294         do_facet mgs $LCTL nodemap_modify --name default \
29295                 --property trusted --value 1
29296         cancel_lru_locks mdc
29297         wait_nm_sync default admin_nodemap
29298         wait_nm_sync default trusted_nodemap
29299
29300         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29301                grep -ci "Operation not permitted") -ne 0 ]; then
29302                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29303         fi
29304 }
29305 run_test 432 "mv dir from outside Lustre"
29306
29307 test_433() {
29308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29309
29310         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29311                 skip "inode cache not supported"
29312
29313         $LCTL set_param llite.*.inode_cache=0
29314         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29315
29316         local count=256
29317         local before
29318         local after
29319
29320         cancel_lru_locks mdc
29321         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29322         createmany -m $DIR/$tdir/f $count
29323         createmany -d $DIR/$tdir/d $count
29324         ls -l $DIR/$tdir > /dev/null
29325         stack_trap "rm -rf $DIR/$tdir"
29326
29327         before=$(num_objects)
29328         cancel_lru_locks mdc
29329         after=$(num_objects)
29330
29331         # sometimes even @before is less than 2 * count
29332         while (( before - after < count )); do
29333                 sleep 1
29334                 after=$(num_objects)
29335                 wait=$((wait + 1))
29336                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29337                 if (( wait > 60 )); then
29338                         error "inode slab grew from $before to $after"
29339                 fi
29340         done
29341
29342         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29343 }
29344 run_test 433 "ldlm lock cancel releases dentries and inodes"
29345
29346 test_434() {
29347         local file
29348         local getxattr_count
29349         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29350         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29351
29352         [[ $(getenforce) == "Disabled" ]] ||
29353                 skip "lsm selinux module have to be disabled for this test"
29354
29355         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29356                 error "fail to create $DIR/$tdir/ on MDT0000"
29357
29358         touch $DIR/$tdir/$tfile-{001..100}
29359
29360         # disable the xattr cache
29361         save_lustre_params client "llite.*.xattr_cache" > $p
29362         lctl set_param llite.*.xattr_cache=0
29363         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29364
29365         # clear clients mdc stats
29366         clear_stats $mdc_stat_param ||
29367                 error "fail to clear stats on mdc MDT0000"
29368
29369         for file in $DIR/$tdir/$tfile-{001..100}; do
29370                 getfattr -n security.selinux $file |&
29371                         grep -q "Operation not supported" ||
29372                         error "getxattr on security.selinux should return EOPNOTSUPP"
29373         done
29374
29375         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29376         (( getxattr_count < 100 )) ||
29377                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29378 }
29379 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29380
29381 test_440() {
29382         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29383                 source $LUSTRE/scripts/bash-completion/lustre
29384         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29385                 source /usr/share/bash-completion/completions/lustre
29386         else
29387                 skip "bash completion scripts not found"
29388         fi
29389
29390         local lctl_completions
29391         local lfs_completions
29392
29393         lctl_completions=$(_lustre_cmds lctl)
29394         if [[ ! $lctl_completions =~ "get_param" ]]; then
29395                 error "lctl bash completion failed"
29396         fi
29397
29398         lfs_completions=$(_lustre_cmds lfs)
29399         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29400                 error "lfs bash completion failed"
29401         fi
29402 }
29403 run_test 440 "bash completion for lfs, lctl"
29404
29405 prep_801() {
29406         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29407         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29408                 skip "Need server version at least 2.9.55"
29409
29410         start_full_debug_logging
29411 }
29412
29413 post_801() {
29414         stop_full_debug_logging
29415 }
29416
29417 barrier_stat() {
29418         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29419                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29420                            awk '/The barrier for/ { print $7 }')
29421                 echo $st
29422         else
29423                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29424                 echo \'$st\'
29425         fi
29426 }
29427
29428 barrier_expired() {
29429         local expired
29430
29431         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29432                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29433                           awk '/will be expired/ { print $7 }')
29434         else
29435                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29436         fi
29437
29438         echo $expired
29439 }
29440
29441 test_801a() {
29442         prep_801
29443
29444         echo "Start barrier_freeze at: $(date)"
29445         #define OBD_FAIL_BARRIER_DELAY          0x2202
29446         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29447         # Do not reduce barrier time - See LU-11873
29448         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29449
29450         sleep 2
29451         local b_status=$(barrier_stat)
29452         echo "Got barrier status at: $(date)"
29453         [ "$b_status" = "'freezing_p1'" ] ||
29454                 error "(1) unexpected barrier status $b_status"
29455
29456         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29457         wait
29458         b_status=$(barrier_stat)
29459         [ "$b_status" = "'frozen'" ] ||
29460                 error "(2) unexpected barrier status $b_status"
29461
29462         local expired=$(barrier_expired)
29463         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29464         sleep $((expired + 3))
29465
29466         b_status=$(barrier_stat)
29467         [ "$b_status" = "'expired'" ] ||
29468                 error "(3) unexpected barrier status $b_status"
29469
29470         # Do not reduce barrier time - See LU-11873
29471         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29472                 error "(4) fail to freeze barrier"
29473
29474         b_status=$(barrier_stat)
29475         [ "$b_status" = "'frozen'" ] ||
29476                 error "(5) unexpected barrier status $b_status"
29477
29478         echo "Start barrier_thaw at: $(date)"
29479         #define OBD_FAIL_BARRIER_DELAY          0x2202
29480         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29481         do_facet mgs $LCTL barrier_thaw $FSNAME &
29482
29483         sleep 2
29484         b_status=$(barrier_stat)
29485         echo "Got barrier status at: $(date)"
29486         [ "$b_status" = "'thawing'" ] ||
29487                 error "(6) unexpected barrier status $b_status"
29488
29489         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29490         wait
29491         b_status=$(barrier_stat)
29492         [ "$b_status" = "'thawed'" ] ||
29493                 error "(7) unexpected barrier status $b_status"
29494
29495         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29496         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29497         do_facet mgs $LCTL barrier_freeze $FSNAME
29498
29499         b_status=$(barrier_stat)
29500         [ "$b_status" = "'failed'" ] ||
29501                 error "(8) unexpected barrier status $b_status"
29502
29503         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29504         do_facet mgs $LCTL barrier_thaw $FSNAME
29505
29506         post_801
29507 }
29508 run_test 801a "write barrier user interfaces and stat machine"
29509
29510 test_801b() {
29511         prep_801
29512
29513         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29514         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29515         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29516         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29517         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29518
29519         cancel_lru_locks mdc
29520
29521         # 180 seconds should be long enough
29522         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29523
29524         local b_status=$(barrier_stat)
29525         [ "$b_status" = "'frozen'" ] ||
29526                 error "(6) unexpected barrier status $b_status"
29527
29528         mkdir $DIR/$tdir/d0/d10 &
29529         mkdir_pid=$!
29530
29531         touch $DIR/$tdir/d1/f13 &
29532         touch_pid=$!
29533
29534         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29535         ln_pid=$!
29536
29537         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29538         mv_pid=$!
29539
29540         rm -f $DIR/$tdir/d4/f12 &
29541         rm_pid=$!
29542
29543         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29544
29545         # To guarantee taht the 'stat' is not blocked
29546         b_status=$(barrier_stat)
29547         [ "$b_status" = "'frozen'" ] ||
29548                 error "(8) unexpected barrier status $b_status"
29549
29550         # let above commands to run at background
29551         sleep 5
29552
29553         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29554         ps -p $touch_pid || error "(10) touch should be blocked"
29555         ps -p $ln_pid || error "(11) link should be blocked"
29556         ps -p $mv_pid || error "(12) rename should be blocked"
29557         ps -p $rm_pid || error "(13) unlink should be blocked"
29558
29559         b_status=$(barrier_stat)
29560         [ "$b_status" = "'frozen'" ] ||
29561                 error "(14) unexpected barrier status $b_status"
29562
29563         do_facet mgs $LCTL barrier_thaw $FSNAME
29564         b_status=$(barrier_stat)
29565         [ "$b_status" = "'thawed'" ] ||
29566                 error "(15) unexpected barrier status $b_status"
29567
29568         wait $mkdir_pid || error "(16) mkdir should succeed"
29569         wait $touch_pid || error "(17) touch should succeed"
29570         wait $ln_pid || error "(18) link should succeed"
29571         wait $mv_pid || error "(19) rename should succeed"
29572         wait $rm_pid || error "(20) unlink should succeed"
29573
29574         post_801
29575 }
29576 run_test 801b "modification will be blocked by write barrier"
29577
29578 test_801c() {
29579         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29580
29581         prep_801
29582
29583         stop mds2 || error "(1) Fail to stop mds2"
29584
29585         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29586
29587         local b_status=$(barrier_stat)
29588         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29589                 do_facet mgs $LCTL barrier_thaw $FSNAME
29590                 error "(2) unexpected barrier status $b_status"
29591         }
29592
29593         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29594                 error "(3) Fail to rescan barrier bitmap"
29595
29596         # Do not reduce barrier time - See LU-11873
29597         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29598
29599         b_status=$(barrier_stat)
29600         [ "$b_status" = "'frozen'" ] ||
29601                 error "(4) unexpected barrier status $b_status"
29602
29603         do_facet mgs $LCTL barrier_thaw $FSNAME
29604         b_status=$(barrier_stat)
29605         [ "$b_status" = "'thawed'" ] ||
29606                 error "(5) unexpected barrier status $b_status"
29607
29608         local devname=$(mdsdevname 2)
29609
29610         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29611
29612         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29613                 error "(7) Fail to rescan barrier bitmap"
29614
29615         post_801
29616 }
29617 run_test 801c "rescan barrier bitmap"
29618
29619 test_802b() {
29620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29621         remote_mds_nodsh && skip "remote MDS with nodsh"
29622
29623         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29624                 skip "readonly option not available"
29625
29626         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29627
29628         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29629                 error "(2) Fail to copy"
29630
29631         # write back all cached data before setting MDT to readonly
29632         cancel_lru_locks
29633         sync_all_data
29634
29635         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29636         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29637
29638         echo "Modify should be refused"
29639         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29640
29641         echo "Read should be allowed"
29642         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29643                 error "(7) Read should succeed under ro mode"
29644
29645         # disable readonly
29646         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29647 }
29648 run_test 802b "be able to set MDTs to readonly"
29649
29650 test_803a() {
29651         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29652         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29653                 skip "MDS needs to be newer than 2.10.54"
29654
29655         mkdir_on_mdt0 $DIR/$tdir
29656         # Create some objects on all MDTs to trigger related logs objects
29657         for idx in $(seq $MDSCOUNT); do
29658                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29659                         $DIR/$tdir/dir${idx} ||
29660                         error "Fail to create $DIR/$tdir/dir${idx}"
29661         done
29662
29663         wait_delete_completed # ensure old test cleanups are finished
29664         sleep 3
29665         echo "before create:"
29666         $LFS df -i $MOUNT
29667         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29668
29669         for i in {1..10}; do
29670                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29671                         error "Fail to create $DIR/$tdir/foo$i"
29672         done
29673
29674         # sync ZFS-on-MDS to refresh statfs data
29675         wait_zfs_commit mds1
29676         sleep 3
29677         echo "after create:"
29678         $LFS df -i $MOUNT
29679         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29680
29681         # allow for an llog to be cleaned up during the test
29682         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29683                 error "before ($before_used) + 10 > after ($after_used)"
29684
29685         for i in {1..10}; do
29686                 rm -rf $DIR/$tdir/foo$i ||
29687                         error "Fail to remove $DIR/$tdir/foo$i"
29688         done
29689
29690         # sync ZFS-on-MDS to refresh statfs data
29691         wait_zfs_commit mds1
29692         wait_delete_completed
29693         sleep 3 # avoid MDT return cached statfs
29694         echo "after unlink:"
29695         $LFS df -i $MOUNT
29696         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29697
29698         # allow for an llog to be created during the test
29699         [ $after_used -le $((before_used + 1)) ] ||
29700                 error "after ($after_used) > before ($before_used) + 1"
29701 }
29702 run_test 803a "verify agent object for remote object"
29703
29704 test_803b() {
29705         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29706         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29707                 skip "MDS needs to be newer than 2.13.56"
29708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29709
29710         for i in $(seq 0 $((MDSCOUNT - 1))); do
29711                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29712         done
29713
29714         local before=0
29715         local after=0
29716
29717         local tmp
29718
29719         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29720         for i in $(seq 0 $((MDSCOUNT - 1))); do
29721                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29722                         awk '/getattr/ { print $2 }')
29723                 before=$((before + tmp))
29724         done
29725         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29726         for i in $(seq 0 $((MDSCOUNT - 1))); do
29727                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29728                         awk '/getattr/ { print $2 }')
29729                 after=$((after + tmp))
29730         done
29731
29732         [ $before -eq $after ] || error "getattr count $before != $after"
29733 }
29734 run_test 803b "remote object can getattr from cache"
29735
29736 test_804() {
29737         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29738         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29739                 skip "MDS needs to be newer than 2.10.54"
29740         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29741
29742         mkdir -p $DIR/$tdir
29743         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29744                 error "Fail to create $DIR/$tdir/dir0"
29745
29746         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29747         local dev=$(mdsdevname 2)
29748
29749         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29750                 grep ${fid} || error "NOT found agent entry for dir0"
29751
29752         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29753                 error "Fail to create $DIR/$tdir/dir1"
29754
29755         touch $DIR/$tdir/dir1/foo0 ||
29756                 error "Fail to create $DIR/$tdir/dir1/foo0"
29757         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29758         local rc=0
29759
29760         for idx in $(seq $MDSCOUNT); do
29761                 dev=$(mdsdevname $idx)
29762                 do_facet mds${idx} \
29763                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29764                         grep ${fid} && rc=$idx
29765         done
29766
29767         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29768                 error "Fail to rename foo0 to foo1"
29769         if [ $rc -eq 0 ]; then
29770                 for idx in $(seq $MDSCOUNT); do
29771                         dev=$(mdsdevname $idx)
29772                         do_facet mds${idx} \
29773                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29774                         grep ${fid} && rc=$idx
29775                 done
29776         fi
29777
29778         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29779                 error "Fail to rename foo1 to foo2"
29780         if [ $rc -eq 0 ]; then
29781                 for idx in $(seq $MDSCOUNT); do
29782                         dev=$(mdsdevname $idx)
29783                         do_facet mds${idx} \
29784                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29785                         grep ${fid} && rc=$idx
29786                 done
29787         fi
29788
29789         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29790
29791         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29792                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29793         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29794                 error "Fail to rename foo2 to foo0"
29795         unlink $DIR/$tdir/dir1/foo0 ||
29796                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29797         rm -rf $DIR/$tdir/dir0 ||
29798                 error "Fail to rm $DIR/$tdir/dir0"
29799
29800         for idx in $(seq $MDSCOUNT); do
29801                 rc=0
29802
29803                 stop mds${idx}
29804                 dev=$(mdsdevname $idx)
29805                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29806                         rc=$?
29807                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29808                         error "mount mds$idx failed"
29809                 df $MOUNT > /dev/null 2>&1
29810
29811                 # e2fsck should not return error
29812                 [ $rc -eq 0 ] ||
29813                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29814         done
29815 }
29816 run_test 804 "verify agent entry for remote entry"
29817
29818 cleanup_805() {
29819         do_facet $SINGLEMDS zfs set quota=$old $fsset
29820         unlinkmany $DIR/$tdir/f- 1000000
29821         trap 0
29822 }
29823
29824 test_805() {
29825         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29826         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29827         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29828                 skip "netfree not implemented before 0.7"
29829         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29830                 skip "Need MDS version at least 2.10.57"
29831
29832         local fsset
29833         local freekb
29834         local usedkb
29835         local old
29836         local quota
29837         local pref="osd-zfs.$FSNAME-MDT0000."
29838
29839         # limit available space on MDS dataset to meet nospace issue
29840         # quickly. then ZFS 0.7.2 can use reserved space if asked
29841         # properly (using netfree flag in osd_declare_destroy()
29842         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29843         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29844                 gawk '{print $3}')
29845         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29846         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29847         let "usedkb=usedkb-freekb"
29848         let "freekb=freekb/2"
29849         if let "freekb > 5000"; then
29850                 let "freekb=5000"
29851         fi
29852         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29853         trap cleanup_805 EXIT
29854         mkdir_on_mdt0 $DIR/$tdir
29855         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29856                 error "Can't set PFL layout"
29857         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29858         rm -rf $DIR/$tdir || error "not able to remove"
29859         do_facet $SINGLEMDS zfs set quota=$old $fsset
29860         trap 0
29861 }
29862 run_test 805 "ZFS can remove from full fs"
29863
29864 # Size-on-MDS test
29865 check_lsom_data()
29866 {
29867         local file=$1
29868         local expect=$(stat -c %s $file)
29869
29870         check_lsom_size $1 $expect
29871
29872         local blocks=$($LFS getsom -b $file)
29873         expect=$(stat -c %b $file)
29874         [[ $blocks == $expect ]] ||
29875                 error "$file expected blocks: $expect, got: $blocks"
29876 }
29877
29878 check_lsom_size()
29879 {
29880         local size
29881         local expect=$2
29882
29883         cancel_lru_locks mdc
29884
29885         size=$($LFS getsom -s $1)
29886         [[ $size == $expect ]] ||
29887                 error "$file expected size: $expect, got: $size"
29888 }
29889
29890 test_806() {
29891         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29892                 skip "Need MDS version at least 2.11.52"
29893
29894         local bs=1048576
29895
29896         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29897
29898         disable_opencache
29899         stack_trap "restore_opencache"
29900
29901         # single-threaded write
29902         echo "Test SOM for single-threaded write"
29903         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29904                 error "write $tfile failed"
29905         check_lsom_size $DIR/$tfile $bs
29906
29907         local num=32
29908         local size=$(($num * $bs))
29909         local offset=0
29910         local i
29911
29912         echo "Test SOM for single client multi-threaded($num) write"
29913         $TRUNCATE $DIR/$tfile 0
29914         for ((i = 0; i < $num; i++)); do
29915                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29916                 local pids[$i]=$!
29917                 offset=$((offset + $bs))
29918         done
29919         for (( i=0; i < $num; i++ )); do
29920                 wait ${pids[$i]}
29921         done
29922         check_lsom_size $DIR/$tfile $size
29923
29924         $TRUNCATE $DIR/$tfile 0
29925         for ((i = 0; i < $num; i++)); do
29926                 offset=$((offset - $bs))
29927                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29928                 local pids[$i]=$!
29929         done
29930         for (( i=0; i < $num; i++ )); do
29931                 wait ${pids[$i]}
29932         done
29933         check_lsom_size $DIR/$tfile $size
29934
29935         # multi-client writes
29936         num=$(get_node_count ${CLIENTS//,/ })
29937         size=$(($num * $bs))
29938         offset=0
29939         i=0
29940
29941         echo "Test SOM for multi-client ($num) writes"
29942         $TRUNCATE $DIR/$tfile 0
29943         for client in ${CLIENTS//,/ }; do
29944                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29945                 local pids[$i]=$!
29946                 i=$((i + 1))
29947                 offset=$((offset + $bs))
29948         done
29949         for (( i=0; i < $num; i++ )); do
29950                 wait ${pids[$i]}
29951         done
29952         check_lsom_size $DIR/$tfile $offset
29953
29954         i=0
29955         $TRUNCATE $DIR/$tfile 0
29956         for client in ${CLIENTS//,/ }; do
29957                 offset=$((offset - $bs))
29958                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29959                 local pids[$i]=$!
29960                 i=$((i + 1))
29961         done
29962         for (( i=0; i < $num; i++ )); do
29963                 wait ${pids[$i]}
29964         done
29965         check_lsom_size $DIR/$tfile $size
29966
29967         # verify SOM blocks count
29968         echo "Verify SOM block count"
29969         $TRUNCATE $DIR/$tfile 0
29970         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29971                 error "failed to write file $tfile with fdatasync and fstat"
29972         check_lsom_data $DIR/$tfile
29973
29974         $TRUNCATE $DIR/$tfile 0
29975         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29976                 error "failed to write file $tfile with fdatasync"
29977         check_lsom_data $DIR/$tfile
29978
29979         $TRUNCATE $DIR/$tfile 0
29980         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29981                 error "failed to write file $tfile with sync IO"
29982         check_lsom_data $DIR/$tfile
29983
29984         # verify truncate
29985         echo "Test SOM for truncate"
29986         # use ftruncate to sync blocks on close request
29987         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29988         check_lsom_size $DIR/$tfile 16384
29989         check_lsom_data $DIR/$tfile
29990
29991         $TRUNCATE $DIR/$tfile 1234
29992         check_lsom_size $DIR/$tfile 1234
29993         # sync blocks on the MDT
29994         $MULTIOP $DIR/$tfile oc
29995         check_lsom_data $DIR/$tfile
29996 }
29997 run_test 806 "Verify Lazy Size on MDS"
29998
29999 test_807() {
30000         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30001         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30002                 skip "Need MDS version at least 2.11.52"
30003
30004         # Registration step
30005         changelog_register || error "changelog_register failed"
30006         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30007         changelog_users $SINGLEMDS | grep -q $cl_user ||
30008                 error "User $cl_user not found in changelog_users"
30009
30010         rm -rf $DIR/$tdir || error "rm $tdir failed"
30011         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30012         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30013         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30014         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30015                 error "truncate $tdir/trunc failed"
30016
30017         local bs=1048576
30018         echo "Test SOM for single-threaded write with fsync"
30019         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30020                 error "write $tfile failed"
30021         sync;sync;sync
30022
30023         # multi-client wirtes
30024         local num=$(get_node_count ${CLIENTS//,/ })
30025         local offset=0
30026         local i=0
30027
30028         echo "Test SOM for multi-client ($num) writes"
30029         touch $DIR/$tfile || error "touch $tfile failed"
30030         $TRUNCATE $DIR/$tfile 0
30031         for client in ${CLIENTS//,/ }; do
30032                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30033                 local pids[$i]=$!
30034                 i=$((i + 1))
30035                 offset=$((offset + $bs))
30036         done
30037         for (( i=0; i < $num; i++ )); do
30038                 wait ${pids[$i]}
30039         done
30040
30041         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30042         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30043         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30044         check_lsom_data $DIR/$tdir/trunc
30045         check_lsom_data $DIR/$tdir/single_dd
30046         check_lsom_data $DIR/$tfile
30047
30048         rm -rf $DIR/$tdir
30049         # Deregistration step
30050         changelog_deregister || error "changelog_deregister failed"
30051 }
30052 run_test 807 "verify LSOM syncing tool"
30053
30054 check_som_nologged()
30055 {
30056         local lines=$($LFS changelog $FSNAME-MDT0000 |
30057                 grep 'x=trusted.som' | wc -l)
30058         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30059 }
30060
30061 test_808() {
30062         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30063                 skip "Need MDS version at least 2.11.55"
30064
30065         # Registration step
30066         changelog_register || error "changelog_register failed"
30067
30068         touch $DIR/$tfile || error "touch $tfile failed"
30069         check_som_nologged
30070
30071         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30072                 error "write $tfile failed"
30073         check_som_nologged
30074
30075         $TRUNCATE $DIR/$tfile 1234
30076         check_som_nologged
30077
30078         $TRUNCATE $DIR/$tfile 1048576
30079         check_som_nologged
30080
30081         # Deregistration step
30082         changelog_deregister || error "changelog_deregister failed"
30083 }
30084 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30085
30086 check_som_nodata()
30087 {
30088         $LFS getsom $1
30089         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30090 }
30091
30092 test_809() {
30093         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30094                 skip "Need MDS version at least 2.11.56"
30095
30096         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30097                 error "failed to create DoM-only file $DIR/$tfile"
30098         touch $DIR/$tfile || error "touch $tfile failed"
30099         check_som_nodata $DIR/$tfile
30100
30101         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30102                 error "write $tfile failed"
30103         check_som_nodata $DIR/$tfile
30104
30105         $TRUNCATE $DIR/$tfile 1234
30106         check_som_nodata $DIR/$tfile
30107
30108         $TRUNCATE $DIR/$tfile 4097
30109         check_som_nodata $DIR/$file
30110 }
30111 run_test 809 "Verify no SOM xattr store for DoM-only files"
30112
30113 test_810() {
30114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30115         $GSS && skip_env "could not run with gss"
30116         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30117                 skip "OST < 2.12.58 doesn't align checksum"
30118
30119         set_checksums 1
30120         stack_trap "set_checksums $ORIG_CSUM" EXIT
30121         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30122
30123         local csum
30124         local before
30125         local after
30126         for csum in $CKSUM_TYPES; do
30127                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30128                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30129                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30130                         eval set -- $i
30131                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30132                         before=$(md5sum $DIR/$tfile)
30133                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30134                         after=$(md5sum $DIR/$tfile)
30135                         [ "$before" == "$after" ] ||
30136                                 error "$csum: $before != $after bs=$1 seek=$2"
30137                 done
30138         done
30139 }
30140 run_test 810 "partial page writes on ZFS (LU-11663)"
30141
30142 test_812a() {
30143         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30144                 skip "OST < 2.12.51 doesn't support this fail_loc"
30145
30146         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30147         # ensure ost1 is connected
30148         stat $DIR/$tfile >/dev/null || error "can't stat"
30149         wait_osc_import_state client ost1 FULL
30150         # no locks, no reqs to let the connection idle
30151         cancel_lru_locks osc
30152
30153         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30154 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30155         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30156         wait_osc_import_state client ost1 CONNECTING
30157         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30158
30159         stat $DIR/$tfile >/dev/null || error "can't stat file"
30160 }
30161 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30162
30163 test_812b() { # LU-12378
30164         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30165                 skip "OST < 2.12.51 doesn't support this fail_loc"
30166
30167         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30168         # ensure ost1 is connected
30169         stat $DIR/$tfile >/dev/null || error "can't stat"
30170         wait_osc_import_state client ost1 FULL
30171         # no locks, no reqs to let the connection idle
30172         cancel_lru_locks osc
30173
30174         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30175 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30176         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30177         wait_osc_import_state client ost1 CONNECTING
30178         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30179
30180         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30181         wait_osc_import_state client ost1 IDLE
30182 }
30183 run_test 812b "do not drop no resend request for idle connect"
30184
30185 test_812c() {
30186         local old
30187
30188         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30189
30190         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30191         $LFS getstripe $DIR/$tfile
30192         $LCTL set_param osc.*.idle_timeout=10
30193         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30194         # ensure ost1 is connected
30195         stat $DIR/$tfile >/dev/null || error "can't stat"
30196         wait_osc_import_state client ost1 FULL
30197         # no locks, no reqs to let the connection idle
30198         cancel_lru_locks osc
30199
30200 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30201         $LCTL set_param fail_loc=0x80000533
30202         sleep 15
30203         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30204 }
30205 run_test 812c "idle import vs lock enqueue race"
30206
30207 test_813() {
30208         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30209         [ -z "$file_heat_sav" ] && skip "no file heat support"
30210
30211         local readsample
30212         local writesample
30213         local readbyte
30214         local writebyte
30215         local readsample1
30216         local writesample1
30217         local readbyte1
30218         local writebyte1
30219
30220         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30221         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30222
30223         $LCTL set_param -n llite.*.file_heat=1
30224         echo "Turn on file heat"
30225         echo "Period second: $period_second, Decay percentage: $decay_pct"
30226
30227         echo "QQQQ" > $DIR/$tfile
30228         echo "QQQQ" > $DIR/$tfile
30229         echo "QQQQ" > $DIR/$tfile
30230         cat $DIR/$tfile > /dev/null
30231         cat $DIR/$tfile > /dev/null
30232         cat $DIR/$tfile > /dev/null
30233         cat $DIR/$tfile > /dev/null
30234
30235         local out=$($LFS heat_get $DIR/$tfile)
30236
30237         $LFS heat_get $DIR/$tfile
30238         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30239         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30240         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30241         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30242
30243         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30244         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30245         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30246         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30247
30248         sleep $((period_second + 3))
30249         echo "Sleep $((period_second + 3)) seconds..."
30250         # The recursion formula to calculate the heat of the file f is as
30251         # follow:
30252         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30253         # Where Hi is the heat value in the period between time points i*I and
30254         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30255         # to the weight of Ci.
30256         out=$($LFS heat_get $DIR/$tfile)
30257         $LFS heat_get $DIR/$tfile
30258         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30259         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30260         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30261         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30262
30263         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30264                 error "read sample ($readsample) is wrong"
30265         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30266                 error "write sample ($writesample) is wrong"
30267         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30268                 error "read bytes ($readbyte) is wrong"
30269         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30270                 error "write bytes ($writebyte) is wrong"
30271
30272         echo "QQQQ" > $DIR/$tfile
30273         echo "QQQQ" > $DIR/$tfile
30274         echo "QQQQ" > $DIR/$tfile
30275         cat $DIR/$tfile > /dev/null
30276         cat $DIR/$tfile > /dev/null
30277         cat $DIR/$tfile > /dev/null
30278         cat $DIR/$tfile > /dev/null
30279
30280         sleep $((period_second + 3))
30281         echo "Sleep $((period_second + 3)) seconds..."
30282
30283         out=$($LFS heat_get $DIR/$tfile)
30284         $LFS heat_get $DIR/$tfile
30285         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30286         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30287         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30288         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30289
30290         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30291                 4 * $decay_pct) / 100") -eq 1 ] ||
30292                 error "read sample ($readsample1) is wrong"
30293         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30294                 3 * $decay_pct) / 100") -eq 1 ] ||
30295                 error "write sample ($writesample1) is wrong"
30296         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30297                 20 * $decay_pct) / 100") -eq 1 ] ||
30298                 error "read bytes ($readbyte1) is wrong"
30299         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30300                 15 * $decay_pct) / 100") -eq 1 ] ||
30301                 error "write bytes ($writebyte1) is wrong"
30302
30303         echo "Turn off file heat for the file $DIR/$tfile"
30304         $LFS heat_set -o $DIR/$tfile
30305
30306         echo "QQQQ" > $DIR/$tfile
30307         echo "QQQQ" > $DIR/$tfile
30308         echo "QQQQ" > $DIR/$tfile
30309         cat $DIR/$tfile > /dev/null
30310         cat $DIR/$tfile > /dev/null
30311         cat $DIR/$tfile > /dev/null
30312         cat $DIR/$tfile > /dev/null
30313
30314         out=$($LFS heat_get $DIR/$tfile)
30315         $LFS heat_get $DIR/$tfile
30316         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30317         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30318         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30319         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30320
30321         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30322         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30323         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30324         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30325
30326         echo "Trun on file heat for the file $DIR/$tfile"
30327         $LFS heat_set -O $DIR/$tfile
30328
30329         echo "QQQQ" > $DIR/$tfile
30330         echo "QQQQ" > $DIR/$tfile
30331         echo "QQQQ" > $DIR/$tfile
30332         cat $DIR/$tfile > /dev/null
30333         cat $DIR/$tfile > /dev/null
30334         cat $DIR/$tfile > /dev/null
30335         cat $DIR/$tfile > /dev/null
30336
30337         out=$($LFS heat_get $DIR/$tfile)
30338         $LFS heat_get $DIR/$tfile
30339         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30340         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30341         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30342         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30343
30344         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30345         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30346         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30347         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30348
30349         $LFS heat_set -c $DIR/$tfile
30350         $LCTL set_param -n llite.*.file_heat=0
30351         echo "Turn off file heat support for the Lustre filesystem"
30352
30353         echo "QQQQ" > $DIR/$tfile
30354         echo "QQQQ" > $DIR/$tfile
30355         echo "QQQQ" > $DIR/$tfile
30356         cat $DIR/$tfile > /dev/null
30357         cat $DIR/$tfile > /dev/null
30358         cat $DIR/$tfile > /dev/null
30359         cat $DIR/$tfile > /dev/null
30360
30361         out=$($LFS heat_get $DIR/$tfile)
30362         $LFS heat_get $DIR/$tfile
30363         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30364         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30365         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30366         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30367
30368         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30369         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30370         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30371         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30372
30373         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30374         rm -f $DIR/$tfile
30375 }
30376 run_test 813 "File heat verfication"
30377
30378 test_814()
30379 {
30380         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30381         echo -n y >> $DIR/$tfile
30382         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30383         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30384 }
30385 run_test 814 "sparse cp works as expected (LU-12361)"
30386
30387 test_815()
30388 {
30389         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30390         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30391 }
30392 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30393
30394 test_816() {
30395         local ost1_imp=$(get_osc_import_name client ost1)
30396         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30397                          cut -d'.' -f2)
30398
30399         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30400         # ensure ost1 is connected
30401
30402         stat $DIR/$tfile >/dev/null || error "can't stat"
30403         wait_osc_import_state client ost1 FULL
30404         # no locks, no reqs to let the connection idle
30405         cancel_lru_locks osc
30406         lru_resize_disable osc
30407         local before
30408         local now
30409         before=$($LCTL get_param -n \
30410                  ldlm.namespaces.$imp_name.lru_size)
30411
30412         wait_osc_import_state client ost1 IDLE
30413         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30414         now=$($LCTL get_param -n \
30415               ldlm.namespaces.$imp_name.lru_size)
30416         [ $before == $now ] || error "lru_size changed $before != $now"
30417 }
30418 run_test 816 "do not reset lru_resize on idle reconnect"
30419
30420 cleanup_817() {
30421         umount $tmpdir
30422         exportfs -u localhost:$DIR/nfsexp
30423         rm -rf $DIR/nfsexp
30424 }
30425
30426 test_817() {
30427         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30428
30429         mkdir -p $DIR/nfsexp
30430         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30431                 error "failed to export nfs"
30432
30433         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30434         stack_trap cleanup_817 EXIT
30435
30436         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30437                 error "failed to mount nfs to $tmpdir"
30438
30439         cp /bin/true $tmpdir
30440         $DIR/nfsexp/true || error "failed to execute 'true' command"
30441 }
30442 run_test 817 "nfsd won't cache write lock for exec file"
30443
30444 test_818() {
30445         test_mkdir -i0 -c1 $DIR/$tdir
30446         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30447         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30448         stop $SINGLEMDS
30449
30450         # restore osp-syn threads
30451         stack_trap "fail $SINGLEMDS"
30452
30453         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30454         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30455         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30456                 error "start $SINGLEMDS failed"
30457         rm -rf $DIR/$tdir
30458
30459         local testid=$(echo $TESTNAME | tr '_' ' ')
30460
30461         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30462                 grep "run LFSCK" || error "run LFSCK is not suggested"
30463 }
30464 run_test 818 "unlink with failed llog"
30465
30466 test_819a() {
30467         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30468         cancel_lru_locks osc
30469         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30470         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30471         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30472         rm -f $TDIR/$tfile
30473 }
30474 run_test 819a "too big niobuf in read"
30475
30476 test_819b() {
30477         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30478         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30479         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30480         cancel_lru_locks osc
30481         sleep 1
30482         rm -f $TDIR/$tfile
30483 }
30484 run_test 819b "too big niobuf in write"
30485
30486
30487 function test_820_start_ost() {
30488         sleep 5
30489
30490         for num in $(seq $OSTCOUNT); do
30491                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30492         done
30493 }
30494
30495 test_820() {
30496         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30497
30498         mkdir $DIR/$tdir
30499         umount_client $MOUNT || error "umount failed"
30500         for num in $(seq $OSTCOUNT); do
30501                 stop ost$num
30502         done
30503
30504         # mount client with no active OSTs
30505         # so that the client can't initialize max LOV EA size
30506         # from OSC notifications
30507         mount_client $MOUNT || error "mount failed"
30508         # delay OST starting to keep this 0 max EA size for a while
30509         test_820_start_ost &
30510
30511         # create a directory on MDS2
30512         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30513                 error "Failed to create directory"
30514         # open intent should update default EA size
30515         # see mdc_update_max_ea_from_body()
30516         # notice this is the very first RPC to MDS2
30517         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30518         ret=$?
30519         echo $out
30520         # With SSK, this situation can lead to -EPERM being returned.
30521         # In that case, simply retry.
30522         if [ $ret -ne 0 ] && $SHARED_KEY; then
30523                 if echo "$out" | grep -q "not permitted"; then
30524                         cp /etc/services $DIR/$tdir/mds2
30525                         ret=$?
30526                 fi
30527         fi
30528         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30529 }
30530 run_test 820 "update max EA from open intent"
30531
30532 test_823() {
30533         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30534         local OST_MAX_PRECREATE=20000
30535
30536         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30537                 skip "Need MDS version at least 2.14.56"
30538
30539         save_lustre_params mds1 \
30540                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30541         do_facet $SINGLEMDS "$LCTL set_param -n \
30542                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30543         do_facet $SINGLEMDS "$LCTL set_param -n \
30544                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30545
30546         stack_trap "restore_lustre_params < $p; rm $p"
30547
30548         do_facet $SINGLEMDS "$LCTL set_param -n \
30549                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30550
30551         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30552                       osp.$FSNAME-OST0000*MDT0000.create_count")
30553         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30554                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30555         local expect_count=$(((($max/2)/256) * 256))
30556
30557         log "setting create_count to 100200:"
30558         log " -result- count: $count with max: $max, expecting: $expect_count"
30559
30560         [[ $count -eq expect_count ]] ||
30561                 error "Create count not set to max precreate."
30562 }
30563 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30564
30565 test_831() {
30566         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30567                 skip "Need MDS version 2.14.56"
30568
30569         local sync_changes=$(do_facet $SINGLEMDS \
30570                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30571
30572         [ "$sync_changes" -gt 100 ] &&
30573                 skip "Sync changes $sync_changes > 100 already"
30574
30575         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30576
30577         $LFS mkdir -i 0 $DIR/$tdir
30578         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30579
30580         save_lustre_params mds1 \
30581                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30582         save_lustre_params mds1 \
30583                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30584
30585         do_facet mds1 "$LCTL set_param -n \
30586                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30587                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30588         stack_trap "restore_lustre_params < $p" EXIT
30589
30590         createmany -o $DIR/$tdir/f- 1000
30591         unlinkmany $DIR/$tdir/f- 1000 &
30592         local UNLINK_PID=$!
30593
30594         while sleep 1; do
30595                 sync_changes=$(do_facet mds1 \
30596                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30597                 # the check in the code is racy, fail the test
30598                 # if the value above the limit by 10.
30599                 [ $sync_changes -gt 110 ] && {
30600                         kill -2 $UNLINK_PID
30601                         wait
30602                         error "osp changes throttling failed, $sync_changes>110"
30603                 }
30604                 kill -0 $UNLINK_PID 2> /dev/null || break
30605         done
30606         wait
30607 }
30608 run_test 831 "throttling unlink/setattr queuing on OSP"
30609
30610 test_832() {
30611         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30612         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30613                 skip "Need MDS version 2.15.52+"
30614         is_rmentry_supported || skip "rm_entry not supported"
30615
30616         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30617         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30618         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30619                 error "mkdir remote_dir failed"
30620         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30621                 error "mkdir striped_dir failed"
30622         touch $DIR/$tdir/file || error "touch file failed"
30623         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30624         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30625 }
30626 run_test 832 "lfs rm_entry"
30627
30628 test_833() {
30629         local file=$DIR/$tfile
30630
30631         stack_trap "rm -f $file" EXIT
30632         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30633
30634         local wpid
30635         local rpid
30636         local rpid2
30637
30638         # Buffered I/O write
30639         (
30640                 while [ ! -e $DIR/sanity.833.lck ]; do
30641                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30642                                 error "failed to write $file"
30643                         sleep 0.$((RANDOM % 4 + 1))
30644                 done
30645         )&
30646         wpid=$!
30647
30648         # Buffered I/O read
30649         (
30650                 while [ ! -e $DIR/sanity.833.lck ]; do
30651                         dd if=$file of=/dev/null bs=1M count=50 ||
30652                                 error "failed to read $file"
30653                         sleep 0.$((RANDOM % 4 + 1))
30654                 done
30655         )&
30656         rpid=$!
30657
30658         # Direct I/O read
30659         (
30660                 while [ ! -e $DIR/sanity.833.lck ]; do
30661                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30662                                 error "failed to read $file in direct I/O mode"
30663                         sleep 0.$((RANDOM % 4 + 1))
30664                 done
30665         )&
30666         rpid2=$!
30667
30668         sleep 30
30669         touch $DIR/sanity.833.lck
30670         wait $wpid || error "$?: buffered write failed"
30671         wait $rpid || error "$?: buffered read failed"
30672         wait $rpid2 || error "$?: direct read failed"
30673 }
30674 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30675
30676 #
30677 # tests that do cleanup/setup should be run at the end
30678 #
30679
30680 test_900() {
30681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30682         local ls
30683
30684         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30685         $LCTL set_param fail_loc=0x903
30686
30687         cancel_lru_locks MGC
30688
30689         FAIL_ON_ERROR=true cleanup
30690         FAIL_ON_ERROR=true setup
30691 }
30692 run_test 900 "umount should not race with any mgc requeue thread"
30693
30694 # LUS-6253/LU-11185
30695 test_901() {
30696         local old
30697         local count
30698         local oldc
30699         local newc
30700         local olds
30701         local news
30702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30703
30704         # some get_param have a bug to handle dot in param name
30705         cancel_lru_locks MGC
30706         old=$(mount -t lustre | wc -l)
30707         # 1 config+sptlrpc
30708         # 2 params
30709         # 3 nodemap
30710         # 4 IR
30711         old=$((old * 4))
30712         oldc=0
30713         count=0
30714         while [ $old -ne $oldc ]; do
30715                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30716                 sleep 1
30717                 ((count++))
30718                 if [ $count -ge $TIMEOUT ]; then
30719                         error "too large timeout"
30720                 fi
30721         done
30722         umount_client $MOUNT || error "umount failed"
30723         mount_client $MOUNT || error "mount failed"
30724         cancel_lru_locks MGC
30725         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30726
30727         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30728
30729         return 0
30730 }
30731 run_test 901 "don't leak a mgc lock on client umount"
30732
30733 # LU-13377
30734 test_902() {
30735         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30736                 skip "client does not have LU-13377 fix"
30737         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30738         $LCTL set_param fail_loc=0x1415
30739         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30740         cancel_lru_locks osc
30741         rm -f $DIR/$tfile
30742 }
30743 run_test 902 "test short write doesn't hang lustre"
30744
30745 # LU-14711
30746 test_903() {
30747         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30748         echo "blah" > $DIR/${tfile}-2
30749         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30750         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30751         $LCTL set_param fail_loc=0x417 fail_val=20
30752
30753         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30754         sleep 1 # To start the destroy
30755         wait_destroy_complete 150 || error "Destroy taking too long"
30756         cat $DIR/$tfile > /dev/null || error "Evicted"
30757 }
30758 run_test 903 "Test long page discard does not cause evictions"
30759
30760 test_904() {
30761         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30762         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30763                 grep -q project || skip "skip project quota not supported"
30764
30765         local testfile="$DIR/$tdir/$tfile"
30766         local xattr="trusted.projid"
30767         local projid
30768         local mdts=$(comma_list $(mdts_nodes))
30769         local saved=$(do_facet mds1 $LCTL get_param -n \
30770                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30771
30772         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30773         stack_trap "do_nodes $mdts $LCTL set_param \
30774                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30775
30776         mkdir -p $DIR/$tdir
30777         touch $testfile
30778         #hide projid xattr on server
30779         $LFS project -p 1 $testfile ||
30780                 error "set $testfile project id failed"
30781         getfattr -m - $testfile | grep $xattr &&
30782                 error "do not show trusted.projid when disabled on server"
30783         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30784         #should be hidden when projid is 0
30785         $LFS project -p 0 $testfile ||
30786                 error "set $testfile project id failed"
30787         getfattr -m - $testfile | grep $xattr &&
30788                 error "do not show trusted.projid with project ID 0"
30789
30790         #still can getxattr explicitly
30791         projid=$(getfattr -n $xattr $testfile |
30792                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30793         [ $projid == "0" ] ||
30794                 error "projid expected 0 not $projid"
30795
30796         #set the projid via setxattr
30797         setfattr -n $xattr -v "1000" $testfile ||
30798                 error "setattr failed with $?"
30799         projid=($($LFS project $testfile))
30800         [ ${projid[0]} == "1000" ] ||
30801                 error "projid expected 1000 not $projid"
30802
30803         #check the new projid via getxattr
30804         $LFS project -p 1001 $testfile ||
30805                 error "set $testfile project id failed"
30806         getfattr -m - $testfile | grep $xattr ||
30807                 error "should show trusted.projid when project ID != 0"
30808         projid=$(getfattr -n $xattr $testfile |
30809                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30810         [ $projid == "1001" ] ||
30811                 error "projid expected 1001 not $projid"
30812
30813         #try to set invalid projid
30814         setfattr -n $xattr -v "4294967295" $testfile &&
30815                 error "set invalid projid should fail"
30816
30817         #remove the xattr means setting projid to 0
30818         setfattr -x $xattr $testfile ||
30819                 error "setfattr failed with $?"
30820         projid=($($LFS project $testfile))
30821         [ ${projid[0]} == "0" ] ||
30822                 error "projid expected 0 not $projid"
30823
30824         #should be hidden when parent has inherit flag and same projid
30825         $LFS project -srp 1002 $DIR/$tdir ||
30826                 error "set $tdir project id failed"
30827         getfattr -m - $testfile | grep $xattr &&
30828                 error "do not show trusted.projid with inherit flag"
30829
30830         #still can getxattr explicitly
30831         projid=$(getfattr -n $xattr $testfile |
30832                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30833         [ $projid == "1002" ] ||
30834                 error "projid expected 1002 not $projid"
30835 }
30836 run_test 904 "virtual project ID xattr"
30837
30838 # LU-8582
30839 test_905() {
30840         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30841                 skip "need OST version >= 2.15.50.220 for fail_loc"
30842
30843         remote_ost_nodsh && skip "remote OST with nodsh"
30844         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30845
30846         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30847
30848         #define OBD_FAIL_OST_OPCODE 0x253
30849         # OST_LADVISE = 21
30850         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30851         $LFS ladvise -a willread $DIR/$tfile &&
30852                 error "unexpected success of ladvise with fault injection"
30853         $LFS ladvise -a willread $DIR/$tfile |&
30854                 grep -q "Operation not supported"
30855         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30856 }
30857 run_test 905 "bad or new opcode should not stuck client"
30858
30859 test_906() {
30860         grep -q io_uring_setup /proc/kallsyms ||
30861                 skip "Client OS does not support io_uring I/O engine"
30862         io_uring_probe || skip "kernel does not support io_uring fully"
30863         which fio || skip_env "no fio installed"
30864         fio --enghelp | grep -q io_uring ||
30865                 skip_env "fio does not support io_uring I/O engine"
30866
30867         local file=$DIR/$tfile
30868         local ioengine="io_uring"
30869         local numjobs=2
30870         local size=50M
30871
30872         fio --name=seqwrite --ioengine=$ioengine        \
30873                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30874                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30875                 error "fio seqwrite $file failed"
30876
30877         fio --name=seqread --ioengine=$ioengine \
30878                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30879                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30880                 error "fio seqread $file failed"
30881
30882         rm -f $file || error "rm -f $file failed"
30883 }
30884 run_test 906 "Simple test for io_uring I/O engine via fio"
30885
30886 test_907() {
30887         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
30888
30889         # set stripe size to max rpc size
30890         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
30891         $LFS getstripe $DIR/$tfile
30892 #define OBD_FAIL_OST_EROFS               0x216
30893         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
30894
30895         local bs=$((max_pages * PAGE_SIZE / 16))
30896
30897         # write full one stripe and one block
30898         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
30899
30900         rm $DIR/$tfile || error "rm failed"
30901 }
30902 run_test 907 "write rpc error during unlink"
30903
30904 complete_test $SECONDS
30905 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30906 check_and_cleanup_lustre
30907 if [ "$I_MOUNTED" != "yes" ]; then
30908         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30909 fi
30910 exit_status