Whamcloud - gitweb
LU-16763 obdclass: add unit tests for OBD life cycle
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47 fi
48
49 # skip the grant tests for ARM until they are fixed
50 if [[ $(uname -m) = aarch64 ]]; then
51         always_except LU-11671 45
52 fi
53
54 # skip nfs tests on kernels >= 4.12.0 until they are fixed
55 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
56         always_except LU-12661 817
57 fi
58 # skip cgroup tests on RHEL8.1 kernels until they are fixed
59 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
60       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
61         always_except LU-13063 411
62 fi
63
64 #                                  5              12     8   12  15   (min)"
65 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
66
67 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
68         #                                               13    (min)"
69         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
70 fi
71
72 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
73         always_except LU-1941 130b 130c 130d 130e 130f 130g
74         always_except LU-9054 312
75 fi
76
77 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
78
79 # Get the SLES distro version
80 #
81 # Returns a version string that should only be used in comparing
82 # strings returned by version_code()
83 sles_version_code()
84 {
85         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
86
87         # All SuSE Linux versions have one decimal. version_code expects two
88         local sles_version=$version.0
89         version_code $sles_version
90 }
91
92 # Check if we are running on Ubuntu or SLES so we can make decisions on
93 # what tests to run
94 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
95         sles_version=$(sles_version_code)
96         [ $sles_version -lt $(version_code 11.4.0) ] &&
97                 always_except LU-4341 170
98
99         [ $sles_version -lt $(version_code 12.0.0) ] &&
100                 always_except LU-3703 234
101 elif [ -r /etc/os-release ]; then
102         if grep -qi ubuntu /etc/os-release; then
103                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
104                                                 -e 's/^VERSION=//p' \
105                                                 /etc/os-release |
106                                                 awk '{ print $1 }'))
107
108                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
109                         always_except LU-10366 410
110                 fi
111         fi
112 fi
113
114 build_test_filter
115 FAIL_ON_ERROR=false
116
117 cleanup() {
118         echo -n "cln.."
119         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
120         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
121 }
122 setup() {
123         echo -n "mnt.."
124         load_modules
125         setupall || exit 10
126         echo "done"
127 }
128
129 check_swap_layouts_support()
130 {
131         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
132                 skip "Does not support layout lock."
133 }
134
135 check_swap_layout_no_dom()
136 {
137         local FOLDER=$1
138         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
139         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
140 }
141
142 check_and_setup_lustre
143 DIR=${DIR:-$MOUNT}
144 assert_DIR
145
146 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
147
148 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
149 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
150 rm -rf $DIR/[Rdfs][0-9]*
151
152 # $RUNAS_ID may get set incorrectly somewhere else
153 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
154         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
155
156 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
157
158 if [ "${ONLY}" = "MOUNT" ] ; then
159         echo "Lustre is up, please go on"
160         exit
161 fi
162
163 echo "preparing for tests involving mounts"
164 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
165 touch $EXT2_DEV
166 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
167 echo # add a newline after mke2fs.
168
169 umask 077
170
171 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
172
173 # ensure all internal functions know we want full debug
174 export PTLDEBUG=all
175 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
176
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare client versions.  Only compare top-3 fields for compatibility
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
232         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "exp version '$exp_client_version'($exp_val) != " \
235                         "'$(lustre_build_version client)'($imp_val)"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_0e() { # LU-13417
240         (( $MDSCOUNT > 1 )) ||
241                 skip "We need at least 2 MDTs for this test"
242
243         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
244                 skip "Need server version at least 2.14.51"
245
246         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
247         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
248
249         [ $default_lmv_count -eq 1 ] ||
250                 error "$MOUNT default stripe count $default_lmv_count"
251
252         [ $default_lmv_index -eq -1 ] ||
253                 error "$MOUNT default stripe index $default_lmv_index"
254
255         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
256         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
257
258         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
259         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
260
261         [ $mdt_index1 -eq $mdt_index2 ] &&
262                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
263
264         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
265 }
266 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
267
268 test_1() {
269         test_mkdir $DIR/$tdir
270         test_mkdir $DIR/$tdir/d2
271         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
273         rmdir $DIR/$tdir/d2
274         rmdir $DIR/$tdir
275         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
276 }
277 run_test 1 "mkdir; remkdir; rmdir"
278
279 test_2() {
280         test_mkdir $DIR/$tdir
281         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
282         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
283         rm -r $DIR/$tdir
284         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
285 }
286 run_test 2 "mkdir; touch; rmdir; check file"
287
288 test_3() {
289         test_mkdir $DIR/$tdir
290         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
291         touch $DIR/$tdir/$tfile
292         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
293         rm -r $DIR/$tdir
294         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
295 }
296 run_test 3 "mkdir; touch; rmdir; check dir"
297
298 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
299 test_4() {
300         test_mkdir -i 1 $DIR/$tdir
301
302         touch $DIR/$tdir/$tfile ||
303                 error "Create file under remote directory failed"
304
305         rmdir $DIR/$tdir &&
306                 error "Expect error removing in-use dir $DIR/$tdir"
307
308         test -d $DIR/$tdir || error "Remote directory disappeared"
309
310         rm -rf $DIR/$tdir || error "remove remote dir error"
311 }
312 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
313
314 test_5() {
315         test_mkdir $DIR/$tdir
316         test_mkdir $DIR/$tdir/d2
317         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
318         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
319         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
320 }
321 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
322
323 test_6a() {
324         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
325         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile does not have perm 0666 or UID $UID"
328         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile should be 0666 and owned by UID $UID"
331 }
332 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
333
334 test_6c() {
335         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
336
337         touch $DIR/$tfile
338         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344 }
345 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
346
347 test_6e() {
348         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
349
350         touch $DIR/$tfile
351         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by GID $UID"
354         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
357 }
358 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
359
360 test_6g() {
361         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
362
363         test_mkdir $DIR/$tdir
364         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
365         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
366         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
367         test_mkdir $DIR/$tdir/d/subdir
368         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
369                 error "$tdir/d/subdir should be GID $RUNAS_GID"
370         if [[ $MDSCOUNT -gt 1 ]]; then
371                 # check remote dir sgid inherite
372                 $LFS mkdir -i 0 $DIR/$tdir.local ||
373                         error "mkdir $tdir.local failed"
374                 chmod g+s $DIR/$tdir.local ||
375                         error "chmod $tdir.local failed"
376                 chgrp $RUNAS_GID $DIR/$tdir.local ||
377                         error "chgrp $tdir.local failed"
378                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
379                         error "mkdir $tdir.remote failed"
380                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
381                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
382                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
383                         error "$tdir.remote should be mode 02755"
384         fi
385 }
386 run_test 6g "verify new dir in sgid dir inherits group"
387
388 test_6h() { # bug 7331
389         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
390
391         touch $DIR/$tfile || error "touch failed"
392         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
393         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
394                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
395         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
396                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
397 }
398 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
399
400 test_7a() {
401         test_mkdir $DIR/$tdir
402         $MCREATE $DIR/$tdir/$tfile
403         chmod 0666 $DIR/$tdir/$tfile
404         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
405                 error "$tdir/$tfile should be mode 0666"
406 }
407 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
408
409 test_7b() {
410         if [ ! -d $DIR/$tdir ]; then
411                 test_mkdir $DIR/$tdir
412         fi
413         $MCREATE $DIR/$tdir/$tfile
414         echo -n foo > $DIR/$tdir/$tfile
415         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
416         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
417 }
418 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
419
420 test_8() {
421         test_mkdir $DIR/$tdir
422         touch $DIR/$tdir/$tfile
423         chmod 0666 $DIR/$tdir/$tfile
424         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
425                 error "$tfile mode not 0666"
426 }
427 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
428
429 test_9() {
430         test_mkdir $DIR/$tdir
431         test_mkdir $DIR/$tdir/d2
432         test_mkdir $DIR/$tdir/d2/d3
433         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
434 }
435 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
436
437 test_10() {
438         test_mkdir $DIR/$tdir
439         test_mkdir $DIR/$tdir/d2
440         touch $DIR/$tdir/d2/$tfile
441         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
442                 error "$tdir/d2/$tfile not a file"
443 }
444 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
445
446 test_11() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         chmod 0666 $DIR/$tdir/d2
450         chmod 0705 $DIR/$tdir/d2
451         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
452                 error "$tdir/d2 mode not 0705"
453 }
454 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
455
456 test_12() {
457         test_mkdir $DIR/$tdir
458         touch $DIR/$tdir/$tfile
459         chmod 0666 $DIR/$tdir/$tfile
460         chmod 0654 $DIR/$tdir/$tfile
461         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
462                 error "$tdir/d2 mode not 0654"
463 }
464 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
465
466 test_13() {
467         test_mkdir $DIR/$tdir
468         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
469         >  $DIR/$tdir/$tfile
470         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
471                 error "$tdir/$tfile size not 0 after truncate"
472 }
473 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
474
475 test_14() {
476         test_mkdir $DIR/$tdir
477         touch $DIR/$tdir/$tfile
478         rm $DIR/$tdir/$tfile
479         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
480 }
481 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
482
483 test_15() {
484         test_mkdir $DIR/$tdir
485         touch $DIR/$tdir/$tfile
486         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
487         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
488                 error "$tdir/${tfile_2} not a file after rename"
489         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
490 }
491 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
492
493 test_16() {
494         test_mkdir $DIR/$tdir
495         touch $DIR/$tdir/$tfile
496         rm -rf $DIR/$tdir/$tfile
497         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
498 }
499 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
500
501 test_17a() {
502         test_mkdir $DIR/$tdir
503         touch $DIR/$tdir/$tfile
504         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
505         ls -l $DIR/$tdir
506         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
507                 error "$tdir/l-exist not a symlink"
508         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
509                 error "$tdir/l-exist not referencing a file"
510         rm -f $DIR/$tdir/l-exist
511         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
512 }
513 run_test 17a "symlinks: create, remove (real)"
514
515 test_17b() {
516         test_mkdir $DIR/$tdir
517         ln -s no-such-file $DIR/$tdir/l-dangle
518         ls -l $DIR/$tdir
519         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
520                 error "$tdir/l-dangle not referencing no-such-file"
521         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
522                 error "$tdir/l-dangle not referencing non-existent file"
523         rm -f $DIR/$tdir/l-dangle
524         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
525 }
526 run_test 17b "symlinks: create, remove (dangling)"
527
528 test_17c() { # bug 3440 - don't save failed open RPC for replay
529         test_mkdir $DIR/$tdir
530         ln -s foo $DIR/$tdir/$tfile
531         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
532 }
533 run_test 17c "symlinks: open dangling (should return error)"
534
535 test_17d() {
536         test_mkdir $DIR/$tdir
537         ln -s foo $DIR/$tdir/$tfile
538         touch $DIR/$tdir/$tfile || error "creating to new symlink"
539 }
540 run_test 17d "symlinks: create dangling"
541
542 test_17e() {
543         test_mkdir $DIR/$tdir
544         local foo=$DIR/$tdir/$tfile
545         ln -s $foo $foo || error "create symlink failed"
546         ls -l $foo || error "ls -l failed"
547         ls $foo && error "ls not failed" || true
548 }
549 run_test 17e "symlinks: create recursive symlink (should return error)"
550
551 test_17f() {
552         test_mkdir $DIR/$tdir
553         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
556         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
559         ls -l  $DIR/$tdir
560 }
561 run_test 17f "symlinks: long and very long symlink name"
562
563 # str_repeat(S, N) generate a string that is string S repeated N times
564 str_repeat() {
565         local s=$1
566         local n=$2
567         local ret=''
568         while [ $((n -= 1)) -ge 0 ]; do
569                 ret=$ret$s
570         done
571         echo $ret
572 }
573
574 # Long symlinks and LU-2241
575 test_17g() {
576         test_mkdir $DIR/$tdir
577         local TESTS="59 60 61 4094 4095"
578
579         # Fix for inode size boundary in 2.1.4
580         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
581                 TESTS="4094 4095"
582
583         # Patch not applied to 2.2 or 2.3 branches
584         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
585         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
586                 TESTS="4094 4095"
587
588         for i in $TESTS; do
589                 local SYMNAME=$(str_repeat 'x' $i)
590                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
591                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
592         done
593 }
594 run_test 17g "symlinks: really long symlink name and inode boundaries"
595
596 test_17h() { #bug 17378
597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
598         remote_mds_nodsh && skip "remote MDS with nodsh"
599
600         local mdt_idx
601
602         test_mkdir $DIR/$tdir
603         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
604         $LFS setstripe -c -1 $DIR/$tdir
605         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
606         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
607         touch $DIR/$tdir/$tfile || true
608 }
609 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
610
611 test_17i() { #bug 20018
612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
613         remote_mds_nodsh && skip "remote MDS with nodsh"
614
615         local foo=$DIR/$tdir/$tfile
616         local mdt_idx
617
618         test_mkdir -c1 $DIR/$tdir
619         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
620         ln -s $foo $foo || error "create symlink failed"
621 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
622         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
623         ls -l $foo && error "error not detected"
624         return 0
625 }
626 run_test 17i "don't panic on short symlink (should return error)"
627
628 test_17k() { #bug 22301
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         [[ -z "$(which rsync 2>/dev/null)" ]] &&
631                 skip "no rsync command"
632         rsync --help | grep -q xattr ||
633                 skip_env "$(rsync --version | head -n1) does not support xattrs"
634         test_mkdir $DIR/$tdir
635         test_mkdir $DIR/$tdir.new
636         touch $DIR/$tdir/$tfile
637         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
638         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
639                 error "rsync failed with xattrs enabled"
640 }
641 run_test 17k "symlinks: rsync with xattrs enabled"
642
643 test_17l() { # LU-279
644         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
645                 skip "no getfattr command"
646
647         test_mkdir $DIR/$tdir
648         touch $DIR/$tdir/$tfile
649         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
650         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
651                 # -h to not follow symlinks. -m '' to list all the xattrs.
652                 # grep to remove first line: '# file: $path'.
653                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
654                 do
655                         lgetxattr_size_check $path $xattr ||
656                                 error "lgetxattr_size_check $path $xattr failed"
657                 done
658         done
659 }
660 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
661
662 # LU-1540
663 test_17m() {
664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
665         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
666         remote_mds_nodsh && skip "remote MDS with nodsh"
667         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
668         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
669                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
670
671         local short_sym="0123456789"
672         local wdir=$DIR/$tdir
673         local i
674
675         test_mkdir $wdir
676         long_sym=$short_sym
677         # create a long symlink file
678         for ((i = 0; i < 4; ++i)); do
679                 long_sym=${long_sym}${long_sym}
680         done
681
682         echo "create 512 short and long symlink files under $wdir"
683         for ((i = 0; i < 256; ++i)); do
684                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
685                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
686         done
687
688         echo "erase them"
689         rm -f $wdir/*
690         sync
691         wait_delete_completed
692
693         echo "recreate the 512 symlink files with a shorter string"
694         for ((i = 0; i < 512; ++i)); do
695                 # rewrite the symlink file with a shorter string
696                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
697                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
698         done
699
700         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
701
702         echo "stop and checking mds${mds_index}:"
703         # e2fsck should not return error
704         stop mds${mds_index}
705         local devname=$(mdsdevname $mds_index)
706         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
707         rc=$?
708
709         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
710                 error "start mds${mds_index} failed"
711         df $MOUNT > /dev/null 2>&1
712         [ $rc -eq 0 ] ||
713                 error "e2fsck detected error for short/long symlink: rc=$rc"
714         rm -f $wdir/*
715 }
716 run_test 17m "run e2fsck against MDT which contains short/long symlink"
717
718 check_fs_consistency_17n() {
719         local mdt_index
720         local rc=0
721
722         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
723         # so it only check MDT1/MDT2 instead of all of MDTs.
724         for mdt_index in 1 2; do
725                 # e2fsck should not return error
726                 stop mds${mdt_index}
727                 local devname=$(mdsdevname $mdt_index)
728                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
729                         rc=$((rc + $?))
730
731                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
732                         error "mount mds$mdt_index failed"
733                 df $MOUNT > /dev/null 2>&1
734         done
735         return $rc
736 }
737
738 test_17n() {
739         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
741         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
742         remote_mds_nodsh && skip "remote MDS with nodsh"
743         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
744         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
745                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
746
747         local i
748
749         test_mkdir $DIR/$tdir
750         for ((i=0; i<10; i++)); do
751                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
752                         error "create remote dir error $i"
753                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
754                         error "create files under remote dir failed $i"
755         done
756
757         check_fs_consistency_17n ||
758                 error "e2fsck report error after create files under remote dir"
759
760         for ((i = 0; i < 10; i++)); do
761                 rm -rf $DIR/$tdir/remote_dir_${i} ||
762                         error "destroy remote dir error $i"
763         done
764
765         check_fs_consistency_17n ||
766                 error "e2fsck report error after unlink files under remote dir"
767
768         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
769                 skip "lustre < 2.4.50 does not support migrate mv"
770
771         for ((i = 0; i < 10; i++)); do
772                 mkdir -p $DIR/$tdir/remote_dir_${i}
773                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
774                         error "create files under remote dir failed $i"
775                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
776                         error "migrate remote dir error $i"
777         done
778         check_fs_consistency_17n || error "e2fsck report error after migration"
779
780         for ((i = 0; i < 10; i++)); do
781                 rm -rf $DIR/$tdir/remote_dir_${i} ||
782                         error "destroy remote dir error $i"
783         done
784
785         check_fs_consistency_17n || error "e2fsck report error after unlink"
786 }
787 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
788
789 test_17o() {
790         remote_mds_nodsh && skip "remote MDS with nodsh"
791         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
792                 skip "Need MDS version at least 2.3.64"
793
794         local wdir=$DIR/${tdir}o
795         local mdt_index
796         local rc=0
797
798         test_mkdir $wdir
799         touch $wdir/$tfile
800         mdt_index=$($LFS getstripe -m $wdir/$tfile)
801         mdt_index=$((mdt_index + 1))
802
803         cancel_lru_locks mdc
804         #fail mds will wait the failover finish then set
805         #following fail_loc to avoid interfer the recovery process.
806         fail mds${mdt_index}
807
808         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
809         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
810         ls -l $wdir/$tfile && rc=1
811         do_facet mds${mdt_index} lctl set_param fail_loc=0
812         [[ $rc -eq 0 ]] || error "stat file should fail"
813 }
814 run_test 17o "stat file with incompat LMA feature"
815
816 test_18() {
817         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
818         ls $DIR || error "Failed to ls $DIR: $?"
819 }
820 run_test 18 "touch .../f ; ls ... =============================="
821
822 test_19a() {
823         touch $DIR/$tfile
824         ls -l $DIR
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
829
830 test_19b() {
831         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
832 }
833 run_test 19b "ls -l .../f19 (should return error) =============="
834
835 test_19c() {
836         [ $RUNAS_ID -eq $UID ] &&
837                 skip_env "RUNAS_ID = UID = $UID -- skipping"
838
839         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
840 }
841 run_test 19c "$RUNAS touch .../f19 (should return error) =="
842
843 test_19d() {
844         cat $DIR/f19 && error || true
845 }
846 run_test 19d "cat .../f19 (should return error) =============="
847
848 test_20() {
849         touch $DIR/$tfile
850         rm $DIR/$tfile
851         touch $DIR/$tfile
852         rm $DIR/$tfile
853         touch $DIR/$tfile
854         rm $DIR/$tfile
855         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
856 }
857 run_test 20 "touch .../f ; ls -l ..."
858
859 test_21() {
860         test_mkdir $DIR/$tdir
861         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
862         ln -s dangle $DIR/$tdir/link
863         echo foo >> $DIR/$tdir/link
864         cat $DIR/$tdir/dangle
865         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
866         $CHECKSTAT -f -t file $DIR/$tdir/link ||
867                 error "$tdir/link not linked to a file"
868 }
869 run_test 21 "write to dangling link"
870
871 test_22() {
872         local wdir=$DIR/$tdir
873         test_mkdir $wdir
874         chown $RUNAS_ID:$RUNAS_GID $wdir
875         (cd $wdir || error "cd $wdir failed";
876                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
877                 $RUNAS tar xf -)
878         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
879         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
880         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
881                 error "checkstat -u failed"
882 }
883 run_test 22 "unpack tar archive as non-root user"
884
885 # was test_23
886 test_23a() {
887         test_mkdir $DIR/$tdir
888         local file=$DIR/$tdir/$tfile
889
890         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
891         openfile -f O_CREAT:O_EXCL $file &&
892                 error "$file recreate succeeded" || true
893 }
894 run_test 23a "O_CREAT|O_EXCL in subdir"
895
896 test_23b() { # bug 18988
897         test_mkdir $DIR/$tdir
898         local file=$DIR/$tdir/$tfile
899
900         rm -f $file
901         echo foo > $file || error "write filed"
902         echo bar >> $file || error "append filed"
903         $CHECKSTAT -s 8 $file || error "wrong size"
904         rm $file
905 }
906 run_test 23b "O_APPEND check"
907
908 # LU-9409, size with O_APPEND and tiny writes
909 test_23c() {
910         local file=$DIR/$tfile
911
912         # single dd
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
914         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
915         rm -f $file
916
917         # racing tiny writes
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
920         wait
921         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
922         rm -f $file
923
924         #racing tiny & normal writes
925         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
926         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
927         wait
928         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
929         rm -f $file
930
931         #racing tiny & normal writes 2, ugly numbers
932         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
934         wait
935         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
936         rm -f $file
937 }
938 run_test 23c "O_APPEND size checks for tiny writes"
939
940 # LU-11069 file offset is correct after appending writes
941 test_23d() {
942         local file=$DIR/$tfile
943         local offset
944
945         echo CentaurHauls > $file
946         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
947         if ((offset != 26)); then
948                 error "wrong offset, expected 26, got '$offset'"
949         fi
950 }
951 run_test 23d "file offset is correct after appending writes"
952
953 # rename sanity
954 test_24a() {
955         echo '-- same directory rename'
956         test_mkdir $DIR/$tdir
957         touch $DIR/$tdir/$tfile.1
958         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
959         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
960 }
961 run_test 24a "rename file to non-existent target"
962
963 test_24b() {
964         test_mkdir $DIR/$tdir
965         touch $DIR/$tdir/$tfile.{1,2}
966         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
967         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
968         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
969 }
970 run_test 24b "rename file to existing target"
971
972 test_24c() {
973         test_mkdir $DIR/$tdir
974         test_mkdir $DIR/$tdir/d$testnum.1
975         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
976         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
977         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
978 }
979 run_test 24c "rename directory to non-existent target"
980
981 test_24d() {
982         test_mkdir -c1 $DIR/$tdir
983         test_mkdir -c1 $DIR/$tdir/d$testnum.1
984         test_mkdir -c1 $DIR/$tdir/d$testnum.2
985         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
986         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
987         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
988 }
989 run_test 24d "rename directory to existing target"
990
991 test_24e() {
992         echo '-- cross directory renames --'
993         test_mkdir $DIR/R5a
994         test_mkdir $DIR/R5b
995         touch $DIR/R5a/f
996         mv $DIR/R5a/f $DIR/R5b/g
997         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
998         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
999 }
1000 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1001
1002 test_24f() {
1003         test_mkdir $DIR/R6a
1004         test_mkdir $DIR/R6b
1005         touch $DIR/R6a/f $DIR/R6b/g
1006         mv $DIR/R6a/f $DIR/R6b/g
1007         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1008         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1009 }
1010 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1011
1012 test_24g() {
1013         test_mkdir $DIR/R7a
1014         test_mkdir $DIR/R7b
1015         test_mkdir $DIR/R7a/d
1016         mv $DIR/R7a/d $DIR/R7b/e
1017         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1018         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1019 }
1020 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1021
1022 test_24h() {
1023         test_mkdir -c1 $DIR/R8a
1024         test_mkdir -c1 $DIR/R8b
1025         test_mkdir -c1 $DIR/R8a/d
1026         test_mkdir -c1 $DIR/R8b/e
1027         mrename $DIR/R8a/d $DIR/R8b/e
1028         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1029         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1030 }
1031 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1032
1033 test_24i() {
1034         echo "-- rename error cases"
1035         test_mkdir $DIR/R9
1036         test_mkdir $DIR/R9/a
1037         touch $DIR/R9/f
1038         mrename $DIR/R9/f $DIR/R9/a
1039         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1040         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1041         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1042 }
1043 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1044
1045 test_24j() {
1046         test_mkdir $DIR/R10
1047         mrename $DIR/R10/f $DIR/R10/g
1048         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1049         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1050         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1051 }
1052 run_test 24j "source does not exist ============================"
1053
1054 test_24k() {
1055         test_mkdir $DIR/R11a
1056         test_mkdir $DIR/R11a/d
1057         touch $DIR/R11a/f
1058         mv $DIR/R11a/f $DIR/R11a/d
1059         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1060         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1061 }
1062 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1063
1064 # bug 2429 - rename foo foo foo creates invalid file
1065 test_24l() {
1066         f="$DIR/f24l"
1067         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1068 }
1069 run_test 24l "Renaming a file to itself ========================"
1070
1071 test_24m() {
1072         f="$DIR/f24m"
1073         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1074         # on ext3 this does not remove either the source or target files
1075         # though the "expected" operation would be to remove the source
1076         $CHECKSTAT -t file ${f} || error "${f} missing"
1077         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1078 }
1079 run_test 24m "Renaming a file to a hard link to itself ========="
1080
1081 test_24n() {
1082     f="$DIR/f24n"
1083     # this stats the old file after it was renamed, so it should fail
1084     touch ${f}
1085     $CHECKSTAT ${f} || error "${f} missing"
1086     mv ${f} ${f}.rename
1087     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1088     $CHECKSTAT -a ${f} || error "${f} exists"
1089 }
1090 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1091
1092 test_24o() {
1093         test_mkdir $DIR/$tdir
1094         rename_many -s random -v -n 10 $DIR/$tdir
1095 }
1096 run_test 24o "rename of files during htree split"
1097
1098 test_24p() {
1099         test_mkdir $DIR/R12a
1100         test_mkdir $DIR/R12b
1101         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1102         mrename $DIR/R12a $DIR/R12b
1103         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1104         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1105         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1106         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1107 }
1108 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1109
1110 cleanup_multiop_pause() {
1111         trap 0
1112         kill -USR1 $MULTIPID
1113 }
1114
1115 test_24q() {
1116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1117
1118         test_mkdir $DIR/R13a
1119         test_mkdir $DIR/R13b
1120         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1121         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1122         MULTIPID=$!
1123
1124         trap cleanup_multiop_pause EXIT
1125         mrename $DIR/R13a $DIR/R13b
1126         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1127         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1128         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1129         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1130         cleanup_multiop_pause
1131         wait $MULTIPID || error "multiop close failed"
1132 }
1133 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1134
1135 test_24r() { #bug 3789
1136         test_mkdir $DIR/R14a
1137         test_mkdir $DIR/R14a/b
1138         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1139         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1140         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1141 }
1142 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1143
1144 test_24s() {
1145         test_mkdir $DIR/R15a
1146         test_mkdir $DIR/R15a/b
1147         test_mkdir $DIR/R15a/b/c
1148         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1149         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1150         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1151 }
1152 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1153
1154 test_24t() {
1155         test_mkdir $DIR/R16a
1156         test_mkdir $DIR/R16a/b
1157         test_mkdir $DIR/R16a/b/c
1158         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1159         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1160         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1161 }
1162 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1163
1164 test_24u() { # bug12192
1165         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1166         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1167 }
1168 run_test 24u "create stripe file"
1169
1170 simple_cleanup_common() {
1171         local createmany=$1
1172         local rc=0
1173
1174         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1175
1176         local start=$SECONDS
1177
1178         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1179         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1180         rc=$?
1181         wait_delete_completed
1182         echo "cleanup time $((SECONDS - start))"
1183         return $rc
1184 }
1185
1186 max_pages_per_rpc() {
1187         local mdtname="$(printf "MDT%04x" ${1:-0})"
1188         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1189 }
1190
1191 test_24v() {
1192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1193
1194         local nrfiles=${COUNT:-100000}
1195         local fname="$DIR/$tdir/$tfile"
1196
1197         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1198         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1199
1200         test_mkdir "$(dirname $fname)"
1201         # assume MDT0000 has the fewest inodes
1202         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1203         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1204         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1205
1206         stack_trap "simple_cleanup_common $nrfiles"
1207
1208         createmany -m "$fname" $nrfiles
1209
1210         cancel_lru_locks mdc
1211         lctl set_param mdc.*.stats clear
1212
1213         # was previously test_24D: LU-6101
1214         # readdir() returns correct number of entries after cursor reload
1215         local num_ls=$(ls $DIR/$tdir | wc -l)
1216         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1217         local num_all=$(ls -a $DIR/$tdir | wc -l)
1218         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1219                 [ $num_all -ne $((nrfiles + 2)) ]; then
1220                         error "Expected $nrfiles files, got $num_ls " \
1221                                 "($num_uniq unique $num_all .&..)"
1222         fi
1223         # LU-5 large readdir
1224         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1225         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1226         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1227         # take into account of overhead in lu_dirpage header and end mark in
1228         # each page, plus one in rpc_num calculation.
1229         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1230         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1231         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1232         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1233         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1234         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1235         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1236         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1237                 error "large readdir doesn't take effect: " \
1238                       "$mds_readpage should be about $rpc_max"
1239 }
1240 run_test 24v "list large directory (test hash collision, b=17560)"
1241
1242 test_24w() { # bug21506
1243         SZ1=234852
1244         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1245         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1246         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1247         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1248         [[ "$SZ1" -eq "$SZ2" ]] ||
1249                 error "Error reading at the end of the file $tfile"
1250 }
1251 run_test 24w "Reading a file larger than 4Gb"
1252
1253 test_24x() {
1254         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1256         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1257                 skip "Need MDS version at least 2.7.56"
1258
1259         local MDTIDX=1
1260         local remote_dir=$DIR/$tdir/remote_dir
1261
1262         test_mkdir $DIR/$tdir
1263         $LFS mkdir -i $MDTIDX $remote_dir ||
1264                 error "create remote directory failed"
1265
1266         test_mkdir $DIR/$tdir/src_dir
1267         touch $DIR/$tdir/src_file
1268         test_mkdir $remote_dir/tgt_dir
1269         touch $remote_dir/tgt_file
1270
1271         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1272                 error "rename dir cross MDT failed!"
1273
1274         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1275                 error "rename file cross MDT failed!"
1276
1277         touch $DIR/$tdir/ln_file
1278         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1279                 error "ln file cross MDT failed"
1280
1281         rm -rf $DIR/$tdir || error "Can not delete directories"
1282 }
1283 run_test 24x "cross MDT rename/link"
1284
1285 test_24y() {
1286         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1288
1289         local remote_dir=$DIR/$tdir/remote_dir
1290         local mdtidx=1
1291
1292         test_mkdir $DIR/$tdir
1293         $LFS mkdir -i $mdtidx $remote_dir ||
1294                 error "create remote directory failed"
1295
1296         test_mkdir $remote_dir/src_dir
1297         touch $remote_dir/src_file
1298         test_mkdir $remote_dir/tgt_dir
1299         touch $remote_dir/tgt_file
1300
1301         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1302                 error "rename subdir in the same remote dir failed!"
1303
1304         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1305                 error "rename files in the same remote dir failed!"
1306
1307         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1308                 error "link files in the same remote dir failed!"
1309
1310         rm -rf $DIR/$tdir || error "Can not delete directories"
1311 }
1312 run_test 24y "rename/link on the same dir should succeed"
1313
1314 test_24z() {
1315         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1316         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1317                 skip "Need MDS version at least 2.12.51"
1318
1319         local index
1320
1321         for index in 0 1; do
1322                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1323                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1324         done
1325
1326         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1327
1328         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1329         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1330
1331         local mdts=$(comma_list $(mdts_nodes))
1332
1333         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1334         stack_trap "do_nodes $mdts $LCTL \
1335                 set_param mdt.*.enable_remote_rename=1" EXIT
1336
1337         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1338
1339         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1340         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1341 }
1342 run_test 24z "cross-MDT rename is done as cp"
1343
1344 test_24A() { # LU-3182
1345         local NFILES=5000
1346
1347         test_mkdir $DIR/$tdir
1348         stack_trap "simple_cleanup_common $NFILES"
1349         createmany -m $DIR/$tdir/$tfile $NFILES
1350         local t=$(ls $DIR/$tdir | wc -l)
1351         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1352         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1353
1354         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1355                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1356 }
1357 run_test 24A "readdir() returns correct number of entries."
1358
1359 test_24B() { # LU-4805
1360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1361
1362         local count
1363
1364         test_mkdir $DIR/$tdir
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1366                 error "create striped dir failed"
1367
1368         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1369         [ $count -eq 2 ] || error "Expected 2, got $count"
1370
1371         touch $DIR/$tdir/striped_dir/a
1372
1373         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1374         [ $count -eq 3 ] || error "Expected 3, got $count"
1375
1376         touch $DIR/$tdir/striped_dir/.f
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 4 ] || error "Expected 4, got $count"
1380
1381         rm -rf $DIR/$tdir || error "Can not delete directories"
1382 }
1383 run_test 24B "readdir for striped dir return correct number of entries"
1384
1385 test_24C() {
1386         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1387
1388         mkdir $DIR/$tdir
1389         mkdir $DIR/$tdir/d0
1390         mkdir $DIR/$tdir/d1
1391
1392         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1393                 error "create striped dir failed"
1394
1395         cd $DIR/$tdir/d0/striped_dir
1396
1397         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1398         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1399         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1400
1401         [ "$d0_ino" = "$parent_ino" ] ||
1402                 error ".. wrong, expect $d0_ino, get $parent_ino"
1403
1404         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1405                 error "mv striped dir failed"
1406
1407         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1408
1409         [ "$d1_ino" = "$parent_ino" ] ||
1410                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1411 }
1412 run_test 24C "check .. in striped dir"
1413
1414 test_24E() {
1415         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1417
1418         mkdir -p $DIR/$tdir
1419         mkdir $DIR/$tdir/src_dir
1420         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1421                 error "create remote source failed"
1422
1423         touch $DIR/$tdir/src_dir/src_child/a
1424
1425         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1426                 error "create remote target dir failed"
1427
1428         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "create remote target child failed"
1430
1431         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1432                 error "rename dir cross MDT failed!"
1433
1434         find $DIR/$tdir
1435
1436         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1437                 error "src_child still exists after rename"
1438
1439         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1440                 error "missing file(a) after rename"
1441
1442         rm -rf $DIR/$tdir || error "Can not delete directories"
1443 }
1444 run_test 24E "cross MDT rename/link"
1445
1446 test_24F () {
1447         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1448
1449         local repeats=1000
1450         [ "$SLOW" = "no" ] && repeats=100
1451
1452         mkdir -p $DIR/$tdir
1453
1454         echo "$repeats repeats"
1455         for ((i = 0; i < repeats; i++)); do
1456                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1457                 touch $DIR/$tdir/test/a || error "touch fails"
1458                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1459                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1460         done
1461
1462         true
1463 }
1464 run_test 24F "hash order vs readdir (LU-11330)"
1465
1466 test_24G () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1468
1469         local ino1
1470         local ino2
1471
1472         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1473         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1474         touch $DIR/$tdir-0/f1 || error "touch f1"
1475         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1476         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1477         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1478         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1479         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1480 }
1481 run_test 24G "migrate symlink in rename"
1482
1483 test_24H() {
1484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1485         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1486                 skip "MDT1 should be on another node"
1487
1488         test_mkdir -i 1 -c 1 $DIR/$tdir
1489 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1490         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1491         touch $DIR/$tdir/$tfile || error "touch failed"
1492 }
1493 run_test 24H "repeat FLD_QUERY rpc"
1494
1495 test_25a() {
1496         echo '== symlink sanity ============================================='
1497
1498         test_mkdir $DIR/d25
1499         ln -s d25 $DIR/s25
1500         touch $DIR/s25/foo ||
1501                 error "File creation in symlinked directory failed"
1502 }
1503 run_test 25a "create file in symlinked directory ==============="
1504
1505 test_25b() {
1506         [ ! -d $DIR/d25 ] && test_25a
1507         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1508 }
1509 run_test 25b "lookup file in symlinked directory ==============="
1510
1511 test_26a() {
1512         test_mkdir $DIR/d26
1513         test_mkdir $DIR/d26/d26-2
1514         ln -s d26/d26-2 $DIR/s26
1515         touch $DIR/s26/foo || error "File creation failed"
1516 }
1517 run_test 26a "multiple component symlink ======================="
1518
1519 test_26b() {
1520         test_mkdir -p $DIR/$tdir/d26-2
1521         ln -s $tdir/d26-2/foo $DIR/s26-2
1522         touch $DIR/s26-2 || error "File creation failed"
1523 }
1524 run_test 26b "multiple component symlink at end of lookup ======"
1525
1526 test_26c() {
1527         test_mkdir $DIR/d26.2
1528         touch $DIR/d26.2/foo
1529         ln -s d26.2 $DIR/s26.2-1
1530         ln -s s26.2-1 $DIR/s26.2-2
1531         ln -s s26.2-2 $DIR/s26.2-3
1532         chmod 0666 $DIR/s26.2-3/foo
1533 }
1534 run_test 26c "chain of symlinks"
1535
1536 # recursive symlinks (bug 439)
1537 test_26d() {
1538         ln -s d26-3/foo $DIR/d26-3
1539 }
1540 run_test 26d "create multiple component recursive symlink"
1541
1542 test_26e() {
1543         [ ! -h $DIR/d26-3 ] && test_26d
1544         rm $DIR/d26-3
1545 }
1546 run_test 26e "unlink multiple component recursive symlink"
1547
1548 # recursive symlinks (bug 7022)
1549 test_26f() {
1550         test_mkdir $DIR/$tdir
1551         test_mkdir $DIR/$tdir/$tfile
1552         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1553         test_mkdir -p lndir/bar1
1554         test_mkdir $DIR/$tdir/$tfile/$tfile
1555         cd $tfile                || error "cd $tfile failed"
1556         ln -s .. dotdot          || error "ln dotdot failed"
1557         ln -s dotdot/lndir lndir || error "ln lndir failed"
1558         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1559         output=`ls $tfile/$tfile/lndir/bar1`
1560         [ "$output" = bar1 ] && error "unexpected output"
1561         rm -r $tfile             || error "rm $tfile failed"
1562         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1563 }
1564 run_test 26f "rm -r of a directory which has recursive symlink"
1565
1566 test_27a() {
1567         test_mkdir $DIR/$tdir
1568         $LFS getstripe $DIR/$tdir
1569         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1570         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1571         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1572 }
1573 run_test 27a "one stripe file"
1574
1575 test_27b() {
1576         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1577
1578         test_mkdir $DIR/$tdir
1579         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1580         $LFS getstripe -c $DIR/$tdir/$tfile
1581         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1582                 error "two-stripe file doesn't have two stripes"
1583
1584         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1585 }
1586 run_test 27b "create and write to two stripe file"
1587
1588 # 27c family tests specific striping, setstripe -o
1589 test_27ca() {
1590         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1591         test_mkdir -p $DIR/$tdir
1592         local osts="1"
1593
1594         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1595         $LFS getstripe -i $DIR/$tdir/$tfile
1596         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1597                 error "stripe not on specified OST"
1598
1599         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1600 }
1601 run_test 27ca "one stripe on specified OST"
1602
1603 test_27cb() {
1604         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1605         test_mkdir -p $DIR/$tdir
1606         local osts="1,0"
1607         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1608         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1609         echo "$getstripe"
1610
1611         # Strip getstripe output to a space separated list of OSTs
1612         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1613                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1614         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1615                 error "stripes not on specified OSTs"
1616
1617         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1618 }
1619 run_test 27cb "two stripes on specified OSTs"
1620
1621 test_27cc() {
1622         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1623         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1624                 skip "server does not support overstriping"
1625
1626         test_mkdir -p $DIR/$tdir
1627         local osts="0,0"
1628         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1629         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1630         echo "$getstripe"
1631
1632         # Strip getstripe output to a space separated list of OSTs
1633         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1634                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1635         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1636                 error "stripes not on specified OSTs"
1637
1638         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1639 }
1640 run_test 27cc "two stripes on the same OST"
1641
1642 test_27cd() {
1643         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1644         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1645                 skip "server does not support overstriping"
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,1,1,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cd "four stripes on two OSTs"
1661
1662 test_27ce() {
1663         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1664                 skip_env "too many osts, skipping"
1665         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1666                 skip "server does not support overstriping"
1667         # We do one more stripe than we have OSTs
1668         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1669                 skip_env "ea_inode feature disabled"
1670
1671         test_mkdir -p $DIR/$tdir
1672         local osts=""
1673         for i in $(seq 0 $OSTCOUNT);
1674         do
1675                 osts=$osts"0"
1676                 if [ $i -ne $OSTCOUNT ]; then
1677                         osts=$osts","
1678                 fi
1679         done
1680         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1681         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1682         echo "$getstripe"
1683
1684         # Strip getstripe output to a space separated list of OSTs
1685         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1686                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1687         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1688                 error "stripes not on specified OSTs"
1689
1690         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1691 }
1692 run_test 27ce "more stripes than OSTs with -o"
1693
1694 test_27cf() {
1695         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1696         local pid=0
1697
1698         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1699         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1700         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1701         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1702                 error "failed to set $osp_proc=0"
1703
1704         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1705         pid=$!
1706         sleep 1
1707         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1709                 error "failed to set $osp_proc=1"
1710         wait $pid
1711         [[ $pid -ne 0 ]] ||
1712                 error "should return error due to $osp_proc=0"
1713 }
1714 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1715
1716 test_27cg() {
1717         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1718                 skip "server does not support overstriping"
1719         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1720         large_xattr_enabled || skip_env "ea_inode feature disabled"
1721
1722         local osts="0"
1723
1724         for ((i=1;i<1000;i++)); do
1725                 osts+=",$((i % OSTCOUNT))"
1726         done
1727
1728         local mdts=$(comma_list $(mdts_nodes))
1729         local before=$(do_nodes $mdts \
1730                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1731                 awk '/many credits/{print $3}' |
1732                 calc_sum)
1733
1734         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1735         $LFS getstripe $DIR/$tfile | grep stripe
1736
1737         rm -f $DIR/$tfile || error "can't unlink"
1738
1739         after=$(do_nodes $mdts \
1740                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1741                 awk '/many credits/{print $3}' |
1742                 calc_sum)
1743
1744         (( before == after )) ||
1745                 error "too many credits happened: $after > $before"
1746 }
1747 run_test 27cg "1000 shouldn't cause too many credits"
1748
1749 test_27d() {
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1752                 error "setstripe failed"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1755 }
1756 run_test 27d "create file with default settings"
1757
1758 test_27e() {
1759         # LU-5839 adds check for existed layout before setting it
1760         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1761                 skip "Need MDS version at least 2.7.56"
1762
1763         test_mkdir $DIR/$tdir
1764         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1765         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1766         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1767 }
1768 run_test 27e "setstripe existing file (should return error)"
1769
1770 test_27f() {
1771         test_mkdir $DIR/$tdir
1772         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1773                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1774         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1775                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1776         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1777         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1778 }
1779 run_test 27f "setstripe with bad stripe size (should return error)"
1780
1781 test_27g() {
1782         test_mkdir $DIR/$tdir
1783         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1784         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1785                 error "$DIR/$tdir/$tfile has object"
1786 }
1787 run_test 27g "$LFS getstripe with no objects"
1788
1789 test_27ga() {
1790         test_mkdir $DIR/$tdir
1791         touch $DIR/$tdir/$tfile || error "touch failed"
1792         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1793         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1794         local rc=$?
1795         (( rc == 2 )) || error "getstripe did not return ENOENT"
1796 }
1797 run_test 27ga "$LFS getstripe with missing file (should return error)"
1798
1799 test_27i() {
1800         test_mkdir $DIR/$tdir
1801         touch $DIR/$tdir/$tfile || error "touch failed"
1802         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1803                 error "missing objects"
1804 }
1805 run_test 27i "$LFS getstripe with some objects"
1806
1807 test_27j() {
1808         test_mkdir $DIR/$tdir
1809         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1810                 error "setstripe failed" || true
1811 }
1812 run_test 27j "setstripe with bad stripe offset (should return error)"
1813
1814 test_27k() { # bug 2844
1815         test_mkdir $DIR/$tdir
1816         local file=$DIR/$tdir/$tfile
1817         local ll_max_blksize=$((4 * 1024 * 1024))
1818         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1819         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1820         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1821         dd if=/dev/zero of=$file bs=4k count=1
1822         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1823         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1824 }
1825 run_test 27k "limit i_blksize for broken user apps"
1826
1827 test_27l() {
1828         mcreate $DIR/$tfile || error "creating file"
1829         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1830                 error "setstripe should have failed" || true
1831 }
1832 run_test 27l "check setstripe permissions (should return error)"
1833
1834 test_27m() {
1835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1836
1837         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1838                 skip_env "multiple clients -- skipping"
1839
1840         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1841                    head -n1)
1842         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1843                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1844         fi
1845         stack_trap simple_cleanup_common
1846         test_mkdir $DIR/$tdir
1847         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1848         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1849                 error "dd should fill OST0"
1850         i=2
1851         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1852                 i=$((i + 1))
1853                 [ $i -gt 256 ] && break
1854         done
1855         i=$((i + 1))
1856         touch $DIR/$tdir/$tfile.$i
1857         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1858             awk '{print $1}'| grep -w "0") ] &&
1859                 error "OST0 was full but new created file still use it"
1860         i=$((i + 1))
1861         touch $DIR/$tdir/$tfile.$i
1862         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1863             awk '{print $1}'| grep -w "0") ] &&
1864                 error "OST0 was full but new created file still use it" || true
1865 }
1866 run_test 27m "create file while OST0 was full"
1867
1868 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1869 # if the OST isn't full anymore.
1870 reset_enospc() {
1871         local ostidx=${1:-""}
1872         local delay
1873         local ready
1874         local get_prealloc
1875
1876         local list=$(comma_list $(osts_nodes))
1877         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1878
1879         do_nodes $list lctl set_param fail_loc=0
1880         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1881         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1882                 awk '{print $1 * 2;exit;}')
1883         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1884                         grep -v \"^0$\""
1885         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1886 }
1887
1888 test_27n() {
1889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1891         remote_mds_nodsh && skip "remote MDS with nodsh"
1892         remote_ost_nodsh && skip "remote OST with nodsh"
1893
1894         reset_enospc
1895         rm -f $DIR/$tdir/$tfile
1896         exhaust_precreations 0 0x80000215
1897         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1898         touch $DIR/$tdir/$tfile || error "touch failed"
1899         $LFS getstripe $DIR/$tdir/$tfile
1900         reset_enospc
1901 }
1902 run_test 27n "create file with some full OSTs"
1903
1904 test_27o() {
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907         remote_mds_nodsh && skip "remote MDS with nodsh"
1908         remote_ost_nodsh && skip "remote OST with nodsh"
1909
1910         reset_enospc
1911         rm -f $DIR/$tdir/$tfile
1912         exhaust_all_precreations 0x215
1913
1914         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1915
1916         reset_enospc
1917         rm -rf $DIR/$tdir/*
1918 }
1919 run_test 27o "create file with all full OSTs (should error)"
1920
1921 function create_and_checktime() {
1922         local fname=$1
1923         local loops=$2
1924         local i
1925
1926         for ((i=0; i < $loops; i++)); do
1927                 local start=$SECONDS
1928                 multiop $fname-$i Oc
1929                 ((SECONDS-start < TIMEOUT)) ||
1930                         error "creation took " $((SECONDS-$start)) && return 1
1931         done
1932 }
1933
1934 test_27oo() {
1935         local mdts=$(comma_list $(mdts_nodes))
1936
1937         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1938                 skip "Need MDS version at least 2.13.57"
1939
1940         local f0=$DIR/${tfile}-0
1941         local f1=$DIR/${tfile}-1
1942
1943         wait_delete_completed
1944
1945         # refill precreated objects
1946         $LFS setstripe -i0 -c1 $f0
1947
1948         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1949         # force QoS allocation policy
1950         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1951         stack_trap "do_nodes $mdts $LCTL set_param \
1952                 lov.*.qos_threshold_rr=$saved" EXIT
1953         sleep_maxage
1954
1955         # one OST is unavailable, but still have few objects preallocated
1956         stop ost1
1957         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1958                 rm -rf $f1 $DIR/$tdir*" EXIT
1959
1960         for ((i=0; i < 7; i++)); do
1961                 mkdir $DIR/$tdir$i || error "can't create dir"
1962                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1963                         error "can't set striping"
1964         done
1965         for ((i=0; i < 7; i++)); do
1966                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1967         done
1968         wait
1969 }
1970 run_test 27oo "don't let few threads to reserve too many objects"
1971
1972 test_27p() {
1973         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1975         remote_mds_nodsh && skip "remote MDS with nodsh"
1976         remote_ost_nodsh && skip "remote OST with nodsh"
1977
1978         reset_enospc
1979         rm -f $DIR/$tdir/$tfile
1980         test_mkdir $DIR/$tdir
1981
1982         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1983         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1984         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1985
1986         exhaust_precreations 0 0x80000215
1987         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1988         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1989         $LFS getstripe $DIR/$tdir/$tfile
1990
1991         reset_enospc
1992 }
1993 run_test 27p "append to a truncated file with some full OSTs"
1994
1995 test_27q() {
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         reset_enospc
2002         rm -f $DIR/$tdir/$tfile
2003
2004         mkdir_on_mdt0 $DIR/$tdir
2005         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2006         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2007                 error "truncate $DIR/$tdir/$tfile failed"
2008         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2009
2010         exhaust_all_precreations 0x215
2011
2012         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2013         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2014
2015         reset_enospc
2016 }
2017 run_test 27q "append to truncated file with all OSTs full (should error)"
2018
2019 test_27r() {
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023         remote_ost_nodsh && skip "remote OST with nodsh"
2024
2025         reset_enospc
2026         rm -f $DIR/$tdir/$tfile
2027         exhaust_precreations 0 0x80000215
2028
2029         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2030
2031         reset_enospc
2032 }
2033 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2034
2035 test_27s() { # bug 10725
2036         test_mkdir $DIR/$tdir
2037         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2038         local stripe_count=0
2039         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2040         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2041                 error "stripe width >= 2^32 succeeded" || true
2042
2043 }
2044 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2045
2046 test_27t() { # bug 10864
2047         WDIR=$(pwd)
2048         WLFS=$(which lfs)
2049         cd $DIR
2050         touch $tfile
2051         $WLFS getstripe $tfile
2052         cd $WDIR
2053 }
2054 run_test 27t "check that utils parse path correctly"
2055
2056 test_27u() { # bug 4900
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         remote_mds_nodsh && skip "remote MDS with nodsh"
2059
2060         local index
2061         local list=$(comma_list $(mdts_nodes))
2062
2063 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2064         do_nodes $list $LCTL set_param fail_loc=0x139
2065         test_mkdir -p $DIR/$tdir
2066         stack_trap "simple_cleanup_common 1000"
2067         createmany -o $DIR/$tdir/$tfile 1000
2068         do_nodes $list $LCTL set_param fail_loc=0
2069
2070         TLOG=$TMP/$tfile.getstripe
2071         $LFS getstripe $DIR/$tdir > $TLOG
2072         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2073         [[ $OBJS -gt 0 ]] &&
2074                 error "$OBJS objects created on OST-0. See $TLOG" ||
2075                 rm -f $TLOG
2076 }
2077 run_test 27u "skip object creation on OSC w/o objects"
2078
2079 test_27v() { # bug 4900
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082         remote_mds_nodsh && skip "remote MDS with nodsh"
2083         remote_ost_nodsh && skip "remote OST with nodsh"
2084
2085         exhaust_all_precreations 0x215
2086         reset_enospc
2087
2088         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2089
2090         touch $DIR/$tdir/$tfile
2091         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2092         # all except ost1
2093         for (( i=1; i < OSTCOUNT; i++ )); do
2094                 do_facet ost$i lctl set_param fail_loc=0x705
2095         done
2096         local START=`date +%s`
2097         createmany -o $DIR/$tdir/$tfile 32
2098
2099         local FINISH=`date +%s`
2100         local TIMEOUT=`lctl get_param -n timeout`
2101         local PROCESS=$((FINISH - START))
2102         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2103                error "$FINISH - $START >= $TIMEOUT / 2"
2104         sleep $((TIMEOUT / 2 - PROCESS))
2105         reset_enospc
2106 }
2107 run_test 27v "skip object creation on slow OST"
2108
2109 test_27w() { # bug 10997
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2112         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2113                 error "stripe size $size != 65536" || true
2114         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2115                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2116 }
2117 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2118
2119 test_27wa() {
2120         [[ $OSTCOUNT -lt 2 ]] &&
2121                 skip_env "skipping multiple stripe count/offset test"
2122
2123         test_mkdir $DIR/$tdir
2124         for i in $(seq 1 $OSTCOUNT); do
2125                 offset=$((i - 1))
2126                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2127                         error "setstripe -c $i -i $offset failed"
2128                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2129                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2130                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2131                 [ $index -ne $offset ] &&
2132                         error "stripe offset $index != $offset" || true
2133         done
2134 }
2135 run_test 27wa "check $LFS setstripe -c -i options"
2136
2137 test_27x() {
2138         remote_ost_nodsh && skip "remote OST with nodsh"
2139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2141
2142         OFFSET=$(($OSTCOUNT - 1))
2143         OSTIDX=0
2144         local OST=$(ostname_from_index $OSTIDX)
2145
2146         test_mkdir $DIR/$tdir
2147         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2151         for i in $(seq 0 $OFFSET); do
2152                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2153                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2154                 error "OST0 was degraded but new created file still use it"
2155         done
2156         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2157 }
2158 run_test 27x "create files while OST0 is degraded"
2159
2160 test_27y() {
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         remote_mds_nodsh && skip "remote MDS with nodsh"
2163         remote_ost_nodsh && skip "remote OST with nodsh"
2164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2165
2166         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2167         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2168                 osp.$mdtosc.prealloc_last_id)
2169         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2170                 osp.$mdtosc.prealloc_next_id)
2171         local fcount=$((last_id - next_id))
2172         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2173         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2174
2175         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2176                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2177         local OST_DEACTIVE_IDX=-1
2178         local OSC
2179         local OSTIDX
2180         local OST
2181
2182         for OSC in $MDS_OSCS; do
2183                 OST=$(osc_to_ost $OSC)
2184                 OSTIDX=$(index_from_ostuuid $OST)
2185                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2186                         OST_DEACTIVE_IDX=$OSTIDX
2187                 fi
2188                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2189                         echo $OSC "is Deactivated:"
2190                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2191                 fi
2192         done
2193
2194         OSTIDX=$(index_from_ostuuid $OST)
2195         test_mkdir $DIR/$tdir
2196         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=1
2205                 fi
2206         done
2207
2208         sleep_maxage
2209         createmany -o $DIR/$tdir/$tfile $fcount
2210
2211         for OSC in $MDS_OSCS; do
2212                 OST=$(osc_to_ost $OSC)
2213                 OSTIDX=$(index_from_ostuuid $OST)
2214                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2215                         echo $OST "is recovered from degraded:"
2216                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2217                                                 obdfilter.$OST.degraded=0
2218                 else
2219                         do_facet $SINGLEMDS lctl --device %$OSC activate
2220                 fi
2221         done
2222
2223         # all osp devices get activated, hence -1 stripe count restored
2224         local stripe_count=0
2225
2226         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2227         # devices get activated.
2228         sleep_maxage
2229         $LFS setstripe -c -1 $DIR/$tfile
2230         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2231         rm -f $DIR/$tfile
2232         [ $stripe_count -ne $OSTCOUNT ] &&
2233                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2234         return 0
2235 }
2236 run_test 27y "create files while OST0 is degraded and the rest inactive"
2237
2238 check_seq_oid()
2239 {
2240         log "check file $1"
2241
2242         lmm_count=$($LFS getstripe -c $1)
2243         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2244         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2245
2246         local old_ifs="$IFS"
2247         IFS=$'[:]'
2248         fid=($($LFS path2fid $1))
2249         IFS="$old_ifs"
2250
2251         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2252         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2253
2254         # compare lmm_seq and lu_fid->f_seq
2255         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2256         # compare lmm_object_id and lu_fid->oid
2257         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2258
2259         # check the trusted.fid attribute of the OST objects of the file
2260         local have_obdidx=false
2261         local stripe_nr=0
2262         $LFS getstripe $1 | while read obdidx oid hex seq; do
2263                 # skip lines up to and including "obdidx"
2264                 [ -z "$obdidx" ] && break
2265                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2266                 $have_obdidx || continue
2267
2268                 local ost=$((obdidx + 1))
2269                 local dev=$(ostdevname $ost)
2270                 local oid_hex
2271
2272                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2273
2274                 seq=$(echo $seq | sed -e "s/^0x//g")
2275                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2276                         oid_hex=$(echo $oid)
2277                 else
2278                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2279                 fi
2280                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2281
2282                 local ff=""
2283                 #
2284                 # Don't unmount/remount the OSTs if we don't need to do that.
2285                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2286                 # update too, until that use mount/ll_decode_filter_fid/mount.
2287                 # Re-enable when debugfs will understand new filter_fid.
2288                 #
2289                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2290                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2291                                 $dev 2>/dev/null" | grep "parent=")
2292                 fi
2293                 if [ -z "$ff" ]; then
2294                         stop ost$ost
2295                         mount_fstype ost$ost
2296                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2297                                 $(facet_mntpt ost$ost)/$obj_file)
2298                         unmount_fstype ost$ost
2299                         start ost$ost $dev $OST_MOUNT_OPTS
2300                         clients_up
2301                 fi
2302
2303                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2304
2305                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2306
2307                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2308                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2309                 #
2310                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2311                 #       stripe_size=1048576 component_id=1 component_start=0 \
2312                 #       component_end=33554432
2313                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2314                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2315                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2316                 local ff_pstripe
2317                 if grep -q 'stripe=' <<<$ff; then
2318                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2319                 else
2320                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2321                         # into f_ver in this case.  See comment on ff_parent.
2322                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2323                 fi
2324
2325                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2326                 [ $ff_pseq = $lmm_seq ] ||
2327                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2328                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2329                 [ $ff_poid = $lmm_oid ] ||
2330                         error "FF parent OID $ff_poid != $lmm_oid"
2331                 (($ff_pstripe == $stripe_nr)) ||
2332                         error "FF stripe $ff_pstripe != $stripe_nr"
2333
2334                 stripe_nr=$((stripe_nr + 1))
2335                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2336                         continue
2337                 if grep -q 'stripe_count=' <<<$ff; then
2338                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2339                                             -e 's/ .*//' <<<$ff)
2340                         [ $lmm_count = $ff_scnt ] ||
2341                                 error "FF stripe count $lmm_count != $ff_scnt"
2342                 fi
2343         done
2344 }
2345
2346 test_27z() {
2347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2348         remote_ost_nodsh && skip "remote OST with nodsh"
2349
2350         test_mkdir $DIR/$tdir
2351         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2352                 { error "setstripe -c -1 failed"; return 1; }
2353         # We need to send a write to every object to get parent FID info set.
2354         # This _should_ also work for setattr, but does not currently.
2355         # touch $DIR/$tdir/$tfile-1 ||
2356         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2357                 { error "dd $tfile-1 failed"; return 2; }
2358         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2359                 { error "setstripe -c -1 failed"; return 3; }
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2361                 { error "dd $tfile-2 failed"; return 4; }
2362
2363         # make sure write RPCs have been sent to OSTs
2364         sync; sleep 5; sync
2365
2366         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2367         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2368 }
2369 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2370
2371 test_27A() { # b=19102
2372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2373
2374         save_layout_restore_at_exit $MOUNT
2375         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2376         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2377                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2378         local default_size=$($LFS getstripe -S $MOUNT)
2379         local default_offset=$($LFS getstripe -i $MOUNT)
2380         local dsize=$(do_facet $SINGLEMDS \
2381                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2382         [ $default_size -eq $dsize ] ||
2383                 error "stripe size $default_size != $dsize"
2384         [ $default_offset -eq -1 ] ||
2385                 error "stripe offset $default_offset != -1"
2386 }
2387 run_test 27A "check filesystem-wide default LOV EA values"
2388
2389 test_27B() { # LU-2523
2390         test_mkdir $DIR/$tdir
2391         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2392         touch $DIR/$tdir/f0
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # rename f0 onto f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2398                 $DIR/$tdir/f0
2399
2400         rm -f $DIR/$tdir/f1
2401         # open f1 with O_LOV_DELAY_CREATE
2402         # unlink f1
2403         # call setstripe ioctl on open file descriptor for f1
2404         # close
2405         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2406
2407         # Allow multiop to fail in imitation of NFS's busted semantics.
2408         true
2409 }
2410 run_test 27B "call setstripe on open unlinked file/rename victim"
2411
2412 # 27C family tests full striping and overstriping
2413 test_27Ca() { #LU-2871
2414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2415
2416         declare -a ost_idx
2417         local index
2418         local found
2419         local i
2420         local j
2421
2422         test_mkdir $DIR/$tdir
2423         cd $DIR/$tdir
2424         for i in $(seq 0 $((OSTCOUNT - 1))); do
2425                 # set stripe across all OSTs starting from OST$i
2426                 $LFS setstripe -i $i -c -1 $tfile$i
2427                 # get striping information
2428                 ost_idx=($($LFS getstripe $tfile$i |
2429                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2430                 echo "OST Index: ${ost_idx[*]}"
2431
2432                 # check the layout
2433                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2434                         error "${#ost_idx[@]} != $OSTCOUNT"
2435
2436                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2437                         found=0
2438                         for j in "${ost_idx[@]}"; do
2439                                 if [ $index -eq $j ]; then
2440                                         found=1
2441                                         break
2442                                 fi
2443                         done
2444                         [ $found = 1 ] ||
2445                                 error "Can not find $index in ${ost_idx[*]}"
2446                 done
2447         done
2448 }
2449 run_test 27Ca "check full striping across all OSTs"
2450
2451 test_27Cb() {
2452         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2453                 skip "server does not support overstriping"
2454         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2455                 skip_env "too many osts, skipping"
2456
2457         test_mkdir -p $DIR/$tdir
2458         local setcount=$(($OSTCOUNT * 2))
2459         [ $setcount -lt 160 ] || large_xattr_enabled ||
2460                 skip_env "ea_inode feature disabled"
2461
2462         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2463                 error "setstripe failed"
2464
2465         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2466         [ $count -eq $setcount ] ||
2467                 error "stripe count $count, should be $setcount"
2468
2469         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2470                 error "overstriped should be set in pattern"
2471
2472         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2473                 error "dd failed"
2474 }
2475 run_test 27Cb "more stripes than OSTs with -C"
2476
2477 test_27Cc() {
2478         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2479                 skip "server does not support overstriping"
2480         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2481
2482         test_mkdir -p $DIR/$tdir
2483         local setcount=$(($OSTCOUNT - 1))
2484
2485         [ $setcount -lt 160 ] || large_xattr_enabled ||
2486                 skip_env "ea_inode feature disabled"
2487
2488         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2489                 error "setstripe failed"
2490
2491         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2492         [ $count -eq $setcount ] ||
2493                 error "stripe count $count, should be $setcount"
2494
2495         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2496                 error "overstriped should not be set in pattern"
2497
2498         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2499                 error "dd failed"
2500 }
2501 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2502
2503 test_27Cd() {
2504         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2505                 skip "server does not support overstriping"
2506         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2507         large_xattr_enabled || skip_env "ea_inode feature disabled"
2508
2509         force_new_seq_all
2510
2511         test_mkdir -p $DIR/$tdir
2512         local setcount=$LOV_MAX_STRIPE_COUNT
2513
2514         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2515                 error "setstripe failed"
2516
2517         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2518         [ $count -eq $setcount ] ||
2519                 error "stripe count $count, should be $setcount"
2520
2521         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2522                 error "overstriped should be set in pattern"
2523
2524         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2525                 error "dd failed"
2526
2527         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2528 }
2529 run_test 27Cd "test maximum stripe count"
2530
2531 test_27Ce() {
2532         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2533                 skip "server does not support overstriping"
2534         test_mkdir -p $DIR/$tdir
2535
2536         pool_add $TESTNAME || error "Pool creation failed"
2537         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2538
2539         local setcount=8
2540
2541         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2542                 error "setstripe failed"
2543
2544         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2545         [ $count -eq $setcount ] ||
2546                 error "stripe count $count, should be $setcount"
2547
2548         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2549                 error "overstriped should be set in pattern"
2550
2551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2552                 error "dd failed"
2553
2554         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2555 }
2556 run_test 27Ce "test pool with overstriping"
2557
2558 test_27Cf() {
2559         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2560                 skip "server does not support overstriping"
2561         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2562                 skip_env "too many osts, skipping"
2563
2564         test_mkdir -p $DIR/$tdir
2565
2566         local setcount=$(($OSTCOUNT * 2))
2567         [ $setcount -lt 160 ] || large_xattr_enabled ||
2568                 skip_env "ea_inode feature disabled"
2569
2570         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2571                 error "setstripe failed"
2572
2573         echo 1 > $DIR/$tdir/$tfile
2574
2575         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2576         [ $count -eq $setcount ] ||
2577                 error "stripe count $count, should be $setcount"
2578
2579         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2580                 error "overstriped should be set in pattern"
2581
2582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2583                 error "dd failed"
2584
2585         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2586 }
2587 run_test 27Cf "test default inheritance with overstriping"
2588
2589 test_27Cg() {
2590         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2591                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2592
2593         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2594         (( $? != 0 )) || error "must be an error for not existent OST#"
2595 }
2596 run_test 27Cg "test setstripe with wrong OST idx"
2597
2598 test_27D() {
2599         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2600         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2601         remote_mds_nodsh && skip "remote MDS with nodsh"
2602
2603         local POOL=${POOL:-testpool}
2604         local first_ost=0
2605         local last_ost=$(($OSTCOUNT - 1))
2606         local ost_step=1
2607         local ost_list=$(seq $first_ost $ost_step $last_ost)
2608         local ost_range="$first_ost $last_ost $ost_step"
2609
2610         test_mkdir $DIR/$tdir
2611         pool_add $POOL || error "pool_add failed"
2612         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2613
2614         local skip27D
2615         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2616                 skip27D+="-s 29"
2617         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2618                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2619                         skip27D+=" -s 30,31"
2620         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2621           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2622                 skip27D+=" -s 32,33"
2623         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2624                 skip27D+=" -s 34"
2625         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2626                 error "llapi_layout_test failed"
2627
2628         destroy_test_pools || error "destroy test pools failed"
2629 }
2630 run_test 27D "validate llapi_layout API"
2631
2632 # Verify that default_easize is increased from its initial value after
2633 # accessing a widely striped file.
2634 test_27E() {
2635         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2636         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2637                 skip "client does not have LU-3338 fix"
2638
2639         # 72 bytes is the minimum space required to store striping
2640         # information for a file striped across one OST:
2641         # (sizeof(struct lov_user_md_v3) +
2642         #  sizeof(struct lov_user_ost_data_v1))
2643         local min_easize=72
2644         $LCTL set_param -n llite.*.default_easize $min_easize ||
2645                 error "lctl set_param failed"
2646         local easize=$($LCTL get_param -n llite.*.default_easize)
2647
2648         [ $easize -eq $min_easize ] ||
2649                 error "failed to set default_easize"
2650
2651         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2652                 error "setstripe failed"
2653         # In order to ensure stat() call actually talks to MDS we need to
2654         # do something drastic to this file to shake off all lock, e.g.
2655         # rename it (kills lookup lock forcing cache cleaning)
2656         mv $DIR/$tfile $DIR/${tfile}-1
2657         ls -l $DIR/${tfile}-1
2658         rm $DIR/${tfile}-1
2659
2660         easize=$($LCTL get_param -n llite.*.default_easize)
2661
2662         [ $easize -gt $min_easize ] ||
2663                 error "default_easize not updated"
2664 }
2665 run_test 27E "check that default extended attribute size properly increases"
2666
2667 test_27F() { # LU-5346/LU-7975
2668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2669         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2670         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2671                 skip "Need MDS version at least 2.8.51"
2672         remote_ost_nodsh && skip "remote OST with nodsh"
2673
2674         test_mkdir $DIR/$tdir
2675         rm -f $DIR/$tdir/f0
2676         $LFS setstripe -c 2 $DIR/$tdir
2677
2678         # stop all OSTs to reproduce situation for LU-7975 ticket
2679         for num in $(seq $OSTCOUNT); do
2680                 stop ost$num
2681         done
2682
2683         # open/create f0 with O_LOV_DELAY_CREATE
2684         # truncate f0 to a non-0 size
2685         # close
2686         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2687
2688         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2689         # open/write it again to force delayed layout creation
2690         cat /etc/hosts > $DIR/$tdir/f0 &
2691         catpid=$!
2692
2693         # restart OSTs
2694         for num in $(seq $OSTCOUNT); do
2695                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2696                         error "ost$num failed to start"
2697         done
2698
2699         wait $catpid || error "cat failed"
2700
2701         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2702         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2703                 error "wrong stripecount"
2704
2705 }
2706 run_test 27F "Client resend delayed layout creation with non-zero size"
2707
2708 test_27G() { #LU-10629
2709         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2710                 skip "Need MDS version at least 2.11.51"
2711         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2712         remote_mds_nodsh && skip "remote MDS with nodsh"
2713         local POOL=${POOL:-testpool}
2714         local ostrange="0 0 1"
2715
2716         test_mkdir $DIR/$tdir
2717         touch $DIR/$tdir/$tfile.nopool
2718         pool_add $POOL || error "pool_add failed"
2719         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2720         $LFS setstripe -p $POOL $DIR/$tdir
2721
2722         local pool=$($LFS getstripe -p $DIR/$tdir)
2723
2724         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2725         touch $DIR/$tdir/$tfile.default
2726         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2727         $LFS find $DIR/$tdir -type f --pool $POOL
2728         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2729         [[ "$found" == "2" ]] ||
2730                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2731
2732         $LFS setstripe -d $DIR/$tdir
2733
2734         pool=$($LFS getstripe -p -d $DIR/$tdir)
2735
2736         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2737 }
2738 run_test 27G "Clear OST pool from stripe"
2739
2740 test_27H() {
2741         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2742                 skip "Need MDS version newer than 2.11.54"
2743         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2744         test_mkdir $DIR/$tdir
2745         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2746         touch $DIR/$tdir/$tfile
2747         $LFS getstripe -c $DIR/$tdir/$tfile
2748         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2749                 error "two-stripe file doesn't have two stripes"
2750
2751         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2752         $LFS getstripe -y $DIR/$tdir/$tfile
2753         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2754              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2755                 error "expected l_ost_idx: [02]$ not matched"
2756
2757         # make sure ost list has been cleared
2758         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2759         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2760                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2761         touch $DIR/$tdir/f3
2762         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2763 }
2764 run_test 27H "Set specific OSTs stripe"
2765
2766 test_27I() {
2767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2768         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2769         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2770                 skip "Need MDS version newer than 2.12.52"
2771         local pool=$TESTNAME
2772         local ostrange="1 1 1"
2773
2774         save_layout_restore_at_exit $MOUNT
2775         $LFS setstripe -c 2 -i 0 $MOUNT
2776         pool_add $pool || error "pool_add failed"
2777         pool_add_targets $pool $ostrange ||
2778                 error "pool_add_targets failed"
2779         test_mkdir $DIR/$tdir
2780         $LFS setstripe -p $pool $DIR/$tdir
2781         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2782         $LFS getstripe $DIR/$tdir/$tfile
2783 }
2784 run_test 27I "check that root dir striping does not break parent dir one"
2785
2786 test_27J() {
2787         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2788                 skip "Need MDS version newer than 2.12.51"
2789
2790         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2791         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2792         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2793            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2794                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2795
2796         test_mkdir $DIR/$tdir
2797         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2798         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2799
2800         # create foreign file (raw way)
2801         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2802                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2803
2804         ! $LFS setstripe --foreign --flags foo \
2805                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2806                         error "creating $tfile with '--flags foo' should fail"
2807
2808         ! $LFS setstripe --foreign --flags 0xffffffff \
2809                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2810                         error "creating $tfile w/ 0xffffffff flags should fail"
2811
2812         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2813                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2814
2815         # verify foreign file (raw way)
2816         parse_foreign_file -f $DIR/$tdir/$tfile |
2817                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2818                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2819         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2820                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2821         parse_foreign_file -f $DIR/$tdir/$tfile |
2822                 grep "lov_foreign_size: 73" ||
2823                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2824         parse_foreign_file -f $DIR/$tdir/$tfile |
2825                 grep "lov_foreign_type: 1" ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_flags: 0x0000DA08" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2830         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2831                 grep "lov_foreign_value: 0x" |
2832                 sed -e 's/lov_foreign_value: 0x//')
2833         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2834         [[ $lov = ${lov2// /} ]] ||
2835                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2836
2837         # create foreign file (lfs + API)
2838         $LFS setstripe --foreign=none --flags 0xda08 \
2839                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2840                 error "$DIR/$tdir/${tfile}2: create failed"
2841
2842         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2843                 grep "lfm_magic:.*0x0BD70BD0" ||
2844                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2845         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2846         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2847                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2849                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2850         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2851                 grep "lfm_flags:.*0x0000DA08" ||
2852                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2853         $LFS getstripe $DIR/$tdir/${tfile}2 |
2854                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2856
2857         # modify striping should fail
2858         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2859                 error "$DIR/$tdir/$tfile: setstripe should fail"
2860         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2861                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2862
2863         # R/W should fail
2864         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2865         cat $DIR/$tdir/${tfile}2 &&
2866                 error "$DIR/$tdir/${tfile}2: read should fail"
2867         cat /etc/passwd > $DIR/$tdir/$tfile &&
2868                 error "$DIR/$tdir/$tfile: write should fail"
2869         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2870                 error "$DIR/$tdir/${tfile}2: write should fail"
2871
2872         # chmod should work
2873         chmod 222 $DIR/$tdir/$tfile ||
2874                 error "$DIR/$tdir/$tfile: chmod failed"
2875         chmod 222 $DIR/$tdir/${tfile}2 ||
2876                 error "$DIR/$tdir/${tfile}2: chmod failed"
2877
2878         # chown should work
2879         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2880                 error "$DIR/$tdir/$tfile: chown failed"
2881         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2882                 error "$DIR/$tdir/${tfile}2: chown failed"
2883
2884         # rename should work
2885         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2886                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2887         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2888                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2889
2890         #remove foreign file
2891         rm $DIR/$tdir/${tfile}.new ||
2892                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2893         rm $DIR/$tdir/${tfile}2.new ||
2894                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2895 }
2896 run_test 27J "basic ops on file with foreign LOV"
2897
2898 test_27K() {
2899         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2900                 skip "Need MDS version newer than 2.12.49"
2901
2902         test_mkdir $DIR/$tdir
2903         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2904         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2905
2906         # create foreign dir (raw way)
2907         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2908                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2909
2910         ! $LFS setdirstripe --foreign --flags foo \
2911                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2912                         error "creating $tdir with '--flags foo' should fail"
2913
2914         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2915                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2916                         error "creating $tdir w/ 0xffffffff flags should fail"
2917
2918         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2919                 error "create_foreign_dir FAILED"
2920
2921         # verify foreign dir (raw way)
2922         parse_foreign_dir -d $DIR/$tdir/$tdir |
2923                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2924                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2925         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2926                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2927         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2928                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2929         parse_foreign_dir -d $DIR/$tdir/$tdir |
2930                 grep "lmv_foreign_flags: 55813$" ||
2931                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2932         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2933                 grep "lmv_foreign_value: 0x" |
2934                 sed 's/lmv_foreign_value: 0x//')
2935         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2936                 sed 's/ //g')
2937         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2938
2939         # create foreign dir (lfs + API)
2940         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2941                 $DIR/$tdir/${tdir}2 ||
2942                 error "$DIR/$tdir/${tdir}2: create failed"
2943
2944         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2945
2946         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2947                 grep "lfm_magic:.*0x0CD50CD0" ||
2948                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2949         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2950         # - sizeof(lfm_type) - sizeof(lfm_flags)
2951         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2953         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2954                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2956                 grep "lfm_flags:.*0x0000DA05" ||
2957                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2958         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2959                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2960                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2961
2962         # file create in dir should fail
2963         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2964         touch $DIR/$tdir/${tdir}2/$tfile &&
2965                 error "$DIR/${tdir}2: file create should fail"
2966
2967         # chmod should work
2968         chmod 777 $DIR/$tdir/$tdir ||
2969                 error "$DIR/$tdir: chmod failed"
2970         chmod 777 $DIR/$tdir/${tdir}2 ||
2971                 error "$DIR/${tdir}2: chmod failed"
2972
2973         # chown should work
2974         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2975                 error "$DIR/$tdir: chown failed"
2976         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2977                 error "$DIR/${tdir}2: chown failed"
2978
2979         # rename should work
2980         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2981                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2982         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2983                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2984
2985         #remove foreign dir
2986         rmdir $DIR/$tdir/${tdir}.new ||
2987                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2988         rmdir $DIR/$tdir/${tdir}2.new ||
2989                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2990 }
2991 run_test 27K "basic ops on dir with foreign LMV"
2992
2993 test_27L() {
2994         remote_mds_nodsh && skip "remote MDS with nodsh"
2995
2996         local POOL=${POOL:-$TESTNAME}
2997
2998         pool_add $POOL || error "pool_add failed"
2999
3000         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3001                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3002                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3003 }
3004 run_test 27L "lfs pool_list gives correct pool name"
3005
3006 test_27M() {
3007         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3008                 skip "Need MDS version >= than 2.12.57"
3009         remote_mds_nodsh && skip "remote MDS with nodsh"
3010         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3011
3012         # Set default striping on directory
3013         local setcount=4
3014         local stripe_opt
3015         local mdts=$(comma_list $(mdts_nodes))
3016
3017         # if we run against a 2.12 server which lacks overstring support
3018         # then the connect_flag will not report overstriping, even if client
3019         # is 2.14+
3020         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3021                 stripe_opt="-C $setcount"
3022         elif (( $OSTCOUNT >= $setcount )); then
3023                 stripe_opt="-c $setcount"
3024         else
3025                 skip "server does not support overstriping"
3026         fi
3027
3028         test_mkdir $DIR/$tdir
3029
3030         # Validate existing append_* params and ensure restore
3031         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3032         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3033         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3034
3035         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3036         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3037         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3038
3039         $LFS setstripe $stripe_opt $DIR/$tdir
3040
3041         echo 1 > $DIR/$tdir/${tfile}.1
3042         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3043         (( $count == $setcount )) ||
3044                 error "(1) stripe count $count, should be $setcount"
3045
3046         local appendcount=$orig_count
3047         echo 1 >> $DIR/$tdir/${tfile}.2_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3049         (( $count == $appendcount )) ||
3050                 error "(2)stripe count $count, should be $appendcount for append"
3051
3052         # Disable O_APPEND striping, verify it works
3053         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3054
3055         # Should now get the default striping, which is 4
3056         setcount=4
3057         echo 1 >> $DIR/$tdir/${tfile}.3_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3059         (( $count == $setcount )) ||
3060                 error "(3) stripe count $count, should be $setcount"
3061
3062         # Try changing the stripe count for append files
3063         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3064
3065         # Append striping is now 2 (directory default is still 4)
3066         appendcount=2
3067         echo 1 >> $DIR/$tdir/${tfile}.4_append
3068         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3069         (( $count == $appendcount )) ||
3070                 error "(4) stripe count $count, should be $appendcount for append"
3071
3072         # Test append stripe count of -1
3073         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3074         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3075                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3076                 touch $DIR/$tdir/$tfile.specific.{1..128}
3077         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3078
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3080         appendcount=$OSTCOUNT
3081         echo 1 >> $DIR/$tdir/${tfile}.5
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3083         (( $count == $appendcount )) ||
3084                 error "(5) stripe count $count, should be $appendcount for append"
3085
3086         # Set append striping back to default of 1
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3088
3089         # Try a new default striping, PFL + DOM
3090         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3091
3092         # Create normal DOM file, DOM returns stripe count == 0
3093         setcount=0
3094         touch $DIR/$tdir/${tfile}.6
3095         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3096         (( $count == $setcount )) ||
3097                 error "(6) stripe count $count, should be $setcount"
3098
3099         # Show
3100         appendcount=1
3101         echo 1 >> $DIR/$tdir/${tfile}.7_append
3102         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3103         (( $count == $appendcount )) ||
3104                 error "(7) stripe count $count, should be $appendcount for append"
3105
3106         # Clean up DOM layout
3107         $LFS setstripe -d $DIR/$tdir
3108
3109         save_layout_restore_at_exit $MOUNT
3110         # Now test that append striping works when layout is from root
3111         $LFS setstripe -c 2 $MOUNT
3112         # Make a special directory for this
3113         mkdir $DIR/${tdir}/${tdir}.2
3114
3115         # Verify for normal file
3116         setcount=2
3117         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3118         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3119         (( $count == $setcount )) ||
3120                 error "(8) stripe count $count, should be $setcount"
3121
3122         appendcount=1
3123         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3124         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3125         (( $count == $appendcount )) ||
3126                 error "(9) stripe count $count, should be $appendcount for append"
3127
3128         # Now test O_APPEND striping with pools
3129         pool_add $TESTNAME || error "pool creation failed"
3130         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3131         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3132
3133         echo 1 >> $DIR/$tdir/${tfile}.10_append
3134
3135         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3136         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3137
3138         # Check that count is still correct
3139         appendcount=1
3140         echo 1 >> $DIR/$tdir/${tfile}.11_append
3141         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3142         (( $count == $appendcount )) ||
3143                 error "(11) stripe count $count, should be $appendcount for append"
3144
3145         # Disable O_APPEND stripe count, verify pool works separately
3146         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3147
3148         echo 1 >> $DIR/$tdir/${tfile}.12_append
3149
3150         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3151         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3152
3153         # Remove pool setting, verify it's not applied
3154         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3155
3156         echo 1 >> $DIR/$tdir/${tfile}.13_append
3157
3158         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3159         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3160 }
3161 run_test 27M "test O_APPEND striping"
3162
3163 test_27N() {
3164         combined_mgs_mds && skip "needs separate MGS/MDT"
3165
3166         pool_add $TESTNAME || error "pool_add failed"
3167         do_facet mgs "$LCTL pool_list $FSNAME" |
3168                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3169                 error "lctl pool_list on MGS failed"
3170 }
3171 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3172
3173 clean_foreign_symlink() {
3174         trap 0
3175         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3176         for i in $DIR/$tdir/* ; do
3177                 $LFS unlink_foreign $i || true
3178         done
3179 }
3180
3181 test_27O() {
3182         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3183                 skip "Need MDS version newer than 2.12.51"
3184
3185         test_mkdir $DIR/$tdir
3186         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3187         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3188
3189         trap clean_foreign_symlink EXIT
3190
3191         # enable foreign_symlink behaviour
3192         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3193
3194         # foreign symlink LOV format is a partial path by default
3195
3196         # create foreign file (lfs + API)
3197         $LFS setstripe --foreign=symlink --flags 0xda05 \
3198                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3199                 error "$DIR/$tdir/${tfile}: create failed"
3200
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_magic:.*0x0BD70BD0" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3204         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3205                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3206         $LFS getstripe -v $DIR/$tdir/${tfile} |
3207                 grep "lfm_flags:.*0x0000DA05" ||
3208                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3209         $LFS getstripe $DIR/$tdir/${tfile} |
3210                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3211                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3212
3213         # modify striping should fail
3214         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: setstripe should fail"
3216
3217         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3218         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3219         cat /etc/passwd > $DIR/$tdir/$tfile &&
3220                 error "$DIR/$tdir/$tfile: write should fail"
3221
3222         # rename should succeed
3223         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3224                 error "$DIR/$tdir/$tfile: rename has failed"
3225
3226         #remove foreign_symlink file should fail
3227         rm $DIR/$tdir/${tfile}.new &&
3228                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3229
3230         #test fake symlink
3231         mkdir /tmp/${uuid1} ||
3232                 error "/tmp/${uuid1}: mkdir has failed"
3233         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3234                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3235         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3236         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3237                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3238         #read should succeed now
3239         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3240                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3241         #write should succeed now
3242         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3243                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3244         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3245                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3246         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3247                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3248
3249         #check that getstripe still works
3250         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3251                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3252
3253         # chmod should still succeed
3254         chmod 644 $DIR/$tdir/${tfile}.new ||
3255                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3256
3257         # chown should still succeed
3258         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3259                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3260
3261         # rename should still succeed
3262         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3263                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3264
3265         #remove foreign_symlink file should still fail
3266         rm $DIR/$tdir/${tfile} &&
3267                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3268
3269         #use special ioctl() to unlink foreign_symlink file
3270         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3271                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3272
3273 }
3274 run_test 27O "basic ops on foreign file of symlink type"
3275
3276 test_27P() {
3277         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3278                 skip "Need MDS version newer than 2.12.49"
3279
3280         test_mkdir $DIR/$tdir
3281         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3282         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3283
3284         trap clean_foreign_symlink EXIT
3285
3286         # enable foreign_symlink behaviour
3287         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3288
3289         # foreign symlink LMV format is a partial path by default
3290
3291         # create foreign dir (lfs + API)
3292         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3293                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3294                 error "$DIR/$tdir/${tdir}: create failed"
3295
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3297
3298         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3299                 grep "lfm_magic:.*0x0CD50CD0" ||
3300                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3301         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3302                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3303         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3304                 grep "lfm_flags:.*0x0000DA05" ||
3305                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3306         $LFS getdirstripe $DIR/$tdir/${tdir} |
3307                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3308                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3309
3310         # file create in dir should fail
3311         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3312         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3313
3314         # rename should succeed
3315         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3316                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3317
3318         #remove foreign_symlink dir should fail
3319         rmdir $DIR/$tdir/${tdir}.new &&
3320                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3321
3322         #test fake symlink
3323         mkdir -p /tmp/${uuid1}/${uuid2} ||
3324                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3325         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3326                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3327         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3328         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3329                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3330         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3331                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3332
3333         #check that getstripe fails now that foreign_symlink enabled
3334         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3335                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3336
3337         # file create in dir should work now
3338         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3339                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3340         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3341                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3342         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3343                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3344
3345         # chmod should still succeed
3346         chmod 755 $DIR/$tdir/${tdir}.new ||
3347                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3348
3349         # chown should still succeed
3350         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3351                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3352
3353         # rename should still succeed
3354         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3355                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3356
3357         #remove foreign_symlink dir should still fail
3358         rmdir $DIR/$tdir/${tdir} &&
3359                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3360
3361         #use special ioctl() to unlink foreign_symlink file
3362         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3363                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3364
3365         #created file should still exist
3366         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3367                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3368         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3369                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3370 }
3371 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3372
3373 test_27Q() {
3374         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3375         stack_trap "rm -f $TMP/$tfile*"
3376
3377         test_mkdir $DIR/$tdir-1
3378         test_mkdir $DIR/$tdir-2
3379
3380         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3381         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3382
3383         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3384         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3385
3386         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3387         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3388
3389         # Create some bad symlinks and ensure that we don't loop
3390         # forever or something. These should return ELOOP (40) and
3391         # ENOENT (2) but I don't want to test for that because there's
3392         # always some weirdo architecture that needs to ruin
3393         # everything by defining these error numbers differently.
3394
3395         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3396         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3397
3398         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3399         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3400
3401         return 0
3402 }
3403 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3404
3405 test_27R() {
3406         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3407                 skip "need MDS 2.14.55 or later"
3408         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3409
3410         local testdir="$DIR/$tdir"
3411         test_mkdir -p $testdir
3412         stack_trap "rm -rf $testdir"
3413         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3414
3415         local f1="$testdir/f1"
3416         touch $f1 || error "failed to touch $f1"
3417         local count=$($LFS getstripe -c $f1)
3418         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3419
3420         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3421         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3422
3423         local maxcount=$(($OSTCOUNT - 1))
3424         local mdts=$(comma_list $(mdts_nodes))
3425         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3426         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3427
3428         local f2="$testdir/f2"
3429         touch $f2 || error "failed to touch $f2"
3430         local count=$($LFS getstripe -c $f2)
3431         (( $count == $maxcount )) || error "wrong stripe count"
3432 }
3433 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3434
3435 test_27T() {
3436         [ $(facet_host client) == $(facet_host ost1) ] &&
3437                 skip "need ost1 and client on different nodes"
3438
3439 #define OBD_FAIL_OSC_NO_GRANT            0x411
3440         $LCTL set_param fail_loc=0x20000411 fail_val=1
3441 #define OBD_FAIL_OST_ENOSPC              0x215
3442         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3443         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3444         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3445                 error "multiop failed"
3446 }
3447 run_test 27T "no eio on close on partial write due to enosp"
3448
3449 test_27U() {
3450         local dir=$DIR/$tdir
3451         local file=$dir/$tfile
3452         local append_pool=${TESTNAME}-append
3453         local normal_pool=${TESTNAME}-normal
3454         local pool
3455         local stripe_count
3456         local stripe_count2
3457         local mdts=$(comma_list $(mdts_nodes))
3458
3459         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3460                 skip "Need MDS version at least 2.15.51 for append pool feature"
3461
3462         # Validate existing append_* params and ensure restore
3463         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3464         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3465         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3466
3467         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3468         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3469         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3470
3471         pool_add $append_pool || error "pool creation failed"
3472         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3473
3474         pool_add $normal_pool || error "pool creation failed"
3475         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3476
3477         test_mkdir $dir
3478         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3479
3480         echo XXX >> $file.1
3481         $LFS getstripe $file.1
3482
3483         pool=$($LFS getstripe -p $file.1)
3484         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3485
3486         stripe_count2=$($LFS getstripe -c $file.1)
3487         ((stripe_count2 == stripe_count)) ||
3488                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3489
3490         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3491
3492         echo XXX >> $file.2
3493         $LFS getstripe $file.2
3494
3495         pool=$($LFS getstripe -p $file.2)
3496         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3497
3498         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3499
3500         echo XXX >> $file.3
3501         $LFS getstripe $file.3
3502
3503         stripe_count2=$($LFS getstripe -c $file.3)
3504         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3505 }
3506 run_test 27U "append pool and stripe count work with composite default layout"
3507
3508 # createtest also checks that device nodes are created and
3509 # then visible correctly (#2091)
3510 test_28() { # bug 2091
3511         test_mkdir $DIR/d28
3512         $CREATETEST $DIR/d28/ct || error "createtest failed"
3513 }
3514 run_test 28 "create/mknod/mkdir with bad file types ============"
3515
3516 test_29() {
3517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3518
3519         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3520                 disable_opencache
3521                 stack_trap "restore_opencache"
3522         }
3523
3524         sync; sleep 1; sync # flush out any dirty pages from previous tests
3525         cancel_lru_locks
3526         test_mkdir $DIR/d29
3527         touch $DIR/d29/foo
3528         log 'first d29'
3529         ls -l $DIR/d29
3530
3531         declare -i LOCKCOUNTORIG=0
3532         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3533                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3534         done
3535         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3536
3537         declare -i LOCKUNUSEDCOUNTORIG=0
3538         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3539                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3540         done
3541
3542         log 'second d29'
3543         ls -l $DIR/d29
3544         log 'done'
3545
3546         declare -i LOCKCOUNTCURRENT=0
3547         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3548                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3549         done
3550
3551         declare -i LOCKUNUSEDCOUNTCURRENT=0
3552         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3553                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3554         done
3555
3556         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3557                 $LCTL set_param -n ldlm.dump_namespaces ""
3558                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3559                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3560                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3561                 return 2
3562         fi
3563         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3564                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3565                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3566                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3567                 return 3
3568         fi
3569 }
3570 run_test 29 "IT_GETATTR regression  ============================"
3571
3572 test_30a() { # was test_30
3573         cp $(which ls) $DIR || cp /bin/ls $DIR
3574         $DIR/ls / || error "Can't execute binary from lustre"
3575         rm $DIR/ls
3576 }
3577 run_test 30a "execute binary from Lustre (execve) =============="
3578
3579 test_30b() {
3580         cp `which ls` $DIR || cp /bin/ls $DIR
3581         chmod go+rx $DIR/ls
3582         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3583         rm $DIR/ls
3584 }
3585 run_test 30b "execute binary from Lustre as non-root ==========="
3586
3587 test_30c() { # b=22376
3588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3589
3590         cp $(which ls) $DIR || cp /bin/ls $DIR
3591         chmod a-rw $DIR/ls
3592         cancel_lru_locks mdc
3593         cancel_lru_locks osc
3594         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3595         rm -f $DIR/ls
3596 }
3597 run_test 30c "execute binary from Lustre without read perms ===="
3598
3599 test_30d() {
3600         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3601
3602         for i in {1..10}; do
3603                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3604                 local PID=$!
3605                 sleep 1
3606                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3607                 wait $PID || error "executing dd from Lustre failed"
3608                 rm -f $DIR/$tfile
3609         done
3610
3611         rm -f $DIR/dd
3612 }
3613 run_test 30d "execute binary from Lustre while clear locks"
3614
3615 test_31a() {
3616         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3617         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3618 }
3619 run_test 31a "open-unlink file =================================="
3620
3621 test_31b() {
3622         touch $DIR/f31 || error "touch $DIR/f31 failed"
3623         ln $DIR/f31 $DIR/f31b || error "ln failed"
3624         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3625         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3626 }
3627 run_test 31b "unlink file with multiple links while open ======="
3628
3629 test_31c() {
3630         touch $DIR/f31 || error "touch $DIR/f31 failed"
3631         ln $DIR/f31 $DIR/f31c || error "ln failed"
3632         multiop_bg_pause $DIR/f31 O_uc ||
3633                 error "multiop_bg_pause for $DIR/f31 failed"
3634         MULTIPID=$!
3635         $MULTIOP $DIR/f31c Ouc
3636         kill -USR1 $MULTIPID
3637         wait $MULTIPID
3638 }
3639 run_test 31c "open-unlink file with multiple links ============="
3640
3641 test_31d() {
3642         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3643         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3644 }
3645 run_test 31d "remove of open directory ========================="
3646
3647 test_31e() { # bug 2904
3648         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3649 }
3650 run_test 31e "remove of open non-empty directory ==============="
3651
3652 test_31f() { # bug 4554
3653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3654
3655         set -vx
3656         test_mkdir $DIR/d31f
3657         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3658         cp /etc/hosts $DIR/d31f
3659         ls -l $DIR/d31f
3660         $LFS getstripe $DIR/d31f/hosts
3661         multiop_bg_pause $DIR/d31f D_c || return 1
3662         MULTIPID=$!
3663
3664         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3665         test_mkdir $DIR/d31f
3666         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3667         cp /etc/hosts $DIR/d31f
3668         ls -l $DIR/d31f
3669         $LFS getstripe $DIR/d31f/hosts
3670         multiop_bg_pause $DIR/d31f D_c || return 1
3671         MULTIPID2=$!
3672
3673         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3674         wait $MULTIPID || error "first opendir $MULTIPID failed"
3675
3676         sleep 6
3677
3678         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3679         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3680         set +vx
3681 }
3682 run_test 31f "remove of open directory with open-unlink file ==="
3683
3684 test_31g() {
3685         echo "-- cross directory link --"
3686         test_mkdir -c1 $DIR/${tdir}ga
3687         test_mkdir -c1 $DIR/${tdir}gb
3688         touch $DIR/${tdir}ga/f
3689         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3690         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3691         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3692         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3693         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3694 }
3695 run_test 31g "cross directory link==============="
3696
3697 test_31h() {
3698         echo "-- cross directory link --"
3699         test_mkdir -c1 $DIR/${tdir}
3700         test_mkdir -c1 $DIR/${tdir}/dir
3701         touch $DIR/${tdir}/f
3702         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3703         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3704         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3705         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3706         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3707 }
3708 run_test 31h "cross directory link under child==============="
3709
3710 test_31i() {
3711         echo "-- cross directory link --"
3712         test_mkdir -c1 $DIR/$tdir
3713         test_mkdir -c1 $DIR/$tdir/dir
3714         touch $DIR/$tdir/dir/f
3715         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3716         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3717         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3718         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3719         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3720 }
3721 run_test 31i "cross directory link under parent==============="
3722
3723 test_31j() {
3724         test_mkdir -c1 -p $DIR/$tdir
3725         test_mkdir -c1 -p $DIR/$tdir/dir1
3726         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3727         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3728         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3729         return 0
3730 }
3731 run_test 31j "link for directory"
3732
3733 test_31k() {
3734         test_mkdir -c1 -p $DIR/$tdir
3735         touch $DIR/$tdir/s
3736         touch $DIR/$tdir/exist
3737         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3738         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3739         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3740         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3741         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3742         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3743         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3744         return 0
3745 }
3746 run_test 31k "link to file: the same, non-existing, dir"
3747
3748 test_31l() {
3749         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3750
3751         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3752         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3753                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3754
3755         touch $DIR/$tfile || error "create failed"
3756         mkdir $DIR/$tdir || error "mkdir failed"
3757         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3758 }
3759 run_test 31l "link to file: target dir has trailing slash"
3760
3761 test_31m() {
3762         mkdir $DIR/d31m
3763         touch $DIR/d31m/s
3764         mkdir $DIR/d31m2
3765         touch $DIR/d31m2/exist
3766         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3767         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3768         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3769         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3770         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3771         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3772         return 0
3773 }
3774 run_test 31m "link to file: the same, non-existing, dir"
3775
3776 test_31n() {
3777         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3778         nlink=$(stat --format=%h $DIR/$tfile)
3779         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3780         local fd=$(free_fd)
3781         local cmd="exec $fd<$DIR/$tfile"
3782         eval $cmd
3783         cmd="exec $fd<&-"
3784         trap "eval $cmd" EXIT
3785         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3786         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3787         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3788         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3789         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3790         eval $cmd
3791 }
3792 run_test 31n "check link count of unlinked file"
3793
3794 link_one() {
3795         local tempfile=$(mktemp $1_XXXXXX)
3796         link $tempfile $1 2> /dev/null &&
3797                 echo "$BASHPID: link $tempfile to $1 succeeded"
3798         unlink $tempfile
3799 }
3800
3801 test_31o() { # LU-2901
3802         test_mkdir $DIR/$tdir
3803         for LOOP in $(seq 100); do
3804                 rm -f $DIR/$tdir/$tfile*
3805                 for THREAD in $(seq 8); do
3806                         link_one $DIR/$tdir/$tfile.$LOOP &
3807                 done
3808                 wait
3809                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3810                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3811                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3812                         break || true
3813         done
3814 }
3815 run_test 31o "duplicate hard links with same filename"
3816
3817 test_31p() {
3818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3819
3820         test_mkdir $DIR/$tdir
3821         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3822         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3823
3824         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3825                 error "open unlink test1 failed"
3826         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3827                 error "open unlink test2 failed"
3828
3829         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3830                 error "test1 still exists"
3831         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3832                 error "test2 still exists"
3833 }
3834 run_test 31p "remove of open striped directory"
3835
3836 test_31q() {
3837         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3838
3839         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3840         index=$($LFS getdirstripe -i $DIR/$tdir)
3841         [ $index -eq 3 ] || error "first stripe index $index != 3"
3842         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3843         [ $index -eq 1 ] || error "second stripe index $index != 1"
3844
3845         # when "-c <stripe_count>" is set, the number of MDTs specified after
3846         # "-i" should equal to the stripe count
3847         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3848 }
3849 run_test 31q "create striped directory on specific MDTs"
3850
3851 #LU-14949
3852 test_31r() {
3853         touch $DIR/$tfile.target
3854         touch $DIR/$tfile.source
3855
3856         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3857         $LCTL set_param fail_loc=0x1419 fail_val=3
3858         cat $DIR/$tfile.target &
3859         CATPID=$!
3860
3861         # Guarantee open is waiting before we get here
3862         sleep 1
3863         mv $DIR/$tfile.source $DIR/$tfile.target
3864
3865         wait $CATPID
3866         RC=$?
3867         if [[ $RC -ne 0 ]]; then
3868                 error "open with cat failed, rc=$RC"
3869         fi
3870 }
3871 run_test 31r "open-rename(replace) race"
3872
3873 cleanup_test32_mount() {
3874         local rc=0
3875         trap 0
3876         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3877         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3878         losetup -d $loopdev || true
3879         rm -rf $DIR/$tdir
3880         return $rc
3881 }
3882
3883 test_32a() {
3884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3885
3886         echo "== more mountpoints and symlinks ================="
3887         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3888         trap cleanup_test32_mount EXIT
3889         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3890         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3891                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3892         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3893                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3894         cleanup_test32_mount
3895 }
3896 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3897
3898 test_32b() {
3899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3900
3901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3902         trap cleanup_test32_mount EXIT
3903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3904         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3905                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3906         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3907                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3908         cleanup_test32_mount
3909 }
3910 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3911
3912 test_32c() {
3913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3914
3915         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3916         trap cleanup_test32_mount EXIT
3917         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3918         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3919                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3920         test_mkdir -p $DIR/$tdir/d2/test_dir
3921         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3922                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3923         cleanup_test32_mount
3924 }
3925 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3926
3927 test_32d() {
3928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3929
3930         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3931         trap cleanup_test32_mount EXIT
3932         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3933         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3934                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3935         test_mkdir -p $DIR/$tdir/d2/test_dir
3936         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3937                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3938         cleanup_test32_mount
3939 }
3940 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3941
3942 test_32e() {
3943         rm -fr $DIR/$tdir
3944         test_mkdir -p $DIR/$tdir/tmp
3945         local tmp_dir=$DIR/$tdir/tmp
3946         ln -s $DIR/$tdir $tmp_dir/symlink11
3947         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3948         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3949         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3950 }
3951 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3952
3953 test_32f() {
3954         rm -fr $DIR/$tdir
3955         test_mkdir -p $DIR/$tdir/tmp
3956         local tmp_dir=$DIR/$tdir/tmp
3957         ln -s $DIR/$tdir $tmp_dir/symlink11
3958         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3959         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3960         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3961 }
3962 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3963
3964 test_32g() {
3965         local tmp_dir=$DIR/$tdir/tmp
3966         test_mkdir -p $tmp_dir
3967         test_mkdir $DIR/${tdir}2
3968         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3969         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3970         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3971         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3972         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3973         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3974 }
3975 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3976
3977 test_32h() {
3978         rm -fr $DIR/$tdir $DIR/${tdir}2
3979         tmp_dir=$DIR/$tdir/tmp
3980         test_mkdir -p $tmp_dir
3981         test_mkdir $DIR/${tdir}2
3982         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3983         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3984         ls $tmp_dir/symlink12 || error "listing symlink12"
3985         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3986 }
3987 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3988
3989 test_32i() {
3990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3991
3992         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3993         trap cleanup_test32_mount EXIT
3994         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3995         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3996                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3997         touch $DIR/$tdir/test_file
3998         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3999                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4000         cleanup_test32_mount
4001 }
4002 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4003
4004 test_32j() {
4005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4006
4007         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4008         trap cleanup_test32_mount EXIT
4009         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4010         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4011                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4012         touch $DIR/$tdir/test_file
4013         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4014                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4015         cleanup_test32_mount
4016 }
4017 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4018
4019 test_32k() {
4020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4021
4022         rm -fr $DIR/$tdir
4023         trap cleanup_test32_mount EXIT
4024         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4025         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4026                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4027         test_mkdir -p $DIR/$tdir/d2
4028         touch $DIR/$tdir/d2/test_file || error "touch failed"
4029         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4030                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4031         cleanup_test32_mount
4032 }
4033 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4034
4035 test_32l() {
4036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4037
4038         rm -fr $DIR/$tdir
4039         trap cleanup_test32_mount EXIT
4040         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4041         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4042                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4043         test_mkdir -p $DIR/$tdir/d2
4044         touch $DIR/$tdir/d2/test_file || error "touch failed"
4045         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4046                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4047         cleanup_test32_mount
4048 }
4049 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4050
4051 test_32m() {
4052         rm -fr $DIR/d32m
4053         test_mkdir -p $DIR/d32m/tmp
4054         TMP_DIR=$DIR/d32m/tmp
4055         ln -s $DIR $TMP_DIR/symlink11
4056         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4057         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4058                 error "symlink11 not a link"
4059         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4060                 error "symlink01 not a link"
4061 }
4062 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4063
4064 test_32n() {
4065         rm -fr $DIR/d32n
4066         test_mkdir -p $DIR/d32n/tmp
4067         TMP_DIR=$DIR/d32n/tmp
4068         ln -s $DIR $TMP_DIR/symlink11
4069         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4070         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4071         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4072 }
4073 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4074
4075 test_32o() {
4076         touch $DIR/$tfile
4077         test_mkdir -p $DIR/d32o/tmp
4078         TMP_DIR=$DIR/d32o/tmp
4079         ln -s $DIR/$tfile $TMP_DIR/symlink12
4080         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4081         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4082                 error "symlink12 not a link"
4083         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4084         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4085                 error "$DIR/d32o/tmp/symlink12 not file type"
4086         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4087                 error "$DIR/d32o/symlink02 not file type"
4088 }
4089 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4090
4091 test_32p() {
4092         log 32p_1
4093         rm -fr $DIR/d32p
4094         log 32p_2
4095         rm -f $DIR/$tfile
4096         log 32p_3
4097         touch $DIR/$tfile
4098         log 32p_4
4099         test_mkdir -p $DIR/d32p/tmp
4100         log 32p_5
4101         TMP_DIR=$DIR/d32p/tmp
4102         log 32p_6
4103         ln -s $DIR/$tfile $TMP_DIR/symlink12
4104         log 32p_7
4105         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4106         log 32p_8
4107         cat $DIR/d32p/tmp/symlink12 ||
4108                 error "Can't open $DIR/d32p/tmp/symlink12"
4109         log 32p_9
4110         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4111         log 32p_10
4112 }
4113 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4114
4115 test_32q() {
4116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4117
4118         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4119         trap cleanup_test32_mount EXIT
4120         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4121         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4122         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4123                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4124         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4125         cleanup_test32_mount
4126 }
4127 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4128
4129 test_32r() {
4130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4131
4132         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4133         trap cleanup_test32_mount EXIT
4134         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4135         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4136         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4137                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4138         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4139         cleanup_test32_mount
4140 }
4141 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4142
4143 test_33aa() {
4144         rm -f $DIR/$tfile
4145         touch $DIR/$tfile
4146         chmod 444 $DIR/$tfile
4147         chown $RUNAS_ID $DIR/$tfile
4148         log 33_1
4149         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4150         log 33_2
4151 }
4152 run_test 33aa "write file with mode 444 (should return error)"
4153
4154 test_33a() {
4155         rm -fr $DIR/$tdir
4156         test_mkdir $DIR/$tdir
4157         chown $RUNAS_ID $DIR/$tdir
4158         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4159                 error "$RUNAS create $tdir/$tfile failed"
4160         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4161                 error "open RDWR" || true
4162 }
4163 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4164
4165 test_33b() {
4166         rm -fr $DIR/$tdir
4167         test_mkdir $DIR/$tdir
4168         chown $RUNAS_ID $DIR/$tdir
4169         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4170 }
4171 run_test 33b "test open file with malformed flags (No panic)"
4172
4173 test_33c() {
4174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4175         remote_ost_nodsh && skip "remote OST with nodsh"
4176
4177         local ostnum
4178         local ostname
4179         local write_bytes
4180         local all_zeros
4181
4182         all_zeros=true
4183         test_mkdir $DIR/$tdir
4184         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4185
4186         sync
4187         for ostnum in $(seq $OSTCOUNT); do
4188                 # test-framework's OST numbering is one-based, while Lustre's
4189                 # is zero-based
4190                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4191                 # check if at least some write_bytes stats are counted
4192                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4193                               obdfilter.$ostname.stats |
4194                               awk '/^write_bytes/ {print $7}' )
4195                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4196                 if (( ${write_bytes:-0} > 0 )); then
4197                         all_zeros=false
4198                         break
4199                 fi
4200         done
4201
4202         $all_zeros || return 0
4203
4204         # Write four bytes
4205         echo foo > $DIR/$tdir/bar
4206         # Really write them
4207         sync
4208
4209         # Total up write_bytes after writing.  We'd better find non-zeros.
4210         for ostnum in $(seq $OSTCOUNT); do
4211                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4212                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4213                               obdfilter/$ostname/stats |
4214                               awk '/^write_bytes/ {print $7}' )
4215                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4216                 if (( ${write_bytes:-0} > 0 )); then
4217                         all_zeros=false
4218                         break
4219                 fi
4220         done
4221
4222         if $all_zeros; then
4223                 for ostnum in $(seq $OSTCOUNT); do
4224                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4225                         echo "Check write_bytes is in obdfilter.*.stats:"
4226                         do_facet ost$ostnum lctl get_param -n \
4227                                 obdfilter.$ostname.stats
4228                 done
4229                 error "OST not keeping write_bytes stats (b=22312)"
4230         fi
4231 }
4232 run_test 33c "test write_bytes stats"
4233
4234 test_33d() {
4235         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4237
4238         local MDTIDX=1
4239         local remote_dir=$DIR/$tdir/remote_dir
4240
4241         test_mkdir $DIR/$tdir
4242         $LFS mkdir -i $MDTIDX $remote_dir ||
4243                 error "create remote directory failed"
4244
4245         touch $remote_dir/$tfile
4246         chmod 444 $remote_dir/$tfile
4247         chown $RUNAS_ID $remote_dir/$tfile
4248
4249         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4250
4251         chown $RUNAS_ID $remote_dir
4252         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4253                                         error "create" || true
4254         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4255                                     error "open RDWR" || true
4256         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4257 }
4258 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4259
4260 test_33e() {
4261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4262
4263         mkdir $DIR/$tdir
4264
4265         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4266         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4267         mkdir $DIR/$tdir/local_dir
4268
4269         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4270         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4271         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4272
4273         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4274                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4275
4276         rmdir $DIR/$tdir/* || error "rmdir failed"
4277
4278         umask 777
4279         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4280         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4281         mkdir $DIR/$tdir/local_dir
4282
4283         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4284         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4285         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4286
4287         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4288                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4289
4290         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4291
4292         umask 000
4293         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4294         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4295         mkdir $DIR/$tdir/local_dir
4296
4297         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4298         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4299         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4300
4301         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4302                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4303 }
4304 run_test 33e "mkdir and striped directory should have same mode"
4305
4306 cleanup_33f() {
4307         trap 0
4308         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4309 }
4310
4311 test_33f() {
4312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4313         remote_mds_nodsh && skip "remote MDS with nodsh"
4314
4315         mkdir $DIR/$tdir
4316         chmod go+rwx $DIR/$tdir
4317         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4318         trap cleanup_33f EXIT
4319
4320         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4321                 error "cannot create striped directory"
4322
4323         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4324                 error "cannot create files in striped directory"
4325
4326         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4327                 error "cannot remove files in striped directory"
4328
4329         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4330                 error "cannot remove striped directory"
4331
4332         cleanup_33f
4333 }
4334 run_test 33f "nonroot user can create, access, and remove a striped directory"
4335
4336 test_33g() {
4337         mkdir -p $DIR/$tdir/dir2
4338
4339         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4340         echo $err
4341         [[ $err =~ "exists" ]] || error "Not exists error"
4342 }
4343 run_test 33g "nonroot user create already existing root created file"
4344
4345 sub_33h() {
4346         local hash_type=$1
4347         local count=250
4348
4349         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4350                 error "lfs mkdir -H $hash_type $tdir failed"
4351         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4352
4353         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4354         local index2
4355         local fname
4356
4357         for fname in $DIR/$tdir/$tfile.bak \
4358                      $DIR/$tdir/$tfile.SAV \
4359                      $DIR/$tdir/$tfile.orig \
4360                      $DIR/$tdir/$tfile~; do
4361                 touch $fname || error "touch $fname failed"
4362                 index2=$($LFS getstripe -m $fname)
4363                 (( $index == $index2 )) ||
4364                         error "$fname MDT index mismatch $index != $index2"
4365         done
4366
4367         local failed=0
4368         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4369         local pattern
4370
4371         for pattern in ${patterns[*]}; do
4372                 echo "pattern $pattern"
4373                 fname=$DIR/$tdir/$pattern
4374                 for (( i = 0; i < $count; i++ )); do
4375                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4376                                 error "mktemp $DIR/$tdir/$pattern failed"
4377                         index2=$($LFS getstripe -m $fname)
4378                         (( $index == $index2 )) && continue
4379
4380                         failed=$((failed + 1))
4381                         echo "$fname MDT index mismatch $index != $index2"
4382                 done
4383         done
4384
4385         echo "$failed/$count MDT index mismatches, expect ~2-4"
4386         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4387
4388         local same=0
4389         local expect
4390
4391         # verify that "crush" is still broken with all files on same MDT,
4392         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4393         [[ "$hash_type" == "crush" ]] && expect=$count ||
4394                 expect=$((count / MDSCOUNT))
4395
4396         # crush2 doesn't put all-numeric suffixes on the same MDT,
4397         # filename like $tfile.12345678 should *not* be considered temp
4398         for pattern in ${patterns[*]}; do
4399                 local base=${pattern%%X*}
4400                 local suff=${pattern#$base}
4401
4402                 echo "pattern $pattern"
4403                 for (( i = 0; i < $count; i++ )); do
4404                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4405                         touch $fname || error "touch $fname failed"
4406                         index2=$($LFS getstripe -m $fname)
4407                         (( $index != $index2 )) && continue
4408
4409                         same=$((same + 1))
4410                 done
4411         done
4412
4413         # the number of "bad" hashes is random, as it depends on the random
4414         # filenames generated by "mktemp".  Allow some margin in the results.
4415         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4416         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4417            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4418                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4419         same=0
4420
4421         # crush2 doesn't put suffixes with special characters on the same MDT
4422         # filename like $tfile.txt.1234 should *not* be considered temp
4423         for pattern in ${patterns[*]}; do
4424                 local base=${pattern%%X*}
4425                 local suff=${pattern#$base}
4426
4427                 pattern=$base...${suff/XXX}
4428                 echo "pattern=$pattern"
4429                 for (( i = 0; i < $count; i++ )); do
4430                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4431                                 error "touch $fname failed"
4432                         index2=$($LFS getstripe -m $fname)
4433                         (( $index != $index2 )) && continue
4434
4435                         same=$((same + 1))
4436                 done
4437         done
4438
4439         # the number of "bad" hashes is random, as it depends on the random
4440         # filenames generated by "mktemp".  Allow some margin in the results.
4441         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4442         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4443            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4444                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4445 }
4446
4447 test_33h() {
4448         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4449         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4450                 skip "Need MDS version at least 2.13.50"
4451
4452         sub_33h crush
4453 }
4454 run_test 33h "temp file is located on the same MDT as target (crush)"
4455
4456 test_33hh() {
4457         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4458         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4459         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4460                 skip "Need MDS version at least 2.15.0 for crush2"
4461
4462         sub_33h crush2
4463 }
4464 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4465
4466 test_33i()
4467 {
4468         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4469
4470         local FNAME=$(str_repeat 'f' 250)
4471
4472         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4473         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4474
4475         local count
4476         local total
4477
4478         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4479
4480         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4481
4482         lctl --device %$MDC deactivate
4483         stack_trap "lctl --device %$MDC activate"
4484         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4485         total=$(\ls -l $DIR/$tdir | wc -l)
4486         # "ls -l" will list total in the first line
4487         total=$((total - 1))
4488         (( total + count == 1000 )) ||
4489                 error "ls list $total files, $count files on MDT1"
4490 }
4491 run_test 33i "striped directory can be accessed when one MDT is down"
4492
4493 test_33j() {
4494         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4495
4496         mkdir -p $DIR/$tdir/
4497
4498         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4499                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4500
4501         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4502                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4503
4504         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4505                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4506
4507         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4508                 error "-D was not specified, but still failed"
4509 }
4510 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4511
4512 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4513 test_34a() {
4514         rm -f $DIR/f34
4515         $MCREATE $DIR/f34 || error "mcreate failed"
4516         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4517                 error "getstripe failed"
4518         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4519         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4520                 error "getstripe failed"
4521         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4522                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4523 }
4524 run_test 34a "truncate file that has not been opened ==========="
4525
4526 test_34b() {
4527         [ ! -f $DIR/f34 ] && test_34a
4528         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4529                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4530         $OPENFILE -f O_RDONLY $DIR/f34
4531         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4532                 error "getstripe failed"
4533         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4534                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4535 }
4536 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4537
4538 test_34c() {
4539         [ ! -f $DIR/f34 ] && test_34a
4540         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4541                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4542         $OPENFILE -f O_RDWR $DIR/f34
4543         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4544                 error "$LFS getstripe failed"
4545         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4546                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4547 }
4548 run_test 34c "O_RDWR opening file-with-size works =============="
4549
4550 test_34d() {
4551         [ ! -f $DIR/f34 ] && test_34a
4552         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4553                 error "dd failed"
4554         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4555                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4556         rm $DIR/f34
4557 }
4558 run_test 34d "write to sparse file ============================="
4559
4560 test_34e() {
4561         rm -f $DIR/f34e
4562         $MCREATE $DIR/f34e || error "mcreate failed"
4563         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4564         $CHECKSTAT -s 1000 $DIR/f34e ||
4565                 error "Size of $DIR/f34e not equal to 1000 bytes"
4566         $OPENFILE -f O_RDWR $DIR/f34e
4567         $CHECKSTAT -s 1000 $DIR/f34e ||
4568                 error "Size of $DIR/f34e not equal to 1000 bytes"
4569 }
4570 run_test 34e "create objects, some with size and some without =="
4571
4572 test_34f() { # bug 6242, 6243
4573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4574
4575         SIZE34F=48000
4576         rm -f $DIR/f34f
4577         $MCREATE $DIR/f34f || error "mcreate failed"
4578         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4579         dd if=$DIR/f34f of=$TMP/f34f
4580         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4581         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4582         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4583         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4584         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4585 }
4586 run_test 34f "read from a file with no objects until EOF ======="
4587
4588 test_34g() {
4589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4590
4591         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4592                 error "dd failed"
4593         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4594         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4595                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4596         cancel_lru_locks osc
4597         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4598                 error "wrong size after lock cancel"
4599
4600         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4602                 error "expanding truncate failed"
4603         cancel_lru_locks osc
4604         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4605                 error "wrong expanded size after lock cancel"
4606 }
4607 run_test 34g "truncate long file ==============================="
4608
4609 test_34h() {
4610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4611
4612         local gid=10
4613         local sz=1000
4614
4615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4616         sync # Flush the cache so that multiop below does not block on cache
4617              # flush when getting the group lock
4618         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4619         MULTIPID=$!
4620
4621         # Since just timed wait is not good enough, let's do a sync write
4622         # that way we are sure enough time for a roundtrip + processing
4623         # passed + 2 seconds of extra margin.
4624         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4625         rm $DIR/${tfile}-1
4626         sleep 2
4627
4628         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4629                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4630                 kill -9 $MULTIPID
4631         fi
4632         wait $MULTIPID
4633         local nsz=`stat -c %s $DIR/$tfile`
4634         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4635 }
4636 run_test 34h "ftruncate file under grouplock should not block"
4637
4638 test_35a() {
4639         cp /bin/sh $DIR/f35a
4640         chmod 444 $DIR/f35a
4641         chown $RUNAS_ID $DIR/f35a
4642         $RUNAS $DIR/f35a && error || true
4643         rm $DIR/f35a
4644 }
4645 run_test 35a "exec file with mode 444 (should return and not leak)"
4646
4647 test_36a() {
4648         rm -f $DIR/f36
4649         utime $DIR/f36 || error "utime failed for MDS"
4650 }
4651 run_test 36a "MDS utime check (mknod, utime)"
4652
4653 test_36b() {
4654         echo "" > $DIR/f36
4655         utime $DIR/f36 || error "utime failed for OST"
4656 }
4657 run_test 36b "OST utime check (open, utime)"
4658
4659 test_36c() {
4660         rm -f $DIR/d36/f36
4661         test_mkdir $DIR/d36
4662         chown $RUNAS_ID $DIR/d36
4663         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4664 }
4665 run_test 36c "non-root MDS utime check (mknod, utime)"
4666
4667 test_36d() {
4668         [ ! -d $DIR/d36 ] && test_36c
4669         echo "" > $DIR/d36/f36
4670         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4671 }
4672 run_test 36d "non-root OST utime check (open, utime)"
4673
4674 test_36e() {
4675         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4676
4677         test_mkdir $DIR/$tdir
4678         touch $DIR/$tdir/$tfile
4679         $RUNAS utime $DIR/$tdir/$tfile &&
4680                 error "utime worked, expected failure" || true
4681 }
4682 run_test 36e "utime on non-owned file (should return error)"
4683
4684 subr_36fh() {
4685         local fl="$1"
4686         local LANG_SAVE=$LANG
4687         local LC_LANG_SAVE=$LC_LANG
4688         export LANG=C LC_LANG=C # for date language
4689
4690         DATESTR="Dec 20  2000"
4691         test_mkdir $DIR/$tdir
4692         lctl set_param fail_loc=$fl
4693         date; date +%s
4694         cp /etc/hosts $DIR/$tdir/$tfile
4695         sync & # write RPC generated with "current" inode timestamp, but delayed
4696         sleep 1
4697         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4698         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4699         cancel_lru_locks $OSC
4700         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4701         date; date +%s
4702         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4703                 echo "BEFORE: $LS_BEFORE" && \
4704                 echo "AFTER : $LS_AFTER" && \
4705                 echo "WANT  : $DATESTR" && \
4706                 error "$DIR/$tdir/$tfile timestamps changed" || true
4707
4708         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4709 }
4710
4711 test_36f() {
4712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4713
4714         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4715         subr_36fh "0x80000214"
4716 }
4717 run_test 36f "utime on file racing with OST BRW write =========="
4718
4719 test_36g() {
4720         remote_ost_nodsh && skip "remote OST with nodsh"
4721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4722         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4723                 skip "Need MDS version at least 2.12.51"
4724
4725         local fmd_max_age
4726         local fmd
4727         local facet="ost1"
4728         local tgt="obdfilter"
4729
4730         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4731
4732         test_mkdir $DIR/$tdir
4733         fmd_max_age=$(do_facet $facet \
4734                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4735                 head -n 1")
4736
4737         echo "FMD max age: ${fmd_max_age}s"
4738         touch $DIR/$tdir/$tfile
4739         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4740                 gawk '{cnt=cnt+$1}  END{print cnt}')
4741         echo "FMD before: $fmd"
4742         [[ $fmd == 0 ]] &&
4743                 error "FMD wasn't create by touch"
4744         sleep $((fmd_max_age + 12))
4745         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4746                 gawk '{cnt=cnt+$1}  END{print cnt}')
4747         echo "FMD after: $fmd"
4748         [[ $fmd == 0 ]] ||
4749                 error "FMD wasn't expired by ping"
4750 }
4751 run_test 36g "FMD cache expiry ====================="
4752
4753 test_36h() {
4754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4755
4756         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4757         subr_36fh "0x80000227"
4758 }
4759 run_test 36h "utime on file racing with OST BRW write =========="
4760
4761 test_36i() {
4762         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4763
4764         test_mkdir $DIR/$tdir
4765         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4766
4767         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4768         local new_mtime=$((mtime + 200))
4769
4770         #change Modify time of striped dir
4771         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4772                         error "change mtime failed"
4773
4774         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4775
4776         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4777 }
4778 run_test 36i "change mtime on striped directory"
4779
4780 # test_37 - duplicate with tests 32q 32r
4781
4782 test_38() {
4783         local file=$DIR/$tfile
4784         touch $file
4785         openfile -f O_DIRECTORY $file
4786         local RC=$?
4787         local ENOTDIR=20
4788         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4789         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4790 }
4791 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4792
4793 test_39a() { # was test_39
4794         touch $DIR/$tfile
4795         touch $DIR/${tfile}2
4796 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4797 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4798 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4799         sleep 2
4800         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4801         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4802                 echo "mtime"
4803                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4804                 echo "atime"
4805                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4806                 echo "ctime"
4807                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4808                 error "O_TRUNC didn't change timestamps"
4809         fi
4810 }
4811 run_test 39a "mtime changed on create"
4812
4813 test_39b() {
4814         test_mkdir -c1 $DIR/$tdir
4815         cp -p /etc/passwd $DIR/$tdir/fopen
4816         cp -p /etc/passwd $DIR/$tdir/flink
4817         cp -p /etc/passwd $DIR/$tdir/funlink
4818         cp -p /etc/passwd $DIR/$tdir/frename
4819         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4820
4821         sleep 1
4822         echo "aaaaaa" >> $DIR/$tdir/fopen
4823         echo "aaaaaa" >> $DIR/$tdir/flink
4824         echo "aaaaaa" >> $DIR/$tdir/funlink
4825         echo "aaaaaa" >> $DIR/$tdir/frename
4826
4827         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4828         local link_new=`stat -c %Y $DIR/$tdir/flink`
4829         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4830         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4831
4832         cat $DIR/$tdir/fopen > /dev/null
4833         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4834         rm -f $DIR/$tdir/funlink2
4835         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4836
4837         for (( i=0; i < 2; i++ )) ; do
4838                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4839                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4840                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4841                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4842
4843                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4844                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4845                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4846                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4847
4848                 cancel_lru_locks $OSC
4849                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4850         done
4851 }
4852 run_test 39b "mtime change on open, link, unlink, rename  ======"
4853
4854 # this should be set to past
4855 TEST_39_MTIME=`date -d "1 year ago" +%s`
4856
4857 # bug 11063
4858 test_39c() {
4859         touch $DIR1/$tfile
4860         sleep 2
4861         local mtime0=`stat -c %Y $DIR1/$tfile`
4862
4863         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4864         local mtime1=`stat -c %Y $DIR1/$tfile`
4865         [ "$mtime1" = $TEST_39_MTIME ] || \
4866                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4867
4868         local d1=`date +%s`
4869         echo hello >> $DIR1/$tfile
4870         local d2=`date +%s`
4871         local mtime2=`stat -c %Y $DIR1/$tfile`
4872         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4873                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4874
4875         mv $DIR1/$tfile $DIR1/$tfile-1
4876
4877         for (( i=0; i < 2; i++ )) ; do
4878                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4879                 [ "$mtime2" = "$mtime3" ] || \
4880                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4881
4882                 cancel_lru_locks $OSC
4883                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4884         done
4885 }
4886 run_test 39c "mtime change on rename ==========================="
4887
4888 # bug 21114
4889 test_39d() {
4890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4891
4892         touch $DIR1/$tfile
4893         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4894
4895         for (( i=0; i < 2; i++ )) ; do
4896                 local mtime=`stat -c %Y $DIR1/$tfile`
4897                 [ $mtime = $TEST_39_MTIME ] || \
4898                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4899
4900                 cancel_lru_locks $OSC
4901                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4902         done
4903 }
4904 run_test 39d "create, utime, stat =============================="
4905
4906 # bug 21114
4907 test_39e() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         touch $DIR1/$tfile
4911         local mtime1=`stat -c %Y $DIR1/$tfile`
4912
4913         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4914
4915         for (( i=0; i < 2; i++ )) ; do
4916                 local mtime2=`stat -c %Y $DIR1/$tfile`
4917                 [ $mtime2 = $TEST_39_MTIME ] || \
4918                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4919
4920                 cancel_lru_locks $OSC
4921                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4922         done
4923 }
4924 run_test 39e "create, stat, utime, stat ========================"
4925
4926 # bug 21114
4927 test_39f() {
4928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4929
4930         touch $DIR1/$tfile
4931         mtime1=`stat -c %Y $DIR1/$tfile`
4932
4933         sleep 2
4934         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local mtime2=`stat -c %Y $DIR1/$tfile`
4938                 [ $mtime2 = $TEST_39_MTIME ] || \
4939                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4940
4941                 cancel_lru_locks $OSC
4942                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4943         done
4944 }
4945 run_test 39f "create, stat, sleep, utime, stat ================="
4946
4947 # bug 11063
4948 test_39g() {
4949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4950
4951         echo hello >> $DIR1/$tfile
4952         local mtime1=`stat -c %Y $DIR1/$tfile`
4953
4954         sleep 2
4955         chmod o+r $DIR1/$tfile
4956
4957         for (( i=0; i < 2; i++ )) ; do
4958                 local mtime2=`stat -c %Y $DIR1/$tfile`
4959                 [ "$mtime1" = "$mtime2" ] || \
4960                         error "lost mtime: $mtime2, should be $mtime1"
4961
4962                 cancel_lru_locks $OSC
4963                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4964         done
4965 }
4966 run_test 39g "write, chmod, stat ==============================="
4967
4968 # bug 11063
4969 test_39h() {
4970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4971
4972         touch $DIR1/$tfile
4973         sleep 1
4974
4975         local d1=`date`
4976         echo hello >> $DIR1/$tfile
4977         local mtime1=`stat -c %Y $DIR1/$tfile`
4978
4979         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4980         local d2=`date`
4981         if [ "$d1" != "$d2" ]; then
4982                 echo "write and touch not within one second"
4983         else
4984                 for (( i=0; i < 2; i++ )) ; do
4985                         local mtime2=`stat -c %Y $DIR1/$tfile`
4986                         [ "$mtime2" = $TEST_39_MTIME ] || \
4987                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4988
4989                         cancel_lru_locks $OSC
4990                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4991                 done
4992         fi
4993 }
4994 run_test 39h "write, utime within one second, stat ============="
4995
4996 test_39i() {
4997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4998
4999         touch $DIR1/$tfile
5000         sleep 1
5001
5002         echo hello >> $DIR1/$tfile
5003         local mtime1=`stat -c %Y $DIR1/$tfile`
5004
5005         mv $DIR1/$tfile $DIR1/$tfile-1
5006
5007         for (( i=0; i < 2; i++ )) ; do
5008                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5009
5010                 [ "$mtime1" = "$mtime2" ] || \
5011                         error "lost mtime: $mtime2, should be $mtime1"
5012
5013                 cancel_lru_locks $OSC
5014                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5015         done
5016 }
5017 run_test 39i "write, rename, stat =============================="
5018
5019 test_39j() {
5020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5021
5022         start_full_debug_logging
5023         touch $DIR1/$tfile
5024         sleep 1
5025
5026         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5027         lctl set_param fail_loc=0x80000412
5028         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5029                 error "multiop failed"
5030         local multipid=$!
5031         local mtime1=`stat -c %Y $DIR1/$tfile`
5032
5033         mv $DIR1/$tfile $DIR1/$tfile-1
5034
5035         kill -USR1 $multipid
5036         wait $multipid || error "multiop close failed"
5037
5038         for (( i=0; i < 2; i++ )) ; do
5039                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5040                 [ "$mtime1" = "$mtime2" ] ||
5041                         error "mtime is lost on close: $mtime2, " \
5042                               "should be $mtime1"
5043
5044                 cancel_lru_locks
5045                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5046         done
5047         lctl set_param fail_loc=0
5048         stop_full_debug_logging
5049 }
5050 run_test 39j "write, rename, close, stat ======================="
5051
5052 test_39k() {
5053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5054
5055         touch $DIR1/$tfile
5056         sleep 1
5057
5058         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5059         local multipid=$!
5060         local mtime1=`stat -c %Y $DIR1/$tfile`
5061
5062         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5063
5064         kill -USR1 $multipid
5065         wait $multipid || error "multiop close failed"
5066
5067         for (( i=0; i < 2; i++ )) ; do
5068                 local mtime2=`stat -c %Y $DIR1/$tfile`
5069
5070                 [ "$mtime2" = $TEST_39_MTIME ] || \
5071                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5072
5073                 cancel_lru_locks
5074                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5075         done
5076 }
5077 run_test 39k "write, utime, close, stat ========================"
5078
5079 # this should be set to future
5080 TEST_39_ATIME=`date -d "1 year" +%s`
5081
5082 test_39l() {
5083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5084         remote_mds_nodsh && skip "remote MDS with nodsh"
5085
5086         local atime_diff=$(do_facet $SINGLEMDS \
5087                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5088         rm -rf $DIR/$tdir
5089         mkdir_on_mdt0 $DIR/$tdir
5090
5091         # test setting directory atime to future
5092         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5093         local atime=$(stat -c %X $DIR/$tdir)
5094         [ "$atime" = $TEST_39_ATIME ] ||
5095                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5096
5097         # test setting directory atime from future to now
5098         local now=$(date +%s)
5099         touch -a -d @$now $DIR/$tdir
5100
5101         atime=$(stat -c %X $DIR/$tdir)
5102         [ "$atime" -eq "$now"  ] ||
5103                 error "atime is not updated from future: $atime, $now"
5104
5105         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5106         sleep 3
5107
5108         # test setting directory atime when now > dir atime + atime_diff
5109         local d1=$(date +%s)
5110         ls $DIR/$tdir
5111         local d2=$(date +%s)
5112         cancel_lru_locks mdc
5113         atime=$(stat -c %X $DIR/$tdir)
5114         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5115                 error "atime is not updated  : $atime, should be $d2"
5116
5117         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5118         sleep 3
5119
5120         # test not setting directory atime when now < dir atime + atime_diff
5121         ls $DIR/$tdir
5122         cancel_lru_locks mdc
5123         atime=$(stat -c %X $DIR/$tdir)
5124         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5125                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5126
5127         do_facet $SINGLEMDS \
5128                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5129 }
5130 run_test 39l "directory atime update ==========================="
5131
5132 test_39m() {
5133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5134
5135         touch $DIR1/$tfile
5136         sleep 2
5137         local far_past_mtime=$(date -d "May 29 1953" +%s)
5138         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5139
5140         touch -m -d @$far_past_mtime $DIR1/$tfile
5141         touch -a -d @$far_past_atime $DIR1/$tfile
5142
5143         for (( i=0; i < 2; i++ )) ; do
5144                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5145                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5146                         error "atime or mtime set incorrectly"
5147
5148                 cancel_lru_locks $OSC
5149                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5150         done
5151 }
5152 run_test 39m "test atime and mtime before 1970"
5153
5154 test_39n() { # LU-3832
5155         remote_mds_nodsh && skip "remote MDS with nodsh"
5156
5157         local atime_diff=$(do_facet $SINGLEMDS \
5158                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5159         local atime0
5160         local atime1
5161         local atime2
5162
5163         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5164
5165         rm -rf $DIR/$tfile
5166         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5167         atime0=$(stat -c %X $DIR/$tfile)
5168
5169         sleep 5
5170         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5171         atime1=$(stat -c %X $DIR/$tfile)
5172
5173         sleep 5
5174         cancel_lru_locks mdc
5175         cancel_lru_locks osc
5176         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5177         atime2=$(stat -c %X $DIR/$tfile)
5178
5179         do_facet $SINGLEMDS \
5180                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5181
5182         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5183         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5184 }
5185 run_test 39n "check that O_NOATIME is honored"
5186
5187 test_39o() {
5188         TESTDIR=$DIR/$tdir/$tfile
5189         [ -e $TESTDIR ] && rm -rf $TESTDIR
5190         mkdir -p $TESTDIR
5191         cd $TESTDIR
5192         links1=2
5193         ls
5194         mkdir a b
5195         ls
5196         links2=$(stat -c %h .)
5197         [ $(($links1 + 2)) != $links2 ] &&
5198                 error "wrong links count $(($links1 + 2)) != $links2"
5199         rmdir b
5200         links3=$(stat -c %h .)
5201         [ $(($links1 + 1)) != $links3 ] &&
5202                 error "wrong links count $links1 != $links3"
5203         return 0
5204 }
5205 run_test 39o "directory cached attributes updated after create"
5206
5207 test_39p() {
5208         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5209
5210         local MDTIDX=1
5211         TESTDIR=$DIR/$tdir/$tdir
5212         [ -e $TESTDIR ] && rm -rf $TESTDIR
5213         test_mkdir -p $TESTDIR
5214         cd $TESTDIR
5215         links1=2
5216         ls
5217         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5218         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5219         ls
5220         links2=$(stat -c %h .)
5221         [ $(($links1 + 2)) != $links2 ] &&
5222                 error "wrong links count $(($links1 + 2)) != $links2"
5223         rmdir remote_dir2
5224         links3=$(stat -c %h .)
5225         [ $(($links1 + 1)) != $links3 ] &&
5226                 error "wrong links count $links1 != $links3"
5227         return 0
5228 }
5229 run_test 39p "remote directory cached attributes updated after create ========"
5230
5231 test_39r() {
5232         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5233                 skip "no atime update on old OST"
5234         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5235                 skip_env "ldiskfs only test"
5236         fi
5237
5238         local saved_adiff
5239         saved_adiff=$(do_facet ost1 \
5240                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5241         stack_trap "do_facet ost1 \
5242                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5243
5244         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5245
5246         $LFS setstripe -i 0 $DIR/$tfile
5247         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5248                 error "can't write initial file"
5249         cancel_lru_locks osc
5250
5251         # exceed atime_diff and access file
5252         sleep 10
5253         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5254                 error "can't udpate atime"
5255
5256         local atime_cli=$(stat -c %X $DIR/$tfile)
5257         echo "client atime: $atime_cli"
5258         # allow atime update to be written to device
5259         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5260         sleep 5
5261
5262         local ostdev=$(ostdevname 1)
5263         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5264         local seq=${fid[3]#0x}
5265         local oid=${fid[1]}
5266         local oid_hex
5267
5268         if [ $seq == 0 ]; then
5269                 oid_hex=${fid[1]}
5270         else
5271                 oid_hex=${fid[2]#0x}
5272         fi
5273         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5274         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5275
5276         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5277         local atime_ost=$(do_facet ost1 "$cmd" |&
5278                           awk -F'[: ]' '/atime:/ { print $4 }')
5279         (( atime_cli == atime_ost )) ||
5280                 error "atime on client $atime_cli != ost $atime_ost"
5281 }
5282 run_test 39r "lazy atime update on OST"
5283
5284 test_39q() { # LU-8041
5285         local testdir=$DIR/$tdir
5286         mkdir -p $testdir
5287         multiop_bg_pause $testdir D_c || error "multiop failed"
5288         local multipid=$!
5289         cancel_lru_locks mdc
5290         kill -USR1 $multipid
5291         local atime=$(stat -c %X $testdir)
5292         [ "$atime" -ne 0 ] || error "atime is zero"
5293 }
5294 run_test 39q "close won't zero out atime"
5295
5296 test_39s() {
5297         local atime0
5298         local atime1
5299         local atime2
5300         local atime3
5301         local atime4
5302
5303         umount_client $MOUNT
5304         mount_client $MOUNT relatime
5305
5306         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5307         atime0=$(stat -c %X $DIR/$tfile)
5308
5309         # First read updates atime
5310         sleep 1
5311         cat $DIR/$tfile >/dev/null
5312         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5313
5314         # Next reads do not update atime
5315         sleep 1
5316         cat $DIR/$tfile >/dev/null
5317         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5318
5319         # If mtime is greater than atime, atime is updated
5320         sleep 1
5321         touch -m $DIR/$tfile # (mtime = now)
5322         sleep 1
5323         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5324         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5325
5326         # Next reads do not update atime
5327         sleep 1
5328         cat $DIR/$tfile >/dev/null
5329         atime4=$(stat -c %X $DIR/$tfile)
5330
5331         # Remount the client to clear 'relatime' option
5332         remount_client $MOUNT
5333
5334         (( atime0 < atime1 )) ||
5335                 error "atime $atime0 should be smaller than $atime1"
5336         (( atime1 == atime2 )) ||
5337                 error "atime $atime1 was updated to $atime2"
5338         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5339         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5340 }
5341 run_test 39s "relatime is supported"
5342
5343 test_40() {
5344         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5345         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5346                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5347         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5348                 error "$tfile is not 4096 bytes in size"
5349 }
5350 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5351
5352 test_41() {
5353         # bug 1553
5354         small_write $DIR/f41 18
5355 }
5356 run_test 41 "test small file write + fstat ====================="
5357
5358 count_ost_writes() {
5359         lctl get_param -n ${OSC}.*.stats |
5360                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5361                         END { printf("%0.0f", writes) }'
5362 }
5363
5364 # decent default
5365 WRITEBACK_SAVE=500
5366 DIRTY_RATIO_SAVE=40
5367 MAX_DIRTY_RATIO=50
5368 BG_DIRTY_RATIO_SAVE=10
5369 MAX_BG_DIRTY_RATIO=25
5370
5371 start_writeback() {
5372         trap 0
5373         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5374         # dirty_ratio, dirty_background_ratio
5375         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5376                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5377                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5378                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5379         else
5380                 # if file not here, we are a 2.4 kernel
5381                 kill -CONT `pidof kupdated`
5382         fi
5383 }
5384
5385 stop_writeback() {
5386         # setup the trap first, so someone cannot exit the test at the
5387         # exact wrong time and mess up a machine
5388         trap start_writeback EXIT
5389         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5390         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5391                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5392                 sysctl -w vm.dirty_writeback_centisecs=0
5393                 sysctl -w vm.dirty_writeback_centisecs=0
5394                 # save and increase /proc/sys/vm/dirty_ratio
5395                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5396                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5397                 # save and increase /proc/sys/vm/dirty_background_ratio
5398                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5399                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5400         else
5401                 # if file not here, we are a 2.4 kernel
5402                 kill -STOP `pidof kupdated`
5403         fi
5404 }
5405
5406 # ensure that all stripes have some grant before we test client-side cache
5407 setup_test42() {
5408         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5409                 dd if=/dev/zero of=$i bs=4k count=1
5410                 rm $i
5411         done
5412 }
5413
5414 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5415 # file truncation, and file removal.
5416 test_42a() {
5417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5418
5419         setup_test42
5420         cancel_lru_locks $OSC
5421         stop_writeback
5422         sync; sleep 1; sync # just to be safe
5423         BEFOREWRITES=`count_ost_writes`
5424         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5425         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5426         AFTERWRITES=`count_ost_writes`
5427         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5428                 error "$BEFOREWRITES < $AFTERWRITES"
5429         start_writeback
5430 }
5431 run_test 42a "ensure that we don't flush on close"
5432
5433 test_42b() {
5434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5435
5436         setup_test42
5437         cancel_lru_locks $OSC
5438         stop_writeback
5439         sync
5440         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5441         BEFOREWRITES=$(count_ost_writes)
5442         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5443         AFTERWRITES=$(count_ost_writes)
5444         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5445                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5446         fi
5447         BEFOREWRITES=$(count_ost_writes)
5448         sync || error "sync: $?"
5449         AFTERWRITES=$(count_ost_writes)
5450         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5451                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5452         fi
5453         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5454         start_writeback
5455         return 0
5456 }
5457 run_test 42b "test destroy of file with cached dirty data ======"
5458
5459 # if these tests just want to test the effect of truncation,
5460 # they have to be very careful.  consider:
5461 # - the first open gets a {0,EOF}PR lock
5462 # - the first write conflicts and gets a {0, count-1}PW
5463 # - the rest of the writes are under {count,EOF}PW
5464 # - the open for truncate tries to match a {0,EOF}PR
5465 #   for the filesize and cancels the PWs.
5466 # any number of fixes (don't get {0,EOF} on open, match
5467 # composite locks, do smarter file size management) fix
5468 # this, but for now we want these tests to verify that
5469 # the cancellation with truncate intent works, so we
5470 # start the file with a full-file pw lock to match against
5471 # until the truncate.
5472 trunc_test() {
5473         test=$1
5474         file=$DIR/$test
5475         offset=$2
5476         cancel_lru_locks $OSC
5477         stop_writeback
5478         # prime the file with 0,EOF PW to match
5479         touch $file
5480         $TRUNCATE $file 0
5481         sync; sync
5482         # now the real test..
5483         dd if=/dev/zero of=$file bs=1024 count=100
5484         BEFOREWRITES=`count_ost_writes`
5485         $TRUNCATE $file $offset
5486         cancel_lru_locks $OSC
5487         AFTERWRITES=`count_ost_writes`
5488         start_writeback
5489 }
5490
5491 test_42c() {
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493
5494         trunc_test 42c 1024
5495         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5496                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5497         rm $file
5498 }
5499 run_test 42c "test partial truncate of file with cached dirty data"
5500
5501 test_42d() {
5502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5503
5504         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5505         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5506         $LCTL set_param debug=+cache
5507
5508         trunc_test 42d 0
5509         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5510                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5511         rm $file
5512 }
5513 run_test 42d "test complete truncate of file with cached dirty data"
5514
5515 test_42e() { # bug22074
5516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5517
5518         local TDIR=$DIR/${tdir}e
5519         local pages=16 # hardcoded 16 pages, don't change it.
5520         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5521         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5522         local max_dirty_mb
5523         local warmup_files
5524
5525         test_mkdir $DIR/${tdir}e
5526         $LFS setstripe -c 1 $TDIR
5527         createmany -o $TDIR/f $files
5528
5529         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5530
5531         # we assume that with $OSTCOUNT files, at least one of them will
5532         # be allocated on OST0.
5533         warmup_files=$((OSTCOUNT * max_dirty_mb))
5534         createmany -o $TDIR/w $warmup_files
5535
5536         # write a large amount of data into one file and sync, to get good
5537         # avail_grant number from OST.
5538         for ((i=0; i<$warmup_files; i++)); do
5539                 idx=$($LFS getstripe -i $TDIR/w$i)
5540                 [ $idx -ne 0 ] && continue
5541                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5542                 break
5543         done
5544         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5545         sync
5546         $LCTL get_param $proc_osc0/cur_dirty_bytes
5547         $LCTL get_param $proc_osc0/cur_grant_bytes
5548
5549         # create as much dirty pages as we can while not to trigger the actual
5550         # RPCs directly. but depends on the env, VFS may trigger flush during this
5551         # period, hopefully we are good.
5552         for ((i=0; i<$warmup_files; i++)); do
5553                 idx=$($LFS getstripe -i $TDIR/w$i)
5554                 [ $idx -ne 0 ] && continue
5555                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5556         done
5557         $LCTL get_param $proc_osc0/cur_dirty_bytes
5558         $LCTL get_param $proc_osc0/cur_grant_bytes
5559
5560         # perform the real test
5561         $LCTL set_param $proc_osc0/rpc_stats 0
5562         for ((;i<$files; i++)); do
5563                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5564                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5565         done
5566         sync
5567         $LCTL get_param $proc_osc0/rpc_stats
5568
5569         local percent=0
5570         local have_ppr=false
5571         $LCTL get_param $proc_osc0/rpc_stats |
5572                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5573                         # skip lines until we are at the RPC histogram data
5574                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5575                         $have_ppr || continue
5576
5577                         # we only want the percent stat for < 16 pages
5578                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5579
5580                         percent=$((percent + WPCT))
5581                         if [[ $percent -gt 15 ]]; then
5582                                 error "less than 16-pages write RPCs" \
5583                                       "$percent% > 15%"
5584                                 break
5585                         fi
5586                 done
5587         rm -rf $TDIR
5588 }
5589 run_test 42e "verify sub-RPC writes are not done synchronously"
5590
5591 test_43A() { # was test_43
5592         test_mkdir $DIR/$tdir
5593         cp -p /bin/ls $DIR/$tdir/$tfile
5594         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5595         pid=$!
5596         # give multiop a chance to open
5597         sleep 1
5598
5599         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5600         kill -USR1 $pid
5601         # Wait for multiop to exit
5602         wait $pid
5603 }
5604 run_test 43A "execution of file opened for write should return -ETXTBSY"
5605
5606 test_43a() {
5607         test_mkdir $DIR/$tdir
5608         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5609         $DIR/$tdir/sleep 60 &
5610         SLEEP_PID=$!
5611         # Make sure exec of $tdir/sleep wins race with truncate
5612         sleep 1
5613         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5614         kill $SLEEP_PID
5615 }
5616 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5617
5618 test_43b() {
5619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5620
5621         test_mkdir $DIR/$tdir
5622         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5623         $DIR/$tdir/sleep 60 &
5624         SLEEP_PID=$!
5625         # Make sure exec of $tdir/sleep wins race with truncate
5626         sleep 1
5627         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5628         kill $SLEEP_PID
5629 }
5630 run_test 43b "truncate of file being executed should return -ETXTBSY"
5631
5632 test_43c() {
5633         local testdir="$DIR/$tdir"
5634         test_mkdir $testdir
5635         cp $SHELL $testdir/
5636         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5637                 ( cd $testdir && md5sum -c )
5638 }
5639 run_test 43c "md5sum of copy into lustre"
5640
5641 test_44A() { # was test_44
5642         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5643
5644         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5645         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5646 }
5647 run_test 44A "zero length read from a sparse stripe"
5648
5649 test_44a() {
5650         local nstripe=$($LFS getstripe -c -d $DIR)
5651         [ -z "$nstripe" ] && skip "can't get stripe info"
5652         [[ $nstripe -gt $OSTCOUNT ]] &&
5653                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5654
5655         local stride=$($LFS getstripe -S -d $DIR)
5656         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5657                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5658         fi
5659
5660         OFFSETS="0 $((stride/2)) $((stride-1))"
5661         for offset in $OFFSETS; do
5662                 for i in $(seq 0 $((nstripe-1))); do
5663                         local GLOBALOFFSETS=""
5664                         # size in Bytes
5665                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5666                         local myfn=$DIR/d44a-$size
5667                         echo "--------writing $myfn at $size"
5668                         ll_sparseness_write $myfn $size ||
5669                                 error "ll_sparseness_write"
5670                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5671                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5672                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5673
5674                         for j in $(seq 0 $((nstripe-1))); do
5675                                 # size in Bytes
5676                                 size=$((((j + $nstripe )*$stride + $offset)))
5677                                 ll_sparseness_write $myfn $size ||
5678                                         error "ll_sparseness_write"
5679                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5680                         done
5681                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5682                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5683                         rm -f $myfn
5684                 done
5685         done
5686 }
5687 run_test 44a "test sparse pwrite ==============================="
5688
5689 dirty_osc_total() {
5690         tot=0
5691         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5692                 tot=$(($tot + $d))
5693         done
5694         echo $tot
5695 }
5696 do_dirty_record() {
5697         before=`dirty_osc_total`
5698         echo executing "\"$*\""
5699         eval $*
5700         after=`dirty_osc_total`
5701         echo before $before, after $after
5702 }
5703 test_45() {
5704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5705
5706         f="$DIR/f45"
5707         # Obtain grants from OST if it supports it
5708         echo blah > ${f}_grant
5709         stop_writeback
5710         sync
5711         do_dirty_record "echo blah > $f"
5712         [[ $before -eq $after ]] && error "write wasn't cached"
5713         do_dirty_record "> $f"
5714         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5715         do_dirty_record "echo blah > $f"
5716         [[ $before -eq $after ]] && error "write wasn't cached"
5717         do_dirty_record "sync"
5718         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5719         do_dirty_record "echo blah > $f"
5720         [[ $before -eq $after ]] && error "write wasn't cached"
5721         do_dirty_record "cancel_lru_locks osc"
5722         [[ $before -gt $after ]] ||
5723                 error "lock cancellation didn't lower dirty count"
5724         start_writeback
5725 }
5726 run_test 45 "osc io page accounting ============================"
5727
5728 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5729 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5730 # objects offset and an assert hit when an rpc was built with 1023's mapped
5731 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5732 test_46() {
5733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5734
5735         f="$DIR/f46"
5736         stop_writeback
5737         sync
5738         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5739         sync
5740         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5741         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5742         sync
5743         start_writeback
5744 }
5745 run_test 46 "dirtying a previously written page ================"
5746
5747 # test_47 is removed "Device nodes check" is moved to test_28
5748
5749 test_48a() { # bug 2399
5750         [ "$mds1_FSTYPE" = "zfs" ] &&
5751         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5752                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5753
5754         test_mkdir $DIR/$tdir
5755         cd $DIR/$tdir
5756         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5757         test_mkdir $DIR/$tdir
5758         touch foo || error "'touch foo' failed after recreating cwd"
5759         test_mkdir bar
5760         touch .foo || error "'touch .foo' failed after recreating cwd"
5761         test_mkdir .bar
5762         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5763         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5764         cd . || error "'cd .' failed after recreating cwd"
5765         mkdir . && error "'mkdir .' worked after recreating cwd"
5766         rmdir . && error "'rmdir .' worked after recreating cwd"
5767         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5768         cd .. || error "'cd ..' failed after recreating cwd"
5769 }
5770 run_test 48a "Access renamed working dir (should return errors)="
5771
5772 test_48b() { # bug 2399
5773         rm -rf $DIR/$tdir
5774         test_mkdir $DIR/$tdir
5775         cd $DIR/$tdir
5776         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5777         touch foo && error "'touch foo' worked after removing cwd"
5778         mkdir foo && error "'mkdir foo' worked after removing cwd"
5779         touch .foo && error "'touch .foo' worked after removing cwd"
5780         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5781         ls . > /dev/null && error "'ls .' worked after removing cwd"
5782         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5783         mkdir . && error "'mkdir .' worked after removing cwd"
5784         rmdir . && error "'rmdir .' worked after removing cwd"
5785         ln -s . foo && error "'ln -s .' worked after removing cwd"
5786         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5787 }
5788 run_test 48b "Access removed working dir (should return errors)="
5789
5790 test_48c() { # bug 2350
5791         #lctl set_param debug=-1
5792         #set -vx
5793         rm -rf $DIR/$tdir
5794         test_mkdir -p $DIR/$tdir/dir
5795         cd $DIR/$tdir/dir
5796         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5797         $TRACE touch foo && error "touch foo worked after removing cwd"
5798         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5799         touch .foo && error "touch .foo worked after removing cwd"
5800         mkdir .foo && error "mkdir .foo worked after removing cwd"
5801         $TRACE ls . && error "'ls .' worked after removing cwd"
5802         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5803         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5804         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5805         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5806         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5807 }
5808 run_test 48c "Access removed working subdir (should return errors)"
5809
5810 test_48d() { # bug 2350
5811         #lctl set_param debug=-1
5812         #set -vx
5813         rm -rf $DIR/$tdir
5814         test_mkdir -p $DIR/$tdir/dir
5815         cd $DIR/$tdir/dir
5816         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5817         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5818         $TRACE touch foo && error "'touch foo' worked after removing parent"
5819         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5820         touch .foo && error "'touch .foo' worked after removing parent"
5821         mkdir .foo && error "mkdir .foo worked after removing parent"
5822         $TRACE ls . && error "'ls .' worked after removing parent"
5823         $TRACE ls .. && error "'ls ..' worked after removing parent"
5824         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5825         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5826         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5827         true
5828 }
5829 run_test 48d "Access removed parent subdir (should return errors)"
5830
5831 test_48e() { # bug 4134
5832         #lctl set_param debug=-1
5833         #set -vx
5834         rm -rf $DIR/$tdir
5835         test_mkdir -p $DIR/$tdir/dir
5836         cd $DIR/$tdir/dir
5837         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5838         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5839         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5840         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5841         # On a buggy kernel addition of "touch foo" after cd .. will
5842         # produce kernel oops in lookup_hash_it
5843         touch ../foo && error "'cd ..' worked after recreate parent"
5844         cd $DIR
5845         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5846 }
5847 run_test 48e "Access to recreated parent subdir (should return errors)"
5848
5849 test_48f() {
5850         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5851                 skip "need MDS >= 2.13.55"
5852         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5853         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5854                 skip "needs different host for mdt1 mdt2"
5855         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5856
5857         $LFS mkdir -i0 $DIR/$tdir
5858         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5859
5860         for d in sub1 sub2 sub3; do
5861                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5862                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5863                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5864         done
5865
5866         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5867 }
5868 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5869
5870 test_49() { # LU-1030
5871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5872         remote_ost_nodsh && skip "remote OST with nodsh"
5873
5874         # get ost1 size - $FSNAME-OST0000
5875         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5876                 awk '{ print $4 }')
5877         # write 800M at maximum
5878         [[ $ost1_size -lt 2 ]] && ost1_size=2
5879         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5880
5881         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5882         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5883         local dd_pid=$!
5884
5885         # change max_pages_per_rpc while writing the file
5886         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5887         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5888         # loop until dd process exits
5889         while ps ax -opid | grep -wq $dd_pid; do
5890                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5891                 sleep $((RANDOM % 5 + 1))
5892         done
5893         # restore original max_pages_per_rpc
5894         $LCTL set_param $osc1_mppc=$orig_mppc
5895         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5896 }
5897 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5898
5899 test_50() {
5900         # bug 1485
5901         test_mkdir $DIR/$tdir
5902         cd $DIR/$tdir
5903         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5904 }
5905 run_test 50 "special situations: /proc symlinks  ==============="
5906
5907 test_51a() {    # was test_51
5908         # bug 1516 - create an empty entry right after ".." then split dir
5909         test_mkdir -c1 $DIR/$tdir
5910         touch $DIR/$tdir/foo
5911         $MCREATE $DIR/$tdir/bar
5912         rm $DIR/$tdir/foo
5913         createmany -m $DIR/$tdir/longfile 201
5914         FNUM=202
5915         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5916                 $MCREATE $DIR/$tdir/longfile$FNUM
5917                 FNUM=$(($FNUM + 1))
5918                 echo -n "+"
5919         done
5920         echo
5921         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5922 }
5923 run_test 51a "special situations: split htree with empty entry =="
5924
5925 cleanup_print_lfs_df () {
5926         trap 0
5927         $LFS df
5928         $LFS df -i
5929 }
5930
5931 test_51b() {
5932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5933
5934         local dir=$DIR/$tdir
5935         local nrdirs=$((65536 + 100))
5936
5937         # cleanup the directory
5938         rm -fr $dir
5939
5940         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5941
5942         $LFS df
5943         $LFS df -i
5944         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5945         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5946         [[ $numfree -lt $nrdirs ]] &&
5947                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5948
5949         # need to check free space for the directories as well
5950         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5951         numfree=$(( blkfree / $(fs_inode_ksize) ))
5952         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5953
5954         trap cleanup_print_lfs_df EXIT
5955
5956         # create files
5957         createmany -d $dir/d $nrdirs || {
5958                 unlinkmany $dir/d $nrdirs
5959                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5960         }
5961
5962         # really created :
5963         nrdirs=$(ls -U $dir | wc -l)
5964
5965         # unlink all but 100 subdirectories, then check it still works
5966         local left=100
5967         local delete=$((nrdirs - left))
5968
5969         $LFS df
5970         $LFS df -i
5971
5972         # for ldiskfs the nlink count should be 1, but this is OSD specific
5973         # and so this is listed for informational purposes only
5974         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5975         unlinkmany -d $dir/d $delete ||
5976                 error "unlink of first $delete subdirs failed"
5977
5978         echo "nlink between: $(stat -c %h $dir)"
5979         local found=$(ls -U $dir | wc -l)
5980         [ $found -ne $left ] &&
5981                 error "can't find subdirs: found only $found, expected $left"
5982
5983         unlinkmany -d $dir/d $delete $left ||
5984                 error "unlink of second $left subdirs failed"
5985         # regardless of whether the backing filesystem tracks nlink accurately
5986         # or not, the nlink count shouldn't be more than "." and ".." here
5987         local after=$(stat -c %h $dir)
5988         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5989                 echo "nlink after: $after"
5990
5991         cleanup_print_lfs_df
5992 }
5993 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5994
5995 test_51d_sub() {
5996         local stripecount=$1
5997         local nfiles=$2
5998
5999         log "create files with stripecount=$stripecount"
6000         $LFS setstripe -C $stripecount $DIR/$tdir
6001         createmany -o $DIR/$tdir/t- $nfiles
6002         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6003         for ((n = 0; n < $OSTCOUNT; n++)); do
6004                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6005                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6006                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6007                             '($1 == '$n') { objs += 1 } \
6008                             END { printf("%0.0f", objs) }')
6009                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6010         done
6011         unlinkmany $DIR/$tdir/t- $nfiles
6012         rm  -f $TMP/$tfile
6013
6014         local nlast
6015         local min=4
6016         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6017
6018         # For some combinations of stripecount and OSTCOUNT current code
6019         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6020         # than others. Rather than skipping this test entirely, check that
6021         # and keep testing to ensure imbalance does not get worse. LU-15282
6022         (( (OSTCOUNT == 6 && stripecount == 4) ||
6023            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6024            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6025         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6026                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6027                         { $LFS df && $LFS df -i &&
6028                         error "stripecount=$stripecount: " \
6029                               "OST $n has fewer objects vs. OST $nlast " \
6030                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6031                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6032                         { $LFS df && $LFS df -i &&
6033                         error "stripecount=$stripecount: " \
6034                               "OST $n has more objects vs. OST $nlast " \
6035                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6036
6037                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6038                         { $LFS df && $LFS df -i &&
6039                         error "stripecount=$stripecount: " \
6040                               "OST $n has fewer #0 objects vs. OST $nlast " \
6041                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6042                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6043                         { $LFS df && $LFS df -i &&
6044                         error "stripecount=$stripecount: " \
6045                               "OST $n has more #0 objects vs. OST $nlast " \
6046                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6047         done
6048 }
6049
6050 test_51d() {
6051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6052         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6053
6054         local stripecount
6055         local per_ost=100
6056         local nfiles=$((per_ost * OSTCOUNT))
6057         local mdts=$(comma_list $(mdts_nodes))
6058         local param="osp.*.create_count"
6059         local qos_old=$(do_facet mds1 \
6060                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6061
6062         do_nodes $mdts \
6063                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6064         stack_trap "do_nodes $mdts \
6065                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6066
6067         test_mkdir $DIR/$tdir
6068         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6069         (( dirstripes > 0 )) || dirstripes=1
6070
6071         # Ensure enough OST objects precreated for tests to pass without
6072         # running out of objects.  This is an LOV r-r OST algorithm test,
6073         # not an OST object precreation test.
6074         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6075         (( old >= nfiles )) ||
6076         {
6077                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6078
6079                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6080                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6081
6082                 # trigger precreation from all MDTs for all OSTs
6083                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6084                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6085                 done
6086         }
6087
6088         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6089                 sleep 8  # allow object precreation to catch up
6090                 test_51d_sub $stripecount $nfiles
6091         done
6092 }
6093 run_test 51d "check LOV round-robin OST object distribution"
6094
6095 test_51e() {
6096         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6097                 skip_env "ldiskfs only test"
6098         fi
6099
6100         test_mkdir -c1 $DIR/$tdir
6101         test_mkdir -c1 $DIR/$tdir/d0
6102
6103         touch $DIR/$tdir/d0/foo
6104         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6105                 error "file exceed 65000 nlink limit!"
6106         unlinkmany $DIR/$tdir/d0/f- 65001
6107         return 0
6108 }
6109 run_test 51e "check file nlink limit"
6110
6111 test_51f() {
6112         test_mkdir $DIR/$tdir
6113
6114         local max=100000
6115         local ulimit_old=$(ulimit -n)
6116         local spare=20 # number of spare fd's for scripts/libraries, etc.
6117         local mdt=$($LFS getstripe -m $DIR/$tdir)
6118         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6119
6120         echo "MDT$mdt numfree=$numfree, max=$max"
6121         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6122         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6123                 while ! ulimit -n $((numfree + spare)); do
6124                         numfree=$((numfree * 3 / 4))
6125                 done
6126                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6127         else
6128                 echo "left ulimit at $ulimit_old"
6129         fi
6130
6131         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6132                 unlinkmany $DIR/$tdir/f $numfree
6133                 error "create+open $numfree files in $DIR/$tdir failed"
6134         }
6135         ulimit -n $ulimit_old
6136
6137         # if createmany exits at 120s there will be fewer than $numfree files
6138         unlinkmany $DIR/$tdir/f $numfree || true
6139 }
6140 run_test 51f "check many open files limit"
6141
6142 test_52a() {
6143         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6144         test_mkdir $DIR/$tdir
6145         touch $DIR/$tdir/foo
6146         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6147         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6148         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6149         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6150         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6151                                         error "link worked"
6152         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6153         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6154         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6155                                                      error "lsattr"
6156         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6157         cp -r $DIR/$tdir $TMP/
6158         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6159 }
6160 run_test 52a "append-only flag test (should return errors)"
6161
6162 test_52b() {
6163         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6164         test_mkdir $DIR/$tdir
6165         touch $DIR/$tdir/foo
6166         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6167         cat test > $DIR/$tdir/foo && error "cat test worked"
6168         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6169         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6170         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6171                                         error "link worked"
6172         echo foo >> $DIR/$tdir/foo && error "echo worked"
6173         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6174         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6175         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6176         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6177                                                         error "lsattr"
6178         chattr -i $DIR/$tdir/foo || error "chattr failed"
6179
6180         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6181 }
6182 run_test 52b "immutable flag test (should return errors) ======="
6183
6184 test_53() {
6185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6186         remote_mds_nodsh && skip "remote MDS with nodsh"
6187         remote_ost_nodsh && skip "remote OST with nodsh"
6188
6189         local param
6190         local param_seq
6191         local ostname
6192         local mds_last
6193         local mds_last_seq
6194         local ost_last
6195         local ost_last_seq
6196         local ost_last_id
6197         local ostnum
6198         local node
6199         local found=false
6200         local support_last_seq=true
6201
6202         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6203                 support_last_seq=false
6204
6205         # only test MDT0000
6206         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6207         local value
6208         for value in $(do_facet $SINGLEMDS \
6209                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6210                 param=$(echo ${value[0]} | cut -d "=" -f1)
6211                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6212
6213                 if $support_last_seq; then
6214                         param_seq=$(echo $param |
6215                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6216                         mds_last_seq=$(do_facet $SINGLEMDS \
6217                                        $LCTL get_param -n $param_seq)
6218                 fi
6219                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6220
6221                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6222                 node=$(facet_active_host ost$((ostnum+1)))
6223                 param="obdfilter.$ostname.last_id"
6224                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6225                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6226                         ost_last_id=$ost_last
6227
6228                         if $support_last_seq; then
6229                                 ost_last_id=$(echo $ost_last |
6230                                               awk -F':' '{print $2}' |
6231                                               sed -e "s/^0x//g")
6232                                 ost_last_seq=$(echo $ost_last |
6233                                                awk -F':' '{print $1}')
6234                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6235                         fi
6236
6237                         if [[ $ost_last_id != $mds_last ]]; then
6238                                 error "$ost_last_id != $mds_last"
6239                         else
6240                                 found=true
6241                                 break
6242                         fi
6243                 done
6244         done
6245         $found || error "can not match last_seq/last_id for $mdtosc"
6246         return 0
6247 }
6248 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6249
6250 test_54a() {
6251         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6252
6253         LANG=C $SOCKETSERVER $DIR/socket ||
6254                 error "$SOCKETSERVER $DIR/socket failed: $?"
6255         LANG=C $SOCKETCLIENT $DIR/socket ||
6256                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6257         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6258 }
6259 run_test 54a "unix domain socket test =========================="
6260
6261 test_54b() {
6262         f="$DIR/f54b"
6263         mknod $f c 1 3
6264         chmod 0666 $f
6265         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6266 }
6267 run_test 54b "char device works in lustre ======================"
6268
6269 find_loop_dev() {
6270         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6271         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6272         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6273
6274         for i in $(seq 3 7); do
6275                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6276                 LOOPDEV=$LOOPBASE$i
6277                 LOOPNUM=$i
6278                 break
6279         done
6280 }
6281
6282 cleanup_54c() {
6283         local rc=0
6284         loopdev="$DIR/loop54c"
6285
6286         trap 0
6287         $UMOUNT $DIR/$tdir || rc=$?
6288         losetup -d $loopdev || true
6289         losetup -d $LOOPDEV || true
6290         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6291         return $rc
6292 }
6293
6294 test_54c() {
6295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6296
6297         loopdev="$DIR/loop54c"
6298
6299         find_loop_dev
6300         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6301         trap cleanup_54c EXIT
6302         mknod $loopdev b 7 $LOOPNUM
6303         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6304         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6305         losetup $loopdev $DIR/$tfile ||
6306                 error "can't set up $loopdev for $DIR/$tfile"
6307         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6308         test_mkdir $DIR/$tdir
6309         mount -t ext2 $loopdev $DIR/$tdir ||
6310                 error "error mounting $loopdev on $DIR/$tdir"
6311         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6312                 error "dd write"
6313         df $DIR/$tdir
6314         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6315                 error "dd read"
6316         cleanup_54c
6317 }
6318 run_test 54c "block device works in lustre ====================="
6319
6320 test_54d() {
6321         local pipe="$DIR/$tfile.pipe"
6322         local string="aaaaaa"
6323
6324         mknod $pipe p
6325         echo -n "$string" > $pipe &
6326         local result=$(cat $pipe)
6327         [[ "$result" == "$string" ]] || error "$result != $string"
6328 }
6329 run_test 54d "fifo device works in lustre ======================"
6330
6331 test_54e() {
6332         f="$DIR/f54e"
6333         string="aaaaaa"
6334         cp -aL /dev/console $f
6335         echo $string > $f || error "echo $string to $f failed"
6336 }
6337 run_test 54e "console/tty device works in lustre ======================"
6338
6339 test_55a() {
6340         local dev_path="/sys/kernel/debug/lustre/devices"
6341
6342         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6343
6344         # This must be run in iteractive mode, since attach and setup
6345         # are stateful
6346         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6347                 attach obd_test obd_name obd_uuid
6348                 setup obd_test
6349         EOF"
6350
6351         echo "Devices:"
6352         cat "$dev_path" | tail -n 10
6353
6354         $LCTL --device "obd_name" cleanup
6355         $LCTL --device "obd_name" detach
6356
6357         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6358                 error "OBD unit test failed"
6359
6360         rmmod -v obd_test ||
6361                 error "rmmod failed (may trigger a failure in a later test)"
6362 }
6363 run_test 55a "OBD device life cycle unit tests"
6364
6365 test_55b() {
6366         local dev_path="/sys/kernel/debug/lustre/devices"
6367         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6368         local num_dev_to_create="$((8192 - $dev_count))"
6369
6370         load_module obdclass/obd_test || error "load_module failed"
6371
6372         local start=$SECONDS
6373
6374         # This must be run in iteractive mode, since attach and setup
6375         # are stateful
6376         for ((i = 1; i <= num_dev_to_create; i++)); do
6377                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6378                 echo "setup obd_test_$i"
6379         done | $LCTL || error "OBD device creation failed"
6380
6381         echo "Load time: $((SECONDS - start))"
6382         echo "Devices:"
6383         cat "$dev_path" | tail -n 10
6384
6385         for ((i = 1; i <= num_dev_to_create; i++)); do
6386                 echo "--device obd_name_$i cleanup"
6387                 echo "--device obd_name_$i detach"
6388         done | $LCTL || error "OBD device cleanup failed"
6389
6390         echo "Unload time: $((SECONDS - start))"
6391
6392         rmmod -v obd_test ||
6393                 error "rmmod failed (may trigger a failure in a later test)"
6394 }
6395 run_test 55b "Load and unload max OBD devices"
6396
6397 test_56a() {
6398         local numfiles=3
6399         local numdirs=2
6400         local dir=$DIR/$tdir
6401
6402         rm -rf $dir
6403         test_mkdir -p $dir/dir
6404         for i in $(seq $numfiles); do
6405                 touch $dir/file$i
6406                 touch $dir/dir/file$i
6407         done
6408
6409         local numcomp=$($LFS getstripe --component-count $dir)
6410
6411         [[ $numcomp == 0 ]] && numcomp=1
6412
6413         # test lfs getstripe with --recursive
6414         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6415
6416         [[ $filenum -eq $((numfiles * 2)) ]] ||
6417                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6418         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6419         [[ $filenum -eq $numfiles ]] ||
6420                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6421         echo "$LFS getstripe showed obdidx or l_ost_idx"
6422
6423         # test lfs getstripe with file instead of dir
6424         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6425         [[ $filenum -eq 1 ]] ||
6426                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6427         echo "$LFS getstripe file1 passed"
6428
6429         #test lfs getstripe with --verbose
6430         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6431         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6432                 error "$LFS getstripe --verbose $dir: "\
6433                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6434         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6435                 error "$LFS getstripe $dir: showed lmm_magic"
6436
6437         #test lfs getstripe with -v prints lmm_fid
6438         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6439         local countfids=$((numdirs + numfiles * numcomp))
6440         [[ $filenum -eq $countfids ]] ||
6441                 error "$LFS getstripe -v $dir: "\
6442                       "got $filenum want $countfids lmm_fid"
6443         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6444                 error "$LFS getstripe $dir: showed lmm_fid by default"
6445         echo "$LFS getstripe --verbose passed"
6446
6447         #check for FID information
6448         local fid1=$($LFS getstripe --fid $dir/file1)
6449         local fid2=$($LFS getstripe --verbose $dir/file1 |
6450                      awk '/lmm_fid: / { print $2; exit; }')
6451         local fid3=$($LFS path2fid $dir/file1)
6452
6453         [ "$fid1" != "$fid2" ] &&
6454                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6455         [ "$fid1" != "$fid3" ] &&
6456                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6457         echo "$LFS getstripe --fid passed"
6458
6459         #test lfs getstripe with --obd
6460         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6461                 error "$LFS getstripe --obd wrong_uuid: should return error"
6462
6463         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6464
6465         local ostidx=1
6466         local obduuid=$(ostuuid_from_index $ostidx)
6467         local found=$($LFS getstripe -r --obd $obduuid $dir |
6468                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6469
6470         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6471         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6472                 ((filenum--))
6473         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6474                 ((filenum--))
6475
6476         [[ $found -eq $filenum ]] ||
6477                 error "$LFS getstripe --obd: found $found expect $filenum"
6478         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6479                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6480                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6481                 error "$LFS getstripe --obd: should not show file on other obd"
6482         echo "$LFS getstripe --obd passed"
6483 }
6484 run_test 56a "check $LFS getstripe"
6485
6486 test_56b() {
6487         local dir=$DIR/$tdir
6488         local numdirs=3
6489
6490         test_mkdir $dir
6491         for i in $(seq $numdirs); do
6492                 test_mkdir $dir/dir$i
6493         done
6494
6495         # test lfs getdirstripe default mode is non-recursion, which is
6496         # different from lfs getstripe
6497         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6498
6499         [[ $dircnt -eq 1 ]] ||
6500                 error "$LFS getdirstripe: found $dircnt, not 1"
6501         dircnt=$($LFS getdirstripe --recursive $dir |
6502                 grep -c lmv_stripe_count)
6503         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6504                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6505 }
6506 run_test 56b "check $LFS getdirstripe"
6507
6508 test_56bb() {
6509         verify_yaml_available || skip_env "YAML verification not installed"
6510         local output_file=$DIR/$tfile.out
6511
6512         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6513
6514         cat $output_file
6515         cat $output_file | verify_yaml || error "layout is not valid YAML"
6516 }
6517 run_test 56bb "check $LFS getdirstripe layout is YAML"
6518
6519 test_56c() {
6520         remote_ost_nodsh && skip "remote OST with nodsh"
6521
6522         local ost_idx=0
6523         local ost_name=$(ostname_from_index $ost_idx)
6524         local old_status=$(ost_dev_status $ost_idx)
6525         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6526
6527         [[ -z "$old_status" ]] ||
6528                 skip_env "OST $ost_name is in $old_status status"
6529
6530         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6531         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6532                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6533         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6534                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6535                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6536         fi
6537
6538         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6539                 error "$LFS df -v showing inactive devices"
6540         sleep_maxage
6541
6542         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6543
6544         [[ "$new_status" =~ "D" ]] ||
6545                 error "$ost_name status is '$new_status', missing 'D'"
6546         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6547                 [[ "$new_status" =~ "N" ]] ||
6548                         error "$ost_name status is '$new_status', missing 'N'"
6549         fi
6550         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6551                 [[ "$new_status" =~ "f" ]] ||
6552                         error "$ost_name status is '$new_status', missing 'f'"
6553         fi
6554
6555         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6556         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6557                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6558         [[ -z "$p" ]] && restore_lustre_params < $p || true
6559         sleep_maxage
6560
6561         new_status=$(ost_dev_status $ost_idx)
6562         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6563                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6564         # can't check 'f' as devices may actually be on flash
6565 }
6566 run_test 56c "check 'lfs df' showing device status"
6567
6568 test_56d() {
6569         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6570         local osts=$($LFS df -v $MOUNT | grep -c OST)
6571
6572         $LFS df $MOUNT
6573
6574         (( mdts == MDSCOUNT )) ||
6575                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6576         (( osts == OSTCOUNT )) ||
6577                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6578 }
6579 run_test 56d "'lfs df -v' prints only configured devices"
6580
6581 test_56e() {
6582         err_enoent=2 # No such file or directory
6583         err_eopnotsupp=95 # Operation not supported
6584
6585         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6586         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6587
6588         # Check for handling of path not exists
6589         output=$($LFS df $enoent_mnt 2>&1)
6590         ret=$?
6591
6592         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6593         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6594                 error "expect failure $err_enoent, not $ret"
6595
6596         # Check for handling of non-Lustre FS
6597         output=$($LFS df $notsup_mnt)
6598         ret=$?
6599
6600         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6601         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6602                 error "expect success $err_eopnotsupp, not $ret"
6603
6604         # Check for multiple LustreFS argument
6605         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6606         ret=$?
6607
6608         [[ $output -eq 3 && $ret -eq 0 ]] ||
6609                 error "expect success 3, not $output, rc = $ret"
6610
6611         # Check for correct non-Lustre FS handling among multiple
6612         # LustreFS argument
6613         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6614                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6615         ret=$?
6616
6617         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6618                 error "expect success 2, not $output, rc = $ret"
6619 }
6620 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6621
6622 NUMFILES=3
6623 NUMDIRS=3
6624 setup_56() {
6625         local local_tdir="$1"
6626         local local_numfiles="$2"
6627         local local_numdirs="$3"
6628         local dir_params="$4"
6629         local dir_stripe_params="$5"
6630
6631         if [ ! -d "$local_tdir" ] ; then
6632                 test_mkdir -p $dir_stripe_params $local_tdir
6633                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6634                 for i in $(seq $local_numfiles) ; do
6635                         touch $local_tdir/file$i
6636                 done
6637                 for i in $(seq $local_numdirs) ; do
6638                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6639                         for j in $(seq $local_numfiles) ; do
6640                                 touch $local_tdir/dir$i/file$j
6641                         done
6642                 done
6643         fi
6644 }
6645
6646 setup_56_special() {
6647         local local_tdir=$1
6648         local local_numfiles=$2
6649         local local_numdirs=$3
6650
6651         setup_56 $local_tdir $local_numfiles $local_numdirs
6652
6653         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6654                 for i in $(seq $local_numfiles) ; do
6655                         mknod $local_tdir/loop${i}b b 7 $i
6656                         mknod $local_tdir/null${i}c c 1 3
6657                         ln -s $local_tdir/file1 $local_tdir/link${i}
6658                 done
6659                 for i in $(seq $local_numdirs) ; do
6660                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6661                         mknod $local_tdir/dir$i/null${i}c c 1 3
6662                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6663                 done
6664         fi
6665 }
6666
6667 test_56g() {
6668         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6669         local expected=$(($NUMDIRS + 2))
6670
6671         setup_56 $dir $NUMFILES $NUMDIRS
6672
6673         # test lfs find with -name
6674         for i in $(seq $NUMFILES) ; do
6675                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6676
6677                 [ $nums -eq $expected ] ||
6678                         error "lfs find -name '*$i' $dir wrong: "\
6679                               "found $nums, expected $expected"
6680         done
6681 }
6682 run_test 56g "check lfs find -name"
6683
6684 test_56h() {
6685         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6686         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6687
6688         setup_56 $dir $NUMFILES $NUMDIRS
6689
6690         # test lfs find with ! -name
6691         for i in $(seq $NUMFILES) ; do
6692                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6693
6694                 [ $nums -eq $expected ] ||
6695                         error "lfs find ! -name '*$i' $dir wrong: "\
6696                               "found $nums, expected $expected"
6697         done
6698 }
6699 run_test 56h "check lfs find ! -name"
6700
6701 test_56i() {
6702         local dir=$DIR/$tdir
6703
6704         test_mkdir $dir
6705
6706         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6707         local out=$($cmd)
6708
6709         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6710 }
6711 run_test 56i "check 'lfs find -ost UUID' skips directories"
6712
6713 test_56j() {
6714         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6715
6716         setup_56_special $dir $NUMFILES $NUMDIRS
6717
6718         local expected=$((NUMDIRS + 1))
6719         local cmd="$LFS find -type d $dir"
6720         local nums=$($cmd | wc -l)
6721
6722         [ $nums -eq $expected ] ||
6723                 error "'$cmd' wrong: found $nums, expected $expected"
6724 }
6725 run_test 56j "check lfs find -type d"
6726
6727 test_56k() {
6728         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6729
6730         setup_56_special $dir $NUMFILES $NUMDIRS
6731
6732         local expected=$(((NUMDIRS + 1) * NUMFILES))
6733         local cmd="$LFS find -type f $dir"
6734         local nums=$($cmd | wc -l)
6735
6736         [ $nums -eq $expected ] ||
6737                 error "'$cmd' wrong: found $nums, expected $expected"
6738 }
6739 run_test 56k "check lfs find -type f"
6740
6741 test_56l() {
6742         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6743
6744         setup_56_special $dir $NUMFILES $NUMDIRS
6745
6746         local expected=$((NUMDIRS + NUMFILES))
6747         local cmd="$LFS find -type b $dir"
6748         local nums=$($cmd | wc -l)
6749
6750         [ $nums -eq $expected ] ||
6751                 error "'$cmd' wrong: found $nums, expected $expected"
6752 }
6753 run_test 56l "check lfs find -type b"
6754
6755 test_56m() {
6756         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6757
6758         setup_56_special $dir $NUMFILES $NUMDIRS
6759
6760         local expected=$((NUMDIRS + NUMFILES))
6761         local cmd="$LFS find -type c $dir"
6762         local nums=$($cmd | wc -l)
6763         [ $nums -eq $expected ] ||
6764                 error "'$cmd' wrong: found $nums, expected $expected"
6765 }
6766 run_test 56m "check lfs find -type c"
6767
6768 test_56n() {
6769         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6770         setup_56_special $dir $NUMFILES $NUMDIRS
6771
6772         local expected=$((NUMDIRS + NUMFILES))
6773         local cmd="$LFS find -type l $dir"
6774         local nums=$($cmd | wc -l)
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778 }
6779 run_test 56n "check lfs find -type l"
6780
6781 test_56o() {
6782         local dir=$DIR/$tdir
6783
6784         setup_56 $dir $NUMFILES $NUMDIRS
6785         utime $dir/file1 > /dev/null || error "utime (1)"
6786         utime $dir/file2 > /dev/null || error "utime (2)"
6787         utime $dir/dir1 > /dev/null || error "utime (3)"
6788         utime $dir/dir2 > /dev/null || error "utime (4)"
6789         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6790         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6791
6792         local expected=4
6793         local nums=$($LFS find -mtime +0 $dir | wc -l)
6794
6795         [ $nums -eq $expected ] ||
6796                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6797
6798         expected=12
6799         cmd="$LFS find -mtime 0 $dir"
6800         nums=$($cmd | wc -l)
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803 }
6804 run_test 56o "check lfs find -mtime for old files"
6805
6806 test_56ob() {
6807         local dir=$DIR/$tdir
6808         local expected=1
6809         local count=0
6810
6811         # just to make sure there is something that won't be found
6812         test_mkdir $dir
6813         touch $dir/$tfile.now
6814
6815         for age in year week day hour min; do
6816                 count=$((count + 1))
6817
6818                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6819                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6820                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6821
6822                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6823                 local nums=$($cmd | wc -l)
6824                 [ $nums -eq $expected ] ||
6825                         error "'$cmd' wrong: found $nums, expected $expected"
6826
6827                 cmd="$LFS find $dir -atime $count${age:0:1}"
6828                 nums=$($cmd | wc -l)
6829                 [ $nums -eq $expected ] ||
6830                         error "'$cmd' wrong: found $nums, expected $expected"
6831         done
6832
6833         sleep 2
6834         cmd="$LFS find $dir -ctime +1s -type f"
6835         nums=$($cmd | wc -l)
6836         (( $nums == $count * 2 + 1)) ||
6837                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6838 }
6839 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6840
6841 test_newerXY_base() {
6842         local x=$1
6843         local y=$2
6844         local dir=$DIR/$tdir
6845         local ref
6846         local negref
6847
6848         if [ $y == "t" ]; then
6849                 if [ $x == "b" ]; then
6850                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6851                 else
6852                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6853                 fi
6854         else
6855                 ref=$DIR/$tfile.newer.$x$y
6856                 touch $ref || error "touch $ref failed"
6857         fi
6858
6859         echo "before = $ref"
6860         sleep 2
6861         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6862         sleep 2
6863         if [ $y == "t" ]; then
6864                 if [ $x == "b" ]; then
6865                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6866                 else
6867                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6868                 fi
6869         else
6870                 negref=$DIR/$tfile.negnewer.$x$y
6871                 touch $negref || error "touch $negref failed"
6872         fi
6873
6874         echo "after = $negref"
6875         local cmd="$LFS find $dir -newer$x$y $ref"
6876         local nums=$(eval $cmd | wc -l)
6877         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6878
6879         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6880                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6881
6882         cmd="$LFS find $dir ! -newer$x$y $negref"
6883         nums=$(eval $cmd | wc -l)
6884         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6885                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6886
6887         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6888         nums=$(eval $cmd | wc -l)
6889         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6890                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6891
6892         rm -rf $DIR/*
6893 }
6894
6895 test_56oc() {
6896         test_newerXY_base "a" "a"
6897         test_newerXY_base "a" "m"
6898         test_newerXY_base "a" "c"
6899         test_newerXY_base "m" "a"
6900         test_newerXY_base "m" "m"
6901         test_newerXY_base "m" "c"
6902         test_newerXY_base "c" "a"
6903         test_newerXY_base "c" "m"
6904         test_newerXY_base "c" "c"
6905
6906         test_newerXY_base "a" "t"
6907         test_newerXY_base "m" "t"
6908         test_newerXY_base "c" "t"
6909
6910         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6911            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6912                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6913
6914         test_newerXY_base "b" "b"
6915         test_newerXY_base "b" "t"
6916 }
6917 run_test 56oc "check lfs find -newerXY work"
6918
6919 test_56od() {
6920         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6921                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6922
6923         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6924                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6925
6926         local dir=$DIR/$tdir
6927         local ref=$DIR/$tfile.ref
6928         local negref=$DIR/$tfile.negref
6929
6930         mkdir $dir || error "mkdir $dir failed"
6931         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6932         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6933         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6934         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6935         touch $ref || error "touch $ref failed"
6936         # sleep 3 seconds at least
6937         sleep 3
6938
6939         local before=$(do_facet mds1 date +%s)
6940         local skew=$(($(date +%s) - before + 1))
6941
6942         if (( skew < 0 && skew > -5 )); then
6943                 sleep $((0 - skew + 1))
6944                 skew=0
6945         fi
6946
6947         # Set the dir stripe params to limit files all on MDT0,
6948         # otherwise we need to calc the max clock skew between
6949         # the client and MDTs.
6950         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6951         sleep 2
6952         touch $negref || error "touch $negref failed"
6953
6954         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6955         local nums=$($cmd | wc -l)
6956         local expected=$(((NUMFILES + 1) * NUMDIRS))
6957
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6962         nums=$($cmd | wc -l)
6963         expected=$((NUMFILES + 1))
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         [ $skew -lt 0 ] && return
6968
6969         local after=$(do_facet mds1 date +%s)
6970         local age=$((after - before + 1 + skew))
6971
6972         cmd="$LFS find $dir -btime -${age}s -type f"
6973         nums=$($cmd | wc -l)
6974         expected=$(((NUMFILES + 1) * NUMDIRS))
6975
6976         echo "Clock skew between client and server: $skew, age:$age"
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=$(($NUMDIRS + 1))
6981         cmd="$LFS find $dir -btime -${age}s -type d"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985         rm -f $ref $negref || error "Failed to remove $ref $negref"
6986 }
6987 run_test 56od "check lfs find -btime with units"
6988
6989 test_56p() {
6990         [ $RUNAS_ID -eq $UID ] &&
6991                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6992
6993         local dir=$DIR/$tdir
6994
6995         setup_56 $dir $NUMFILES $NUMDIRS
6996         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6997
6998         local expected=$NUMFILES
6999         local cmd="$LFS find -uid $RUNAS_ID $dir"
7000         local nums=$($cmd | wc -l)
7001
7002         [ $nums -eq $expected ] ||
7003                 error "'$cmd' wrong: found $nums, expected $expected"
7004
7005         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7006         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7007         nums=$($cmd | wc -l)
7008         [ $nums -eq $expected ] ||
7009                 error "'$cmd' wrong: found $nums, expected $expected"
7010 }
7011 run_test 56p "check lfs find -uid and ! -uid"
7012
7013 test_56q() {
7014         [ $RUNAS_ID -eq $UID ] &&
7015                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7016
7017         local dir=$DIR/$tdir
7018
7019         setup_56 $dir $NUMFILES $NUMDIRS
7020         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7021
7022         local expected=$NUMFILES
7023         local cmd="$LFS find -gid $RUNAS_GID $dir"
7024         local nums=$($cmd | wc -l)
7025
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7030         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034 }
7035 run_test 56q "check lfs find -gid and ! -gid"
7036
7037 test_56r() {
7038         local dir=$DIR/$tdir
7039
7040         setup_56 $dir $NUMFILES $NUMDIRS
7041
7042         local expected=12
7043         local cmd="$LFS find -size 0 -type f -lazy $dir"
7044         local nums=$($cmd | wc -l)
7045
7046         [ $nums -eq $expected ] ||
7047                 error "'$cmd' wrong: found $nums, expected $expected"
7048         cmd="$LFS find -size 0 -type f $dir"
7049         nums=$($cmd | wc -l)
7050         [ $nums -eq $expected ] ||
7051                 error "'$cmd' wrong: found $nums, expected $expected"
7052
7053         expected=0
7054         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7055         nums=$($cmd | wc -l)
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058         cmd="$LFS find ! -size 0 -type f $dir"
7059         nums=$($cmd | wc -l)
7060         [ $nums -eq $expected ] ||
7061                 error "'$cmd' wrong: found $nums, expected $expected"
7062
7063         echo "test" > $dir/$tfile
7064         echo "test2" > $dir/$tfile.2 && sync
7065         expected=1
7066         cmd="$LFS find -size 5 -type f -lazy $dir"
7067         nums=$($cmd | wc -l)
7068         [ $nums -eq $expected ] ||
7069                 error "'$cmd' wrong: found $nums, expected $expected"
7070         cmd="$LFS find -size 5 -type f $dir"
7071         nums=$($cmd | wc -l)
7072         [ $nums -eq $expected ] ||
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074
7075         expected=1
7076         cmd="$LFS find -size +5 -type f -lazy $dir"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         cmd="$LFS find -size +5 -type f $dir"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] ||
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084
7085         expected=2
7086         cmd="$LFS find -size +0 -type f -lazy $dir"
7087         nums=$($cmd | wc -l)
7088         [ $nums -eq $expected ] ||
7089                 error "'$cmd' wrong: found $nums, expected $expected"
7090         cmd="$LFS find -size +0 -type f $dir"
7091         nums=$($cmd | wc -l)
7092         [ $nums -eq $expected ] ||
7093                 error "'$cmd' wrong: found $nums, expected $expected"
7094
7095         expected=2
7096         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7097         nums=$($cmd | wc -l)
7098         [ $nums -eq $expected ] ||
7099                 error "'$cmd' wrong: found $nums, expected $expected"
7100         cmd="$LFS find ! -size -5 -type f $dir"
7101         nums=$($cmd | wc -l)
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         expected=12
7106         cmd="$LFS find -size -5 -type f -lazy $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110         cmd="$LFS find -size -5 -type f $dir"
7111         nums=$($cmd | wc -l)
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114 }
7115 run_test 56r "check lfs find -size works"
7116
7117 test_56ra_sub() {
7118         local expected=$1
7119         local glimpses=$2
7120         local cmd="$3"
7121
7122         cancel_lru_locks $OSC
7123
7124         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7125         local nums=$($cmd | wc -l)
7126
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129
7130         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7131
7132         if (( rpcs_before + glimpses != rpcs_after )); then
7133                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7134                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7135
7136                 if [[ $glimpses == 0 ]]; then
7137                         error "'$cmd' should not send glimpse RPCs to OST"
7138                 else
7139                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7140                 fi
7141         fi
7142 }
7143
7144 test_56ra() {
7145         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7146                 skip "MDS < 2.12.58 doesn't return LSOM data"
7147         local dir=$DIR/$tdir
7148         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7149
7150         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7151
7152         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7153         $LCTL set_param -n llite.*.statahead_agl=0
7154         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7155
7156         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7157         # open and close all files to ensure LSOM is updated
7158         cancel_lru_locks $OSC
7159         find $dir -type f | xargs cat > /dev/null
7160
7161         #   expect_found  glimpse_rpcs  command_to_run
7162         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7163         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7164         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7165         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7166
7167         echo "test" > $dir/$tfile
7168         echo "test2" > $dir/$tfile.2 && sync
7169         cancel_lru_locks $OSC
7170         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7171
7172         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7173         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7174         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7175         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7176
7177         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7178         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7179         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7180         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7181         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7182         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7183 }
7184 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7185
7186 test_56rb() {
7187         local dir=$DIR/$tdir
7188         local tmp=$TMP/$tfile.log
7189         local mdt_idx;
7190
7191         test_mkdir -p $dir || error "failed to mkdir $dir"
7192         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7193                 error "failed to setstripe $dir/$tfile"
7194         mdt_idx=$($LFS getdirstripe -i $dir)
7195         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7196
7197         stack_trap "rm -f $tmp" EXIT
7198         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7199         ! grep -q obd_uuid $tmp ||
7200                 error "failed to find --size +100K --ost 0 $dir"
7201         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7202         ! grep -q obd_uuid $tmp ||
7203                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7204 }
7205 run_test 56rb "check lfs find --size --ost/--mdt works"
7206
7207 test_56rc() {
7208         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7209         local dir=$DIR/$tdir
7210         local found
7211
7212         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7213         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7214         (( $MDSCOUNT > 2 )) &&
7215                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7216         mkdir $dir/$tdir-{1..10}
7217         touch $dir/$tfile-{1..10}
7218
7219         found=$($LFS find $dir --mdt-count 2 | wc -l)
7220         expect=11
7221         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7222
7223         found=$($LFS find $dir -T +1 | wc -l)
7224         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7225         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7226
7227         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7228         expect=11
7229         (( $found == $expect )) || error "found $found all_char, expect $expect"
7230
7231         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7232         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7233         (( $found == $expect )) || error "found $found all_char, expect $expect"
7234 }
7235 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7236
7237 test_56rd() {
7238         local dir=$DIR/$tdir
7239
7240         test_mkdir $dir
7241         rm -f $dir/*
7242
7243         mkfifo $dir/fifo || error "failed to create fifo file"
7244         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7245                 error "should not fail even cannot get projid from pipe file"
7246         found=$($LFS find $dir -t p --printf "%y")
7247         [[ "p" == $found ]] || error "found $found, expect p"
7248
7249         mknod $dir/chardev c 1 5 ||
7250                 error "failed to create character device file"
7251         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7252                 error "should not fail even cannot get projid from chardev file"
7253         found=$($LFS find $dir -t c --printf "%y")
7254         [[ "c" == $found ]] || error "found $found, expect c"
7255
7256         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7257         (( found == 2 )) || error "unable to list all files"
7258 }
7259 run_test 56rd "check lfs find --printf special files"
7260
7261 test_56s() { # LU-611 #LU-9369
7262         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7263
7264         local dir=$DIR/$tdir
7265         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7266
7267         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7268         for i in $(seq $NUMDIRS); do
7269                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7270         done
7271
7272         local expected=$NUMDIRS
7273         local cmd="$LFS find -c $OSTCOUNT $dir"
7274         local nums=$($cmd | wc -l)
7275
7276         [ $nums -eq $expected ] || {
7277                 $LFS getstripe -R $dir
7278                 error "'$cmd' wrong: found $nums, expected $expected"
7279         }
7280
7281         expected=$((NUMDIRS + onestripe))
7282         cmd="$LFS find -stripe-count +0 -type f $dir"
7283         nums=$($cmd | wc -l)
7284         [ $nums -eq $expected ] || {
7285                 $LFS getstripe -R $dir
7286                 error "'$cmd' wrong: found $nums, expected $expected"
7287         }
7288
7289         expected=$onestripe
7290         cmd="$LFS find -stripe-count 1 -type f $dir"
7291         nums=$($cmd | wc -l)
7292         [ $nums -eq $expected ] || {
7293                 $LFS getstripe -R $dir
7294                 error "'$cmd' wrong: found $nums, expected $expected"
7295         }
7296
7297         cmd="$LFS find -stripe-count -2 -type f $dir"
7298         nums=$($cmd | wc -l)
7299         [ $nums -eq $expected ] || {
7300                 $LFS getstripe -R $dir
7301                 error "'$cmd' wrong: found $nums, expected $expected"
7302         }
7303
7304         expected=0
7305         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7306         nums=$($cmd | wc -l)
7307         [ $nums -eq $expected ] || {
7308                 $LFS getstripe -R $dir
7309                 error "'$cmd' wrong: found $nums, expected $expected"
7310         }
7311 }
7312 run_test 56s "check lfs find -stripe-count works"
7313
7314 test_56t() { # LU-611 #LU-9369
7315         local dir=$DIR/$tdir
7316
7317         setup_56 $dir 0 $NUMDIRS
7318         for i in $(seq $NUMDIRS); do
7319                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7320         done
7321
7322         local expected=$NUMDIRS
7323         local cmd="$LFS find -S 8M $dir"
7324         local nums=$($cmd | wc -l)
7325
7326         [ $nums -eq $expected ] || {
7327                 $LFS getstripe -R $dir
7328                 error "'$cmd' wrong: found $nums, expected $expected"
7329         }
7330         rm -rf $dir
7331
7332         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7333
7334         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7335
7336         expected=$(((NUMDIRS + 1) * NUMFILES))
7337         cmd="$LFS find -stripe-size 512k -type f $dir"
7338         nums=$($cmd | wc -l)
7339         [ $nums -eq $expected ] ||
7340                 error "'$cmd' wrong: found $nums, expected $expected"
7341
7342         cmd="$LFS find -stripe-size +320k -type f $dir"
7343         nums=$($cmd | wc -l)
7344         [ $nums -eq $expected ] ||
7345                 error "'$cmd' wrong: found $nums, expected $expected"
7346
7347         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7348         cmd="$LFS find -stripe-size +200k -type f $dir"
7349         nums=$($cmd | wc -l)
7350         [ $nums -eq $expected ] ||
7351                 error "'$cmd' wrong: found $nums, expected $expected"
7352
7353         cmd="$LFS find -stripe-size -640k -type f $dir"
7354         nums=$($cmd | wc -l)
7355         [ $nums -eq $expected ] ||
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357
7358         expected=4
7359         cmd="$LFS find -stripe-size 256k -type f $dir"
7360         nums=$($cmd | wc -l)
7361         [ $nums -eq $expected ] ||
7362                 error "'$cmd' wrong: found $nums, expected $expected"
7363
7364         cmd="$LFS find -stripe-size -320k -type f $dir"
7365         nums=$($cmd | wc -l)
7366         [ $nums -eq $expected ] ||
7367                 error "'$cmd' wrong: found $nums, expected $expected"
7368
7369         expected=0
7370         cmd="$LFS find -stripe-size 1024k -type f $dir"
7371         nums=$($cmd | wc -l)
7372         [ $nums -eq $expected ] ||
7373                 error "'$cmd' wrong: found $nums, expected $expected"
7374 }
7375 run_test 56t "check lfs find -stripe-size works"
7376
7377 test_56u() { # LU-611
7378         local dir=$DIR/$tdir
7379
7380         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7381
7382         if [[ $OSTCOUNT -gt 1 ]]; then
7383                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7384                 onestripe=4
7385         else
7386                 onestripe=0
7387         fi
7388
7389         local expected=$(((NUMDIRS + 1) * NUMFILES))
7390         local cmd="$LFS find -stripe-index 0 -type f $dir"
7391         local nums=$($cmd | wc -l)
7392
7393         [ $nums -eq $expected ] ||
7394                 error "'$cmd' wrong: found $nums, expected $expected"
7395
7396         expected=$onestripe
7397         cmd="$LFS find -stripe-index 1 -type f $dir"
7398         nums=$($cmd | wc -l)
7399         [ $nums -eq $expected ] ||
7400                 error "'$cmd' wrong: found $nums, expected $expected"
7401
7402         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7403         nums=$($cmd | wc -l)
7404         [ $nums -eq $expected ] ||
7405                 error "'$cmd' wrong: found $nums, expected $expected"
7406
7407         expected=0
7408         # This should produce an error and not return any files
7409         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7410         nums=$($cmd 2>/dev/null | wc -l)
7411         [ $nums -eq $expected ] ||
7412                 error "'$cmd' wrong: found $nums, expected $expected"
7413
7414         if [[ $OSTCOUNT -gt 1 ]]; then
7415                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7416                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7417                 nums=$($cmd | wc -l)
7418                 [ $nums -eq $expected ] ||
7419                         error "'$cmd' wrong: found $nums, expected $expected"
7420         fi
7421 }
7422 run_test 56u "check lfs find -stripe-index works"
7423
7424 test_56v() {
7425         local mdt_idx=0
7426         local dir=$DIR/$tdir
7427
7428         setup_56 $dir $NUMFILES $NUMDIRS
7429
7430         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7431         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7432
7433         for file in $($LFS find -m $UUID $dir); do
7434                 file_midx=$($LFS getstripe -m $file)
7435                 [ $file_midx -eq $mdt_idx ] ||
7436                         error "lfs find -m $UUID != getstripe -m $file_midx"
7437         done
7438 }
7439 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7440
7441 test_56wa() {
7442         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7444
7445         local dir=$DIR/$tdir
7446
7447         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7448         stack_trap "rm -rf $dir"
7449
7450         local stripe_size=$($LFS getstripe -S -d $dir) ||
7451                 error "$LFS getstripe -S -d $dir failed"
7452         stripe_size=${stripe_size%% *}
7453
7454         local file_size=$((stripe_size * OSTCOUNT))
7455         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7456         local required_space=$((file_num * file_size))
7457         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7458                            head -n1)
7459         (( free_space >= required_space / 1024 )) ||
7460                 skip_env "need $required_space, have $free_space kbytes"
7461
7462         local dd_bs=65536
7463         local dd_count=$((file_size / dd_bs))
7464
7465         # write data into the files
7466         local i
7467         local j
7468         local file
7469
7470         for ((i = 1; i <= NUMFILES; i++ )); do
7471                 file=$dir/file$i
7472                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7473                         error "write data into $file failed"
7474         done
7475         for ((i = 1; i <= NUMDIRS; i++ )); do
7476                 for ((j = 1; j <= NUMFILES; j++ )); do
7477                         file=$dir/dir$i/file$j
7478                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7479                                 error "write data into $file failed"
7480                 done
7481         done
7482
7483         # $LFS_MIGRATE will fail if hard link migration is unsupported
7484         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7485                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7486                         error "creating links to $dir/dir1/file1 failed"
7487         fi
7488
7489         local expected=-1
7490
7491         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7492
7493         # lfs_migrate file
7494         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7495
7496         echo "$cmd"
7497         eval $cmd || error "$cmd failed"
7498
7499         check_stripe_count $dir/file1 $expected
7500
7501         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7502                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7503                 # OST 1 if it is on OST 0. This file is small enough to
7504                 # be on only one stripe.
7505                 file=$dir/migr_1_ost
7506                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7507                         error "write data into $file failed"
7508                 local obdidx=$($LFS getstripe -i $file)
7509                 local oldmd5=$(md5sum $file)
7510                 local newobdidx=0
7511
7512                 (( obdidx != 0 )) || newobdidx=1
7513                 cmd="$LFS migrate -i $newobdidx $file"
7514                 echo $cmd
7515                 eval $cmd || error "$cmd failed"
7516
7517                 local realobdix=$($LFS getstripe -i $file)
7518                 local newmd5=$(md5sum $file)
7519
7520                 (( $newobdidx == $realobdix )) ||
7521                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7522                 [[ "$oldmd5" == "$newmd5" ]] ||
7523                         error "md5sum differ: $oldmd5, $newmd5"
7524         fi
7525
7526         # lfs_migrate dir
7527         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7528         echo "$cmd"
7529         eval $cmd || error "$cmd failed"
7530
7531         for (( j = 1; j <= NUMFILES; j++ )); do
7532                 check_stripe_count $dir/dir1/file$j $expected
7533         done
7534
7535         # lfs_migrate works with lfs find
7536         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7537              $LFS_MIGRATE -y -c $expected"
7538         echo "$cmd"
7539         eval $cmd || error "$cmd failed"
7540
7541         for (( i = 2; i <= NUMFILES; i++ )); do
7542                 check_stripe_count $dir/file$i $expected
7543         done
7544         for (( i = 2; i <= NUMDIRS; i++ )); do
7545                 for (( j = 1; j <= NUMFILES; j++ )); do
7546                         check_stripe_count $dir/dir$i/file$j $expected
7547                 done
7548         done
7549 }
7550 run_test 56wa "check lfs_migrate -c stripe_count works"
7551
7552 test_56wb() {
7553         local file1=$DIR/$tdir/file1
7554         local create_pool=false
7555         local initial_pool=$($LFS getstripe -p $DIR)
7556         local pool_list=()
7557         local pool=""
7558
7559         echo -n "Creating test dir..."
7560         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7561         echo "done."
7562
7563         echo -n "Creating test file..."
7564         touch $file1 || error "cannot create file"
7565         echo "done."
7566
7567         echo -n "Detecting existing pools..."
7568         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7569
7570         if [ ${#pool_list[@]} -gt 0 ]; then
7571                 echo "${pool_list[@]}"
7572                 for thispool in "${pool_list[@]}"; do
7573                         if [[ -z "$initial_pool" ||
7574                               "$initial_pool" != "$thispool" ]]; then
7575                                 pool="$thispool"
7576                                 echo "Using existing pool '$pool'"
7577                                 break
7578                         fi
7579                 done
7580         else
7581                 echo "none detected."
7582         fi
7583         if [ -z "$pool" ]; then
7584                 pool=${POOL:-testpool}
7585                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7586                 echo -n "Creating pool '$pool'..."
7587                 create_pool=true
7588                 pool_add $pool &> /dev/null ||
7589                         error "pool_add failed"
7590                 echo "done."
7591
7592                 echo -n "Adding target to pool..."
7593                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7594                         error "pool_add_targets failed"
7595                 echo "done."
7596         fi
7597
7598         echo -n "Setting pool using -p option..."
7599         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7600                 error "migrate failed rc = $?"
7601         echo "done."
7602
7603         echo -n "Verifying test file is in pool after migrating..."
7604         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7605                 error "file was not migrated to pool $pool"
7606         echo "done."
7607
7608         echo -n "Removing test file from pool '$pool'..."
7609         # "lfs migrate $file" won't remove the file from the pool
7610         # until some striping information is changed.
7611         $LFS migrate -c 1 $file1 &> /dev/null ||
7612                 error "cannot remove from pool"
7613         [ "$($LFS getstripe -p $file1)" ] &&
7614                 error "pool still set"
7615         echo "done."
7616
7617         echo -n "Setting pool using --pool option..."
7618         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7619                 error "migrate failed rc = $?"
7620         echo "done."
7621
7622         # Clean up
7623         rm -f $file1
7624         if $create_pool; then
7625                 destroy_test_pools 2> /dev/null ||
7626                         error "destroy test pools failed"
7627         fi
7628 }
7629 run_test 56wb "check lfs_migrate pool support"
7630
7631 test_56wc() {
7632         local file1="$DIR/$tdir/$tfile"
7633         local md5
7634         local parent_ssize
7635         local parent_scount
7636         local cur_ssize
7637         local cur_scount
7638         local orig_ssize
7639         local new_scount
7640         local cur_comp
7641
7642         echo -n "Creating test dir..."
7643         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7644         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7645                 error "cannot set stripe by '-S 1M -c 1'"
7646         echo "done"
7647
7648         echo -n "Setting initial stripe for test file..."
7649         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7650                 error "cannot set stripe"
7651         cur_ssize=$($LFS getstripe -S "$file1")
7652         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7653         echo "done."
7654
7655         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7656         stack_trap "rm -f $file1"
7657         md5="$(md5sum $file1)"
7658
7659         # File currently set to -S 512K -c 1
7660
7661         # Ensure -c and -S options are rejected when -R is set
7662         echo -n "Verifying incompatible options are detected..."
7663         $LFS_MIGRATE -R -c 1 "$file1" &&
7664                 error "incompatible -R and -c options not detected"
7665         $LFS_MIGRATE -R -S 1M "$file1" &&
7666                 error "incompatible -R and -S options not detected"
7667         $LFS_MIGRATE -R -p pool "$file1" &&
7668                 error "incompatible -R and -p options not detected"
7669         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7670                 error "incompatible -R and -E options not detected"
7671         $LFS_MIGRATE -R -A "$file1" &&
7672                 error "incompatible -R and -A options not detected"
7673         $LFS_MIGRATE -A -c 1 "$file1" &&
7674                 error "incompatible -A and -c options not detected"
7675         $LFS_MIGRATE -A -S 1M "$file1" &&
7676                 error "incompatible -A and -S options not detected"
7677         $LFS_MIGRATE -A -p pool "$file1" &&
7678                 error "incompatible -A and -p options not detected"
7679         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7680                 error "incompatible -A and -E options not detected"
7681         echo "done."
7682
7683         # Ensure unrecognized options are passed through to 'lfs migrate'
7684         echo -n "Verifying -S option is passed through to lfs migrate..."
7685         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7686         cur_ssize=$($LFS getstripe -S "$file1")
7687         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7688         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7689         echo "done."
7690
7691         # File currently set to -S 1M -c 1
7692
7693         # Ensure long options are supported
7694         echo -n "Verifying long options supported..."
7695         $LFS_MIGRATE --non-block "$file1" ||
7696                 error "long option without argument not supported"
7697         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7698                 error "long option with argument not supported"
7699         cur_ssize=$($LFS getstripe -S "$file1")
7700         (( cur_ssize == 524288 )) ||
7701                 error "migrate --stripe-size $cur_ssize != 524288"
7702         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7703         echo "done."
7704
7705         # File currently set to -S 512K -c 1
7706
7707         if (( OSTCOUNT > 1 )); then
7708                 echo -n "Verifying explicit stripe count can be set..."
7709                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7710                 cur_scount=$($LFS getstripe -c "$file1")
7711                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7712                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7713                         error "file data has changed (3)"
7714                 echo "done."
7715         fi
7716
7717         # File currently set to -S 512K -c 1 or -S 512K -c 2
7718
7719         # Ensure parent striping is used if -R is set, and no stripe
7720         # count or size is specified
7721         echo -n "Setting stripe for parent directory..."
7722         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7723                 error "cannot set stripe '-S 2M -c 1'"
7724         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7725         echo "done."
7726
7727         echo -n "Verifying restripe option uses parent stripe settings..."
7728         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7729         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7730         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7731         cur_ssize=$($LFS getstripe -S "$file1")
7732         (( cur_ssize == parent_ssize )) ||
7733                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7734         cur_scount=$($LFS getstripe -c "$file1")
7735         (( cur_scount == parent_scount )) ||
7736                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7737         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7738         echo "done."
7739
7740         # File currently set to -S 1M -c 1
7741
7742         # Ensure striping is preserved if -R is not set, and no stripe
7743         # count or size is specified
7744         echo -n "Verifying striping size preserved when not specified..."
7745         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7746         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7747                 error "cannot set stripe on parent directory"
7748         $LFS_MIGRATE "$file1" || error "migrate failed"
7749         cur_ssize=$($LFS getstripe -S "$file1")
7750         (( cur_ssize == orig_ssize )) ||
7751                 error "migrate by default $cur_ssize != $orig_ssize"
7752         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7753         echo "done."
7754
7755         # Ensure file name properly detected when final option has no argument
7756         echo -n "Verifying file name properly detected..."
7757         $LFS_MIGRATE "$file1" ||
7758                 error "file name interpreted as option argument"
7759         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7760         echo "done."
7761
7762         # Ensure PFL arguments are passed through properly
7763         echo -n "Verifying PFL options passed through..."
7764         new_scount=$(((OSTCOUNT + 1) / 2))
7765         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7766                 error "migrate PFL arguments failed"
7767         cur_comp=$($LFS getstripe --comp-count $file1)
7768         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7769         cur_scount=$($LFS getstripe --stripe-count $file1)
7770         (( cur_scount == new_scount)) ||
7771                 error "PFL stripe count $cur_scount != $new_scount"
7772         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7773         echo "done."
7774 }
7775 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7776
7777 test_56wd() {
7778         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7779
7780         local file1=$DIR/$tdir/$tfile
7781
7782         echo -n "Creating test dir..."
7783         test_mkdir $DIR/$tdir || error "cannot create dir"
7784         echo "done."
7785
7786         echo -n "Creating test file..."
7787         echo "$tfile" > $file1
7788         echo "done."
7789
7790         # Ensure 'lfs migrate' will fail by using a non-existent option,
7791         # and make sure rsync is not called to recover
7792         echo -n "Make sure --no-rsync option works..."
7793         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7794                 grep -q 'refusing to fall back to rsync' ||
7795                 error "rsync was called with --no-rsync set"
7796         echo "done."
7797
7798         # Ensure rsync is called without trying 'lfs migrate' first
7799         echo -n "Make sure --rsync option works..."
7800         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7801                 grep -q 'falling back to rsync' &&
7802                 error "lfs migrate was called with --rsync set"
7803         echo "done."
7804 }
7805 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7806
7807 test_56we() {
7808         local td=$DIR/$tdir
7809         local tf=$td/$tfile
7810
7811         test_mkdir $td || error "cannot create $td"
7812         touch $tf || error "cannot touch $tf"
7813
7814         echo -n "Make sure --non-direct|-D works..."
7815         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7816                 grep -q "lfs migrate --non-direct" ||
7817                 error "--non-direct option cannot work correctly"
7818         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7819                 grep -q "lfs migrate -D" ||
7820                 error "-D option cannot work correctly"
7821         echo "done."
7822 }
7823 run_test 56we "check lfs_migrate --non-direct|-D support"
7824
7825 test_56x() {
7826         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7827         check_swap_layouts_support
7828
7829         local dir=$DIR/$tdir
7830         local ref1=/etc/passwd
7831         local file1=$dir/file1
7832
7833         test_mkdir $dir || error "creating dir $dir"
7834         $LFS setstripe -c 2 $file1
7835         cp $ref1 $file1
7836         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7837         stripe=$($LFS getstripe -c $file1)
7838         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7839         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7840
7841         # clean up
7842         rm -f $file1
7843 }
7844 run_test 56x "lfs migration support"
7845
7846 test_56xa() {
7847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7848         check_swap_layouts_support
7849
7850         local dir=$DIR/$tdir/$testnum
7851
7852         test_mkdir -p $dir
7853
7854         local ref1=/etc/passwd
7855         local file1=$dir/file1
7856
7857         $LFS setstripe -c 2 $file1
7858         cp $ref1 $file1
7859         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7860
7861         local stripe=$($LFS getstripe -c $file1)
7862
7863         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7864         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7865
7866         # clean up
7867         rm -f $file1
7868 }
7869 run_test 56xa "lfs migration --block support"
7870
7871 check_migrate_links() {
7872         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7873         local dir="$1"
7874         local file1="$dir/file1"
7875         local begin="$2"
7876         local count="$3"
7877         local runas="$4"
7878         local total_count=$(($begin + $count - 1))
7879         local symlink_count=10
7880         local uniq_count=10
7881
7882         if [ ! -f "$file1" ]; then
7883                 echo -n "creating initial file..."
7884                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7885                         error "cannot setstripe initial file"
7886                 echo "done"
7887
7888                 echo -n "creating symlinks..."
7889                 for s in $(seq 1 $symlink_count); do
7890                         ln -s "$file1" "$dir/slink$s" ||
7891                                 error "cannot create symlinks"
7892                 done
7893                 echo "done"
7894
7895                 echo -n "creating nonlinked files..."
7896                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7897                         error "cannot create nonlinked files"
7898                 echo "done"
7899         fi
7900
7901         # create hard links
7902         if [ ! -f "$dir/file$total_count" ]; then
7903                 echo -n "creating hard links $begin:$total_count..."
7904                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7905                         /dev/null || error "cannot create hard links"
7906                 echo "done"
7907         fi
7908
7909         echo -n "checking number of hard links listed in xattrs..."
7910         local fid=$($LFS getstripe -F "$file1")
7911         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7912
7913         echo "${#paths[*]}"
7914         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7915                         skip "hard link list has unexpected size, skipping test"
7916         fi
7917         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7918                         error "link names should exceed xattrs size"
7919         fi
7920
7921         echo -n "migrating files..."
7922         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7923         local rc=$?
7924         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7925         echo "done"
7926
7927         # make sure all links have been properly migrated
7928         echo -n "verifying files..."
7929         fid=$($LFS getstripe -F "$file1") ||
7930                 error "cannot get fid for file $file1"
7931         for i in $(seq 2 $total_count); do
7932                 local fid2=$($LFS getstripe -F $dir/file$i)
7933
7934                 [ "$fid2" == "$fid" ] ||
7935                         error "migrated hard link has mismatched FID"
7936         done
7937
7938         # make sure hard links were properly detected, and migration was
7939         # performed only once for the entire link set; nonlinked files should
7940         # also be migrated
7941         local actual=$(grep -c 'done' <<< "$migrate_out")
7942         local expected=$(($uniq_count + 1))
7943
7944         [ "$actual" -eq  "$expected" ] ||
7945                 error "hard links individually migrated ($actual != $expected)"
7946
7947         # make sure the correct number of hard links are present
7948         local hardlinks=$(stat -c '%h' "$file1")
7949
7950         [ $hardlinks -eq $total_count ] ||
7951                 error "num hard links $hardlinks != $total_count"
7952         echo "done"
7953
7954         return 0
7955 }
7956
7957 test_56xb() {
7958         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7959                 skip "Need MDS version at least 2.10.55"
7960
7961         local dir="$DIR/$tdir"
7962
7963         test_mkdir "$dir" || error "cannot create dir $dir"
7964
7965         echo "testing lfs migrate mode when all links fit within xattrs"
7966         check_migrate_links "$dir" 2 99
7967
7968         echo "testing rsync mode when all links fit within xattrs"
7969         check_migrate_links --rsync "$dir" 2 99
7970
7971         echo "testing lfs migrate mode when all links do not fit within xattrs"
7972         check_migrate_links "$dir" 101 100
7973
7974         echo "testing rsync mode when all links do not fit within xattrs"
7975         check_migrate_links --rsync "$dir" 101 100
7976
7977         chown -R $RUNAS_ID $dir
7978         echo "testing non-root lfs migrate mode when not all links are in xattr"
7979         check_migrate_links "$dir" 101 100 "$RUNAS"
7980
7981         # clean up
7982         rm -rf $dir
7983 }
7984 run_test 56xb "lfs migration hard link support"
7985
7986 test_56xc() {
7987         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7988
7989         local dir="$DIR/$tdir"
7990
7991         test_mkdir "$dir" || error "cannot create dir $dir"
7992
7993         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7994         echo -n "Setting initial stripe for 20MB test file..."
7995         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7996                 error "cannot setstripe 20MB file"
7997         echo "done"
7998         echo -n "Sizing 20MB test file..."
7999         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8000         echo "done"
8001         echo -n "Verifying small file autostripe count is 1..."
8002         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8003                 error "cannot migrate 20MB file"
8004         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8005                 error "cannot get stripe for $dir/20mb"
8006         [ $stripe_count -eq 1 ] ||
8007                 error "unexpected stripe count $stripe_count for 20MB file"
8008         rm -f "$dir/20mb"
8009         echo "done"
8010
8011         # Test 2: File is small enough to fit within the available space on
8012         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8013         # have at least an additional 1KB for each desired stripe for test 3
8014         echo -n "Setting stripe for 1GB test file..."
8015         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8016         echo "done"
8017         echo -n "Sizing 1GB test file..."
8018         # File size is 1GB + 3KB
8019         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8020         echo "done"
8021
8022         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8023         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8024         if (( avail > 524288 * OSTCOUNT )); then
8025                 echo -n "Migrating 1GB file..."
8026                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8027                         error "cannot migrate 1GB file"
8028                 echo "done"
8029                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8030                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8031                         error "cannot getstripe for 1GB file"
8032                 [ $stripe_count -eq 2 ] ||
8033                         error "unexpected stripe count $stripe_count != 2"
8034                 echo "done"
8035         fi
8036
8037         # Test 3: File is too large to fit within the available space on
8038         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8039         if [ $OSTCOUNT -ge 3 ]; then
8040                 # The required available space is calculated as
8041                 # file size (1GB + 3KB) / OST count (3).
8042                 local kb_per_ost=349526
8043
8044                 echo -n "Migrating 1GB file with limit..."
8045                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8046                         error "cannot migrate 1GB file with limit"
8047                 echo "done"
8048
8049                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8050                 echo -n "Verifying 1GB autostripe count with limited space..."
8051                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8052                         error "unexpected stripe count $stripe_count (min 3)"
8053                 echo "done"
8054         fi
8055
8056         # clean up
8057         rm -rf $dir
8058 }
8059 run_test 56xc "lfs migration autostripe"
8060
8061 test_56xd() {
8062         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8063
8064         local dir=$DIR/$tdir
8065         local f_mgrt=$dir/$tfile.mgrt
8066         local f_yaml=$dir/$tfile.yaml
8067         local f_copy=$dir/$tfile.copy
8068         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8069         local layout_copy="-c 2 -S 2M -i 1"
8070         local yamlfile=$dir/yamlfile
8071         local layout_before;
8072         local layout_after;
8073
8074         test_mkdir "$dir" || error "cannot create dir $dir"
8075         stack_trap "rm -rf $dir"
8076         $LFS setstripe $layout_yaml $f_yaml ||
8077                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8078         $LFS getstripe --yaml $f_yaml > $yamlfile
8079         $LFS setstripe $layout_copy $f_copy ||
8080                 error "cannot setstripe $f_copy with layout $layout_copy"
8081         touch $f_mgrt
8082         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8083
8084         # 1. test option --yaml
8085         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8086                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8087         layout_before=$(get_layout_param $f_yaml)
8088         layout_after=$(get_layout_param $f_mgrt)
8089         [ "$layout_after" == "$layout_before" ] ||
8090                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8091
8092         # 2. test option --copy
8093         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8094                 error "cannot migrate $f_mgrt with --copy $f_copy"
8095         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8096         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8097         [ "$layout_after" == "$layout_before" ] ||
8098                 error "lfs_migrate --copy: $layout_after != $layout_before"
8099 }
8100 run_test 56xd "check lfs_migrate --yaml and --copy support"
8101
8102 test_56xe() {
8103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8104
8105         local dir=$DIR/$tdir
8106         local f_comp=$dir/$tfile
8107         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8108         local layout_before=""
8109         local layout_after=""
8110
8111         test_mkdir "$dir" || error "cannot create dir $dir"
8112         stack_trap "rm -rf $dir"
8113         $LFS setstripe $layout $f_comp ||
8114                 error "cannot setstripe $f_comp with layout $layout"
8115         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8116         dd if=/dev/zero of=$f_comp bs=1M count=4
8117
8118         # 1. migrate a comp layout file by lfs_migrate
8119         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8120         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8121         [ "$layout_before" == "$layout_after" ] ||
8122                 error "lfs_migrate: $layout_before != $layout_after"
8123
8124         # 2. migrate a comp layout file by lfs migrate
8125         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8126         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8127         [ "$layout_before" == "$layout_after" ] ||
8128                 error "lfs migrate: $layout_before != $layout_after"
8129 }
8130 run_test 56xe "migrate a composite layout file"
8131
8132 test_56xf() {
8133         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8134
8135         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8136                 skip "Need server version at least 2.13.53"
8137
8138         local dir=$DIR/$tdir
8139         local f_comp=$dir/$tfile
8140         local layout="-E 1M -c1 -E -1 -c2"
8141         local fid_before=""
8142         local fid_after=""
8143
8144         test_mkdir "$dir" || error "cannot create dir $dir"
8145         stack_trap "rm -rf $dir"
8146         $LFS setstripe $layout $f_comp ||
8147                 error "cannot setstripe $f_comp with layout $layout"
8148         fid_before=$($LFS getstripe --fid $f_comp)
8149         dd if=/dev/zero of=$f_comp bs=1M count=4
8150
8151         # 1. migrate a comp layout file to a comp layout
8152         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8153         fid_after=$($LFS getstripe --fid $f_comp)
8154         [ "$fid_before" == "$fid_after" ] ||
8155                 error "comp-to-comp migrate: $fid_before != $fid_after"
8156
8157         # 2. migrate a comp layout file to a plain layout
8158         $LFS migrate -c2 $f_comp ||
8159                 error "cannot migrate $f_comp by lfs migrate"
8160         fid_after=$($LFS getstripe --fid $f_comp)
8161         [ "$fid_before" == "$fid_after" ] ||
8162                 error "comp-to-plain migrate: $fid_before != $fid_after"
8163
8164         # 3. migrate a plain layout file to a comp layout
8165         $LFS migrate $layout $f_comp ||
8166                 error "cannot migrate $f_comp by lfs migrate"
8167         fid_after=$($LFS getstripe --fid $f_comp)
8168         [ "$fid_before" == "$fid_after" ] ||
8169                 error "plain-to-comp migrate: $fid_before != $fid_after"
8170 }
8171 run_test 56xf "FID is not lost during migration of a composite layout file"
8172
8173 check_file_ost_range() {
8174         local file="$1"
8175         shift
8176         local range="$*"
8177         local -a file_range
8178         local idx
8179
8180         file_range=($($LFS getstripe -y "$file" |
8181                 awk '/l_ost_idx:/ { print $NF }'))
8182
8183         if [[ "${#file_range[@]}" = 0 ]]; then
8184                 echo "No osts found for $file"
8185                 return 1
8186         fi
8187
8188         for idx in "${file_range[@]}"; do
8189                 [[ " $range " =~ " $idx " ]] ||
8190                         return 1
8191         done
8192
8193         return 0
8194 }
8195
8196 sub_test_56xg() {
8197         local stripe_opt="$1"
8198         local pool="$2"
8199         shift 2
8200         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8201
8202         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8203                 error "Fail to migrate $tfile on $pool"
8204         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8205                 error "$tfile is not in pool $pool"
8206         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8207                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8208 }
8209
8210 test_56xg() {
8211         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8212         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8213         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8214                 skip "Need MDS version newer than 2.14.52"
8215
8216         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8217         local -a pool_ranges=("0 0" "1 1" "0 1")
8218
8219         # init pools
8220         for i in "${!pool_names[@]}"; do
8221                 pool_add ${pool_names[$i]} ||
8222                         error "pool_add failed (pool: ${pool_names[$i]})"
8223                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8224                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8225         done
8226
8227         # init the file to migrate
8228         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8229                 error "Unable to create $tfile on OST1"
8230         stack_trap "rm -f $DIR/$tfile"
8231         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8232                 error "Unable to write on $tfile"
8233
8234         echo "1. migrate $tfile on pool ${pool_names[0]}"
8235         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8236
8237         echo "2. migrate $tfile on pool ${pool_names[2]}"
8238         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8239
8240         echo "3. migrate $tfile on pool ${pool_names[1]}"
8241         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8242
8243         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8244         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8245         echo
8246
8247         # Clean pools
8248         destroy_test_pools ||
8249                 error "pool_destroy failed"
8250 }
8251 run_test 56xg "lfs migrate pool support"
8252
8253 test_56xh() {
8254         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8255
8256         local size_mb=25
8257         local file1=$DIR/$tfile
8258         local tmp1=$TMP/$tfile.tmp
8259
8260         $LFS setstripe -c 2 $file1
8261
8262         stack_trap "rm -f $file1 $tmp1"
8263         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8264                         error "error creating $tmp1"
8265         ls -lsh $tmp1
8266         cp $tmp1 $file1
8267
8268         local start=$SECONDS
8269
8270         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8271                 error "migrate failed rc = $?"
8272
8273         local elapsed=$((SECONDS - start))
8274
8275         # with 1MB/s, elapsed should equal size_mb
8276         (( elapsed >= size_mb * 95 / 100 )) ||
8277                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8278
8279         (( elapsed <= size_mb * 120 / 100 )) ||
8280                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8281
8282         (( elapsed <= size_mb * 350 / 100 )) ||
8283                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8284
8285         stripe=$($LFS getstripe -c $file1)
8286         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8287         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8288
8289         # Clean up file (since it is multiple MB)
8290         rm -f $file1 $tmp1
8291 }
8292 run_test 56xh "lfs migrate bandwidth limitation support"
8293
8294 test_56xi() {
8295         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8296         verify_yaml_available || skip_env "YAML verification not installed"
8297
8298         local size_mb=5
8299         local file1=$DIR/$tfile.1
8300         local file2=$DIR/$tfile.2
8301         local file3=$DIR/$tfile.3
8302         local output_file=$DIR/$tfile.out
8303         local tmp1=$TMP/$tfile.tmp
8304
8305         $LFS setstripe -c 2 $file1
8306         $LFS setstripe -c 2 $file2
8307         $LFS setstripe -c 2 $file3
8308
8309         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8310         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8311                         error "error creating $tmp1"
8312         ls -lsh $tmp1
8313         cp $tmp1 $file1
8314         cp $tmp1 $file2
8315         cp $tmp1 $file3
8316
8317         $LFS migrate --stats --stats-interval=1 \
8318                 -c 1 $file1 $file2 $file3 1> $output_file ||
8319                 error "migrate failed rc = $?"
8320
8321         cat $output_file
8322         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8323
8324         # Clean up file (since it is multiple MB)
8325         rm -f $file1 $file2 $file3 $tmp1 $output_file
8326 }
8327 run_test 56xi "lfs migrate stats support"
8328
8329 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8330         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8331
8332         local file=$DIR/$tfile
8333         local linkdir=$DIR/$tdir
8334
8335         test_mkdir $linkdir || error "fail to create $linkdir"
8336         $LFS setstripe -i 0 -c 1 -S1M $file
8337         stack_trap "rm -rf $file $linkdir"
8338         dd if=/dev/urandom of=$file bs=1M count=10 ||
8339                 error "fail to create $file"
8340
8341         # Create file links
8342         local cpts
8343         local threads_max
8344         local nlinks
8345
8346         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8347         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8348         (( nlinks = thread_max * 3 / 2 / cpts))
8349
8350         echo "create $nlinks hard links of $file"
8351         createmany -l $file $linkdir/link $nlinks
8352
8353         # Parallel migrates (should not block)
8354         local i
8355         for ((i = 0; i < nlinks; i++)); do
8356                 echo $linkdir/link$i
8357         done | xargs -n1 -P $nlinks $LFS migrate -c2
8358
8359         local stripe_count
8360         stripe_count=$($LFS getstripe -c $file) ||
8361                 error "fail to get stripe count on $file"
8362
8363         ((stripe_count == 2)) ||
8364                 error "fail to migrate $file (stripe_count = $stripe_count)"
8365 }
8366 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8367
8368 test_56xk() {
8369         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8370
8371         local size_mb=5
8372         local file1=$DIR/$tfile
8373
8374         stack_trap "rm -f $file1"
8375         $LFS setstripe -c 1 $file1
8376         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8377                 error "error creating $file1"
8378         $LFS mirror extend -N $file1 || error "can't mirror"
8379         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8380                 error "can't dd"
8381         $LFS getstripe $file1 | grep stale ||
8382                 error "one component must be stale"
8383
8384         local start=$SECONDS
8385         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8386                 error "migrate failed rc = $?"
8387         local elapsed=$((SECONDS - start))
8388         $LFS getstripe $file1 | grep stale &&
8389                 error "all components must be sync"
8390
8391         # with 1MB/s, elapsed should equal size_mb
8392         (( elapsed >= size_mb * 95 / 100 )) ||
8393                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8394
8395         (( elapsed <= size_mb * 120 / 100 )) ||
8396                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8397
8398         (( elapsed <= size_mb * 350 / 100 )) ||
8399                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8400 }
8401 run_test 56xk "lfs mirror resync bandwidth limitation support"
8402
8403 test_56xl() {
8404         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8405         verify_yaml_available || skip_env "YAML verification not installed"
8406
8407         local size_mb=5
8408         local file1=$DIR/$tfile.1
8409         local output_file=$DIR/$tfile.out
8410
8411         stack_trap "rm -f $file1"
8412         $LFS setstripe -c 1 $file1
8413         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8414                 error "error creating $file1"
8415         $LFS mirror extend -N $file1 || error "can't mirror"
8416         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8417                 error "can't dd"
8418         $LFS getstripe $file1 | grep stale ||
8419                 error "one component must be stale"
8420         $LFS getstripe $file1
8421
8422         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8423                 error "resync failed rc = $?"
8424         $LFS getstripe $file1 | grep stale &&
8425                 error "all components must be sync"
8426
8427         cat $output_file
8428         cat $output_file | verify_yaml || error "stats is not valid YAML"
8429 }
8430 run_test 56xl "lfs mirror resync stats support"
8431
8432 test_56y() {
8433         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8434                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8435
8436         local res=""
8437         local dir=$DIR/$tdir
8438         local f1=$dir/file1
8439         local f2=$dir/file2
8440
8441         test_mkdir -p $dir || error "creating dir $dir"
8442         touch $f1 || error "creating std file $f1"
8443         $MULTIOP $f2 H2c || error "creating released file $f2"
8444
8445         # a directory can be raid0, so ask only for files
8446         res=$($LFS find $dir -L raid0 -type f | wc -l)
8447         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8448
8449         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8450         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8451
8452         # only files can be released, so no need to force file search
8453         res=$($LFS find $dir -L released)
8454         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8455
8456         res=$($LFS find $dir -type f \! -L released)
8457         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8458 }
8459 run_test 56y "lfs find -L raid0|released"
8460
8461 test_56z() { # LU-4824
8462         # This checks to make sure 'lfs find' continues after errors
8463         # There are two classes of errors that should be caught:
8464         # - If multiple paths are provided, all should be searched even if one
8465         #   errors out
8466         # - If errors are encountered during the search, it should not terminate
8467         #   early
8468         local dir=$DIR/$tdir
8469         local i
8470
8471         test_mkdir $dir
8472         for i in d{0..9}; do
8473                 test_mkdir $dir/$i
8474                 touch $dir/$i/$tfile
8475         done
8476         $LFS find $DIR/non_existent_dir $dir &&
8477                 error "$LFS find did not return an error"
8478         # Make a directory unsearchable. This should NOT be the last entry in
8479         # directory order.  Arbitrarily pick the 6th entry
8480         chmod 700 $($LFS find $dir -type d | sed '6!d')
8481
8482         $RUNAS $LFS find $DIR/non_existent $dir
8483         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8484
8485         # The user should be able to see 10 directories and 9 files
8486         (( count == 19 )) ||
8487                 error "$LFS find found $count != 19 entries after error"
8488 }
8489 run_test 56z "lfs find should continue after an error"
8490
8491 test_56aa() { # LU-5937
8492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8493
8494         local dir=$DIR/$tdir
8495
8496         mkdir $dir
8497         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8498
8499         createmany -o $dir/striped_dir/${tfile}- 1024
8500         local dirs=$($LFS find --size +8k $dir/)
8501
8502         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8503 }
8504 run_test 56aa "lfs find --size under striped dir"
8505
8506 test_56ab() { # LU-10705
8507         test_mkdir $DIR/$tdir
8508         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8509         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8510         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8511         # Flush writes to ensure valid blocks.  Need to be more thorough for
8512         # ZFS, since blocks are not allocated/returned to client immediately.
8513         sync_all_data
8514         wait_zfs_commit ost1 2
8515         cancel_lru_locks osc
8516         ls -ls $DIR/$tdir
8517
8518         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8519
8520         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8521
8522         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8523         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8524
8525         rm -f $DIR/$tdir/$tfile.[123]
8526 }
8527 run_test 56ab "lfs find --blocks"
8528
8529 # LU-11188
8530 test_56aca() {
8531         local dir="$DIR/$tdir"
8532         local perms=(001 002 003 004 005 006 007
8533                      010 020 030 040 050 060 070
8534                      100 200 300 400 500 600 700
8535                      111 222 333 444 555 666 777)
8536         local perm_minus=(8 8 4 8 4 4 2
8537                           8 8 4 8 4 4 2
8538                           8 8 4 8 4 4 2
8539                           4 4 2 4 2 2 1)
8540         local perm_slash=(8  8 12  8 12 12 14
8541                           8  8 12  8 12 12 14
8542                           8  8 12  8 12 12 14
8543                          16 16 24 16 24 24 28)
8544
8545         test_mkdir "$dir"
8546         for perm in ${perms[*]}; do
8547                 touch "$dir/$tfile.$perm"
8548                 chmod $perm "$dir/$tfile.$perm"
8549         done
8550
8551         for ((i = 0; i < ${#perms[*]}; i++)); do
8552                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8553                 (( $num == 1 )) ||
8554                         error "lfs find -perm ${perms[i]}:"\
8555                               "$num != 1"
8556
8557                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8558                 (( $num == ${perm_minus[i]} )) ||
8559                         error "lfs find -perm -${perms[i]}:"\
8560                               "$num != ${perm_minus[i]}"
8561
8562                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8563                 (( $num == ${perm_slash[i]} )) ||
8564                         error "lfs find -perm /${perms[i]}:"\
8565                               "$num != ${perm_slash[i]}"
8566         done
8567 }
8568 run_test 56aca "check lfs find -perm with octal representation"
8569
8570 test_56acb() {
8571         local dir=$DIR/$tdir
8572         # p is the permission of write and execute for user, group and other
8573         # without the umask. It is used to test +wx.
8574         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8575         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8576         local symbolic=(+t  a+t u+t g+t o+t
8577                         g+s u+s o+s +s o+sr
8578                         o=r,ug+o,u+w
8579                         u+ g+ o+ a+ ugo+
8580                         u- g- o- a- ugo-
8581                         u= g= o= a= ugo=
8582                         o=r,ug+o,u+w u=r,a+u,u+w
8583                         g=r,ugo=g,u+w u+x,+X +X
8584                         u+x,u+X u+X u+x,g+X o+r,+X
8585                         u+x,go+X +wx +rwx)
8586
8587         test_mkdir $dir
8588         for perm in ${perms[*]}; do
8589                 touch "$dir/$tfile.$perm"
8590                 chmod $perm "$dir/$tfile.$perm"
8591         done
8592
8593         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8594                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8595
8596                 (( $num == 1 )) ||
8597                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8598         done
8599 }
8600 run_test 56acb "check lfs find -perm with symbolic representation"
8601
8602 test_56acc() {
8603         local dir=$DIR/$tdir
8604         local tests="17777 787 789 abcd
8605                 ug=uu ug=a ug=gu uo=ou urw
8606                 u+xg+x a=r,u+x,"
8607
8608         test_mkdir $dir
8609         for err in $tests; do
8610                 if $LFS find $dir -perm $err 2>/dev/null; then
8611                         error "lfs find -perm $err: parsing should have failed"
8612                 fi
8613         done
8614 }
8615 run_test 56acc "check parsing error for lfs find -perm"
8616
8617 test_56ba() {
8618         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8619                 skip "Need MDS version at least 2.10.50"
8620
8621         # Create composite files with one component
8622         local dir=$DIR/$tdir
8623
8624         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8625         # Create composite files with three components
8626         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8627         # LU-16904 Create plain layout files
8628         lfs setstripe -c 1 $dir/$tfile-{1..10}
8629
8630         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8631
8632         [[ $nfiles == 10 ]] ||
8633                 error "lfs find -E 1M found $nfiles != 10 files"
8634
8635         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8636         [[ $nfiles == 25 ]] ||
8637                 error "lfs find ! -E 1M found $nfiles != 25 files"
8638
8639         # All files have a component that starts at 0
8640         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8641         [[ $nfiles == 35 ]] ||
8642                 error "lfs find --component-start 0 - $nfiles != 35 files"
8643
8644         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8645         [[ $nfiles == 15 ]] ||
8646                 error "lfs find --component-start 2M - $nfiles != 15 files"
8647
8648         # All files created here have a componenet that does not starts at 2M
8649         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8650         [[ $nfiles == 35 ]] ||
8651                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8652
8653         # Find files with a specified number of components
8654         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8655         [[ $nfiles == 15 ]] ||
8656                 error "lfs find --component-count 3 - $nfiles != 15 files"
8657
8658         # Remember non-composite files have a component count of zero
8659         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8660         [[ $nfiles == 10 ]] ||
8661                 error "lfs find --component-count 0 - $nfiles != 10 files"
8662
8663         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8664         [[ $nfiles == 20 ]] ||
8665                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8666
8667         # All files have a flag called "init"
8668         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8669         [[ $nfiles == 35 ]] ||
8670                 error "lfs find --component-flags init - $nfiles != 35 files"
8671
8672         # Multi-component files will have a component not initialized
8673         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8674         [[ $nfiles == 15 ]] ||
8675                 error "lfs find !--component-flags init - $nfiles != 15 files"
8676
8677         rm -rf $dir
8678
8679 }
8680 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8681
8682 test_56ca() {
8683         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8684                 skip "Need MDS version at least 2.10.57"
8685
8686         local td=$DIR/$tdir
8687         local tf=$td/$tfile
8688         local dir
8689         local nfiles
8690         local cmd
8691         local i
8692         local j
8693
8694         # create mirrored directories and mirrored files
8695         mkdir $td || error "mkdir $td failed"
8696         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8697         createmany -o $tf- 10 || error "create $tf- failed"
8698
8699         for i in $(seq 2); do
8700                 dir=$td/dir$i
8701                 mkdir $dir || error "mkdir $dir failed"
8702                 $LFS mirror create -N$((3 + i)) $dir ||
8703                         error "create mirrored dir $dir failed"
8704                 createmany -o $dir/$tfile- 10 ||
8705                         error "create $dir/$tfile- failed"
8706         done
8707
8708         # change the states of some mirrored files
8709         echo foo > $tf-6
8710         for i in $(seq 2); do
8711                 dir=$td/dir$i
8712                 for j in $(seq 4 9); do
8713                         echo foo > $dir/$tfile-$j
8714                 done
8715         done
8716
8717         # find mirrored files with specific mirror count
8718         cmd="$LFS find --mirror-count 3 --type f $td"
8719         nfiles=$($cmd | wc -l)
8720         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8721
8722         cmd="$LFS find ! --mirror-count 3 --type f $td"
8723         nfiles=$($cmd | wc -l)
8724         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8725
8726         cmd="$LFS find --mirror-count +2 --type f $td"
8727         nfiles=$($cmd | wc -l)
8728         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8729
8730         cmd="$LFS find --mirror-count -6 --type f $td"
8731         nfiles=$($cmd | wc -l)
8732         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8733
8734         # find mirrored files with specific file state
8735         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8736         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8737
8738         cmd="$LFS find --mirror-state=ro --type f $td"
8739         nfiles=$($cmd | wc -l)
8740         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8741
8742         cmd="$LFS find ! --mirror-state=ro --type f $td"
8743         nfiles=$($cmd | wc -l)
8744         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8745
8746         cmd="$LFS find --mirror-state=wp --type f $td"
8747         nfiles=$($cmd | wc -l)
8748         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8749
8750         cmd="$LFS find ! --mirror-state=sp --type f $td"
8751         nfiles=$($cmd | wc -l)
8752         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8753 }
8754 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8755
8756 test_56da() { # LU-14179
8757         local path=$DIR/$tdir
8758
8759         test_mkdir $path
8760         cd $path
8761
8762         local longdir=$(str_repeat 'a' 255)
8763
8764         for i in {1..15}; do
8765                 path=$path/$longdir
8766                 test_mkdir $longdir
8767                 cd $longdir
8768         done
8769
8770         local len=${#path}
8771         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8772
8773         test_mkdir $lastdir
8774         cd $lastdir
8775         # PATH_MAX-1
8776         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8777
8778         # NAME_MAX
8779         touch $(str_repeat 'f' 255)
8780
8781         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8782                 error "lfs find reported an error"
8783
8784         rm -rf $DIR/$tdir
8785 }
8786 run_test 56da "test lfs find with long paths"
8787
8788 test_56ea() { #LU-10378
8789         local path=$DIR/$tdir
8790         local pool=$TESTNAME
8791
8792         # Create ost pool
8793         pool_add $pool || error "pool_add $pool failed"
8794         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8795                 error "adding targets to $pool failed"
8796
8797         # Set default pool on directory before creating file
8798         mkdir $path || error "mkdir $path failed"
8799         $LFS setstripe -p $pool $path ||
8800                 error "set OST pool on $pool failed"
8801         touch $path/$tfile || error "touch $path/$tfile failed"
8802
8803         # Compare basic file attributes from -printf and stat
8804         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8805         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8806
8807         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8808                 error "Attrs from lfs find and stat don't match"
8809
8810         # Compare Lustre attributes from lfs find and lfs getstripe
8811         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8812         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8813         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8814         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8815         local fpool=$($LFS getstripe --pool $path/$tfile)
8816         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8817
8818         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8819                 error "Attrs from lfs find and lfs getstripe don't match"
8820
8821         # Verify behavior for unknown escape/format sequences
8822         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8823
8824         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8825                 error "Escape/format codes don't match"
8826 }
8827 run_test 56ea "test lfs find -printf option"
8828
8829 test_56eb() {
8830         local dir=$DIR/$tdir
8831         local subdir_1=$dir/subdir_1
8832
8833         test_mkdir -p $subdir_1
8834         ln -s subdir_1 $dir/link_1
8835
8836         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8837                 error "symlink is not followed"
8838
8839         $LFS getstripe --no-follow $dir |
8840                 grep "^$dir/link_1 has no stripe info$" ||
8841                 error "symlink should not have stripe info"
8842
8843         touch $dir/testfile
8844         ln -s testfile $dir/file_link_2
8845
8846         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8847                 error "symlink is not followed"
8848
8849         $LFS getstripe --no-follow $dir |
8850                 grep "^$dir/file_link_2 has no stripe info$" ||
8851                 error "symlink should not have stripe info"
8852 }
8853 run_test 56eb "check lfs getstripe on symlink"
8854
8855 test_56ec() {
8856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8857         local dir=$DIR/$tdir
8858         local srcfile=$dir/srcfile
8859         local srcyaml=$dir/srcyaml
8860         local destfile=$dir/destfile
8861
8862         test_mkdir -p $dir
8863
8864         $LFS setstripe -i 1 $srcfile
8865         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8866         # if the setstripe yaml parsing fails for any reason, the command can
8867         # randomly assign the correct OST index, leading to an erroneous
8868         # success. but the chance of false success is low enough that a
8869         # regression should still be quickly caught.
8870         $LFS setstripe --yaml=$srcyaml $destfile
8871
8872         local srcindex=$($LFS getstripe -i $srcfile)
8873         local destindex=$($LFS getstripe -i $destfile)
8874
8875         if [[ ! $srcindex -eq $destindex ]]; then
8876                 error "setstripe did not set OST index correctly"
8877         fi
8878 }
8879 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8880
8881 test_56eda() {
8882         local dir=$DIR/$tdir
8883         local subdir=$dir/subdir
8884         local file1=$dir/$tfile
8885         local file2=$dir/$tfile\2
8886         local link=$dir/$tfile-link
8887         local nfiles
8888
8889         test_mkdir -p $dir
8890         $LFS setdirstripe -c1 $subdir
8891         touch $file1
8892         touch $file2
8893         ln $file2 $link
8894
8895         nfiles=$($LFS find --links 1 $dir | wc -l)
8896         (( $nfiles == 1 )) ||
8897                 error "lfs find --links expected 1 file, got $nfiles"
8898
8899         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8900         (( $nfiles == 2 )) ||
8901                 error "lfs find --links expected 2 files, got $nfiles"
8902
8903         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8904         (( $nfiles == 1 )) ||
8905                 error "lfs find --links expected 1 directory, got $nfiles"
8906 }
8907 run_test 56eda "check lfs find --links"
8908
8909 test_56edb() {
8910         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8911
8912         local dir=$DIR/$tdir
8913         local stripedir=$dir/stripedir
8914         local nfiles
8915
8916         test_mkdir -p $dir
8917
8918         $LFS setdirstripe -c2 $stripedir
8919
8920         $LFS getdirstripe $stripedir
8921
8922         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8923         (( $nfiles == 1 )) ||
8924                 error "lfs find --links expected 1 directory, got $nfiles"
8925 }
8926 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8927
8928 test_56ef() {
8929         local dir=$DIR/$tdir
8930         local dir1=$dir/d1
8931         local dir2=$dir/d2
8932         local nfiles
8933
8934         test_mkdir -p $dir
8935
8936         mkdir $dir1
8937         mkdir $dir2
8938
8939         touch $dir1/f
8940         touch $dir2/f
8941
8942         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8943         (( $nfiles == 2 )) ||
8944                 error "(1) lfs find expected 2 files, got $nfiles"
8945
8946         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8947         (( $nfiles == 2 )) ||
8948                 error "(2) lfs find expected 2 files, got $nfiles"
8949
8950         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8951         (( $nfiles == 2 )) ||
8952                 error "(3) lfs find expected 2 files, got $nfiles"
8953 }
8954 run_test 56ef "lfs find with multiple paths"
8955
8956 test_57a() {
8957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8958         # note test will not do anything if MDS is not local
8959         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8960                 skip_env "ldiskfs only test"
8961         fi
8962         remote_mds_nodsh && skip "remote MDS with nodsh"
8963
8964         local MNTDEV="osd*.*MDT*.mntdev"
8965         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8966         [ -z "$DEV" ] && error "can't access $MNTDEV"
8967         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8968                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8969                         error "can't access $DEV"
8970                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8971                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8972                 rm $TMP/t57a.dump
8973         done
8974 }
8975 run_test 57a "verify MDS filesystem created with large inodes =="
8976
8977 test_57b() {
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8980                 skip_env "ldiskfs only test"
8981         fi
8982         remote_mds_nodsh && skip "remote MDS with nodsh"
8983
8984         local dir=$DIR/$tdir
8985         local filecount=100
8986         local file1=$dir/f1
8987         local fileN=$dir/f$filecount
8988
8989         rm -rf $dir || error "removing $dir"
8990         test_mkdir -c1 $dir
8991         local mdtidx=$($LFS getstripe -m $dir)
8992         local mdtname=MDT$(printf %04x $mdtidx)
8993         local facet=mds$((mdtidx + 1))
8994
8995         echo "mcreating $filecount files"
8996         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8997
8998         # verify that files do not have EAs yet
8999         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9000                 error "$file1 has an EA"
9001         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9002                 error "$fileN has an EA"
9003
9004         sync
9005         sleep 1
9006         df $dir  #make sure we get new statfs data
9007         local mdsfree=$(do_facet $facet \
9008                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9009         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9010         local file
9011
9012         echo "opening files to create objects/EAs"
9013         for file in $(seq -f $dir/f%g 1 $filecount); do
9014                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9015                         error "opening $file"
9016         done
9017
9018         # verify that files have EAs now
9019         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9020                 error "$file1 missing EA"
9021         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9022                 error "$fileN missing EA"
9023
9024         sleep 1  #make sure we get new statfs data
9025         df $dir
9026         local mdsfree2=$(do_facet $facet \
9027                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9028         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9029
9030         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9031                 if [ "$mdsfree" != "$mdsfree2" ]; then
9032                         error "MDC before $mdcfree != after $mdcfree2"
9033                 else
9034                         echo "MDC before $mdcfree != after $mdcfree2"
9035                         echo "unable to confirm if MDS has large inodes"
9036                 fi
9037         fi
9038         rm -rf $dir
9039 }
9040 run_test 57b "default LOV EAs are stored inside large inodes ==="
9041
9042 test_58() {
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044         [ -z "$(which wiretest 2>/dev/null)" ] &&
9045                         skip_env "could not find wiretest"
9046
9047         wiretest
9048 }
9049 run_test 58 "verify cross-platform wire constants =============="
9050
9051 test_59() {
9052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9053
9054         echo "touch 130 files"
9055         createmany -o $DIR/f59- 130
9056         echo "rm 130 files"
9057         unlinkmany $DIR/f59- 130
9058         sync
9059         # wait for commitment of removal
9060         wait_delete_completed
9061 }
9062 run_test 59 "verify cancellation of llog records async ========="
9063
9064 TEST60_HEAD="test_60 run $RANDOM"
9065 test_60a() {
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         remote_mgs_nodsh && skip "remote MGS with nodsh"
9068         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9069                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9070                         skip_env "missing subtest run-llog.sh"
9071
9072         log "$TEST60_HEAD - from kernel mode"
9073         do_facet mgs "$LCTL dk > /dev/null"
9074         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9075         do_facet mgs $LCTL dk > $TMP/$tfile
9076
9077         # LU-6388: test llog_reader
9078         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9079         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9080         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9081                         skip_env "missing llog_reader"
9082         local fstype=$(facet_fstype mgs)
9083         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9084                 skip_env "Only for ldiskfs or zfs type mgs"
9085
9086         local mntpt=$(facet_mntpt mgs)
9087         local mgsdev=$(mgsdevname 1)
9088         local fid_list
9089         local fid
9090         local rec_list
9091         local rec
9092         local rec_type
9093         local obj_file
9094         local path
9095         local seq
9096         local oid
9097         local pass=true
9098
9099         #get fid and record list
9100         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9101                 tail -n 4))
9102         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9103                 tail -n 4))
9104         #remount mgs as ldiskfs or zfs type
9105         stop mgs || error "stop mgs failed"
9106         mount_fstype mgs || error "remount mgs failed"
9107         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9108                 fid=${fid_list[i]}
9109                 rec=${rec_list[i]}
9110                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9111                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9112                 oid=$((16#$oid))
9113
9114                 case $fstype in
9115                         ldiskfs )
9116                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9117                         zfs )
9118                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9119                 esac
9120                 echo "obj_file is $obj_file"
9121                 do_facet mgs $llog_reader $obj_file
9122
9123                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9124                         awk '{ print $3 }' | sed -e "s/^type=//g")
9125                 if [ $rec_type != $rec ]; then
9126                         echo "FAILED test_60a wrong record type $rec_type," \
9127                               "should be $rec"
9128                         pass=false
9129                         break
9130                 fi
9131
9132                 #check obj path if record type is LLOG_LOGID_MAGIC
9133                 if [ "$rec" == "1064553b" ]; then
9134                         path=$(do_facet mgs $llog_reader $obj_file |
9135                                 grep "path=" | awk '{ print $NF }' |
9136                                 sed -e "s/^path=//g")
9137                         if [ $obj_file != $mntpt/$path ]; then
9138                                 echo "FAILED test_60a wrong obj path" \
9139                                       "$montpt/$path, should be $obj_file"
9140                                 pass=false
9141                                 break
9142                         fi
9143                 fi
9144         done
9145         rm -f $TMP/$tfile
9146         #restart mgs before "error", otherwise it will block the next test
9147         stop mgs || error "stop mgs failed"
9148         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9149         $pass || error "test failed, see FAILED test_60a messages for specifics"
9150 }
9151 run_test 60a "llog_test run from kernel module and test llog_reader"
9152
9153 test_60b() { # bug 6411
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155
9156         dmesg > $DIR/$tfile
9157         LLOG_COUNT=$(do_facet mgs dmesg |
9158                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9159                           /llog_[a-z]*.c:[0-9]/ {
9160                                 if (marker)
9161                                         from_marker++
9162                                 from_begin++
9163                           }
9164                           END {
9165                                 if (marker)
9166                                         print from_marker
9167                                 else
9168                                         print from_begin
9169                           }")
9170
9171         [[ $LLOG_COUNT -gt 120 ]] &&
9172                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9173 }
9174 run_test 60b "limit repeated messages from CERROR/CWARN"
9175
9176 test_60c() {
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178
9179         echo "create 5000 files"
9180         createmany -o $DIR/f60c- 5000
9181 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9182         lctl set_param fail_loc=0x80000137
9183         unlinkmany $DIR/f60c- 5000
9184         lctl set_param fail_loc=0
9185 }
9186 run_test 60c "unlink file when mds full"
9187
9188 test_60d() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190
9191         SAVEPRINTK=$(lctl get_param -n printk)
9192         # verify "lctl mark" is even working"
9193         MESSAGE="test message ID $RANDOM $$"
9194         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9195         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9196
9197         lctl set_param printk=0 || error "set lnet.printk failed"
9198         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9199         MESSAGE="new test message ID $RANDOM $$"
9200         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9201         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9202         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9203
9204         lctl set_param -n printk="$SAVEPRINTK"
9205 }
9206 run_test 60d "test printk console message masking"
9207
9208 test_60e() {
9209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9210         remote_mds_nodsh && skip "remote MDS with nodsh"
9211
9212         touch $DIR/$tfile
9213 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9214         do_facet mds1 lctl set_param fail_loc=0x15b
9215         rm $DIR/$tfile
9216 }
9217 run_test 60e "no space while new llog is being created"
9218
9219 test_60f() {
9220         local old_path=$($LCTL get_param -n debug_path)
9221
9222         stack_trap "$LCTL set_param debug_path=$old_path"
9223         stack_trap "rm -f $TMP/$tfile*"
9224         rm -f $TMP/$tfile* 2> /dev/null
9225         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9226         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9227         test_mkdir $DIR/$tdir
9228         # retry in case the open is cached and not released
9229         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9230                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9231                 sleep 0.1
9232         done
9233         ls $TMP/$tfile*
9234         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9235 }
9236 run_test 60f "change debug_path works"
9237
9238 test_60g() {
9239         local pid
9240         local i
9241
9242         test_mkdir -c $MDSCOUNT $DIR/$tdir
9243
9244         (
9245                 local index=0
9246                 while true; do
9247                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9248                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9249                                 2>/dev/null
9250                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9251                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9252                         index=$((index + 1))
9253                 done
9254         ) &
9255
9256         pid=$!
9257
9258         for i in {0..100}; do
9259                 # define OBD_FAIL_OSD_TXN_START    0x19a
9260                 local index=$((i % MDSCOUNT + 1))
9261
9262                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9263                         > /dev/null
9264                 sleep 0.01
9265         done
9266
9267         kill -9 $pid
9268
9269         for i in $(seq $MDSCOUNT); do
9270                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9271         done
9272
9273         mkdir $DIR/$tdir/new || error "mkdir failed"
9274         rmdir $DIR/$tdir/new || error "rmdir failed"
9275
9276         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9277                 -t namespace
9278         for i in $(seq $MDSCOUNT); do
9279                 wait_update_facet mds$i "$LCTL get_param -n \
9280                         mdd.$(facet_svc mds$i).lfsck_namespace |
9281                         awk '/^status/ { print \\\$2 }'" "completed"
9282         done
9283
9284         ls -R $DIR/$tdir
9285         rm -rf $DIR/$tdir || error "rmdir failed"
9286 }
9287 run_test 60g "transaction abort won't cause MDT hung"
9288
9289 test_60h() {
9290         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9291                 skip "Need MDS version at least 2.12.52"
9292         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9293
9294         local f
9295
9296         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9297         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9298         for fail_loc in 0x80000188 0x80000189; do
9299                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9300                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9301                         error "mkdir $dir-$fail_loc failed"
9302                 for i in {0..10}; do
9303                         # create may fail on missing stripe
9304                         echo $i > $DIR/$tdir-$fail_loc/$i
9305                 done
9306                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9307                         error "getdirstripe $tdir-$fail_loc failed"
9308                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9309                         error "migrate $tdir-$fail_loc failed"
9310                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9311                         error "getdirstripe $tdir-$fail_loc failed"
9312                 pushd $DIR/$tdir-$fail_loc
9313                 for f in *; do
9314                         echo $f | cmp $f - || error "$f data mismatch"
9315                 done
9316                 popd
9317                 rm -rf $DIR/$tdir-$fail_loc
9318         done
9319 }
9320 run_test 60h "striped directory with missing stripes can be accessed"
9321
9322 function t60i_load() {
9323         mkdir $DIR/$tdir
9324         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9325         $LCTL set_param fail_loc=0x131c fail_val=1
9326         for ((i=0; i<5000; i++)); do
9327                 touch $DIR/$tdir/f$i
9328         done
9329 }
9330
9331 test_60i() {
9332         changelog_register || error "changelog_register failed"
9333         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9334         changelog_users $SINGLEMDS | grep -q $cl_user ||
9335                 error "User $cl_user not found in changelog_users"
9336         changelog_chmask "ALL"
9337         t60i_load &
9338         local PID=$!
9339         for((i=0; i<100; i++)); do
9340                 changelog_dump >/dev/null ||
9341                         error "can't read changelog"
9342         done
9343         kill $PID
9344         wait $PID
9345         changelog_deregister || error "changelog_deregister failed"
9346         $LCTL set_param fail_loc=0
9347 }
9348 run_test 60i "llog: new record vs reader race"
9349
9350 test_60j() {
9351         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9352                 skip "need MDS version at least 2.15.50"
9353         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9354         remote_mds_nodsh && skip "remote MDS with nodsh"
9355         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9356
9357         changelog_users $SINGLEMDS | grep "^cl" &&
9358                 skip "active changelog user"
9359
9360         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9361
9362         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9363                 skip_env "missing llog_reader"
9364
9365         mkdir_on_mdt0 $DIR/$tdir
9366
9367         local f=$DIR/$tdir/$tfile
9368         local mdt_dev
9369         local tmpfile
9370         local plain
9371
9372         changelog_register || error "cannot register changelog user"
9373
9374         # set changelog_mask to ALL
9375         changelog_chmask "ALL"
9376         changelog_clear
9377
9378         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9379         unlinkmany ${f}- 100 || error "unlinkmany failed"
9380
9381         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9382         mdt_dev=$(facet_device $SINGLEMDS)
9383
9384         do_facet $SINGLEMDS sync
9385         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9386                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9387                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9388
9389         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9390
9391         # if $tmpfile is not on EXT3 filesystem for some reason
9392         [[ ${plain:0:1} == 'O' ]] ||
9393                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9394
9395         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9396                 $mdt_dev; stat -c %s $tmpfile")
9397         echo "Truncate llog from $size to $((size - size % 8192))"
9398         size=$((size - size % 8192))
9399         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9400         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9401                 grep -c 'in bitmap only')
9402         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9403
9404         size=$((size - 9000))
9405         echo "Corrupt llog in the middle at $size"
9406         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9407                 count=333 conv=notrunc
9408         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9409                 grep -c 'next chunk')
9410         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9411 }
9412 run_test 60j "llog_reader reports corruptions"
9413
9414 test_61a() {
9415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9416
9417         f="$DIR/f61"
9418         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9419         cancel_lru_locks osc
9420         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9421         sync
9422 }
9423 run_test 61a "mmap() writes don't make sync hang ================"
9424
9425 test_61b() {
9426         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9427 }
9428 run_test 61b "mmap() of unstriped file is successful"
9429
9430 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9431 # Though this test is irrelevant anymore, it helped to reveal some
9432 # other grant bugs (LU-4482), let's keep it.
9433 test_63a() {   # was test_63
9434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9435
9436         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9437
9438         for i in `seq 10` ; do
9439                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9440                 sleep 5
9441                 kill $!
9442                 sleep 1
9443         done
9444
9445         rm -f $DIR/f63 || true
9446 }
9447 run_test 63a "Verify oig_wait interruption does not crash ======="
9448
9449 # bug 2248 - async write errors didn't return to application on sync
9450 # bug 3677 - async write errors left page locked
9451 test_63b() {
9452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9453
9454         debugsave
9455         lctl set_param debug=-1
9456
9457         # ensure we have a grant to do async writes
9458         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9459         rm $DIR/$tfile
9460
9461         sync    # sync lest earlier test intercept the fail_loc
9462
9463         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9464         lctl set_param fail_loc=0x80000406
9465         $MULTIOP $DIR/$tfile Owy && \
9466                 error "sync didn't return ENOMEM"
9467         sync; sleep 2; sync     # do a real sync this time to flush page
9468         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9469                 error "locked page left in cache after async error" || true
9470         debugrestore
9471 }
9472 run_test 63b "async write errors should be returned to fsync ==="
9473
9474 test_64a () {
9475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9476
9477         lfs df $DIR
9478         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9479 }
9480 run_test 64a "verify filter grant calculations (in kernel) ====="
9481
9482 test_64b () {
9483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9484
9485         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9486 }
9487 run_test 64b "check out-of-space detection on client"
9488
9489 test_64c() {
9490         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9491 }
9492 run_test 64c "verify grant shrink"
9493
9494 import_param() {
9495         local tgt=$1
9496         local param=$2
9497
9498         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9499 }
9500
9501 # this does exactly what osc_request.c:osc_announce_cached() does in
9502 # order to calculate max amount of grants to ask from server
9503 want_grant() {
9504         local tgt=$1
9505
9506         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9507         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9508
9509         ((rpc_in_flight++));
9510         nrpages=$((nrpages * rpc_in_flight))
9511
9512         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9513
9514         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9515
9516         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9517         local undirty=$((nrpages * PAGE_SIZE))
9518
9519         local max_extent_pages
9520         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9521         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9522         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9523         local grant_extent_tax
9524         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9525
9526         undirty=$((undirty + nrextents * grant_extent_tax))
9527
9528         echo $undirty
9529 }
9530
9531 # this is size of unit for grant allocation. It should be equal to
9532 # what tgt_grant.c:tgt_grant_chunk() calculates
9533 grant_chunk() {
9534         local tgt=$1
9535         local max_brw_size
9536         local grant_extent_tax
9537
9538         max_brw_size=$(import_param $tgt max_brw_size)
9539
9540         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9541
9542         echo $(((max_brw_size + grant_extent_tax) * 2))
9543 }
9544
9545 test_64d() {
9546         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9547                 skip "OST < 2.10.55 doesn't limit grants enough"
9548
9549         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9550
9551         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9552                 skip "no grant_param connect flag"
9553
9554         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9555
9556         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9557         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9558
9559
9560         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9561         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9562
9563         $LFS setstripe $DIR/$tfile -i 0 -c 1
9564         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9565         ddpid=$!
9566
9567         while kill -0 $ddpid; do
9568                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9569
9570                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9571                         kill $ddpid
9572                         error "cur_grant $cur_grant > $max_cur_granted"
9573                 fi
9574
9575                 sleep 1
9576         done
9577 }
9578 run_test 64d "check grant limit exceed"
9579
9580 check_grants() {
9581         local tgt=$1
9582         local expected=$2
9583         local msg=$3
9584         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9585
9586         ((cur_grants == expected)) ||
9587                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9588 }
9589
9590 round_up_p2() {
9591         echo $((($1 + $2 - 1) & ~($2 - 1)))
9592 }
9593
9594 test_64e() {
9595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9596         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9597                 skip "Need OSS version at least 2.11.56"
9598
9599         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9600         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9601         $LCTL set_param debug=+cache
9602
9603         # Remount client to reset grant
9604         remount_client $MOUNT || error "failed to remount client"
9605         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9606
9607         local init_grants=$(import_param $osc_tgt initial_grant)
9608
9609         check_grants $osc_tgt $init_grants "init grants"
9610
9611         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9612         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9613         local gbs=$(import_param $osc_tgt grant_block_size)
9614
9615         # write random number of bytes from max_brw_size / 4 to max_brw_size
9616         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9617         # align for direct io
9618         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9619         # round to grant consumption unit
9620         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9621
9622         local grants=$((wb_round_up + extent_tax))
9623
9624         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9625         stack_trap "rm -f $DIR/$tfile"
9626
9627         # define OBD_FAIL_TGT_NO_GRANT 0x725
9628         # make the server not grant more back
9629         do_facet ost1 $LCTL set_param fail_loc=0x725
9630         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9631
9632         do_facet ost1 $LCTL set_param fail_loc=0
9633
9634         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9635
9636         rm -f $DIR/$tfile || error "rm failed"
9637
9638         # Remount client to reset grant
9639         remount_client $MOUNT || error "failed to remount client"
9640         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9641
9642         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9643
9644         # define OBD_FAIL_TGT_NO_GRANT 0x725
9645         # make the server not grant more back
9646         do_facet ost1 $LCTL set_param fail_loc=0x725
9647         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9648         do_facet ost1 $LCTL set_param fail_loc=0
9649
9650         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9651 }
9652 run_test 64e "check grant consumption (no grant allocation)"
9653
9654 test_64f() {
9655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9656
9657         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9658         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9659         $LCTL set_param debug=+cache
9660
9661         # Remount client to reset grant
9662         remount_client $MOUNT || error "failed to remount client"
9663         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9664
9665         local init_grants=$(import_param $osc_tgt initial_grant)
9666         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9667         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9668         local gbs=$(import_param $osc_tgt grant_block_size)
9669         local chunk=$(grant_chunk $osc_tgt)
9670
9671         # write random number of bytes from max_brw_size / 4 to max_brw_size
9672         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9673         # align for direct io
9674         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9675         # round to grant consumption unit
9676         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9677
9678         local grants=$((wb_round_up + extent_tax))
9679
9680         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9681         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9682                 error "error writing to $DIR/$tfile"
9683
9684         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9685                 "direct io with grant allocation"
9686
9687         rm -f $DIR/$tfile || error "rm failed"
9688
9689         # Remount client to reset grant
9690         remount_client $MOUNT || error "failed to remount client"
9691         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9692
9693         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9694
9695         # Testing that buffered IO consumes grant on the client
9696
9697         # Delay the RPC on the server so it's guaranteed to not complete even
9698         # if the RPC is sent from the client
9699         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9700         $LCTL set_param fail_loc=0x50a fail_val=3
9701         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9702                 error "error writing to $DIR/$tfile with buffered IO"
9703
9704         check_grants $osc_tgt $((init_grants - grants)) \
9705                 "buffered io, not write rpc"
9706
9707         # Clear the fail loc and do a sync on the client
9708         $LCTL set_param fail_loc=0 fail_val=0
9709         sync
9710
9711         # RPC is now known to have sent
9712         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9713                 "buffered io, one RPC"
9714 }
9715 run_test 64f "check grant consumption (with grant allocation)"
9716
9717 test_64g() {
9718         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9719                 skip "Need MDS version at least 2.14.56"
9720
9721         local mdts=$(comma_list $(mdts_nodes))
9722
9723         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9724                         tr '\n' ' ')
9725         stack_trap "$LCTL set_param $old"
9726
9727         # generate dirty pages and increase dirty granted on MDT
9728         stack_trap "rm -f $DIR/$tfile-*"
9729         for (( i = 0; i < 10; i++)); do
9730                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9731                         error "can't set stripe"
9732                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9733                         error "can't dd"
9734                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9735                         $LFS getstripe $DIR/$tfile-$i
9736                         error "not DoM file"
9737                 }
9738         done
9739
9740         # flush dirty pages
9741         sync
9742
9743         # wait until grant shrink reset grant dirty on MDTs
9744         for ((i = 0; i < 120; i++)); do
9745                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9746                         awk '{sum=sum+$1} END {print sum}')
9747                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9748                 echo "$grant_dirty grants, $vm_dirty pages"
9749                 (( grant_dirty + vm_dirty == 0 )) && break
9750                 (( i == 3 )) && sync &&
9751                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9752                 sleep 1
9753         done
9754
9755         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9756                 awk '{sum=sum+$1} END {print sum}')
9757         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9758 }
9759 run_test 64g "grant shrink on MDT"
9760
9761 test_64h() {
9762         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9763                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9764
9765         local instance=$($LFS getname -i $DIR)
9766         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9767         local num_exps=$(do_facet ost1 \
9768             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9769         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9770         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9771         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9772
9773         # 10MiB is for file to be written, max_brw_size * 16 *
9774         # num_exps is space reserve so that tgt_grant_shrink() decided
9775         # to not shrink
9776         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9777         (( avail * 1024 < expect )) &&
9778                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9779
9780         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9781         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9782         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9783         $LCTL set_param osc.*OST0000*.grant_shrink=1
9784         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9785
9786         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9787         stack_trap "rm -f $DIR/$tfile"
9788         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9789
9790         # drop cache so that coming read would do rpc
9791         cancel_lru_locks osc
9792
9793         # shrink interval is set to 10, pause for 7 seconds so that
9794         # grant thread did not wake up yet but coming read entered
9795         # shrink mode for rpc (osc_should_shrink_grant())
9796         sleep 7
9797
9798         declare -a cur_grant_bytes
9799         declare -a tot_granted
9800         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9801         tot_granted[0]=$(do_facet ost1 \
9802             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9803
9804         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9805
9806         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9807         tot_granted[1]=$(do_facet ost1 \
9808             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9809
9810         # grant change should be equal on both sides
9811         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9812                 tot_granted[0] - tot_granted[1])) ||
9813                 error "grant change mismatch, "                                \
9814                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9815                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9816 }
9817 run_test 64h "grant shrink on read"
9818
9819 test_64i() {
9820         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9821                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9822
9823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9824         remote_ost_nodsh && skip "remote OSTs with nodsh"
9825
9826         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9827         stack_trap "rm -f $DIR/$tfile"
9828
9829         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9830
9831         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9832         local instance=$($LFS getname -i $DIR)
9833
9834         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9835         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9836
9837         # shrink grants and simulate rpc loss
9838         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9839         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9840         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9841
9842         fail ost1
9843
9844         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9845
9846         local testid=$(echo $TESTNAME | tr '_' ' ')
9847
9848         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9849                 grep "GRANT, real grant" &&
9850                 error "client has more grants then it owns" || true
9851 }
9852 run_test 64i "shrink on reconnect"
9853
9854 # bug 1414 - set/get directories' stripe info
9855 test_65a() {
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857
9858         test_mkdir $DIR/$tdir
9859         touch $DIR/$tdir/f1
9860         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9861 }
9862 run_test 65a "directory with no stripe info"
9863
9864 test_65b() {
9865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9866
9867         test_mkdir $DIR/$tdir
9868         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9869
9870         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9871                                                 error "setstripe"
9872         touch $DIR/$tdir/f2
9873         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9874 }
9875 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9876
9877 test_65c() {
9878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9879         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9880
9881         test_mkdir $DIR/$tdir
9882         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9883
9884         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9885                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9886         touch $DIR/$tdir/f3
9887         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9888 }
9889 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9890
9891 test_65d() {
9892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9893
9894         test_mkdir $DIR/$tdir
9895         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9896         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9897
9898         if [[ $STRIPECOUNT -le 0 ]]; then
9899                 sc=1
9900         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9901                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9902                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9903         else
9904                 sc=$(($STRIPECOUNT - 1))
9905         fi
9906         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9907         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9908         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9909                 error "lverify failed"
9910 }
9911 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9912
9913 test_65e() {
9914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9915
9916         # LU-16904 delete layout when root is set as PFL layout
9917         save_layout_restore_at_exit $MOUNT
9918         $LFS setstripe -d $MOUNT || error "setstripe failed"
9919
9920         test_mkdir $DIR/$tdir
9921
9922         $LFS setstripe $DIR/$tdir || error "setstripe"
9923         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9924                                         error "no stripe info failed"
9925         touch $DIR/$tdir/f6
9926         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9927 }
9928 run_test 65e "directory setstripe defaults"
9929
9930 test_65f() {
9931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9932
9933         test_mkdir $DIR/${tdir}f
9934         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9935                 error "setstripe succeeded" || true
9936 }
9937 run_test 65f "dir setstripe permission (should return error) ==="
9938
9939 test_65g() {
9940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9941
9942         # LU-16904 delete layout when root is set as PFL layout
9943         save_layout_restore_at_exit $MOUNT
9944         $LFS setstripe -d $MOUNT || error "setstripe failed"
9945
9946         test_mkdir $DIR/$tdir
9947         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9948
9949         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9950                 error "setstripe -S failed"
9951         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9952         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9953                 error "delete default stripe failed"
9954 }
9955 run_test 65g "directory setstripe -d"
9956
9957 test_65h() {
9958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9959
9960         test_mkdir $DIR/$tdir
9961         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9962
9963         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9964                 error "setstripe -S failed"
9965         test_mkdir $DIR/$tdir/dd1
9966         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9967                 error "stripe info inherit failed"
9968 }
9969 run_test 65h "directory stripe info inherit ===================="
9970
9971 test_65i() {
9972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9973
9974         save_layout_restore_at_exit $MOUNT
9975
9976         # bug6367: set non-default striping on root directory
9977         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9978
9979         # bug12836: getstripe on -1 default directory striping
9980         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9981
9982         # bug12836: getstripe -v on -1 default directory striping
9983         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9984
9985         # bug12836: new find on -1 default directory striping
9986         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9987 }
9988 run_test 65i "various tests to set root directory striping"
9989
9990 test_65j() { # bug6367
9991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9992
9993         sync; sleep 1
9994
9995         # if we aren't already remounting for each test, do so for this test
9996         if [ "$I_MOUNTED" = "yes" ]; then
9997                 cleanup || error "failed to unmount"
9998                 setup
9999         fi
10000
10001         save_layout_restore_at_exit $MOUNT
10002
10003         $LFS setstripe -d $MOUNT || error "setstripe failed"
10004 }
10005 run_test 65j "set default striping on root directory (bug 6367)="
10006
10007 cleanup_65k() {
10008         rm -rf $DIR/$tdir
10009         wait_delete_completed
10010         do_facet $SINGLEMDS "lctl set_param -n \
10011                 osp.$ost*MDT0000.max_create_count=$max_count"
10012         do_facet $SINGLEMDS "lctl set_param -n \
10013                 osp.$ost*MDT0000.create_count=$count"
10014         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10015         echo $INACTIVE_OSC "is Activate"
10016
10017         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10018 }
10019
10020 test_65k() { # bug11679
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10023         remote_mds_nodsh && skip "remote MDS with nodsh"
10024
10025         local disable_precreate=true
10026         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10027                 disable_precreate=false
10028
10029         echo "Check OST status: "
10030         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10031                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10032
10033         for OSC in $MDS_OSCS; do
10034                 echo $OSC "is active"
10035                 do_facet $SINGLEMDS lctl --device %$OSC activate
10036         done
10037
10038         for INACTIVE_OSC in $MDS_OSCS; do
10039                 local ost=$(osc_to_ost $INACTIVE_OSC)
10040                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10041                                lov.*md*.target_obd |
10042                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10043
10044                 mkdir -p $DIR/$tdir
10045                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10046                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10047
10048                 echo "Deactivate: " $INACTIVE_OSC
10049                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10050
10051                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10052                               osp.$ost*MDT0000.create_count")
10053                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10054                                   osp.$ost*MDT0000.max_create_count")
10055                 $disable_precreate &&
10056                         do_facet $SINGLEMDS "lctl set_param -n \
10057                                 osp.$ost*MDT0000.max_create_count=0"
10058
10059                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10060                         [ -f $DIR/$tdir/$idx ] && continue
10061                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10062                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10063                                 { cleanup_65k;
10064                                   error "setstripe $idx should succeed"; }
10065                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10066                 done
10067                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10068                 rmdir $DIR/$tdir
10069
10070                 do_facet $SINGLEMDS "lctl set_param -n \
10071                         osp.$ost*MDT0000.max_create_count=$max_count"
10072                 do_facet $SINGLEMDS "lctl set_param -n \
10073                         osp.$ost*MDT0000.create_count=$count"
10074                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10075                 echo $INACTIVE_OSC "is Activate"
10076
10077                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10078         done
10079 }
10080 run_test 65k "validate manual striping works properly with deactivated OSCs"
10081
10082 test_65l() { # bug 12836
10083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10084
10085         test_mkdir -p $DIR/$tdir/test_dir
10086         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10087         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10088 }
10089 run_test 65l "lfs find on -1 stripe dir ========================"
10090
10091 test_65m() {
10092         local layout=$(save_layout $MOUNT)
10093         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10094                 restore_layout $MOUNT $layout
10095                 error "setstripe should fail by non-root users"
10096         }
10097         true
10098 }
10099 run_test 65m "normal user can't set filesystem default stripe"
10100
10101 test_65n() {
10102         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10103         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10104                 skip "Need MDS version at least 2.12.50"
10105         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10106
10107         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10108         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10109         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10110
10111         save_layout_restore_at_exit $MOUNT
10112
10113         # new subdirectory under root directory should not inherit
10114         # the default layout from root
10115         # LU-16904 check if the root is set as PFL layout
10116         local numcomp=$($LFS getstripe --component-count $MOUNT)
10117
10118         if [[ $numcomp -eq 0 ]]; then
10119                 local dir1=$MOUNT/$tdir-1
10120                 mkdir $dir1 || error "mkdir $dir1 failed"
10121                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10122                         error "$dir1 shouldn't have LOV EA"
10123         fi
10124
10125         # delete the default layout on root directory
10126         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10127
10128         local dir2=$MOUNT/$tdir-2
10129         mkdir $dir2 || error "mkdir $dir2 failed"
10130         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10131                 error "$dir2 shouldn't have LOV EA"
10132
10133         # set a new striping pattern on root directory
10134         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10135         local new_def_stripe_size=$((def_stripe_size * 2))
10136         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10137                 error "set stripe size on $MOUNT failed"
10138
10139         # new file created in $dir2 should inherit the new stripe size from
10140         # the filesystem default
10141         local file2=$dir2/$tfile-2
10142         touch $file2 || error "touch $file2 failed"
10143
10144         local file2_stripe_size=$($LFS getstripe -S $file2)
10145         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10146         {
10147                 echo "file2_stripe_size: '$file2_stripe_size'"
10148                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10149                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10150         }
10151
10152         local dir3=$MOUNT/$tdir-3
10153         mkdir $dir3 || error "mkdir $dir3 failed"
10154         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10155         # the root layout, which is the actual default layout that will be used
10156         # when new files are created in $dir3.
10157         local dir3_layout=$(get_layout_param $dir3)
10158         local root_dir_layout=$(get_layout_param $MOUNT)
10159         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10160         {
10161                 echo "dir3_layout: '$dir3_layout'"
10162                 echo "root_dir_layout: '$root_dir_layout'"
10163                 error "$dir3 should show the default layout from $MOUNT"
10164         }
10165
10166         # set OST pool on root directory
10167         local pool=$TESTNAME
10168         pool_add $pool || error "add $pool failed"
10169         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10170                 error "add targets to $pool failed"
10171
10172         $LFS setstripe -p $pool $MOUNT ||
10173                 error "set OST pool on $MOUNT failed"
10174
10175         # new file created in $dir3 should inherit the pool from
10176         # the filesystem default
10177         local file3=$dir3/$tfile-3
10178         touch $file3 || error "touch $file3 failed"
10179
10180         local file3_pool=$($LFS getstripe -p $file3)
10181         [[ "$file3_pool" = "$pool" ]] ||
10182                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10183
10184         local dir4=$MOUNT/$tdir-4
10185         mkdir $dir4 || error "mkdir $dir4 failed"
10186         local dir4_layout=$(get_layout_param $dir4)
10187         root_dir_layout=$(get_layout_param $MOUNT)
10188         echo "$LFS getstripe -d $dir4"
10189         $LFS getstripe -d $dir4
10190         echo "$LFS getstripe -d $MOUNT"
10191         $LFS getstripe -d $MOUNT
10192         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10193         {
10194                 echo "dir4_layout: '$dir4_layout'"
10195                 echo "root_dir_layout: '$root_dir_layout'"
10196                 error "$dir4 should show the default layout from $MOUNT"
10197         }
10198
10199         # new file created in $dir4 should inherit the pool from
10200         # the filesystem default
10201         local file4=$dir4/$tfile-4
10202         touch $file4 || error "touch $file4 failed"
10203
10204         local file4_pool=$($LFS getstripe -p $file4)
10205         [[ "$file4_pool" = "$pool" ]] ||
10206                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10207
10208         # new subdirectory under non-root directory should inherit
10209         # the default layout from its parent directory
10210         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10211                 error "set directory layout on $dir4 failed"
10212
10213         local dir5=$dir4/$tdir-5
10214         mkdir $dir5 || error "mkdir $dir5 failed"
10215
10216         dir4_layout=$(get_layout_param $dir4)
10217         local dir5_layout=$(get_layout_param $dir5)
10218         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10219         {
10220                 echo "dir4_layout: '$dir4_layout'"
10221                 echo "dir5_layout: '$dir5_layout'"
10222                 error "$dir5 should inherit the default layout from $dir4"
10223         }
10224
10225         # though subdir under ROOT doesn't inherit default layout, but
10226         # its sub dir/file should be created with default layout.
10227         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10228         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10229                 skip "Need MDS version at least 2.12.59"
10230
10231         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10232         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10233         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10234
10235         if [ $default_lmv_hash == "none" ]; then
10236                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10237         else
10238                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10239                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10240         fi
10241
10242         $LFS setdirstripe -D -c 2 $MOUNT ||
10243                 error "setdirstripe -D -c 2 failed"
10244         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10245         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10246         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10247
10248         # $dir4 layout includes pool
10249         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10250         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10251                 error "pool lost on setstripe"
10252         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10253         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10254                 error "pool lost on compound layout setstripe"
10255 }
10256 run_test 65n "don't inherit default layout from root for new subdirectories"
10257
10258 test_65o() {
10259         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10260                 skip "need MDS version at least 2.14.57"
10261
10262         # set OST pool on root directory
10263         local pool=$TESTNAME
10264
10265         pool_add $pool || error "add $pool failed"
10266         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10267                 error "add targets to $pool failed"
10268
10269         local dir1=$MOUNT/$tdir
10270
10271         mkdir $dir1 || error "mkdir $dir1 failed"
10272
10273         # set a new striping pattern on root directory
10274         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10275
10276         $LFS setstripe -p $pool $dir1 ||
10277                 error "set directory layout on $dir1 failed"
10278
10279         # $dir1 layout includes pool
10280         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10281         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10282                 error "pool lost on setstripe"
10283         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10284         $LFS getstripe $dir1
10285         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10286                 error "pool lost on compound layout setstripe"
10287
10288         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10289                 error "setdirstripe failed on sub-dir with inherited pool"
10290         $LFS getstripe $dir1/dir2
10291         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10292                 error "pool lost on compound layout setdirstripe"
10293
10294         $LFS setstripe -E -1 -c 1 $dir1
10295         $LFS getstripe -d $dir1
10296         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10297                 error "pool lost on setstripe"
10298 }
10299 run_test 65o "pool inheritance for mdt component"
10300
10301 test_65p () { # LU-16152
10302         local src_dir=$DIR/$tdir/src_dir
10303         local dst_dir=$DIR/$tdir/dst_dir
10304         local yaml_file=$DIR/$tdir/layout.yaml
10305         local border
10306
10307         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10308                 skip "Need at least version 2.15.51"
10309
10310         test_mkdir -p $src_dir
10311         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10312                 error "failed to setstripe"
10313         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10314                 error "failed to getstripe"
10315
10316         test_mkdir -p $dst_dir
10317         $LFS setstripe --yaml $yaml_file $dst_dir ||
10318                 error "failed to setstripe with yaml file"
10319         border=$($LFS getstripe -d $dst_dir |
10320                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10321                 error "failed to getstripe"
10322
10323         # 2048M is 0x80000000, or 2147483648
10324         (( $border == 2147483648 )) ||
10325                 error "failed to handle huge number in yaml layout"
10326 }
10327 run_test 65p "setstripe with yaml file and huge number"
10328
10329 # bug 2543 - update blocks count on client
10330 test_66() {
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332
10333         local COUNT=${COUNT:-8}
10334         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10335         sync; sync_all_data; sync; sync_all_data
10336         cancel_lru_locks osc
10337         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10338         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10339 }
10340 run_test 66 "update inode blocks count on client ==============="
10341
10342 meminfo() {
10343         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10344 }
10345
10346 swap_used() {
10347         swapon -s | awk '($1 == "'$1'") { print $4 }'
10348 }
10349
10350 # bug5265, obdfilter oa2dentry return -ENOENT
10351 # #define OBD_FAIL_SRV_ENOENT 0x217
10352 test_69() {
10353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10354         remote_ost_nodsh && skip "remote OST with nodsh"
10355
10356         f="$DIR/$tfile"
10357         $LFS setstripe -c 1 -i 0 $f
10358         stack_trap "rm -f $f ${f}.2"
10359
10360         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10361
10362         do_facet ost1 lctl set_param fail_loc=0x217
10363         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10364         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10365
10366         do_facet ost1 lctl set_param fail_loc=0
10367         $DIRECTIO write $f 0 2 || error "write error"
10368
10369         cancel_lru_locks osc
10370         $DIRECTIO read $f 0 1 || error "read error"
10371
10372         do_facet ost1 lctl set_param fail_loc=0x217
10373         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10374
10375         do_facet ost1 lctl set_param fail_loc=0
10376 }
10377 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10378
10379 test_71() {
10380         test_mkdir $DIR/$tdir
10381         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10382         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10383 }
10384 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10385
10386 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10388         [ "$RUNAS_ID" = "$UID" ] &&
10389                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10390         # Check that testing environment is properly set up. Skip if not
10391         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10392                 skip_env "User $RUNAS_ID does not exist - skipping"
10393
10394         touch $DIR/$tfile
10395         chmod 777 $DIR/$tfile
10396         chmod ug+s $DIR/$tfile
10397         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10398                 error "$RUNAS dd $DIR/$tfile failed"
10399         # See if we are still setuid/sgid
10400         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10401                 error "S/gid is not dropped on write"
10402         # Now test that MDS is updated too
10403         cancel_lru_locks mdc
10404         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10405                 error "S/gid is not dropped on MDS"
10406         rm -f $DIR/$tfile
10407 }
10408 run_test 72a "Test that remove suid works properly (bug5695) ===="
10409
10410 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10411         local perm
10412
10413         [ "$RUNAS_ID" = "$UID" ] &&
10414                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10415         [ "$RUNAS_ID" -eq 0 ] &&
10416                 skip_env "RUNAS_ID = 0 -- skipping"
10417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10418         # Check that testing environment is properly set up. Skip if not
10419         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10420                 skip_env "User $RUNAS_ID does not exist - skipping"
10421
10422         touch $DIR/${tfile}-f{g,u}
10423         test_mkdir $DIR/${tfile}-dg
10424         test_mkdir $DIR/${tfile}-du
10425         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10426         chmod g+s $DIR/${tfile}-{f,d}g
10427         chmod u+s $DIR/${tfile}-{f,d}u
10428         for perm in 777 2777 4777; do
10429                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10430                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10431                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10432                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10433         done
10434         true
10435 }
10436 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10437
10438 # bug 3462 - multiple simultaneous MDC requests
10439 test_73() {
10440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10441
10442         test_mkdir $DIR/d73-1
10443         test_mkdir $DIR/d73-2
10444         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10445         pid1=$!
10446
10447         lctl set_param fail_loc=0x80000129
10448         $MULTIOP $DIR/d73-1/f73-2 Oc &
10449         sleep 1
10450         lctl set_param fail_loc=0
10451
10452         $MULTIOP $DIR/d73-2/f73-3 Oc &
10453         pid3=$!
10454
10455         kill -USR1 $pid1
10456         wait $pid1 || return 1
10457
10458         sleep 25
10459
10460         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10461         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10462         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10463
10464         rm -rf $DIR/d73-*
10465 }
10466 run_test 73 "multiple MDC requests (should not deadlock)"
10467
10468 test_74a() { # bug 6149, 6184
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470
10471         touch $DIR/f74a
10472         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10473         #
10474         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10475         # will spin in a tight reconnection loop
10476         $LCTL set_param fail_loc=0x8000030e
10477         # get any lock that won't be difficult - lookup works.
10478         ls $DIR/f74a
10479         $LCTL set_param fail_loc=0
10480         rm -f $DIR/f74a
10481         true
10482 }
10483 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10484
10485 test_74b() { # bug 13310
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487
10488         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10489         #
10490         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10491         # will spin in a tight reconnection loop
10492         $LCTL set_param fail_loc=0x8000030e
10493         # get a "difficult" lock
10494         touch $DIR/f74b
10495         $LCTL set_param fail_loc=0
10496         rm -f $DIR/f74b
10497         true
10498 }
10499 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10500
10501 test_74c() {
10502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10503
10504         #define OBD_FAIL_LDLM_NEW_LOCK
10505         $LCTL set_param fail_loc=0x319
10506         touch $DIR/$tfile && error "touch successful"
10507         $LCTL set_param fail_loc=0
10508         true
10509 }
10510 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10511
10512 slab_lic=/sys/kernel/slab/lustre_inode_cache
10513 num_objects() {
10514         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10515         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10516                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10517 }
10518
10519 test_76a() { # Now for b=20433, added originally in b=1443
10520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10521
10522         cancel_lru_locks osc
10523         # there may be some slab objects cached per core
10524         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10525         local before=$(num_objects)
10526         local count=$((512 * cpus))
10527         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10528         local margin=$((count / 10))
10529         if [[ -f $slab_lic/aliases ]]; then
10530                 local aliases=$(cat $slab_lic/aliases)
10531                 (( aliases > 0 )) && margin=$((margin * aliases))
10532         fi
10533
10534         echo "before slab objects: $before"
10535         for i in $(seq $count); do
10536                 touch $DIR/$tfile
10537                 rm -f $DIR/$tfile
10538         done
10539         cancel_lru_locks osc
10540         local after=$(num_objects)
10541         echo "created: $count, after slab objects: $after"
10542         # shared slab counts are not very accurate, allow significant margin
10543         # the main goal is that the cache growth is not permanently > $count
10544         while (( after > before + margin )); do
10545                 sleep 1
10546                 after=$(num_objects)
10547                 wait=$((wait + 1))
10548                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10549                 if (( wait > 60 )); then
10550                         error "inode slab grew from $before+$margin to $after"
10551                 fi
10552         done
10553 }
10554 run_test 76a "confirm clients recycle inodes properly ===="
10555
10556 test_76b() {
10557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10558         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10559
10560         local count=512
10561         local before=$(num_objects)
10562
10563         for i in $(seq $count); do
10564                 mkdir $DIR/$tdir
10565                 rmdir $DIR/$tdir
10566         done
10567
10568         local after=$(num_objects)
10569         local wait=0
10570
10571         while (( after > before )); do
10572                 sleep 1
10573                 after=$(num_objects)
10574                 wait=$((wait + 1))
10575                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10576                 if (( wait > 60 )); then
10577                         error "inode slab grew from $before to $after"
10578                 fi
10579         done
10580
10581         echo "slab objects before: $before, after: $after"
10582 }
10583 run_test 76b "confirm clients recycle directory inodes properly ===="
10584
10585 export ORIG_CSUM=""
10586 set_checksums()
10587 {
10588         # Note: in sptlrpc modes which enable its own bulk checksum, the
10589         # original crc32_le bulk checksum will be automatically disabled,
10590         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10591         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10592         # In this case set_checksums() will not be no-op, because sptlrpc
10593         # bulk checksum will be enabled all through the test.
10594
10595         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10596         lctl set_param -n osc.*.checksums $1
10597         return 0
10598 }
10599
10600 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10601                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10602 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10603                              tr -d [] | head -n1)}
10604 set_checksum_type()
10605 {
10606         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10607         rc=$?
10608         log "set checksum type to $1, rc = $rc"
10609         return $rc
10610 }
10611
10612 get_osc_checksum_type()
10613 {
10614         # arugment 1: OST name, like OST0000
10615         ost=$1
10616         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10617                         sed 's/.*\[\(.*\)\].*/\1/g')
10618         rc=$?
10619         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10620         echo $checksum_type
10621 }
10622
10623 F77_TMP=$TMP/f77-temp
10624 F77SZ=8
10625 setup_f77() {
10626         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10627                 error "error writing to $F77_TMP"
10628 }
10629
10630 test_77a() { # bug 10889
10631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10632         $GSS && skip_env "could not run with gss"
10633
10634         [ ! -f $F77_TMP ] && setup_f77
10635         set_checksums 1
10636         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10637         set_checksums 0
10638         rm -f $DIR/$tfile
10639 }
10640 run_test 77a "normal checksum read/write operation"
10641
10642 test_77b() { # bug 10889
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644         $GSS && skip_env "could not run with gss"
10645
10646         [ ! -f $F77_TMP ] && setup_f77
10647         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10648         $LCTL set_param fail_loc=0x80000409
10649         set_checksums 1
10650
10651         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10652                 error "dd error: $?"
10653         $LCTL set_param fail_loc=0
10654
10655         for algo in $CKSUM_TYPES; do
10656                 cancel_lru_locks osc
10657                 set_checksum_type $algo
10658                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10659                 $LCTL set_param fail_loc=0x80000408
10660                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10661                 $LCTL set_param fail_loc=0
10662         done
10663         set_checksums 0
10664         set_checksum_type $ORIG_CSUM_TYPE
10665         rm -f $DIR/$tfile
10666 }
10667 run_test 77b "checksum error on client write, read"
10668
10669 cleanup_77c() {
10670         trap 0
10671         set_checksums 0
10672         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10673         $check_ost &&
10674                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10675         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10676         $check_ost && [ -n "$ost_file_prefix" ] &&
10677                 do_facet ost1 rm -f ${ost_file_prefix}\*
10678 }
10679
10680 test_77c() {
10681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10682         $GSS && skip_env "could not run with gss"
10683         remote_ost_nodsh && skip "remote OST with nodsh"
10684
10685         local bad1
10686         local osc_file_prefix
10687         local osc_file
10688         local check_ost=false
10689         local ost_file_prefix
10690         local ost_file
10691         local orig_cksum
10692         local dump_cksum
10693         local fid
10694
10695         # ensure corruption will occur on first OSS/OST
10696         $LFS setstripe -i 0 $DIR/$tfile
10697
10698         [ ! -f $F77_TMP ] && setup_f77
10699         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10700                 error "dd write error: $?"
10701         fid=$($LFS path2fid $DIR/$tfile)
10702
10703         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10704         then
10705                 check_ost=true
10706                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10707                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10708         else
10709                 echo "OSS do not support bulk pages dump upon error"
10710         fi
10711
10712         osc_file_prefix=$($LCTL get_param -n debug_path)
10713         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10714
10715         trap cleanup_77c EXIT
10716
10717         set_checksums 1
10718         # enable bulk pages dump upon error on Client
10719         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10720         # enable bulk pages dump upon error on OSS
10721         $check_ost &&
10722                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10723
10724         # flush Client cache to allow next read to reach OSS
10725         cancel_lru_locks osc
10726
10727         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10728         $LCTL set_param fail_loc=0x80000408
10729         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10730         $LCTL set_param fail_loc=0
10731
10732         rm -f $DIR/$tfile
10733
10734         # check cksum dump on Client
10735         osc_file=$(ls ${osc_file_prefix}*)
10736         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10737         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10738         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10739         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10740         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10741                      cksum)
10742         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10743         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10744                 error "dump content does not match on Client"
10745
10746         $check_ost || skip "No need to check cksum dump on OSS"
10747
10748         # check cksum dump on OSS
10749         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10750         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10751         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10752         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10753         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10754                 error "dump content does not match on OSS"
10755
10756         cleanup_77c
10757 }
10758 run_test 77c "checksum error on client read with debug"
10759
10760 test_77d() { # bug 10889
10761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10762         $GSS && skip_env "could not run with gss"
10763
10764         stack_trap "rm -f $DIR/$tfile"
10765         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10766         $LCTL set_param fail_loc=0x80000409
10767         set_checksums 1
10768         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10769                 error "direct write: rc=$?"
10770         $LCTL set_param fail_loc=0
10771         set_checksums 0
10772
10773         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10774         $LCTL set_param fail_loc=0x80000408
10775         set_checksums 1
10776         cancel_lru_locks osc
10777         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10778                 error "direct read: rc=$?"
10779         $LCTL set_param fail_loc=0
10780         set_checksums 0
10781 }
10782 run_test 77d "checksum error on OST direct write, read"
10783
10784 test_77f() { # bug 10889
10785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10786         $GSS && skip_env "could not run with gss"
10787
10788         set_checksums 1
10789         stack_trap "rm -f $DIR/$tfile"
10790         for algo in $CKSUM_TYPES; do
10791                 cancel_lru_locks osc
10792                 set_checksum_type $algo
10793                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10794                 $LCTL set_param fail_loc=0x409
10795                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10796                         error "direct write succeeded"
10797                 $LCTL set_param fail_loc=0
10798         done
10799         set_checksum_type $ORIG_CSUM_TYPE
10800         set_checksums 0
10801 }
10802 run_test 77f "repeat checksum error on write (expect error)"
10803
10804 test_77g() { # bug 10889
10805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10806         $GSS && skip_env "could not run with gss"
10807         remote_ost_nodsh && skip "remote OST with nodsh"
10808
10809         [ ! -f $F77_TMP ] && setup_f77
10810
10811         local file=$DIR/$tfile
10812         stack_trap "rm -f $file" EXIT
10813
10814         $LFS setstripe -c 1 -i 0 $file
10815         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10816         do_facet ost1 lctl set_param fail_loc=0x8000021a
10817         set_checksums 1
10818         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10819                 error "write error: rc=$?"
10820         do_facet ost1 lctl set_param fail_loc=0
10821         set_checksums 0
10822
10823         cancel_lru_locks osc
10824         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10825         do_facet ost1 lctl set_param fail_loc=0x8000021b
10826         set_checksums 1
10827         cmp $F77_TMP $file || error "file compare failed"
10828         do_facet ost1 lctl set_param fail_loc=0
10829         set_checksums 0
10830 }
10831 run_test 77g "checksum error on OST write, read"
10832
10833 test_77k() { # LU-10906
10834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10835         $GSS && skip_env "could not run with gss"
10836
10837         local cksum_param="osc.$FSNAME*.checksums"
10838         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10839         local checksum
10840         local i
10841
10842         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10843         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10844         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10845
10846         for i in 0 1; do
10847                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10848                         error "failed to set checksum=$i on MGS"
10849                 wait_update $HOSTNAME "$get_checksum" $i
10850                 #remount
10851                 echo "remount client, checksum should be $i"
10852                 remount_client $MOUNT || error "failed to remount client"
10853                 checksum=$(eval $get_checksum)
10854                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10855         done
10856         # remove persistent param to avoid races with checksum mountopt below
10857         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10858                 error "failed to delete checksum on MGS"
10859
10860         for opt in "checksum" "nochecksum"; do
10861                 #remount with mount option
10862                 echo "remount client with option $opt, checksum should be $i"
10863                 umount_client $MOUNT || error "failed to umount client"
10864                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10865                         error "failed to mount client with option '$opt'"
10866                 checksum=$(eval $get_checksum)
10867                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10868                 i=$((i - 1))
10869         done
10870
10871         remount_client $MOUNT || error "failed to remount client"
10872 }
10873 run_test 77k "enable/disable checksum correctly"
10874
10875 test_77l() {
10876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10877         $GSS && skip_env "could not run with gss"
10878
10879         set_checksums 1
10880         stack_trap "set_checksums $ORIG_CSUM" EXIT
10881         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10882
10883         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10884
10885         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10886         for algo in $CKSUM_TYPES; do
10887                 set_checksum_type $algo || error "fail to set checksum type $algo"
10888                 osc_algo=$(get_osc_checksum_type OST0000)
10889                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10890
10891                 # no locks, no reqs to let the connection idle
10892                 cancel_lru_locks osc
10893                 lru_resize_disable osc
10894                 wait_osc_import_state client ost1 IDLE
10895
10896                 # ensure ost1 is connected
10897                 stat $DIR/$tfile >/dev/null || error "can't stat"
10898                 wait_osc_import_state client ost1 FULL
10899
10900                 osc_algo=$(get_osc_checksum_type OST0000)
10901                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10902         done
10903         return 0
10904 }
10905 run_test 77l "preferred checksum type is remembered after reconnected"
10906
10907 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10908 rm -f $F77_TMP
10909 unset F77_TMP
10910
10911 test_77m() {
10912         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10913                 skip "Need at least version 2.14.52"
10914         local param=checksum_speed
10915
10916         $LCTL get_param $param || error "reading $param failed"
10917
10918         csum_speeds=$($LCTL get_param -n $param)
10919
10920         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10921                 error "known checksum types are missing"
10922 }
10923 run_test 77m "Verify checksum_speed is correctly read"
10924
10925 check_filefrag_77n() {
10926         local nr_ext=0
10927         local starts=()
10928         local ends=()
10929
10930         while read extidx a b start end rest; do
10931                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10932                         nr_ext=$(( $nr_ext + 1 ))
10933                         starts+=( ${start%..} )
10934                         ends+=( ${end%:} )
10935                 fi
10936         done < <( filefrag -sv $1 )
10937
10938         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10939         return 1
10940 }
10941
10942 test_77n() {
10943         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10944
10945         touch $DIR/$tfile
10946         $TRUNCATE $DIR/$tfile 0
10947         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10948         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10949         check_filefrag_77n $DIR/$tfile ||
10950                 skip "$tfile blocks not contiguous around hole"
10951
10952         set_checksums 1
10953         stack_trap "set_checksums $ORIG_CSUM" EXIT
10954         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10955         stack_trap "rm -f $DIR/$tfile"
10956
10957         for algo in $CKSUM_TYPES; do
10958                 if [[ "$algo" =~ ^t10 ]]; then
10959                         set_checksum_type $algo ||
10960                                 error "fail to set checksum type $algo"
10961                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10962                                 error "fail to read $tfile with $algo"
10963                 fi
10964         done
10965         rm -f $DIR/$tfile
10966         return 0
10967 }
10968 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10969
10970 test_77o() {
10971         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10972                 skip "Need MDS version at least 2.14.55"
10973         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10974                 skip "Need OST version at least 2.14.55"
10975         local ofd=obdfilter
10976         local mdt=mdt
10977
10978         # print OST checksum_type
10979         echo "$ofd.$FSNAME-*.checksum_type:"
10980         do_nodes $(comma_list $(osts_nodes)) \
10981                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10982
10983         # print MDT checksum_type
10984         echo "$mdt.$FSNAME-*.checksum_type:"
10985         do_nodes $(comma_list $(mdts_nodes)) \
10986                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10987
10988         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10989                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10990
10991         (( $o_count == $OSTCOUNT )) ||
10992                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10993
10994         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10995                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10996
10997         (( $m_count == $MDSCOUNT )) ||
10998                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10999 }
11000 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11001
11002 cleanup_test_78() {
11003         trap 0
11004         rm -f $DIR/$tfile
11005 }
11006
11007 test_78() { # bug 10901
11008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11009         remote_ost || skip_env "local OST"
11010
11011         NSEQ=5
11012         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11013         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11014         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11015         echo "MemTotal: $MEMTOTAL"
11016
11017         # reserve 256MB of memory for the kernel and other running processes,
11018         # and then take 1/2 of the remaining memory for the read/write buffers.
11019         if [ $MEMTOTAL -gt 512 ] ;then
11020                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11021         else
11022                 # for those poor memory-starved high-end clusters...
11023                 MEMTOTAL=$((MEMTOTAL / 2))
11024         fi
11025         echo "Mem to use for directio: $MEMTOTAL"
11026
11027         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11028         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11029         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11030         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11031                 head -n1)
11032         echo "Smallest OST: $SMALLESTOST"
11033         [[ $SMALLESTOST -lt 10240 ]] &&
11034                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11035
11036         trap cleanup_test_78 EXIT
11037
11038         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11039                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11040
11041         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11042         echo "File size: $F78SIZE"
11043         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11044         for i in $(seq 1 $NSEQ); do
11045                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11046                 echo directIO rdwr round $i of $NSEQ
11047                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11048         done
11049
11050         cleanup_test_78
11051 }
11052 run_test 78 "handle large O_DIRECT writes correctly ============"
11053
11054 test_79() { # bug 12743
11055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11056
11057         wait_delete_completed
11058
11059         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11060         BKFREE=$(calc_osc_kbytes kbytesfree)
11061         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11062
11063         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11064         DFTOTAL=`echo $STRING | cut -d, -f1`
11065         DFUSED=`echo $STRING  | cut -d, -f2`
11066         DFAVAIL=`echo $STRING | cut -d, -f3`
11067         DFFREE=$(($DFTOTAL - $DFUSED))
11068
11069         ALLOWANCE=$((64 * $OSTCOUNT))
11070
11071         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11072            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11073                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11074         fi
11075         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11076            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11077                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11078         fi
11079         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11080            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11081                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11082         fi
11083 }
11084 run_test 79 "df report consistency check ======================="
11085
11086 test_80() { # bug 10718
11087         remote_ost_nodsh && skip "remote OST with nodsh"
11088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11089
11090         # relax strong synchronous semantics for slow backends like ZFS
11091         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11092                 local soc="obdfilter.*.sync_lock_cancel"
11093                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11094
11095                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11096                 if [ -z "$save" ]; then
11097                         soc="obdfilter.*.sync_on_lock_cancel"
11098                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11099                 fi
11100
11101                 if [ "$save" != "never" ]; then
11102                         local hosts=$(comma_list $(osts_nodes))
11103
11104                         do_nodes $hosts $LCTL set_param $soc=never
11105                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11106                 fi
11107         fi
11108
11109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11110         sync; sleep 1; sync
11111         local before=$(date +%s)
11112         cancel_lru_locks osc
11113         local after=$(date +%s)
11114         local diff=$((after - before))
11115         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11116
11117         rm -f $DIR/$tfile
11118 }
11119 run_test 80 "Page eviction is equally fast at high offsets too"
11120
11121 test_81a() { # LU-456
11122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11123         remote_ost_nodsh && skip "remote OST with nodsh"
11124
11125         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11126         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11127         do_facet ost1 lctl set_param fail_loc=0x80000228
11128
11129         # write should trigger a retry and success
11130         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11132         RC=$?
11133         if [ $RC -ne 0 ] ; then
11134                 error "write should success, but failed for $RC"
11135         fi
11136 }
11137 run_test 81a "OST should retry write when get -ENOSPC ==============="
11138
11139 test_81b() { # LU-456
11140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11141         remote_ost_nodsh && skip "remote OST with nodsh"
11142
11143         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11144         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11145         do_facet ost1 lctl set_param fail_loc=0x228
11146
11147         # write should retry several times and return -ENOSPC finally
11148         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11150         RC=$?
11151         ENOSPC=28
11152         if [ $RC -ne $ENOSPC ] ; then
11153                 error "dd should fail for -ENOSPC, but succeed."
11154         fi
11155 }
11156 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11157
11158 test_99() {
11159         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11160
11161         test_mkdir $DIR/$tdir.cvsroot
11162         chown $RUNAS_ID $DIR/$tdir.cvsroot
11163
11164         cd $TMP
11165         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11166
11167         cd /etc/init.d
11168         # some versions of cvs import exit(1) when asked to import links or
11169         # files they can't read.  ignore those files.
11170         local toignore=$(find . -type l -printf '-I %f\n' -o \
11171                          ! -perm /4 -printf '-I %f\n')
11172         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11173                 $tdir.reposname vtag rtag
11174
11175         cd $DIR
11176         test_mkdir $DIR/$tdir.reposname
11177         chown $RUNAS_ID $DIR/$tdir.reposname
11178         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11179
11180         cd $DIR/$tdir.reposname
11181         $RUNAS touch foo99
11182         $RUNAS cvs add -m 'addmsg' foo99
11183         $RUNAS cvs update
11184         $RUNAS cvs commit -m 'nomsg' foo99
11185         rm -fr $DIR/$tdir.cvsroot
11186 }
11187 run_test 99 "cvs strange file/directory operations"
11188
11189 test_100() {
11190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11191         [[ "$NETTYPE" =~ tcp ]] ||
11192                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11193         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11194         remote_ost_nodsh && skip "remote OST with nodsh"
11195         remote_mds_nodsh && skip "remote MDS with nodsh"
11196         remote_servers || skip "useless for local single node setup"
11197
11198         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11199                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11200
11201                 rc=0
11202                 if (( ${LOCAL/*:/} >= 1024 )); then
11203                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11204                         ss -tna
11205                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11206                 fi
11207         done
11208         (( $rc == 0 )) || error "privileged port not found" )
11209 }
11210 run_test 100 "check local port using privileged port"
11211
11212 function get_named_value()
11213 {
11214     local tag=$1
11215
11216     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11217 }
11218
11219 test_101a() {
11220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11221
11222         local s
11223         local discard
11224         local nreads=10000
11225         local cache_limit=32
11226
11227         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11228         $LCTL set_param -n llite.*.read_ahead_stats=0
11229         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11230                               awk '/^max_cached_mb/ { print $2 }')
11231         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11232         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11233
11234         #
11235         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11236         #
11237         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11238         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11239
11240         discard=0
11241         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11242                    get_named_value 'read.but.discarded'); do
11243                         discard=$(($discard + $s))
11244         done
11245
11246         $LCTL get_param osc.*-osc*.rpc_stats
11247         $LCTL get_param llite.*.read_ahead_stats
11248
11249         # Discard is generally zero, but sometimes a few random reads line up
11250         # and trigger larger readahead, which is wasted & leads to discards.
11251         if [[ $(($discard)) -gt $nreads ]]; then
11252                 error "too many ($discard) discarded pages"
11253         fi
11254         rm -f $DIR/$tfile || true
11255 }
11256 run_test 101a "check read-ahead for random reads"
11257
11258 setup_test101bc() {
11259         test_mkdir $DIR/$tdir
11260         local ssize=$1
11261         local FILE_LENGTH=$2
11262         STRIPE_OFFSET=0
11263
11264         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11265
11266         local list=$(comma_list $(osts_nodes))
11267         set_osd_param $list '' read_cache_enable 0
11268         set_osd_param $list '' writethrough_cache_enable 0
11269
11270         trap cleanup_test101bc EXIT
11271         # prepare the read-ahead file
11272         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11273
11274         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11275                                 count=$FILE_SIZE_MB 2> /dev/null
11276
11277 }
11278
11279 cleanup_test101bc() {
11280         trap 0
11281         rm -rf $DIR/$tdir
11282         rm -f $DIR/$tfile
11283
11284         local list=$(comma_list $(osts_nodes))
11285         set_osd_param $list '' read_cache_enable 1
11286         set_osd_param $list '' writethrough_cache_enable 1
11287 }
11288
11289 calc_total() {
11290         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11291 }
11292
11293 ra_check_101() {
11294         local read_size=$1
11295         local stripe_size=$2
11296         local stride_length=$((stripe_size / read_size))
11297         local stride_width=$((stride_length * OSTCOUNT))
11298         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11299                                 (stride_width - stride_length) ))
11300         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11301                   get_named_value 'read.but.discarded' | calc_total)
11302
11303         if [[ $discard -gt $discard_limit ]]; then
11304                 $LCTL get_param llite.*.read_ahead_stats
11305                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11306         else
11307                 echo "Read-ahead success for size ${read_size}"
11308         fi
11309 }
11310
11311 test_101b() {
11312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11313         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11314
11315         local STRIPE_SIZE=1048576
11316         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11317
11318         if [ $SLOW == "yes" ]; then
11319                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11320         else
11321                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11322         fi
11323
11324         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11325
11326         # prepare the read-ahead file
11327         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11328         cancel_lru_locks osc
11329         for BIDX in 2 4 8 16 32 64 128 256
11330         do
11331                 local BSIZE=$((BIDX*4096))
11332                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11333                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11334                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11335                 $LCTL set_param -n llite.*.read_ahead_stats=0
11336                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11337                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11338                 cancel_lru_locks osc
11339                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11340         done
11341         cleanup_test101bc
11342         true
11343 }
11344 run_test 101b "check stride-io mode read-ahead ================="
11345
11346 test_101c() {
11347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11348
11349         local STRIPE_SIZE=1048576
11350         local FILE_LENGTH=$((STRIPE_SIZE*100))
11351         local nreads=10000
11352         local rsize=65536
11353         local osc_rpc_stats
11354
11355         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11356
11357         cancel_lru_locks osc
11358         $LCTL set_param osc.*.rpc_stats=0
11359         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11360         $LCTL get_param osc.*.rpc_stats
11361         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11362                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11363                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11364                 local size
11365
11366                 if [ $lines -le 20 ]; then
11367                         echo "continue debug"
11368                         continue
11369                 fi
11370                 for size in 1 2 4 8; do
11371                         local rpc=$(echo "$stats" |
11372                                     awk '($1 == "'$size':") {print $2; exit; }')
11373                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11374                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11375                 done
11376                 echo "$osc_rpc_stats check passed!"
11377         done
11378         cleanup_test101bc
11379         true
11380 }
11381 run_test 101c "check stripe_size aligned read-ahead"
11382
11383 test_101d() {
11384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11385
11386         local file=$DIR/$tfile
11387         local sz_MB=${FILESIZE_101d:-80}
11388         local ra_MB=${READAHEAD_MB:-40}
11389
11390         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11391         [ $free_MB -lt $sz_MB ] &&
11392                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11393
11394         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11395         $LFS setstripe -c -1 $file || error "setstripe failed"
11396
11397         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11398         echo Cancel LRU locks on lustre client to flush the client cache
11399         cancel_lru_locks osc
11400
11401         echo Disable read-ahead
11402         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11403         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11404         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11405         $LCTL get_param -n llite.*.max_read_ahead_mb
11406
11407         echo "Reading the test file $file with read-ahead disabled"
11408         local sz_KB=$((sz_MB * 1024 / 4))
11409         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11410         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11411         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11412                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11413
11414         echo "Cancel LRU locks on lustre client to flush the client cache"
11415         cancel_lru_locks osc
11416         echo Enable read-ahead with ${ra_MB}MB
11417         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11418
11419         echo "Reading the test file $file with read-ahead enabled"
11420         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11421                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11422
11423         echo "read-ahead disabled time read $raOFF"
11424         echo "read-ahead enabled time read $raON"
11425
11426         rm -f $file
11427         wait_delete_completed
11428
11429         # use awk for this check instead of bash because it handles decimals
11430         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11431                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11432 }
11433 run_test 101d "file read with and without read-ahead enabled"
11434
11435 test_101e() {
11436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11437
11438         local file=$DIR/$tfile
11439         local size_KB=500  #KB
11440         local count=100
11441         local bsize=1024
11442
11443         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11444         local need_KB=$((count * size_KB))
11445         [[ $free_KB -le $need_KB ]] &&
11446                 skip_env "Need free space $need_KB, have $free_KB"
11447
11448         echo "Creating $count ${size_KB}K test files"
11449         for ((i = 0; i < $count; i++)); do
11450                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11451         done
11452
11453         echo "Cancel LRU locks on lustre client to flush the client cache"
11454         cancel_lru_locks $OSC
11455
11456         echo "Reset readahead stats"
11457         $LCTL set_param -n llite.*.read_ahead_stats=0
11458
11459         for ((i = 0; i < $count; i++)); do
11460                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11461         done
11462
11463         $LCTL get_param llite.*.max_cached_mb
11464         $LCTL get_param llite.*.read_ahead_stats
11465         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11466                      get_named_value 'misses' | calc_total)
11467
11468         for ((i = 0; i < $count; i++)); do
11469                 rm -rf $file.$i 2>/dev/null
11470         done
11471
11472         #10000 means 20% reads are missing in readahead
11473         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11474 }
11475 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11476
11477 test_101f() {
11478         which iozone || skip_env "no iozone installed"
11479
11480         local old_debug=$($LCTL get_param debug)
11481         old_debug=${old_debug#*=}
11482         $LCTL set_param debug="reada mmap"
11483
11484         # create a test file
11485         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11486
11487         echo Cancel LRU locks on lustre client to flush the client cache
11488         cancel_lru_locks osc
11489
11490         echo Reset readahead stats
11491         $LCTL set_param -n llite.*.read_ahead_stats=0
11492
11493         echo mmap read the file with small block size
11494         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11495                 > /dev/null 2>&1
11496
11497         echo checking missing pages
11498         $LCTL get_param llite.*.read_ahead_stats
11499         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11500                         get_named_value 'misses' | calc_total)
11501
11502         $LCTL set_param debug="$old_debug"
11503         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11504         rm -f $DIR/$tfile
11505 }
11506 run_test 101f "check mmap read performance"
11507
11508 test_101g_brw_size_test() {
11509         local mb=$1
11510         local pages=$((mb * 1048576 / PAGE_SIZE))
11511         local file=$DIR/$tfile
11512
11513         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11514                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11515         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11516                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11517                         return 2
11518         done
11519
11520         stack_trap "rm -f $file" EXIT
11521         $LCTL set_param -n osc.*.rpc_stats=0
11522
11523         # 10 RPCs should be enough for the test
11524         local count=10
11525         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11526                 { error "dd write ${mb} MB blocks failed"; return 3; }
11527         cancel_lru_locks osc
11528         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11529                 { error "dd write ${mb} MB blocks failed"; return 4; }
11530
11531         # calculate number of full-sized read and write RPCs
11532         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11533                 sed -n '/pages per rpc/,/^$/p' |
11534                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11535                 END { print reads,writes }'))
11536         # allow one extra full-sized read RPC for async readahead
11537         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11538                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11539         [[ ${rpcs[1]} == $count ]] ||
11540                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11541 }
11542
11543 test_101g() {
11544         remote_ost_nodsh && skip "remote OST with nodsh"
11545
11546         local rpcs
11547         local osts=$(get_facets OST)
11548         local list=$(comma_list $(osts_nodes))
11549         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11550         local brw_size="obdfilter.*.brw_size"
11551
11552         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11553
11554         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11555
11556         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11557                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11558                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11559            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11560                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11561                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11562
11563                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11564                         suffix="M"
11565
11566                 if [[ $orig_mb -lt 16 ]]; then
11567                         save_lustre_params $osts "$brw_size" > $p
11568                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11569                                 error "set 16MB RPC size failed"
11570
11571                         echo "remount client to enable new RPC size"
11572                         remount_client $MOUNT || error "remount_client failed"
11573                 fi
11574
11575                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11576                 # should be able to set brw_size=12, but no rpc_stats for that
11577                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11578         fi
11579
11580         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11581
11582         if [[ $orig_mb -lt 16 ]]; then
11583                 restore_lustre_params < $p
11584                 remount_client $MOUNT || error "remount_client restore failed"
11585         fi
11586
11587         rm -f $p $DIR/$tfile
11588 }
11589 run_test 101g "Big bulk(4/16 MiB) readahead"
11590
11591 test_101h() {
11592         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11593
11594         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11595                 error "dd 70M file failed"
11596         echo Cancel LRU locks on lustre client to flush the client cache
11597         cancel_lru_locks osc
11598
11599         echo "Reset readahead stats"
11600         $LCTL set_param -n llite.*.read_ahead_stats 0
11601
11602         echo "Read 10M of data but cross 64M bundary"
11603         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11604         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11605                      get_named_value 'misses' | calc_total)
11606         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11607         rm -f $p $DIR/$tfile
11608 }
11609 run_test 101h "Readahead should cover current read window"
11610
11611 test_101i() {
11612         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11613                 error "dd 10M file failed"
11614
11615         local max_per_file_mb=$($LCTL get_param -n \
11616                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11617         cancel_lru_locks osc
11618         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11619         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11620                 error "set max_read_ahead_per_file_mb to 1 failed"
11621
11622         echo "Reset readahead stats"
11623         $LCTL set_param llite.*.read_ahead_stats=0
11624
11625         dd if=$DIR/$tfile of=/dev/null bs=2M
11626
11627         $LCTL get_param llite.*.read_ahead_stats
11628         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11629                      awk '/misses/ { print $2 }')
11630         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11631         rm -f $DIR/$tfile
11632 }
11633 run_test 101i "allow current readahead to exceed reservation"
11634
11635 test_101j() {
11636         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11637                 error "setstripe $DIR/$tfile failed"
11638         local file_size=$((1048576 * 16))
11639         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11640         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11641
11642         echo Disable read-ahead
11643         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11644
11645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11646         for blk in $PAGE_SIZE 1048576 $file_size; do
11647                 cancel_lru_locks osc
11648                 echo "Reset readahead stats"
11649                 $LCTL set_param -n llite.*.read_ahead_stats=0
11650                 local count=$(($file_size / $blk))
11651                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11652                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11653                              get_named_value 'failed.to.fast.read' | calc_total)
11654                 $LCTL get_param -n llite.*.read_ahead_stats
11655                 [ $miss -eq $count ] || error "expected $count got $miss"
11656         done
11657
11658         rm -f $p $DIR/$tfile
11659 }
11660 run_test 101j "A complete read block should be submitted when no RA"
11661
11662 test_readahead_base() {
11663         local file=$DIR/$tfile
11664         local size=$1
11665         local iosz
11666         local ramax
11667         local ranum
11668
11669         $LCTL set_param -n llite.*.read_ahead_stats=0
11670         # The first page is not accounted into readahead
11671         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11672         iosz=$(((size + 1048575) / 1048576 * 1048576))
11673         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11674
11675         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11676         fallocate -l $size $file || error "failed to fallocate $file"
11677         cancel_lru_locks osc
11678         $MULTIOP $file or${iosz}c || error "failed to read $file"
11679         $LCTL get_param -n llite.*.read_ahead_stats
11680         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11681                 awk '/readahead.pages/ { print $7 }' | calc_total)
11682         (( $ranum <= $ramax )) ||
11683                 error "read-ahead pages is $ranum more than $ramax"
11684         rm -rf $file || error "failed to remove $file"
11685 }
11686
11687 test_101m()
11688 {
11689         local file=$DIR/$tfile
11690         local ramax
11691         local ranum
11692         local size
11693         local iosz
11694
11695         check_set_fallocate_or_skip
11696         stack_trap "rm -f $file" EXIT
11697
11698         test_readahead_base 4096
11699
11700         # file size: 16K = 16384
11701         test_readahead_base 16384
11702         test_readahead_base 16385
11703         test_readahead_base 16383
11704
11705         # file size: 1M + 1 = 1048576 + 1
11706         test_readahead_base 1048577
11707         # file size: 1M + 16K
11708         test_readahead_base $((1048576 + 16384))
11709
11710         # file size: stripe_size * (stripe_count - 1) + 16K
11711         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11712         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11713         # file size: stripe_size * stripe_count + 16K
11714         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11715         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11716         # file size: 2 * stripe_size * stripe_count + 16K
11717         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11718         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11719 }
11720 run_test 101m "read ahead for small file and last stripe of the file"
11721
11722 setup_test102() {
11723         test_mkdir $DIR/$tdir
11724         chown $RUNAS_ID $DIR/$tdir
11725         STRIPE_SIZE=65536
11726         STRIPE_OFFSET=1
11727         STRIPE_COUNT=$OSTCOUNT
11728         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11729
11730         trap cleanup_test102 EXIT
11731         cd $DIR
11732         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11733         cd $DIR/$tdir
11734         for num in 1 2 3 4; do
11735                 for count in $(seq 1 $STRIPE_COUNT); do
11736                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11737                                 local size=`expr $STRIPE_SIZE \* $num`
11738                                 local file=file"$num-$idx-$count"
11739                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11740                         done
11741                 done
11742         done
11743
11744         cd $DIR
11745         $1 tar cf $TMP/f102.tar $tdir --xattrs
11746 }
11747
11748 cleanup_test102() {
11749         trap 0
11750         rm -f $TMP/f102.tar
11751         rm -rf $DIR/d0.sanity/d102
11752 }
11753
11754 test_102a() {
11755         [ "$UID" != 0 ] && skip "must run as root"
11756         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11757                 skip_env "must have user_xattr"
11758
11759         [ -z "$(which setfattr 2>/dev/null)" ] &&
11760                 skip_env "could not find setfattr"
11761
11762         local testfile=$DIR/$tfile
11763
11764         touch $testfile
11765         echo "set/get xattr..."
11766         setfattr -n trusted.name1 -v value1 $testfile ||
11767                 error "setfattr -n trusted.name1=value1 $testfile failed"
11768         getfattr -n trusted.name1 $testfile 2> /dev/null |
11769           grep "trusted.name1=.value1" ||
11770                 error "$testfile missing trusted.name1=value1"
11771
11772         setfattr -n user.author1 -v author1 $testfile ||
11773                 error "setfattr -n user.author1=author1 $testfile failed"
11774         getfattr -n user.author1 $testfile 2> /dev/null |
11775           grep "user.author1=.author1" ||
11776                 error "$testfile missing trusted.author1=author1"
11777
11778         echo "listxattr..."
11779         setfattr -n trusted.name2 -v value2 $testfile ||
11780                 error "$testfile unable to set trusted.name2"
11781         setfattr -n trusted.name3 -v value3 $testfile ||
11782                 error "$testfile unable to set trusted.name3"
11783         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11784             grep "trusted.name" | wc -l) -eq 3 ] ||
11785                 error "$testfile missing 3 trusted.name xattrs"
11786
11787         setfattr -n user.author2 -v author2 $testfile ||
11788                 error "$testfile unable to set user.author2"
11789         setfattr -n user.author3 -v author3 $testfile ||
11790                 error "$testfile unable to set user.author3"
11791         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11792             grep "user.author" | wc -l) -eq 3 ] ||
11793                 error "$testfile missing 3 user.author xattrs"
11794
11795         echo "remove xattr..."
11796         setfattr -x trusted.name1 $testfile ||
11797                 error "$testfile error deleting trusted.name1"
11798         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11799                 error "$testfile did not delete trusted.name1 xattr"
11800
11801         setfattr -x user.author1 $testfile ||
11802                 error "$testfile error deleting user.author1"
11803         echo "set lustre special xattr ..."
11804         $LFS setstripe -c1 $testfile
11805         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11806                 awk -F "=" '/trusted.lov/ { print $2 }' )
11807         setfattr -n "trusted.lov" -v $lovea $testfile ||
11808                 error "$testfile doesn't ignore setting trusted.lov again"
11809         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11810                 error "$testfile allow setting invalid trusted.lov"
11811         rm -f $testfile
11812 }
11813 run_test 102a "user xattr test =================================="
11814
11815 check_102b_layout() {
11816         local layout="$*"
11817         local testfile=$DIR/$tfile
11818
11819         echo "test layout '$layout'"
11820         $LFS setstripe $layout $testfile || error "setstripe failed"
11821         $LFS getstripe -y $testfile
11822
11823         echo "get/set/list trusted.lov xattr ..." # b=10930
11824         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11825         [[ "$value" =~ "trusted.lov" ]] ||
11826                 error "can't get trusted.lov from $testfile"
11827         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11828                 error "getstripe failed"
11829
11830         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11831
11832         value=$(cut -d= -f2 <<<$value)
11833         # LU-13168: truncated xattr should fail if short lov_user_md header
11834         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11835                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11836         for len in $lens; do
11837                 echo "setfattr $len $testfile.2"
11838                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11839                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11840         done
11841         local stripe_size=$($LFS getstripe -S $testfile.2)
11842         local stripe_count=$($LFS getstripe -c $testfile.2)
11843         [[ $stripe_size -eq 65536 ]] ||
11844                 error "stripe size $stripe_size != 65536"
11845         [[ $stripe_count -eq $stripe_count_orig ]] ||
11846                 error "stripe count $stripe_count != $stripe_count_orig"
11847         rm $testfile $testfile.2
11848 }
11849
11850 test_102b() {
11851         [ -z "$(which setfattr 2>/dev/null)" ] &&
11852                 skip_env "could not find setfattr"
11853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11854
11855         # check plain layout
11856         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11857
11858         # and also check composite layout
11859         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11860
11861 }
11862 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11863
11864 test_102c() {
11865         [ -z "$(which setfattr 2>/dev/null)" ] &&
11866                 skip_env "could not find setfattr"
11867         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11868
11869         # b10930: get/set/list lustre.lov xattr
11870         echo "get/set/list lustre.lov xattr ..."
11871         test_mkdir $DIR/$tdir
11872         chown $RUNAS_ID $DIR/$tdir
11873         local testfile=$DIR/$tdir/$tfile
11874         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11875                 error "setstripe failed"
11876         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11877                 error "getstripe failed"
11878         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11879         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11880
11881         local testfile2=${testfile}2
11882         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11883                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11884
11885         $RUNAS $MCREATE $testfile2
11886         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11887         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11888         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11889         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11890         [ $stripe_count -eq $STRIPECOUNT ] ||
11891                 error "stripe count $stripe_count != $STRIPECOUNT"
11892 }
11893 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11894
11895 compare_stripe_info1() {
11896         local stripe_index_all_zero=true
11897
11898         for num in 1 2 3 4; do
11899                 for count in $(seq 1 $STRIPE_COUNT); do
11900                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11901                                 local size=$((STRIPE_SIZE * num))
11902                                 local file=file"$num-$offset-$count"
11903                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11904                                 [[ $stripe_size -ne $size ]] &&
11905                                     error "$file: size $stripe_size != $size"
11906                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11907                                 # allow fewer stripes to be created, ORI-601
11908                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11909                                     error "$file: count $stripe_count != $count"
11910                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11911                                 [[ $stripe_index -ne 0 ]] &&
11912                                         stripe_index_all_zero=false
11913                         done
11914                 done
11915         done
11916         $stripe_index_all_zero &&
11917                 error "all files are being extracted starting from OST index 0"
11918         return 0
11919 }
11920
11921 have_xattrs_include() {
11922         tar --help | grep -q xattrs-include &&
11923                 echo --xattrs-include="lustre.*"
11924 }
11925
11926 test_102d() {
11927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11928         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11929
11930         XINC=$(have_xattrs_include)
11931         setup_test102
11932         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11933         cd $DIR/$tdir/$tdir
11934         compare_stripe_info1
11935 }
11936 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11937
11938 test_102f() {
11939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11941
11942         XINC=$(have_xattrs_include)
11943         setup_test102
11944         test_mkdir $DIR/$tdir.restore
11945         cd $DIR
11946         tar cf - --xattrs $tdir | tar xf - \
11947                 -C $DIR/$tdir.restore --xattrs $XINC
11948         cd $DIR/$tdir.restore/$tdir
11949         compare_stripe_info1
11950 }
11951 run_test 102f "tar copy files, not keep osts"
11952
11953 grow_xattr() {
11954         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11955                 skip "must have user_xattr"
11956         [ -z "$(which setfattr 2>/dev/null)" ] &&
11957                 skip_env "could not find setfattr"
11958         [ -z "$(which getfattr 2>/dev/null)" ] &&
11959                 skip_env "could not find getfattr"
11960
11961         local xsize=${1:-1024}  # in bytes
11962         local file=$DIR/$tfile
11963         local value="$(generate_string $xsize)"
11964         local xbig=trusted.big
11965         local toobig=$2
11966
11967         touch $file
11968         log "save $xbig on $file"
11969         if [ -z "$toobig" ]
11970         then
11971                 setfattr -n $xbig -v $value $file ||
11972                         error "saving $xbig on $file failed"
11973         else
11974                 setfattr -n $xbig -v $value $file &&
11975                         error "saving $xbig on $file succeeded"
11976                 return 0
11977         fi
11978
11979         local orig=$(get_xattr_value $xbig $file)
11980         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11981
11982         local xsml=trusted.sml
11983         log "save $xsml on $file"
11984         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11985
11986         local new=$(get_xattr_value $xbig $file)
11987         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11988
11989         log "grow $xsml on $file"
11990         setfattr -n $xsml -v "$value" $file ||
11991                 error "growing $xsml on $file failed"
11992
11993         new=$(get_xattr_value $xbig $file)
11994         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11995         log "$xbig still valid after growing $xsml"
11996
11997         rm -f $file
11998 }
11999
12000 test_102h() { # bug 15777
12001         grow_xattr 1024
12002 }
12003 run_test 102h "grow xattr from inside inode to external block"
12004
12005 test_102ha() {
12006         large_xattr_enabled || skip_env "ea_inode feature disabled"
12007
12008         echo "setting xattr of max xattr size: $(max_xattr_size)"
12009         grow_xattr $(max_xattr_size)
12010
12011         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12012         echo "This should fail:"
12013         grow_xattr $(($(max_xattr_size) + 10)) 1
12014 }
12015 run_test 102ha "grow xattr from inside inode to external inode"
12016
12017 test_102i() { # bug 17038
12018         [ -z "$(which getfattr 2>/dev/null)" ] &&
12019                 skip "could not find getfattr"
12020
12021         touch $DIR/$tfile
12022         ln -s $DIR/$tfile $DIR/${tfile}link
12023         getfattr -n trusted.lov $DIR/$tfile ||
12024                 error "lgetxattr on $DIR/$tfile failed"
12025         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12026                 grep -i "no such attr" ||
12027                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12028         rm -f $DIR/$tfile $DIR/${tfile}link
12029 }
12030 run_test 102i "lgetxattr test on symbolic link ============"
12031
12032 test_102j() {
12033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12034         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12035
12036         XINC=$(have_xattrs_include)
12037         setup_test102 "$RUNAS"
12038         chown $RUNAS_ID $DIR/$tdir
12039         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12040         cd $DIR/$tdir/$tdir
12041         compare_stripe_info1 "$RUNAS"
12042 }
12043 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12044
12045 test_102k() {
12046         [ -z "$(which setfattr 2>/dev/null)" ] &&
12047                 skip "could not find setfattr"
12048
12049         touch $DIR/$tfile
12050         # b22187 just check that does not crash for regular file.
12051         setfattr -n trusted.lov $DIR/$tfile
12052         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12053         local test_kdir=$DIR/$tdir
12054         test_mkdir $test_kdir
12055         local default_size=$($LFS getstripe -S $test_kdir)
12056         local default_count=$($LFS getstripe -c $test_kdir)
12057         local default_offset=$($LFS getstripe -i $test_kdir)
12058         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12059                 error 'dir setstripe failed'
12060         setfattr -n trusted.lov $test_kdir
12061         local stripe_size=$($LFS getstripe -S $test_kdir)
12062         local stripe_count=$($LFS getstripe -c $test_kdir)
12063         local stripe_offset=$($LFS getstripe -i $test_kdir)
12064         [ $stripe_size -eq $default_size ] ||
12065                 error "stripe size $stripe_size != $default_size"
12066         [ $stripe_count -eq $default_count ] ||
12067                 error "stripe count $stripe_count != $default_count"
12068         [ $stripe_offset -eq $default_offset ] ||
12069                 error "stripe offset $stripe_offset != $default_offset"
12070         rm -rf $DIR/$tfile $test_kdir
12071 }
12072 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12073
12074 test_102l() {
12075         [ -z "$(which getfattr 2>/dev/null)" ] &&
12076                 skip "could not find getfattr"
12077
12078         # LU-532 trusted. xattr is invisible to non-root
12079         local testfile=$DIR/$tfile
12080
12081         touch $testfile
12082
12083         echo "listxattr as user..."
12084         chown $RUNAS_ID $testfile
12085         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12086             grep -q "trusted" &&
12087                 error "$testfile trusted xattrs are user visible"
12088
12089         return 0;
12090 }
12091 run_test 102l "listxattr size test =================================="
12092
12093 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12094         local path=$DIR/$tfile
12095         touch $path
12096
12097         listxattr_size_check $path || error "listattr_size_check $path failed"
12098 }
12099 run_test 102m "Ensure listxattr fails on small bufffer ========"
12100
12101 cleanup_test102
12102
12103 getxattr() { # getxattr path name
12104         # Return the base64 encoding of the value of xattr name on path.
12105         local path=$1
12106         local name=$2
12107
12108         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12109         # file: $path
12110         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12111         #
12112         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12113
12114         getfattr --absolute-names --encoding=base64 --name=$name $path |
12115                 awk -F= -v name=$name '$1 == name {
12116                         print substr($0, index($0, "=") + 1);
12117         }'
12118 }
12119
12120 test_102n() { # LU-4101 mdt: protect internal xattrs
12121         [ -z "$(which setfattr 2>/dev/null)" ] &&
12122                 skip "could not find setfattr"
12123         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12124         then
12125                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12126         fi
12127
12128         local file0=$DIR/$tfile.0
12129         local file1=$DIR/$tfile.1
12130         local xattr0=$TMP/$tfile.0
12131         local xattr1=$TMP/$tfile.1
12132         local namelist="lov lma lmv link fid version som hsm"
12133         local name
12134         local value
12135
12136         rm -rf $file0 $file1 $xattr0 $xattr1
12137         touch $file0 $file1
12138
12139         # Get 'before' xattrs of $file1.
12140         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12141
12142         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12143                 namelist+=" lfsck_namespace"
12144         for name in $namelist; do
12145                 # Try to copy xattr from $file0 to $file1.
12146                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12147
12148                 setfattr --name=trusted.$name --value="$value" $file1 ||
12149                         error "setxattr 'trusted.$name' failed"
12150
12151                 # Try to set a garbage xattr.
12152                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12153
12154                 if [[ x$name == "xlov" ]]; then
12155                         setfattr --name=trusted.lov --value="$value" $file1 &&
12156                         error "setxattr invalid 'trusted.lov' success"
12157                 else
12158                         setfattr --name=trusted.$name --value="$value" $file1 ||
12159                                 error "setxattr invalid 'trusted.$name' failed"
12160                 fi
12161
12162                 # Try to remove the xattr from $file1. We don't care if this
12163                 # appears to succeed or fail, we just don't want there to be
12164                 # any changes or crashes.
12165                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12166         done
12167
12168         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12169         then
12170                 name="lfsck_ns"
12171                 # Try to copy xattr from $file0 to $file1.
12172                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12173
12174                 setfattr --name=trusted.$name --value="$value" $file1 ||
12175                         error "setxattr 'trusted.$name' failed"
12176
12177                 # Try to set a garbage xattr.
12178                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12179
12180                 setfattr --name=trusted.$name --value="$value" $file1 ||
12181                         error "setxattr 'trusted.$name' failed"
12182
12183                 # Try to remove the xattr from $file1. We don't care if this
12184                 # appears to succeed or fail, we just don't want there to be
12185                 # any changes or crashes.
12186                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12187         fi
12188
12189         # Get 'after' xattrs of file1.
12190         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12191
12192         if ! diff $xattr0 $xattr1; then
12193                 error "before and after xattrs of '$file1' differ"
12194         fi
12195
12196         rm -rf $file0 $file1 $xattr0 $xattr1
12197
12198         return 0
12199 }
12200 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12201
12202 test_102p() { # LU-4703 setxattr did not check ownership
12203         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12204                 skip "MDS needs to be at least 2.5.56"
12205
12206         local testfile=$DIR/$tfile
12207
12208         touch $testfile
12209
12210         echo "setfacl as user..."
12211         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12212         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12213
12214         echo "setfattr as user..."
12215         setfacl -m "u:$RUNAS_ID:---" $testfile
12216         $RUNAS setfattr -x system.posix_acl_access $testfile
12217         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12218 }
12219 run_test 102p "check setxattr(2) correctly fails without permission"
12220
12221 test_102q() {
12222         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12223                 skip "MDS needs to be at least 2.6.92"
12224
12225         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12226 }
12227 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12228
12229 test_102r() {
12230         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12231                 skip "MDS needs to be at least 2.6.93"
12232
12233         touch $DIR/$tfile || error "touch"
12234         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12235         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12236         rm $DIR/$tfile || error "rm"
12237
12238         #normal directory
12239         mkdir -p $DIR/$tdir || error "mkdir"
12240         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12241         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12242         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12243                 error "$testfile error deleting user.author1"
12244         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12245                 grep "user.$(basename $tdir)" &&
12246                 error "$tdir did not delete user.$(basename $tdir)"
12247         rmdir $DIR/$tdir || error "rmdir"
12248
12249         #striped directory
12250         test_mkdir $DIR/$tdir
12251         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12252         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12253         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12254                 error "$testfile error deleting user.author1"
12255         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12256                 grep "user.$(basename $tdir)" &&
12257                 error "$tdir did not delete user.$(basename $tdir)"
12258         rmdir $DIR/$tdir || error "rm striped dir"
12259 }
12260 run_test 102r "set EAs with empty values"
12261
12262 test_102s() {
12263         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12264                 skip "MDS needs to be at least 2.11.52"
12265
12266         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12267
12268         save_lustre_params client "llite.*.xattr_cache" > $save
12269
12270         for cache in 0 1; do
12271                 lctl set_param llite.*.xattr_cache=$cache
12272
12273                 rm -f $DIR/$tfile
12274                 touch $DIR/$tfile || error "touch"
12275                 for prefix in lustre security system trusted user; do
12276                         # Note getxattr() may fail with 'Operation not
12277                         # supported' or 'No such attribute' depending
12278                         # on prefix and cache.
12279                         getfattr -n $prefix.n102s $DIR/$tfile &&
12280                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12281                 done
12282         done
12283
12284         restore_lustre_params < $save
12285 }
12286 run_test 102s "getting nonexistent xattrs should fail"
12287
12288 test_102t() {
12289         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12290                 skip "MDS needs to be at least 2.11.52"
12291
12292         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12293
12294         save_lustre_params client "llite.*.xattr_cache" > $save
12295
12296         for cache in 0 1; do
12297                 lctl set_param llite.*.xattr_cache=$cache
12298
12299                 for buf_size in 0 256; do
12300                         rm -f $DIR/$tfile
12301                         touch $DIR/$tfile || error "touch"
12302                         setfattr -n user.multiop $DIR/$tfile
12303                         $MULTIOP $DIR/$tfile oa$buf_size ||
12304                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12305                 done
12306         done
12307
12308         restore_lustre_params < $save
12309 }
12310 run_test 102t "zero length xattr values handled correctly"
12311
12312 run_acl_subtest()
12313 {
12314         local test=$LUSTRE/tests/acl/$1.test
12315         local tmp=$(mktemp -t $1-XXXXXX).test
12316         local bin=$2
12317         local dmn=$3
12318         local grp=$4
12319         local nbd=$5
12320         export LANG=C
12321
12322
12323         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12324         local sedgroups="-e s/:users/:$grp/g"
12325         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12326
12327         sed $sedusers $sedgroups < $test > $tmp
12328         stack_trap "rm -f $tmp"
12329         [[ -s $tmp ]] || error "sed failed to create test script"
12330
12331         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12332         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12333 }
12334
12335 test_103a() {
12336         [ "$UID" != 0 ] && skip "must run as root"
12337         $GSS && skip_env "could not run under gss"
12338         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12339                 skip_env "must have acl enabled"
12340         which setfacl || skip_env "could not find setfacl"
12341         remote_mds_nodsh && skip "remote MDS with nodsh"
12342
12343         local mdts=$(comma_list $(mdts_nodes))
12344         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12345
12346         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12347         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12348
12349         ACLBIN=${ACLBIN:-"bin"}
12350         ACLDMN=${ACLDMN:-"daemon"}
12351         ACLGRP=${ACLGRP:-"users"}
12352         ACLNBD=${ACLNBD:-"nobody"}
12353
12354         if ! id $ACLBIN ||
12355            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12356                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12357                 ACLBIN=$USER0
12358                 if ! id $ACLBIN ; then
12359                         cat /etc/passwd
12360                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12361                 fi
12362         fi
12363         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12364            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12365                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12366                 ACLDMN=$USER1
12367                 if ! id $ACLDMN ; then
12368                         cat /etc/passwd
12369                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12370                 fi
12371         fi
12372         if ! getent group $ACLGRP; then
12373                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12374                 ACLGRP="$TSTUSR"
12375                 if ! getent group $ACLGRP; then
12376                         echo "cannot find group '$ACLGRP', adding it"
12377                         cat /etc/group
12378                         add_group 60000 $ACLGRP
12379                 fi
12380         fi
12381
12382         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12383         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12384         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12385
12386         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12387                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12388                 ACLGRP="$TSTUSR"
12389                 if ! getent group $ACLGRP; then
12390                         echo "cannot find group '$ACLGRP', adding it"
12391                         cat /etc/group
12392                         add_group 60000 $ACLGRP
12393                 fi
12394                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12395                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12396                         cat /etc/group
12397                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12398                 fi
12399         fi
12400
12401         gpasswd -a $ACLDMN $ACLBIN ||
12402                 error "setting client group failed"             # LU-5641
12403         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12404                 error "setting MDS group failed"                # LU-5641
12405
12406         declare -a identity_old
12407
12408         for num in $(seq $MDSCOUNT); do
12409                 switch_identity $num true || identity_old[$num]=$?
12410         done
12411
12412         SAVE_UMASK=$(umask)
12413         umask 0022
12414         mkdir -p $DIR/$tdir
12415         cd $DIR/$tdir
12416
12417         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12418         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12419         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12420         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12421         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12422         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12423         if ! id -u $ACLNBD ||
12424            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12425                 ACLNBD="nfsnobody"
12426                 if ! id -u $ACLNBD; then
12427                         ACLNBD=""
12428                 fi
12429         fi
12430         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12431                 add_group $(id -u $ACLNBD) $ACLNBD
12432                 if ! getent group $ACLNBD; then
12433                         ACLNBD=""
12434                 fi
12435         fi
12436         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12437            [[ -n "$ACLNBD" ]] && which setfattr; then
12438                 run_acl_subtest permissions_xattr \
12439                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12440         elif [[ -z "$ACLNBD" ]]; then
12441                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12442         else
12443                 echo "skip 'permission_xattr' test - missing setfattr command"
12444         fi
12445         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12446
12447         # inheritance test got from HP
12448         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12449         chmod +x make-tree || error "chmod +x failed"
12450         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12451         rm -f make-tree
12452
12453         echo "LU-974 ignore umask when acl is enabled..."
12454         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12455         if [ $MDSCOUNT -ge 2 ]; then
12456                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12457         fi
12458
12459         echo "LU-2561 newly created file is same size as directory..."
12460         if [ "$mds1_FSTYPE" != "zfs" ]; then
12461                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12462         else
12463                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12464         fi
12465
12466         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12467
12468         cd $SAVE_PWD
12469         umask $SAVE_UMASK
12470
12471         for num in $(seq $MDSCOUNT); do
12472                 if [ "${identity_old[$num]}" = 1 ]; then
12473                         switch_identity $num false || identity_old[$num]=$?
12474                 fi
12475         done
12476 }
12477 run_test 103a "acl test"
12478
12479 test_103b() {
12480         declare -a pids
12481         local U
12482
12483         stack_trap "rm -f $DIR/$tfile.*"
12484         for U in {0..511}; do
12485                 {
12486                 local O=$(printf "%04o" $U)
12487
12488                 umask $(printf "%04o" $((511 ^ $O)))
12489                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12490                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12491
12492                 (( $S == ($O & 0666) )) ||
12493                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12494
12495                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12496                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12497                 (( $S == ($O & 0666) )) ||
12498                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12499
12500                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12501                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12502                 (( $S == ($O & 0666) )) ||
12503                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12504                 rm -f $DIR/$tfile.[smp]$0
12505                 } &
12506                 local pid=$!
12507
12508                 # limit the concurrently running threads to 64. LU-11878
12509                 local idx=$((U % 64))
12510                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12511                 pids[idx]=$pid
12512         done
12513         wait
12514 }
12515 run_test 103b "umask lfs setstripe"
12516
12517 test_103c() {
12518         mkdir -p $DIR/$tdir
12519         cp -rp $DIR/$tdir $DIR/$tdir.bak
12520
12521         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12522                 error "$DIR/$tdir shouldn't contain default ACL"
12523         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12524                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12525         true
12526 }
12527 run_test 103c "'cp -rp' won't set empty acl"
12528
12529 test_103e() {
12530         local numacl
12531         local fileacl
12532         local saved_debug=$($LCTL get_param -n debug)
12533
12534         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12535                 skip "MDS needs to be at least 2.14.52"
12536
12537         large_xattr_enabled || skip_env "ea_inode feature disabled"
12538
12539         mkdir -p $DIR/$tdir
12540         # add big LOV EA to cause reply buffer overflow earlier
12541         $LFS setstripe -C 1000 $DIR/$tdir
12542         lctl set_param mdc.*-mdc*.stats=clear
12543
12544         $LCTL set_param debug=0
12545         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12546         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12547
12548         # add a large number of default ACLs (expect 8000+ for 2.13+)
12549         for U in {2..7000}; do
12550                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12551                         error "Able to add just $U default ACLs"
12552         done
12553         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12554         echo "$numacl default ACLs created"
12555
12556         stat $DIR/$tdir || error "Cannot stat directory"
12557         # check file creation
12558         touch $DIR/$tdir/$tfile ||
12559                 error "failed to create $tfile with $numacl default ACLs"
12560         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12561         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12562         echo "$fileacl ACLs were inherited"
12563         (( $fileacl == $numacl )) ||
12564                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12565         # check that new ACLs creation adds new ACLs to inherited ACLs
12566         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12567                 error "Cannot set new ACL"
12568         numacl=$((numacl + 1))
12569         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12570         (( $fileacl == $numacl )) ||
12571                 error "failed to add new ACL: $fileacl != $numacl as expected"
12572         # adds more ACLs to a file to reach their maximum at 8000+
12573         numacl=0
12574         for U in {20000..25000}; do
12575                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12576                 numacl=$((numacl + 1))
12577         done
12578         echo "Added $numacl more ACLs to the file"
12579         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12580         echo "Total $fileacl ACLs in file"
12581         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12582         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12583         rmdir $DIR/$tdir || error "Cannot remove directory"
12584 }
12585 run_test 103e "inheritance of big amount of default ACLs"
12586
12587 test_103f() {
12588         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12589                 skip "MDS needs to be at least 2.14.51"
12590
12591         large_xattr_enabled || skip_env "ea_inode feature disabled"
12592
12593         # enable changelog to consume more internal MDD buffers
12594         changelog_register
12595
12596         mkdir -p $DIR/$tdir
12597         # add big LOV EA
12598         $LFS setstripe -C 1000 $DIR/$tdir
12599         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12600         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12601         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12602         rmdir $DIR/$tdir || error "Cannot remove directory"
12603 }
12604 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12605
12606 test_104a() {
12607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12608
12609         touch $DIR/$tfile
12610         lfs df || error "lfs df failed"
12611         lfs df -ih || error "lfs df -ih failed"
12612         lfs df -h $DIR || error "lfs df -h $DIR failed"
12613         lfs df -i $DIR || error "lfs df -i $DIR failed"
12614         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12615         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12616
12617         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12618         lctl --device %$OSC deactivate
12619         lfs df || error "lfs df with deactivated OSC failed"
12620         lctl --device %$OSC activate
12621         # wait the osc back to normal
12622         wait_osc_import_ready client ost
12623
12624         lfs df || error "lfs df with reactivated OSC failed"
12625         rm -f $DIR/$tfile
12626 }
12627 run_test 104a "lfs df [-ih] [path] test ========================="
12628
12629 test_104b() {
12630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12631         [ $RUNAS_ID -eq $UID ] &&
12632                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12633
12634         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12635                         grep "Permission denied" | wc -l)))
12636         if [ $denied_cnt -ne 0 ]; then
12637                 error "lfs check servers test failed"
12638         fi
12639 }
12640 run_test 104b "$RUNAS lfs check servers test ===================="
12641
12642 #
12643 # Verify $1 is within range of $2.
12644 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12645 # $1 is <= 2% of $2. Else Fail.
12646 #
12647 value_in_range() {
12648         # Strip all units (M, G, T)
12649         actual=$(echo $1 | tr -d A-Z)
12650         expect=$(echo $2 | tr -d A-Z)
12651
12652         expect_lo=$(($expect * 98 / 100)) # 2% below
12653         expect_hi=$(($expect * 102 / 100)) # 2% above
12654
12655         # permit 2% drift above and below
12656         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12657 }
12658
12659 test_104c() {
12660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12661         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12662
12663         local ost_param="osd-zfs.$FSNAME-OST0000."
12664         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12665         local ofacets=$(get_facets OST)
12666         local mfacets=$(get_facets MDS)
12667         local saved_ost_blocks=
12668         local saved_mdt_blocks=
12669
12670         echo "Before recordsize change"
12671         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12672         df=($(df -h | grep "$MOUNT"$))
12673
12674         # For checking.
12675         echo "lfs output : ${lfs_df[*]}"
12676         echo "df  output : ${df[*]}"
12677
12678         for facet in ${ofacets//,/ }; do
12679                 if [ -z $saved_ost_blocks ]; then
12680                         saved_ost_blocks=$(do_facet $facet \
12681                                 lctl get_param -n $ost_param.blocksize)
12682                         echo "OST Blocksize: $saved_ost_blocks"
12683                 fi
12684                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12685                 do_facet $facet zfs set recordsize=32768 $ost
12686         done
12687
12688         # BS too small. Sufficient for functional testing.
12689         for facet in ${mfacets//,/ }; do
12690                 if [ -z $saved_mdt_blocks ]; then
12691                         saved_mdt_blocks=$(do_facet $facet \
12692                                 lctl get_param -n $mdt_param.blocksize)
12693                         echo "MDT Blocksize: $saved_mdt_blocks"
12694                 fi
12695                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12696                 do_facet $facet zfs set recordsize=32768 $mdt
12697         done
12698
12699         # Give new values chance to reflect change
12700         sleep 2
12701
12702         echo "After recordsize change"
12703         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12704         df_after=($(df -h | grep "$MOUNT"$))
12705
12706         # For checking.
12707         echo "lfs output : ${lfs_df_after[*]}"
12708         echo "df  output : ${df_after[*]}"
12709
12710         # Verify lfs df
12711         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12712                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12713         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12714                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12715         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12716                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12717
12718         # Verify df
12719         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12720                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12721         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12722                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12723         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12724                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12725
12726         # Restore MDT recordize back to original
12727         for facet in ${mfacets//,/ }; do
12728                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12729                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12730         done
12731
12732         # Restore OST recordize back to original
12733         for facet in ${ofacets//,/ }; do
12734                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12735                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12736         done
12737
12738         return 0
12739 }
12740 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12741
12742 test_104d() {
12743         (( $RUNAS_ID != $UID )) ||
12744                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12745
12746         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12747                 skip "lustre version doesn't support lctl dl with non-root"
12748
12749         # debugfs only allows root users to access files, so the
12750         # previous move of the "devices" file to debugfs broke
12751         # "lctl dl" for non-root users. The LU-9680 Netlink
12752         # interface again allows non-root users to list devices.
12753         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12754                 error "lctl dl doesn't work for non root"
12755
12756         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12757         [ "$ost_count" -eq $OSTCOUNT ]  ||
12758                 error "lctl dl reports wrong number of OST devices"
12759
12760         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12761         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12762                 error "lctl dl reports wrong number of MDT devices"
12763 }
12764 run_test 104d "$RUNAS lctl dl test"
12765
12766 test_105a() {
12767         # doesn't work on 2.4 kernels
12768         touch $DIR/$tfile
12769         if $(flock_is_enabled); then
12770                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12771         else
12772                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12773         fi
12774         rm -f $DIR/$tfile
12775 }
12776 run_test 105a "flock when mounted without -o flock test ========"
12777
12778 test_105b() {
12779         touch $DIR/$tfile
12780         if $(flock_is_enabled); then
12781                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12782         else
12783                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12784         fi
12785         rm -f $DIR/$tfile
12786 }
12787 run_test 105b "fcntl when mounted without -o flock test ========"
12788
12789 test_105c() {
12790         touch $DIR/$tfile
12791         if $(flock_is_enabled); then
12792                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12793         else
12794                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12795         fi
12796         rm -f $DIR/$tfile
12797 }
12798 run_test 105c "lockf when mounted without -o flock test"
12799
12800 test_105d() { # bug 15924
12801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12802
12803         test_mkdir $DIR/$tdir
12804         flock_is_enabled || skip_env "mount w/o flock enabled"
12805         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12806         $LCTL set_param fail_loc=0x80000315
12807         flocks_test 2 $DIR/$tdir
12808 }
12809 run_test 105d "flock race (should not freeze) ========"
12810
12811 test_105e() { # bug 22660 && 22040
12812         flock_is_enabled || skip_env "mount w/o flock enabled"
12813
12814         touch $DIR/$tfile
12815         flocks_test 3 $DIR/$tfile
12816 }
12817 run_test 105e "Two conflicting flocks from same process"
12818
12819 test_106() { #bug 10921
12820         test_mkdir $DIR/$tdir
12821         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12822         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12823 }
12824 run_test 106 "attempt exec of dir followed by chown of that dir"
12825
12826 test_107() {
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828
12829         CDIR=`pwd`
12830         local file=core
12831
12832         cd $DIR
12833         rm -f $file
12834
12835         local save_pattern=$(sysctl -n kernel.core_pattern)
12836         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12837         sysctl -w kernel.core_pattern=$file
12838         sysctl -w kernel.core_uses_pid=0
12839
12840         ulimit -c unlimited
12841         sleep 60 &
12842         SLEEPPID=$!
12843
12844         sleep 1
12845
12846         kill -s 11 $SLEEPPID
12847         wait $SLEEPPID
12848         if [ -e $file ]; then
12849                 size=`stat -c%s $file`
12850                 [ $size -eq 0 ] && error "Fail to create core file $file"
12851         else
12852                 error "Fail to create core file $file"
12853         fi
12854         rm -f $file
12855         sysctl -w kernel.core_pattern=$save_pattern
12856         sysctl -w kernel.core_uses_pid=$save_uses_pid
12857         cd $CDIR
12858 }
12859 run_test 107 "Coredump on SIG"
12860
12861 test_110() {
12862         test_mkdir $DIR/$tdir
12863         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12864         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12865                 error "mkdir with 256 char should fail, but did not"
12866         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12867                 error "create with 255 char failed"
12868         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12869                 error "create with 256 char should fail, but did not"
12870
12871         ls -l $DIR/$tdir
12872         rm -rf $DIR/$tdir
12873 }
12874 run_test 110 "filename length checking"
12875
12876 test_116a() { # was previously test_116()
12877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12879         remote_mds_nodsh && skip "remote MDS with nodsh"
12880
12881         echo -n "Free space priority "
12882         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12883                 head -n1
12884         declare -a AVAIL
12885         free_min_max
12886
12887         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12888         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12889         stack_trap simple_cleanup_common
12890
12891         # Check if we need to generate uneven OSTs
12892         test_mkdir -p $DIR/$tdir/OST${MINI}
12893         local FILL=$((MINV / 4))
12894         local DIFF=$((MAXV - MINV))
12895         local DIFF2=$((DIFF * 100 / MINV))
12896
12897         local threshold=$(do_facet $SINGLEMDS \
12898                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12899         threshold=${threshold%%%}
12900         echo -n "Check for uneven OSTs: "
12901         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12902
12903         if [[ $DIFF2 -gt $threshold ]]; then
12904                 echo "ok"
12905                 echo "Don't need to fill OST$MINI"
12906         else
12907                 # generate uneven OSTs. Write 2% over the QOS threshold value
12908                 echo "no"
12909                 DIFF=$((threshold - DIFF2 + 2))
12910                 DIFF2=$((MINV * DIFF / 100))
12911                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12912                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12913                         error "setstripe failed"
12914                 DIFF=$((DIFF2 / 2048))
12915                 i=0
12916                 while [ $i -lt $DIFF ]; do
12917                         i=$((i + 1))
12918                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12919                                 bs=2M count=1 2>/dev/null
12920                         echo -n .
12921                 done
12922                 echo .
12923                 sync
12924                 sleep_maxage
12925                 free_min_max
12926         fi
12927
12928         DIFF=$((MAXV - MINV))
12929         DIFF2=$((DIFF * 100 / MINV))
12930         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12931         if [ $DIFF2 -gt $threshold ]; then
12932                 echo "ok"
12933         else
12934                 skip "QOS imbalance criteria not met"
12935         fi
12936
12937         MINI1=$MINI
12938         MINV1=$MINV
12939         MAXI1=$MAXI
12940         MAXV1=$MAXV
12941
12942         # now fill using QOS
12943         $LFS setstripe -c 1 $DIR/$tdir
12944         FILL=$((FILL / 200))
12945         if [ $FILL -gt 600 ]; then
12946                 FILL=600
12947         fi
12948         echo "writing $FILL files to QOS-assigned OSTs"
12949         i=0
12950         while [ $i -lt $FILL ]; do
12951                 i=$((i + 1))
12952                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12953                         count=1 2>/dev/null
12954                 echo -n .
12955         done
12956         echo "wrote $i 200k files"
12957         sync
12958         sleep_maxage
12959
12960         echo "Note: free space may not be updated, so measurements might be off"
12961         free_min_max
12962         DIFF2=$((MAXV - MINV))
12963         echo "free space delta: orig $DIFF final $DIFF2"
12964         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12965         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12966         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12967         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12968         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12969         if [[ $DIFF -gt 0 ]]; then
12970                 FILL=$((DIFF2 * 100 / DIFF - 100))
12971                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12972         fi
12973
12974         # Figure out which files were written where
12975         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12976                awk '/'$MINI1': / {print $2; exit}')
12977         echo $UUID
12978         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12979         echo "$MINC files created on smaller OST $MINI1"
12980         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12981                awk '/'$MAXI1': / {print $2; exit}')
12982         echo $UUID
12983         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12984         echo "$MAXC files created on larger OST $MAXI1"
12985         if [[ $MINC -gt 0 ]]; then
12986                 FILL=$((MAXC * 100 / MINC - 100))
12987                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12988         fi
12989         [[ $MAXC -gt $MINC ]] ||
12990                 error_ignore LU-9 "stripe QOS didn't balance free space"
12991 }
12992 run_test 116a "stripe QOS: free space balance ==================="
12993
12994 test_116b() { # LU-2093
12995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12996         remote_mds_nodsh && skip "remote MDS with nodsh"
12997
12998 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12999         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13000                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13001         [ -z "$old_rr" ] && skip "no QOS"
13002         do_facet $SINGLEMDS lctl set_param \
13003                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13004         mkdir -p $DIR/$tdir
13005         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13006         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13007         do_facet $SINGLEMDS lctl set_param fail_loc=0
13008         rm -rf $DIR/$tdir
13009         do_facet $SINGLEMDS lctl set_param \
13010                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13011 }
13012 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13013
13014 test_117() # bug 10891
13015 {
13016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13017
13018         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13019         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13020         lctl set_param fail_loc=0x21e
13021         > $DIR/$tfile || error "truncate failed"
13022         lctl set_param fail_loc=0
13023         echo "Truncate succeeded."
13024         rm -f $DIR/$tfile
13025 }
13026 run_test 117 "verify osd extend =========="
13027
13028 NO_SLOW_RESENDCOUNT=4
13029 export OLD_RESENDCOUNT=""
13030 set_resend_count () {
13031         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13032         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13033         lctl set_param -n $PROC_RESENDCOUNT $1
13034         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13035 }
13036
13037 # for reduce test_118* time (b=14842)
13038 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13039
13040 # Reset async IO behavior after error case
13041 reset_async() {
13042         FILE=$DIR/reset_async
13043
13044         # Ensure all OSCs are cleared
13045         $LFS setstripe -c -1 $FILE
13046         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13047         sync
13048         rm $FILE
13049 }
13050
13051 test_118a() #bug 11710
13052 {
13053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13054
13055         reset_async
13056
13057         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13058         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13059         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13060
13061         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13062                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13063                 return 1;
13064         fi
13065         rm -f $DIR/$tfile
13066 }
13067 run_test 118a "verify O_SYNC works =========="
13068
13069 test_118b()
13070 {
13071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13072         remote_ost_nodsh && skip "remote OST with nodsh"
13073
13074         reset_async
13075
13076         #define OBD_FAIL_SRV_ENOENT 0x217
13077         set_nodes_failloc "$(osts_nodes)" 0x217
13078         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13079         RC=$?
13080         set_nodes_failloc "$(osts_nodes)" 0
13081         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13082         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13083                     grep -c writeback)
13084
13085         if [[ $RC -eq 0 ]]; then
13086                 error "Must return error due to dropped pages, rc=$RC"
13087                 return 1;
13088         fi
13089
13090         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13091                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13092                 return 1;
13093         fi
13094
13095         echo "Dirty pages not leaked on ENOENT"
13096
13097         # Due to the above error the OSC will issue all RPCs syncronously
13098         # until a subsequent RPC completes successfully without error.
13099         $MULTIOP $DIR/$tfile Ow4096yc
13100         rm -f $DIR/$tfile
13101
13102         return 0
13103 }
13104 run_test 118b "Reclaim dirty pages on fatal error =========="
13105
13106 test_118c()
13107 {
13108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13109
13110         # for 118c, restore the original resend count, LU-1940
13111         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13112                                 set_resend_count $OLD_RESENDCOUNT
13113         remote_ost_nodsh && skip "remote OST with nodsh"
13114
13115         reset_async
13116
13117         #define OBD_FAIL_OST_EROFS               0x216
13118         set_nodes_failloc "$(osts_nodes)" 0x216
13119
13120         # multiop should block due to fsync until pages are written
13121         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13122         MULTIPID=$!
13123         sleep 1
13124
13125         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13126                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13127         fi
13128
13129         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13130                     grep -c writeback)
13131         if [[ $WRITEBACK -eq 0 ]]; then
13132                 error "No page in writeback, writeback=$WRITEBACK"
13133         fi
13134
13135         set_nodes_failloc "$(osts_nodes)" 0
13136         wait $MULTIPID
13137         RC=$?
13138         if [[ $RC -ne 0 ]]; then
13139                 error "Multiop fsync failed, rc=$RC"
13140         fi
13141
13142         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13143         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13144                     grep -c writeback)
13145         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13146                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13147         fi
13148
13149         rm -f $DIR/$tfile
13150         echo "Dirty pages flushed via fsync on EROFS"
13151         return 0
13152 }
13153 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13154
13155 # continue to use small resend count to reduce test_118* time (b=14842)
13156 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13157
13158 test_118d()
13159 {
13160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13161         remote_ost_nodsh && skip "remote OST with nodsh"
13162
13163         reset_async
13164
13165         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13166         set_nodes_failloc "$(osts_nodes)" 0x214
13167         # multiop should block due to fsync until pages are written
13168         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13169         MULTIPID=$!
13170         sleep 1
13171
13172         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13173                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13174         fi
13175
13176         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13177                     grep -c writeback)
13178         if [[ $WRITEBACK -eq 0 ]]; then
13179                 error "No page in writeback, writeback=$WRITEBACK"
13180         fi
13181
13182         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13183         set_nodes_failloc "$(osts_nodes)" 0
13184
13185         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13186         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13187                     grep -c writeback)
13188         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13189                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13190         fi
13191
13192         rm -f $DIR/$tfile
13193         echo "Dirty pages gaurenteed flushed via fsync"
13194         return 0
13195 }
13196 run_test 118d "Fsync validation inject a delay of the bulk =========="
13197
13198 test_118f() {
13199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13200
13201         reset_async
13202
13203         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13204         lctl set_param fail_loc=0x8000040a
13205
13206         # Should simulate EINVAL error which is fatal
13207         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13208         RC=$?
13209         if [[ $RC -eq 0 ]]; then
13210                 error "Must return error due to dropped pages, rc=$RC"
13211         fi
13212
13213         lctl set_param fail_loc=0x0
13214
13215         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13216         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13217         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13218                     grep -c writeback)
13219         if [[ $LOCKED -ne 0 ]]; then
13220                 error "Locked pages remain in cache, locked=$LOCKED"
13221         fi
13222
13223         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13224                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13225         fi
13226
13227         rm -f $DIR/$tfile
13228         echo "No pages locked after fsync"
13229
13230         reset_async
13231         return 0
13232 }
13233 run_test 118f "Simulate unrecoverable OSC side error =========="
13234
13235 test_118g() {
13236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13237
13238         reset_async
13239
13240         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13241         lctl set_param fail_loc=0x406
13242
13243         # simulate local -ENOMEM
13244         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13245         RC=$?
13246
13247         lctl set_param fail_loc=0
13248         if [[ $RC -eq 0 ]]; then
13249                 error "Must return error due to dropped pages, rc=$RC"
13250         fi
13251
13252         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13253         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13254         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13255                         grep -c writeback)
13256         if [[ $LOCKED -ne 0 ]]; then
13257                 error "Locked pages remain in cache, locked=$LOCKED"
13258         fi
13259
13260         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13261                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13262         fi
13263
13264         rm -f $DIR/$tfile
13265         echo "No pages locked after fsync"
13266
13267         reset_async
13268         return 0
13269 }
13270 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13271
13272 test_118h() {
13273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13274         remote_ost_nodsh && skip "remote OST with nodsh"
13275
13276         reset_async
13277
13278         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13279         set_nodes_failloc "$(osts_nodes)" 0x20e
13280         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13281         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13282         RC=$?
13283
13284         set_nodes_failloc "$(osts_nodes)" 0
13285         if [[ $RC -eq 0 ]]; then
13286                 error "Must return error due to dropped pages, rc=$RC"
13287         fi
13288
13289         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13290         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13291         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13292                     grep -c writeback)
13293         if [[ $LOCKED -ne 0 ]]; then
13294                 error "Locked pages remain in cache, locked=$LOCKED"
13295         fi
13296
13297         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13298                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13299         fi
13300
13301         rm -f $DIR/$tfile
13302         echo "No pages locked after fsync"
13303
13304         return 0
13305 }
13306 run_test 118h "Verify timeout in handling recoverables errors  =========="
13307
13308 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13309
13310 test_118i() {
13311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13312         remote_ost_nodsh && skip "remote OST with nodsh"
13313
13314         reset_async
13315
13316         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13317         set_nodes_failloc "$(osts_nodes)" 0x20e
13318
13319         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13320         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13321         PID=$!
13322         sleep 5
13323         set_nodes_failloc "$(osts_nodes)" 0
13324
13325         wait $PID
13326         RC=$?
13327         if [[ $RC -ne 0 ]]; then
13328                 error "got error, but should be not, rc=$RC"
13329         fi
13330
13331         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13332         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13333         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13334         if [[ $LOCKED -ne 0 ]]; then
13335                 error "Locked pages remain in cache, locked=$LOCKED"
13336         fi
13337
13338         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13339                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13340         fi
13341
13342         rm -f $DIR/$tfile
13343         echo "No pages locked after fsync"
13344
13345         return 0
13346 }
13347 run_test 118i "Fix error before timeout in recoverable error  =========="
13348
13349 [ "$SLOW" = "no" ] && set_resend_count 4
13350
13351 test_118j() {
13352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13353         remote_ost_nodsh && skip "remote OST with nodsh"
13354
13355         reset_async
13356
13357         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13358         set_nodes_failloc "$(osts_nodes)" 0x220
13359
13360         # return -EIO from OST
13361         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13362         RC=$?
13363         set_nodes_failloc "$(osts_nodes)" 0x0
13364         if [[ $RC -eq 0 ]]; then
13365                 error "Must return error due to dropped pages, rc=$RC"
13366         fi
13367
13368         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13369         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13370         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13371         if [[ $LOCKED -ne 0 ]]; then
13372                 error "Locked pages remain in cache, locked=$LOCKED"
13373         fi
13374
13375         # in recoverable error on OST we want resend and stay until it finished
13376         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13377                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13378         fi
13379
13380         rm -f $DIR/$tfile
13381         echo "No pages locked after fsync"
13382
13383         return 0
13384 }
13385 run_test 118j "Simulate unrecoverable OST side error =========="
13386
13387 test_118k()
13388 {
13389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13390         remote_ost_nodsh && skip "remote OSTs with nodsh"
13391
13392         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13393         set_nodes_failloc "$(osts_nodes)" 0x20e
13394         test_mkdir $DIR/$tdir
13395
13396         for ((i=0;i<10;i++)); do
13397                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13398                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13399                 SLEEPPID=$!
13400                 sleep 0.500s
13401                 kill $SLEEPPID
13402                 wait $SLEEPPID
13403         done
13404
13405         set_nodes_failloc "$(osts_nodes)" 0
13406         rm -rf $DIR/$tdir
13407 }
13408 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13409
13410 test_118l() # LU-646
13411 {
13412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13413
13414         test_mkdir $DIR/$tdir
13415         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13416         rm -rf $DIR/$tdir
13417 }
13418 run_test 118l "fsync dir"
13419
13420 test_118m() # LU-3066
13421 {
13422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13423
13424         test_mkdir $DIR/$tdir
13425         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13426         rm -rf $DIR/$tdir
13427 }
13428 run_test 118m "fdatasync dir ========="
13429
13430 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13431
13432 test_118n()
13433 {
13434         local begin
13435         local end
13436
13437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13438         remote_ost_nodsh && skip "remote OSTs with nodsh"
13439
13440         # Sleep to avoid a cached response.
13441         #define OBD_STATFS_CACHE_SECONDS 1
13442         sleep 2
13443
13444         # Inject a 10 second delay in the OST_STATFS handler.
13445         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13446         set_nodes_failloc "$(osts_nodes)" 0x242
13447
13448         begin=$SECONDS
13449         stat --file-system $MOUNT > /dev/null
13450         end=$SECONDS
13451
13452         set_nodes_failloc "$(osts_nodes)" 0
13453
13454         if ((end - begin > 20)); then
13455             error "statfs took $((end - begin)) seconds, expected 10"
13456         fi
13457 }
13458 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13459
13460 test_119a() # bug 11737
13461 {
13462         BSIZE=$((512 * 1024))
13463         directio write $DIR/$tfile 0 1 $BSIZE
13464         # We ask to read two blocks, which is more than a file size.
13465         # directio will indicate an error when requested and actual
13466         # sizes aren't equeal (a normal situation in this case) and
13467         # print actual read amount.
13468         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13469         if [ "$NOB" != "$BSIZE" ]; then
13470                 error "read $NOB bytes instead of $BSIZE"
13471         fi
13472         rm -f $DIR/$tfile
13473 }
13474 run_test 119a "Short directIO read must return actual read amount"
13475
13476 test_119b() # bug 11737
13477 {
13478         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13479
13480         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13481         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13482         sync
13483         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13484                 error "direct read failed"
13485         rm -f $DIR/$tfile
13486 }
13487 run_test 119b "Sparse directIO read must return actual read amount"
13488
13489 test_119c() # bug 13099
13490 {
13491         BSIZE=1048576
13492         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13493         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13494         rm -f $DIR/$tfile
13495 }
13496 run_test 119c "Testing for direct read hitting hole"
13497
13498 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13499 # Maloo test history
13500
13501 test_119e()
13502 {
13503         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13504
13505         local stripe_size=$((1024 * 1024)) #1 MiB
13506         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13507         local file_size=$((25 * stripe_size))
13508         local bsizes
13509
13510         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13511         stack_trap "rm -f $DIR/$tfile*"
13512
13513         # Just a bit bigger than the largest size in the test set below
13514         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13515                 error "buffered i/o to create file failed"
13516
13517         if zfs_or_rotational; then
13518                 # DIO on ZFS can take up to 2 seconds per IO
13519                 # rotational is better, but still slow.
13520                 # Limit testing on those media to larger sizes
13521                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13522         else
13523                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13524                         $((stripe_size * 4))"
13525         fi
13526
13527         for bs in $bsizes; do
13528                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13529                 echo "Read/write with DIO at size $bs"
13530                 # Read and write with DIO from source to dest
13531                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13532                         iflag=direct oflag=direct ||
13533                         error "dio failed"
13534
13535                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13536                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13537                         error "size incorrect, file copy read/write bsize: $bs"
13538                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13539                         error "files differ, bsize $bs"
13540                 rm -f $DIR/$tfile.2
13541         done
13542 }
13543 run_test 119e "Basic tests of dio read and write at various sizes"
13544
13545 test_119f()
13546 {
13547         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13548
13549         local stripe_size=$((1024 * 1024)) #1 MiB
13550         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13551         local file_size=$((25 * stripe_size))
13552         local bsizes
13553
13554         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13555         stack_trap "rm -f $DIR/$tfile*"
13556
13557         # Just a bit bigger than the largest size in the test set below
13558         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13559                 error "buffered i/o to create file failed"
13560
13561         if zfs_or_rotational; then
13562                 # DIO on ZFS can take up to 2 seconds per IO
13563                 # rotational is better, but still slow.
13564                 # Limit testing on those media to larger sizes
13565                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13566         else
13567                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13568                         $((stripe_size * 4))"
13569         fi
13570
13571         for bs in $bsizes; do
13572                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13573                 # Read and write with DIO from source to dest in two
13574                 # threads - should give correct copy of file
13575
13576                 echo "bs: $bs"
13577                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13578                         oflag=direct conv=notrunc &
13579                 pid_dio1=$!
13580                 # Note block size is different here for a more interesting race
13581                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13582                         iflag=direct oflag=direct conv=notrunc &
13583                 pid_dio2=$!
13584                 wait $pid_dio1
13585                 rc1=$?
13586                 wait $pid_dio2
13587                 rc2=$?
13588                 if (( rc1 != 0 )); then
13589                         error "dio copy 1 w/bsize $bs failed: $rc1"
13590                 fi
13591                 if (( rc2 != 0 )); then
13592                         error "dio copy 2 w/bsize $bs failed: $rc2"
13593                 fi
13594
13595
13596                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13597                         error "size incorrect, file copy read/write bsize: $bs"
13598                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13599                         error "files differ, bsize $bs"
13600                 rm -f $DIR/$tfile.2
13601         done
13602 }
13603 run_test 119f "dio vs dio race"
13604
13605 test_119g()
13606 {
13607         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13608
13609         local stripe_size=$((1024 * 1024)) #1 MiB
13610         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13611         local file_size=$((25 * stripe_size))
13612         local bsizes
13613
13614         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13615         stack_trap "rm -f $DIR/$tfile*"
13616
13617         # Just a bit bigger than the largest size in the test set below
13618         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13619                 error "buffered i/o to create file failed"
13620
13621         if zfs_or_rotational; then
13622                 # DIO on ZFS can take up to 2 seconds per IO
13623                 # rotational is better, but still slow.
13624                 # Limit testing on those media to larger sizes
13625                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13626         else
13627                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13628                         $((stripe_size * 4))"
13629         fi
13630
13631         for bs in $bsizes; do
13632                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13633                 echo "bs: $bs"
13634                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13635                         oflag=direct conv=notrunc &
13636                 pid_dio1=$!
13637                 # Buffered I/O with similar but not the same block size
13638                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13639                 pid_bio2=$!
13640                 wait $pid_dio1
13641                 rc1=$?
13642                 wait $pid_bio2
13643                 rc2=$?
13644                 if (( rc1 != 0 )); then
13645                         error "dio copy 1 w/bsize $bs failed: $rc1"
13646                 fi
13647                 if (( rc2 != 0 )); then
13648                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13649                 fi
13650
13651                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13652                         error "size incorrect"
13653                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13654                         error "files differ, bsize $bs"
13655                 rm -f $DIR/$tfile.2
13656         done
13657 }
13658 run_test 119g "dio vs buffered I/O race"
13659
13660 test_120a() {
13661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13662         remote_mds_nodsh && skip "remote MDS with nodsh"
13663         test_mkdir -i0 -c1 $DIR/$tdir
13664         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13665                 skip_env "no early lock cancel on server"
13666
13667         lru_resize_disable mdc
13668         lru_resize_disable osc
13669         cancel_lru_locks mdc
13670         # asynchronous object destroy at MDT could cause bl ast to client
13671         cancel_lru_locks osc
13672
13673         stat $DIR/$tdir > /dev/null
13674         can1=$(do_facet mds1 \
13675                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13676                awk '/ldlm_cancel/ {print $2}')
13677         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13678                awk '/ldlm_bl_callback/ {print $2}')
13679         test_mkdir -i0 -c1 $DIR/$tdir/d1
13680         can2=$(do_facet mds1 \
13681                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13682                awk '/ldlm_cancel/ {print $2}')
13683         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13684                awk '/ldlm_bl_callback/ {print $2}')
13685         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13686         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13687         lru_resize_enable mdc
13688         lru_resize_enable osc
13689 }
13690 run_test 120a "Early Lock Cancel: mkdir test"
13691
13692 test_120b() {
13693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13694         remote_mds_nodsh && skip "remote MDS with nodsh"
13695         test_mkdir $DIR/$tdir
13696         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13697                 skip_env "no early lock cancel on server"
13698
13699         lru_resize_disable mdc
13700         lru_resize_disable osc
13701         cancel_lru_locks mdc
13702         stat $DIR/$tdir > /dev/null
13703         can1=$(do_facet $SINGLEMDS \
13704                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13705                awk '/ldlm_cancel/ {print $2}')
13706         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13707                awk '/ldlm_bl_callback/ {print $2}')
13708         touch $DIR/$tdir/f1
13709         can2=$(do_facet $SINGLEMDS \
13710                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13711                awk '/ldlm_cancel/ {print $2}')
13712         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13713                awk '/ldlm_bl_callback/ {print $2}')
13714         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13715         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13716         lru_resize_enable mdc
13717         lru_resize_enable osc
13718 }
13719 run_test 120b "Early Lock Cancel: create test"
13720
13721 test_120c() {
13722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13723         remote_mds_nodsh && skip "remote MDS with nodsh"
13724         test_mkdir -i0 -c1 $DIR/$tdir
13725         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13726                 skip "no early lock cancel on server"
13727
13728         lru_resize_disable mdc
13729         lru_resize_disable osc
13730         test_mkdir -i0 -c1 $DIR/$tdir/d1
13731         test_mkdir -i0 -c1 $DIR/$tdir/d2
13732         touch $DIR/$tdir/d1/f1
13733         cancel_lru_locks mdc
13734         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13735         can1=$(do_facet mds1 \
13736                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13737                awk '/ldlm_cancel/ {print $2}')
13738         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13739                awk '/ldlm_bl_callback/ {print $2}')
13740         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13741         can2=$(do_facet mds1 \
13742                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13743                awk '/ldlm_cancel/ {print $2}')
13744         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13745                awk '/ldlm_bl_callback/ {print $2}')
13746         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13747         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13748         lru_resize_enable mdc
13749         lru_resize_enable osc
13750 }
13751 run_test 120c "Early Lock Cancel: link test"
13752
13753 test_120d() {
13754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13755         remote_mds_nodsh && skip "remote MDS with nodsh"
13756         test_mkdir -i0 -c1 $DIR/$tdir
13757         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13758                 skip_env "no early lock cancel on server"
13759
13760         lru_resize_disable mdc
13761         lru_resize_disable osc
13762         touch $DIR/$tdir
13763         cancel_lru_locks mdc
13764         stat $DIR/$tdir > /dev/null
13765         can1=$(do_facet mds1 \
13766                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13767                awk '/ldlm_cancel/ {print $2}')
13768         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13769                awk '/ldlm_bl_callback/ {print $2}')
13770         chmod a+x $DIR/$tdir
13771         can2=$(do_facet mds1 \
13772                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13773                awk '/ldlm_cancel/ {print $2}')
13774         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13775                awk '/ldlm_bl_callback/ {print $2}')
13776         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13777         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13778         lru_resize_enable mdc
13779         lru_resize_enable osc
13780 }
13781 run_test 120d "Early Lock Cancel: setattr test"
13782
13783 test_120e() {
13784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13785         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13786                 skip_env "no early lock cancel on server"
13787         remote_mds_nodsh && skip "remote MDS with nodsh"
13788
13789         local dlmtrace_set=false
13790
13791         test_mkdir -i0 -c1 $DIR/$tdir
13792         lru_resize_disable mdc
13793         lru_resize_disable osc
13794         ! $LCTL get_param debug | grep -q dlmtrace &&
13795                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13796         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13797         cancel_lru_locks mdc
13798         cancel_lru_locks osc
13799         dd if=$DIR/$tdir/f1 of=/dev/null
13800         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13801         # XXX client can not do early lock cancel of OST lock
13802         # during unlink (LU-4206), so cancel osc lock now.
13803         sleep 2
13804         cancel_lru_locks osc
13805         can1=$(do_facet mds1 \
13806                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13807                awk '/ldlm_cancel/ {print $2}')
13808         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13809                awk '/ldlm_bl_callback/ {print $2}')
13810         unlink $DIR/$tdir/f1
13811         sleep 5
13812         can2=$(do_facet mds1 \
13813                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13814                awk '/ldlm_cancel/ {print $2}')
13815         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13816                awk '/ldlm_bl_callback/ {print $2}')
13817         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13818                 $LCTL dk $TMP/cancel.debug.txt
13819         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13820                 $LCTL dk $TMP/blocking.debug.txt
13821         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13822         lru_resize_enable mdc
13823         lru_resize_enable osc
13824 }
13825 run_test 120e "Early Lock Cancel: unlink test"
13826
13827 test_120f() {
13828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13829         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13830                 skip_env "no early lock cancel on server"
13831         remote_mds_nodsh && skip "remote MDS with nodsh"
13832
13833         test_mkdir -i0 -c1 $DIR/$tdir
13834         lru_resize_disable mdc
13835         lru_resize_disable osc
13836         test_mkdir -i0 -c1 $DIR/$tdir/d1
13837         test_mkdir -i0 -c1 $DIR/$tdir/d2
13838         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13839         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13840         cancel_lru_locks mdc
13841         cancel_lru_locks osc
13842         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13843         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13844         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13845         # XXX client can not do early lock cancel of OST lock
13846         # during rename (LU-4206), so cancel osc lock now.
13847         sleep 2
13848         cancel_lru_locks osc
13849         can1=$(do_facet mds1 \
13850                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13851                awk '/ldlm_cancel/ {print $2}')
13852         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13853                awk '/ldlm_bl_callback/ {print $2}')
13854         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13855         sleep 5
13856         can2=$(do_facet mds1 \
13857                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13858                awk '/ldlm_cancel/ {print $2}')
13859         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13860                awk '/ldlm_bl_callback/ {print $2}')
13861         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13862         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13863         lru_resize_enable mdc
13864         lru_resize_enable osc
13865 }
13866 run_test 120f "Early Lock Cancel: rename test"
13867
13868 test_120g() {
13869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13870         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13871                 skip_env "no early lock cancel on server"
13872         remote_mds_nodsh && skip "remote MDS with nodsh"
13873
13874         lru_resize_disable mdc
13875         lru_resize_disable osc
13876         count=10000
13877         echo create $count files
13878         test_mkdir $DIR/$tdir
13879         cancel_lru_locks mdc
13880         cancel_lru_locks osc
13881         t0=$(date +%s)
13882
13883         can0=$(do_facet $SINGLEMDS \
13884                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13885                awk '/ldlm_cancel/ {print $2}')
13886         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13887                awk '/ldlm_bl_callback/ {print $2}')
13888         createmany -o $DIR/$tdir/f $count
13889         sync
13890         can1=$(do_facet $SINGLEMDS \
13891                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13892                awk '/ldlm_cancel/ {print $2}')
13893         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13894                awk '/ldlm_bl_callback/ {print $2}')
13895         t1=$(date +%s)
13896         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13897         echo rm $count files
13898         rm -r $DIR/$tdir
13899         sync
13900         can2=$(do_facet $SINGLEMDS \
13901                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13902                awk '/ldlm_cancel/ {print $2}')
13903         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13904                awk '/ldlm_bl_callback/ {print $2}')
13905         t2=$(date +%s)
13906         echo total: $count removes in $((t2-t1))
13907         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13908         sleep 2
13909         # wait for commitment of removal
13910         lru_resize_enable mdc
13911         lru_resize_enable osc
13912 }
13913 run_test 120g "Early Lock Cancel: performance test"
13914
13915 test_121() { #bug #10589
13916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13917
13918         rm -rf $DIR/$tfile
13919         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13920 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13921         lctl set_param fail_loc=0x310
13922         cancel_lru_locks osc > /dev/null
13923         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13924         lctl set_param fail_loc=0
13925         [[ $reads -eq $writes ]] ||
13926                 error "read $reads blocks, must be $writes blocks"
13927 }
13928 run_test 121 "read cancel race ========="
13929
13930 test_123a_base() { # was test 123, statahead(bug 11401)
13931         local lsx="$1"
13932
13933         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13934
13935         SLOWOK=0
13936         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13937                 log "testing UP system. Performance may be lower than expected."
13938                 SLOWOK=1
13939         fi
13940         running_in_vm && SLOWOK=1
13941
13942         $LCTL set_param mdc.*.batch_stats=0
13943
13944         rm -rf $DIR/$tdir
13945         test_mkdir $DIR/$tdir
13946         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13947         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13948         MULT=10
13949         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13950                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13951
13952                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13953                 lctl set_param -n llite.*.statahead_max 0
13954                 lctl get_param llite.*.statahead_max
13955                 cancel_lru_locks mdc
13956                 cancel_lru_locks osc
13957                 stime=$(date +%s)
13958                 time $lsx $DIR/$tdir | wc -l
13959                 etime=$(date +%s)
13960                 delta=$((etime - stime))
13961                 log "$lsx $i files without statahead: $delta sec"
13962                 lctl set_param llite.*.statahead_max=$max
13963
13964                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13965                          awk '/statahead.wrong:/ { print $NF }')
13966                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13967                 cancel_lru_locks mdc
13968                 cancel_lru_locks osc
13969                 stime=$(date +%s)
13970                 time $lsx $DIR/$tdir | wc -l
13971                 etime=$(date +%s)
13972                 delta_sa=$((etime - stime))
13973                 log "$lsx $i files with statahead: $delta_sa sec"
13974                 lctl get_param -n llite.*.statahead_stats
13975                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13976                          awk '/statahead.wrong:/ { print $NF }')
13977
13978                 [[ $swrong -lt $ewrong ]] &&
13979                         log "statahead was stopped, maybe too many locks held!"
13980                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13981
13982                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13983                         max=$(lctl get_param -n llite.*.statahead_max |
13984                                 head -n 1)
13985                         lctl set_param -n llite.*.statahead_max 0
13986                         lctl get_param llite.*.statahead_max
13987                         cancel_lru_locks mdc
13988                         cancel_lru_locks osc
13989                         stime=$(date +%s)
13990                         time $lsx $DIR/$tdir | wc -l
13991                         etime=$(date +%s)
13992                         delta=$((etime - stime))
13993                         log "$lsx $i files again without statahead: $delta sec"
13994                         lctl set_param llite.*.statahead_max=$max
13995                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13996                                 if [ $SLOWOK -eq 0 ]; then
13997                                         error "$lsx $i files is slower with statahead!"
13998                                 else
13999                                         log "$lsx $i files is slower with statahead!"
14000                                 fi
14001                                 break
14002                         fi
14003                 fi
14004
14005                 [ $delta -gt 20 ] && break
14006                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14007                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14008         done
14009         log "$lsx done"
14010
14011         stime=$(date +%s)
14012         rm -r $DIR/$tdir
14013         sync
14014         etime=$(date +%s)
14015         delta=$((etime - stime))
14016         log "rm -r $DIR/$tdir/: $delta seconds"
14017         log "rm done"
14018         lctl get_param -n llite.*.statahead_stats
14019         $LCTL get_param mdc.*.batch_stats
14020 }
14021
14022 test_123aa() {
14023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14024
14025         test_123a_base "ls -l"
14026 }
14027 run_test 123aa "verify statahead work"
14028
14029 test_123ab() {
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         statx_supported || skip_env "Test must be statx() syscall supported"
14033
14034         test_123a_base "$STATX -l"
14035 }
14036 run_test 123ab "verify statahead work by using statx"
14037
14038 test_123ac() {
14039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14040
14041         statx_supported || skip_env "Test must be statx() syscall supported"
14042
14043         local rpcs_before
14044         local rpcs_after
14045         local agl_before
14046         local agl_after
14047
14048         cancel_lru_locks $OSC
14049         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14050         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14051                      awk '/agl.total:/ { print $NF }')
14052         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14053         test_123a_base "$STATX --cached=always -D"
14054         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14055                     awk '/agl.total:/ { print $NF }')
14056         [ $agl_before -eq $agl_after ] ||
14057                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14058         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14059         [ $rpcs_after -eq $rpcs_before ] ||
14060                 error "$STATX should not send glimpse RPCs to $OSC"
14061 }
14062 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14063
14064 test_batch_statahead() {
14065         local max=$1
14066         local batch_max=$2
14067         local num=10000
14068         local batch_rpcs
14069         local unbatch_rpcs
14070         local hit_total
14071
14072         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14073         $LCTL set_param mdc.*.batch_stats=0
14074         $LCTL set_param llite.*.statahead_max=$max
14075         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14076         # Verify that batched statahead is faster than one without statahead
14077         test_123a_base "ls -l"
14078
14079         stack_trap "rm -rf $DIR/$tdir" EXIT
14080         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14081         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14082
14083         # unbatched statahead
14084         $LCTL set_param llite.*.statahead_batch_max=0
14085         $LCTL set_param llite.*.statahead_stats=clear
14086         $LCTL set_param mdc.*.stats=clear
14087         cancel_lru_locks mdc
14088         cancel_lru_locks osc
14089         time ls -l $DIR/$tdir | wc -l
14090         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14091         sleep 2
14092         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14093                     awk '/hit.total:/ { print $NF }')
14094         # hit ratio should be larger than 75% (7500).
14095         (( $hit_total > 7500 )) ||
14096                 error "unbatched statahead hit count ($hit_total) is too low"
14097
14098         # batched statahead
14099         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14100         $LCTL set_param llite.*.statahead_stats=clear
14101         $LCTL set_param mdc.*.batch_stats=clear
14102         $LCTL set_param mdc.*.stats=clear
14103         cancel_lru_locks mdc
14104         cancel_lru_locks osc
14105         time ls -l $DIR/$tdir | wc -l
14106         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14107         # wait for statahead thread to quit and update statahead stats
14108         sleep 2
14109         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14110                     awk '/hit.total:/ { print $NF }')
14111         # hit ratio should be larger than 75% (7500).
14112         (( $hit_total > 7500 )) ||
14113                 error "batched statahead hit count ($hit_total) is too low"
14114
14115         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14116         (( $unbatch_rpcs > $batch_rpcs )) ||
14117                 error "batched statahead does not reduce RPC count"
14118         $LCTL get_param mdc.*.batch_stats
14119 }
14120
14121 test_123ad() {
14122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14123
14124         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14125                 skip "Need server version at least 2.15.53"
14126
14127         local max
14128         local batch_max
14129
14130         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14131         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14132
14133         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14134         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14135
14136         test_batch_statahead 32 32
14137         test_batch_statahead 2048 256
14138 }
14139 run_test 123ad "Verify batching statahead works correctly"
14140
14141 test_123b () { # statahead(bug 15027)
14142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14143
14144         test_mkdir $DIR/$tdir
14145         createmany -o $DIR/$tdir/$tfile-%d 1000
14146
14147         cancel_lru_locks mdc
14148         cancel_lru_locks osc
14149
14150 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14151         lctl set_param fail_loc=0x80000803
14152         ls -lR $DIR/$tdir > /dev/null
14153         log "ls done"
14154         lctl set_param fail_loc=0x0
14155         lctl get_param -n llite.*.statahead_stats
14156         rm -r $DIR/$tdir
14157         sync
14158
14159 }
14160 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14161
14162 test_123c() {
14163         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14164
14165         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14166         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14167         touch $DIR/$tdir.1/{1..3}
14168         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14169
14170         remount_client $MOUNT
14171
14172         $MULTIOP $DIR/$tdir.0 Q
14173
14174         # let statahead to complete
14175         ls -l $DIR/$tdir.0 > /dev/null
14176
14177         testid=$(echo $TESTNAME | tr '_' ' ')
14178         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14179                 error "statahead warning" || true
14180 }
14181 run_test 123c "Can not initialize inode warning on DNE statahead"
14182
14183 test_123d() {
14184         local num=100
14185         local swrong
14186         local ewrong
14187
14188         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14189         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14190                 error "setdirstripe $DIR/$tdir failed"
14191         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14192         remount_client $MOUNT
14193         $LCTL get_param llite.*.statahead_max
14194         $LCTL set_param llite.*.statahead_stats=0 ||
14195                 error "clear statahead_stats failed"
14196         swrong=$(lctl get_param -n llite.*.statahead_stats |
14197                  awk '/statahead.wrong:/ { print $NF }')
14198         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14199         # wait for statahead thread finished to update hit/miss stats.
14200         sleep 1
14201         $LCTL get_param -n llite.*.statahead_stats
14202         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14203                  awk '/statahead.wrong:/ { print $NF }')
14204         (( $swrong == $ewrong )) ||
14205                 log "statahead was stopped, maybe too many locks held!"
14206 }
14207 run_test 123d "Statahead on striped directories works correctly"
14208
14209 test_123e() {
14210         local max
14211         local batch_max
14212         local dir=$DIR/$tdir
14213
14214         mkdir $dir || error "mkdir $dir failed"
14215         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14216         stack_trap "rm -rf $dir"
14217
14218         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14219
14220         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14221         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14222         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14223         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14224
14225         $LCTL set_param llite.*.statahead_max=2048
14226         $LCTL set_param llite.*.statahead_batch_max=1024
14227
14228         ls -l $dir
14229         $LCTL get_param mdc.*.batch_stats
14230         $LCTL get_param llite.*.statahead_*
14231 }
14232 run_test 123e "statahead with large wide striping"
14233
14234 test_123f() {
14235         local max
14236         local batch_max
14237         local dir=$DIR/$tdir
14238
14239         mkdir $dir || error "mkdir $dir failed"
14240         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14241         stack_trap "rm -rf $dir"
14242
14243         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14244
14245         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14246         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14247
14248         $LCTL set_param llite.*.statahead_max=64
14249         $LCTL set_param llite.*.statahead_batch_max=64
14250
14251         ls -l $dir
14252         lctl get_param mdc.*.batch_stats
14253         lctl get_param llite.*.statahead_*
14254
14255         $LCTL set_param llite.*.statahead_max=$max
14256         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14257 }
14258 run_test 123f "Retry mechanism with large wide striping files"
14259
14260 test_124a() {
14261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14262         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14263                 skip_env "no lru resize on server"
14264
14265         local NR=2000
14266
14267         test_mkdir $DIR/$tdir
14268
14269         log "create $NR files at $DIR/$tdir"
14270         createmany -o $DIR/$tdir/f $NR ||
14271                 error "failed to create $NR files in $DIR/$tdir"
14272
14273         cancel_lru_locks mdc
14274         ls -l $DIR/$tdir > /dev/null
14275
14276         local NSDIR=""
14277         local LRU_SIZE=0
14278         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14279                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14280                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14281                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14282                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14283                         log "NSDIR=$NSDIR"
14284                         log "NS=$(basename $NSDIR)"
14285                         break
14286                 fi
14287         done
14288
14289         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14290                 skip "Not enough cached locks created!"
14291         fi
14292         log "LRU=$LRU_SIZE"
14293
14294         local SLEEP=30
14295
14296         # We know that lru resize allows one client to hold $LIMIT locks
14297         # for 10h. After that locks begin to be killed by client.
14298         local MAX_HRS=10
14299         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14300         log "LIMIT=$LIMIT"
14301         if [ $LIMIT -lt $LRU_SIZE ]; then
14302                 skip "Limit is too small $LIMIT"
14303         fi
14304
14305         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14306         # killing locks. Some time was spent for creating locks. This means
14307         # that up to the moment of sleep finish we must have killed some of
14308         # them (10-100 locks). This depends on how fast ther were created.
14309         # Many of them were touched in almost the same moment and thus will
14310         # be killed in groups.
14311         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14312
14313         # Use $LRU_SIZE_B here to take into account real number of locks
14314         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14315         local LRU_SIZE_B=$LRU_SIZE
14316         log "LVF=$LVF"
14317         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14318         log "OLD_LVF=$OLD_LVF"
14319         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14320
14321         # Let's make sure that we really have some margin. Client checks
14322         # cached locks every 10 sec.
14323         SLEEP=$((SLEEP+20))
14324         log "Sleep ${SLEEP} sec"
14325         local SEC=0
14326         while ((SEC<$SLEEP)); do
14327                 echo -n "..."
14328                 sleep 5
14329                 SEC=$((SEC+5))
14330                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14331                 echo -n "$LRU_SIZE"
14332         done
14333         echo ""
14334         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14335         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14336
14337         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14338                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14339                 unlinkmany $DIR/$tdir/f $NR
14340                 return
14341         }
14342
14343         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14344         log "unlink $NR files at $DIR/$tdir"
14345         unlinkmany $DIR/$tdir/f $NR
14346 }
14347 run_test 124a "lru resize ======================================="
14348
14349 get_max_pool_limit()
14350 {
14351         local limit=$($LCTL get_param \
14352                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14353         local max=0
14354         for l in $limit; do
14355                 if [[ $l -gt $max ]]; then
14356                         max=$l
14357                 fi
14358         done
14359         echo $max
14360 }
14361
14362 test_124b() {
14363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14364         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14365                 skip_env "no lru resize on server"
14366
14367         LIMIT=$(get_max_pool_limit)
14368
14369         NR=$(($(default_lru_size)*20))
14370         if [[ $NR -gt $LIMIT ]]; then
14371                 log "Limit lock number by $LIMIT locks"
14372                 NR=$LIMIT
14373         fi
14374
14375         IFree=$(mdsrate_inodes_available)
14376         if [ $IFree -lt $NR ]; then
14377                 log "Limit lock number by $IFree inodes"
14378                 NR=$IFree
14379         fi
14380
14381         lru_resize_disable mdc
14382         test_mkdir -p $DIR/$tdir/disable_lru_resize
14383
14384         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14385         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14386         cancel_lru_locks mdc
14387         stime=`date +%s`
14388         PID=""
14389         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14390         PID="$PID $!"
14391         sleep 2
14392         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14393         PID="$PID $!"
14394         sleep 2
14395         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14396         PID="$PID $!"
14397         wait $PID
14398         etime=`date +%s`
14399         nolruresize_delta=$((etime-stime))
14400         log "ls -la time: $nolruresize_delta seconds"
14401         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14402         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14403
14404         lru_resize_enable mdc
14405         test_mkdir -p $DIR/$tdir/enable_lru_resize
14406
14407         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14408         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14409         cancel_lru_locks mdc
14410         stime=`date +%s`
14411         PID=""
14412         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14413         PID="$PID $!"
14414         sleep 2
14415         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14416         PID="$PID $!"
14417         sleep 2
14418         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14419         PID="$PID $!"
14420         wait $PID
14421         etime=`date +%s`
14422         lruresize_delta=$((etime-stime))
14423         log "ls -la time: $lruresize_delta seconds"
14424         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14425
14426         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14427                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14428         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14429                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14430         else
14431                 log "lru resize performs the same with no lru resize"
14432         fi
14433         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14434 }
14435 run_test 124b "lru resize (performance test) ======================="
14436
14437 test_124c() {
14438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14439         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14440                 skip_env "no lru resize on server"
14441
14442         # cache ununsed locks on client
14443         local nr=100
14444         cancel_lru_locks mdc
14445         test_mkdir $DIR/$tdir
14446         createmany -o $DIR/$tdir/f $nr ||
14447                 error "failed to create $nr files in $DIR/$tdir"
14448         ls -l $DIR/$tdir > /dev/null
14449
14450         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14451         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14452         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14453         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14454         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14455
14456         # set lru_max_age to 1 sec
14457         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14458         echo "sleep $((recalc_p * 2)) seconds..."
14459         sleep $((recalc_p * 2))
14460
14461         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14462         # restore lru_max_age
14463         $LCTL set_param -n $nsdir.lru_max_age $max_age
14464         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14465         unlinkmany $DIR/$tdir/f $nr
14466 }
14467 run_test 124c "LRUR cancel very aged locks"
14468
14469 test_124d() {
14470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14471         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14472                 skip_env "no lru resize on server"
14473
14474         # cache ununsed locks on client
14475         local nr=100
14476
14477         lru_resize_disable mdc
14478         stack_trap "lru_resize_enable mdc" EXIT
14479
14480         cancel_lru_locks mdc
14481
14482         # asynchronous object destroy at MDT could cause bl ast to client
14483         test_mkdir $DIR/$tdir
14484         createmany -o $DIR/$tdir/f $nr ||
14485                 error "failed to create $nr files in $DIR/$tdir"
14486         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14487
14488         ls -l $DIR/$tdir > /dev/null
14489
14490         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14491         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14492         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14493         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14494
14495         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14496
14497         # set lru_max_age to 1 sec
14498         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14499         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14500
14501         echo "sleep $((recalc_p * 2)) seconds..."
14502         sleep $((recalc_p * 2))
14503
14504         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14505
14506         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14507 }
14508 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14509
14510 test_125() { # 13358
14511         $LCTL get_param -n llite.*.client_type | grep -q local ||
14512                 skip "must run as local client"
14513         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14514                 skip_env "must have acl enabled"
14515         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14516         id $USER0 || skip_env "missing user $USER0"
14517
14518         test_mkdir $DIR/$tdir
14519         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14520         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14521                 error "setfacl $DIR/$tdir failed"
14522         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14523 }
14524 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14525
14526 test_126() { # bug 12829/13455
14527         $GSS && skip_env "must run as gss disabled"
14528         $LCTL get_param -n llite.*.client_type | grep -q local ||
14529                 skip "must run as local client"
14530         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14531
14532         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14533         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14534         rm -f $DIR/$tfile
14535         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14536 }
14537 run_test 126 "check that the fsgid provided by the client is taken into account"
14538
14539 test_127a() { # bug 15521
14540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14541         local name count samp unit min max sum sumsq
14542         local tmpfile=$TMP/$tfile.tmp
14543
14544         # enable stats header if it is disabled
14545         $LCTL set_param enable_stats_header=1
14546
14547         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14548         echo "stats before reset"
14549         stack_trap "rm -f $tmpfile"
14550         local now=$(date +%s)
14551
14552         $LCTL get_param osc.*.stats | tee $tmpfile
14553
14554         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14555         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14556         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14557         local uptime=$(awk '{ print $1 }' /proc/uptime)
14558
14559         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14560         (( ${snapshot_time%\.*} >= $now - 5 &&
14561            ${snapshot_time%\.*} <= $now + 5 )) ||
14562                 error "snapshot_time=$snapshot_time != now=$now"
14563         # elapsed _should_ be from mount, but at least less than uptime
14564         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14565                 error "elapsed=$elapsed > uptime=$uptime"
14566         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14567            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14568                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14569
14570         $LCTL set_param osc.*.stats=0
14571         local reset=$(date +%s)
14572         local fsize=$((2048 * 1024))
14573
14574         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14575         cancel_lru_locks osc
14576         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14577
14578         now=$(date +%s)
14579         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14580         while read name count samp unit min max sum sumsq; do
14581                 [[ "$samp" == "samples" ]] || continue
14582
14583                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14584                 [ ! $min ] && error "Missing min value for $name proc entry"
14585                 eval $name=$count || error "Wrong proc format"
14586
14587                 case $name in
14588                 read_bytes|write_bytes)
14589                         [[ "$unit" =~ "bytes" ]] ||
14590                                 error "unit is not 'bytes': $unit"
14591                         (( $min >= 4096 )) || error "min is too small: $min"
14592                         (( $min <= $fsize )) || error "min is too big: $min"
14593                         (( $max >= 4096 )) || error "max is too small: $max"
14594                         (( $max <= $fsize )) || error "max is too big: $max"
14595                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14596                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14597                                 error "sumsquare is too small: $sumsq"
14598                         (( $sumsq <= $fsize * $fsize )) ||
14599                                 error "sumsquare is too big: $sumsq"
14600                         ;;
14601                 ost_read|ost_write)
14602                         [[ "$unit" =~ "usec" ]] ||
14603                                 error "unit is not 'usec': $unit"
14604                         ;;
14605                 *)      ;;
14606                 esac
14607         done < $tmpfile
14608
14609         #check that we actually got some stats
14610         [ "$read_bytes" ] || error "Missing read_bytes stats"
14611         [ "$write_bytes" ] || error "Missing write_bytes stats"
14612         [ "$read_bytes" != 0 ] || error "no read done"
14613         [ "$write_bytes" != 0 ] || error "no write done"
14614
14615         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14616         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14617         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14618
14619         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14620         (( ${snapshot_time%\.*} >= $now - 5 &&
14621            ${snapshot_time%\.*} <= $now + 5 )) ||
14622                 error "reset snapshot_time=$snapshot_time != now=$now"
14623         # elapsed should be from time of stats reset
14624         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14625            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14626                 error "reset elapsed=$elapsed > $now - $reset"
14627         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14628            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14629                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14630 }
14631 run_test 127a "verify the client stats are sane"
14632
14633 test_127b() { # bug LU-333
14634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14635         local name count samp unit min max sum sumsq
14636
14637         echo "stats before reset"
14638         $LCTL get_param llite.*.stats
14639         $LCTL set_param llite.*.stats=0
14640
14641         # perform 2 reads and writes so MAX is different from SUM.
14642         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14643         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14644         cancel_lru_locks osc
14645         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14646         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14647
14648         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14649         stack_trap "rm -f $TMP/$tfile.tmp"
14650         while read name count samp unit min max sum sumsq; do
14651                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14652                 eval $name=$count || error "Wrong proc format"
14653
14654                 case $name in
14655                 read_bytes|write_bytes)
14656                         [[ "$unit" =~ "bytes" ]] ||
14657                                 error "unit is not 'bytes': $unit"
14658                         (( $count == 2 )) || error "count is not 2: $count"
14659                         (( $min == $PAGE_SIZE )) ||
14660                                 error "min is not $PAGE_SIZE: $min"
14661                         (( $max == $PAGE_SIZE )) ||
14662                                 error "max is not $PAGE_SIZE: $max"
14663                         (( $sum == $PAGE_SIZE * 2 )) ||
14664                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14665                         ;;
14666                 read|write)
14667                         [[ "$unit" =~ "usec" ]] ||
14668                                 error "unit is not 'usec': $unit"
14669                         ;;
14670                 *)      ;;
14671                 esac
14672         done < $TMP/$tfile.tmp
14673
14674         #check that we actually got some stats
14675         [ "$read_bytes" ] || error "Missing read_bytes stats"
14676         [ "$write_bytes" ] || error "Missing write_bytes stats"
14677         [ "$read_bytes" != 0 ] || error "no read done"
14678         [ "$write_bytes" != 0 ] || error "no write done"
14679 }
14680 run_test 127b "verify the llite client stats are sane"
14681
14682 test_127c() { # LU-12394
14683         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14684         local size
14685         local bsize
14686         local reads
14687         local writes
14688         local count
14689
14690         $LCTL set_param llite.*.extents_stats=1
14691         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14692
14693         # Use two stripes so there is enough space in default config
14694         $LFS setstripe -c 2 $DIR/$tfile
14695
14696         # Extent stats start at 0-4K and go in power of two buckets
14697         # LL_HIST_START = 12 --> 2^12 = 4K
14698         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14699         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14700         # small configs
14701         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14702                 do
14703                 # Write and read, 2x each, second time at a non-zero offset
14704                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14705                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14706                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14707                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14708                 rm -f $DIR/$tfile
14709         done
14710
14711         $LCTL get_param llite.*.extents_stats
14712
14713         count=2
14714         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14715                 do
14716                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14717                                 grep -m 1 $bsize)
14718                 reads=$(echo $bucket | awk '{print $5}')
14719                 writes=$(echo $bucket | awk '{print $9}')
14720                 [ "$reads" -eq $count ] ||
14721                         error "$reads reads in < $bsize bucket, expect $count"
14722                 [ "$writes" -eq $count ] ||
14723                         error "$writes writes in < $bsize bucket, expect $count"
14724         done
14725
14726         # Test mmap write and read
14727         $LCTL set_param llite.*.extents_stats=c
14728         size=512
14729         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14730         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14731         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14732
14733         $LCTL get_param llite.*.extents_stats
14734
14735         count=$(((size*1024) / PAGE_SIZE))
14736
14737         bsize=$((2 * PAGE_SIZE / 1024))K
14738
14739         bucket=$($LCTL get_param -n llite.*.extents_stats |
14740                         grep -m 1 $bsize)
14741         reads=$(echo $bucket | awk '{print $5}')
14742         writes=$(echo $bucket | awk '{print $9}')
14743         # mmap writes fault in the page first, creating an additonal read
14744         [ "$reads" -eq $((2 * count)) ] ||
14745                 error "$reads reads in < $bsize bucket, expect $count"
14746         [ "$writes" -eq $count ] ||
14747                 error "$writes writes in < $bsize bucket, expect $count"
14748 }
14749 run_test 127c "test llite extent stats with regular & mmap i/o"
14750
14751 test_128() { # bug 15212
14752         touch $DIR/$tfile
14753         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14754                 find $DIR/$tfile
14755                 find $DIR/$tfile
14756         EOF
14757
14758         result=$(grep error $TMP/$tfile.log)
14759         rm -f $DIR/$tfile $TMP/$tfile.log
14760         [ -z "$result" ] ||
14761                 error "consecutive find's under interactive lfs failed"
14762 }
14763 run_test 128 "interactive lfs for 2 consecutive find's"
14764
14765 set_dir_limits () {
14766         local mntdev
14767         local canondev
14768         local node
14769
14770         local ldproc=/proc/fs/ldiskfs
14771         local facets=$(get_facets MDS)
14772
14773         for facet in ${facets//,/ }; do
14774                 canondev=$(ldiskfs_canon \
14775                            *.$(convert_facet2label $facet).mntdev $facet)
14776                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14777                         ldproc=/sys/fs/ldiskfs
14778                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14779                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14780         done
14781 }
14782
14783 check_mds_dmesg() {
14784         local facets=$(get_facets MDS)
14785         for facet in ${facets//,/ }; do
14786                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14787         done
14788         return 1
14789 }
14790
14791 test_129() {
14792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14793         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14794                 skip "Need MDS version with at least 2.5.56"
14795         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14796                 skip_env "ldiskfs only test"
14797         fi
14798         remote_mds_nodsh && skip "remote MDS with nodsh"
14799
14800         local ENOSPC=28
14801         local has_warning=false
14802
14803         rm -rf $DIR/$tdir
14804         mkdir -p $DIR/$tdir
14805
14806         # block size of mds1
14807         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14808         set_dir_limits $maxsize $((maxsize * 6 / 8))
14809         stack_trap "set_dir_limits 0 0"
14810         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14811         local dirsize=$(stat -c%s "$DIR/$tdir")
14812         local nfiles=0
14813         while (( $dirsize <= $maxsize )); do
14814                 $MCREATE $DIR/$tdir/file_base_$nfiles
14815                 rc=$?
14816                 # check two errors:
14817                 # ENOSPC for ext4 max_dir_size, which has been used since
14818                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14819                 if (( rc == ENOSPC )); then
14820                         set_dir_limits 0 0
14821                         echo "rc=$rc returned as expected after $nfiles files"
14822
14823                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14824                                 error "create failed w/o dir size limit"
14825
14826                         # messages may be rate limited if test is run repeatedly
14827                         check_mds_dmesg '"is approaching max"' ||
14828                                 echo "warning message should be output"
14829                         check_mds_dmesg '"has reached max"' ||
14830                                 echo "reached message should be output"
14831
14832                         dirsize=$(stat -c%s "$DIR/$tdir")
14833
14834                         [[ $dirsize -ge $maxsize ]] && return 0
14835                         error "dirsize $dirsize < $maxsize after $nfiles files"
14836                 elif (( rc != 0 )); then
14837                         break
14838                 fi
14839                 nfiles=$((nfiles + 1))
14840                 dirsize=$(stat -c%s "$DIR/$tdir")
14841         done
14842
14843         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14844 }
14845 run_test 129 "test directory size limit ========================"
14846
14847 OLDIFS="$IFS"
14848 cleanup_130() {
14849         trap 0
14850         IFS="$OLDIFS"
14851         rm -f $DIR/$tfile
14852 }
14853
14854 test_130a() {
14855         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14856         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14857
14858         trap cleanup_130 EXIT RETURN
14859
14860         local fm_file=$DIR/$tfile
14861         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14862         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14863                 error "dd failed for $fm_file"
14864
14865         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14866         filefrag -ves $fm_file
14867         local rc=$?
14868         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14869                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14870         (( $rc == 0 )) || error "filefrag $fm_file failed"
14871
14872         filefrag_op=$(filefrag -ve -k $fm_file |
14873                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14874         local lun=$($LFS getstripe -i $fm_file)
14875
14876         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14877         IFS=$'\n'
14878         local tot_len=0
14879         for line in $filefrag_op; do
14880                 local frag_lun=$(echo $line | cut -d: -f5)
14881                 local ext_len=$(echo $line | cut -d: -f4)
14882
14883                 if (( $frag_lun != $lun )); then
14884                         error "FIEMAP on 1-stripe file($fm_file) failed"
14885                         return
14886                 fi
14887                 (( tot_len += ext_len ))
14888         done
14889
14890         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14891                 error "FIEMAP on 1-stripe file($fm_file) failed"
14892                 return
14893         fi
14894
14895         echo "FIEMAP on single striped file succeeded"
14896 }
14897 run_test 130a "FIEMAP (1-stripe file)"
14898
14899 test_130b() {
14900         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14901
14902         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14903         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14904         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14905                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14906
14907         trap cleanup_130 EXIT RETURN
14908
14909         local fm_file=$DIR/$tfile
14910         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14911                 error "setstripe on $fm_file"
14912
14913         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14914                 error "dd failed on $fm_file"
14915
14916         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14917         filefrag_op=$(filefrag -ve -k $fm_file |
14918                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14919
14920         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14921                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14922
14923         IFS=$'\n'
14924         local tot_len=0
14925         local num_luns=1
14926
14927         for line in $filefrag_op; do
14928                 local frag_lun=$(echo $line | cut -d: -f5 |
14929                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14930                 local ext_len=$(echo $line | cut -d: -f4)
14931                 if (( $frag_lun != $last_lun )); then
14932                         if (( tot_len != 1024 )); then
14933                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14934                                 return
14935                         else
14936                                 (( num_luns += 1 ))
14937                                 tot_len=0
14938                         fi
14939                 fi
14940                 (( tot_len += ext_len ))
14941                 last_lun=$frag_lun
14942         done
14943         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14944                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14945                 return
14946         fi
14947
14948         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14949 }
14950 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14951
14952 test_130c() {
14953         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14954
14955         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14956         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14957         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14958                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14959
14960         trap cleanup_130 EXIT RETURN
14961
14962         local fm_file=$DIR/$tfile
14963         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14964
14965         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14966                 error "dd failed on $fm_file"
14967
14968         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14969         filefrag_op=$(filefrag -ve -k $fm_file |
14970                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14971
14972         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14973                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14974
14975         IFS=$'\n'
14976         local tot_len=0
14977         local num_luns=1
14978         for line in $filefrag_op; do
14979                 local frag_lun=$(echo $line | cut -d: -f5 |
14980                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14981                 local ext_len=$(echo $line | cut -d: -f4)
14982                 if (( $frag_lun != $last_lun )); then
14983                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14984                         if (( logical != 512 )); then
14985                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14986                                 return
14987                         fi
14988                         if (( tot_len != 512 )); then
14989                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14990                                 return
14991                         else
14992                                 (( num_luns += 1 ))
14993                                 tot_len=0
14994                         fi
14995                 fi
14996                 (( tot_len += ext_len ))
14997                 last_lun=$frag_lun
14998         done
14999         if (( num_luns != 2 || tot_len != 512 )); then
15000                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15001                 return
15002         fi
15003
15004         echo "FIEMAP on 2-stripe file with hole succeeded"
15005 }
15006 run_test 130c "FIEMAP (2-stripe file with hole)"
15007
15008 test_130d() {
15009         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15010
15011         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15012         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15013         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15014                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15015
15016         trap cleanup_130 EXIT RETURN
15017
15018         local fm_file=$DIR/$tfile
15019         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15020                         error "setstripe on $fm_file"
15021
15022         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15023         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15024                 error "dd failed on $fm_file"
15025
15026         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15027         filefrag_op=$(filefrag -ve -k $fm_file |
15028                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15029
15030         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15031                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15032
15033         IFS=$'\n'
15034         local tot_len=0
15035         local num_luns=1
15036         for line in $filefrag_op; do
15037                 local frag_lun=$(echo $line | cut -d: -f5 |
15038                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15039                 local ext_len=$(echo $line | cut -d: -f4)
15040                 if (( $frag_lun != $last_lun )); then
15041                         if (( tot_len != 1024 )); then
15042                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15043                                 return
15044                         else
15045                                 (( num_luns += 1 ))
15046                                 local tot_len=0
15047                         fi
15048                 fi
15049                 (( tot_len += ext_len ))
15050                 last_lun=$frag_lun
15051         done
15052         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15053                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15054                 return
15055         fi
15056
15057         echo "FIEMAP on N-stripe file succeeded"
15058 }
15059 run_test 130d "FIEMAP (N-stripe file)"
15060
15061 test_130e() {
15062         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15063
15064         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15065         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15066         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15067                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15068
15069         trap cleanup_130 EXIT RETURN
15070
15071         local fm_file=$DIR/$tfile
15072         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15073         stack_trap "rm -f $fm_file"
15074
15075         local num_blks=512
15076         local expected_len=$(( (num_blks / 2) * 64 ))
15077         for ((i = 0; i < $num_blks; i++)); do
15078                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15079                         conv=notrunc > /dev/null 2>&1
15080         done
15081
15082         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15083         filefrag_op=$(filefrag -ve -k $fm_file |
15084                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15085
15086         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15087
15088         IFS=$'\n'
15089         local tot_len=0
15090         local num_luns=1
15091         for line in $filefrag_op; do
15092                 local frag_lun=$(echo $line | cut -d: -f5)
15093                 local ext_len=$(echo $line | cut -d: -f4)
15094                 if (( $frag_lun != $last_lun )); then
15095                         if (( tot_len != $expected_len )); then
15096                                 error "OST$last_lun $tot_len != $expected_len"
15097                         else
15098                                 (( num_luns += 1 ))
15099                                 tot_len=0
15100                         fi
15101                 fi
15102                 (( tot_len += ext_len ))
15103                 last_lun=$frag_lun
15104         done
15105         if (( num_luns != 2 || tot_len != $expected_len )); then
15106                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15107         fi
15108
15109         echo "FIEMAP with continuation calls succeeded"
15110 }
15111 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15112
15113 test_130f() {
15114         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15115         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15116         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15117                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15118
15119         local fm_file=$DIR/$tfile
15120         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15121                 error "multiop create with lov_delay_create on $fm_file"
15122
15123         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15124         filefrag_extents=$(filefrag -vek $fm_file |
15125                            awk '/extents? found/ { print $2 }')
15126         if (( $filefrag_extents != 0 )); then
15127                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15128         fi
15129
15130         rm -f $fm_file
15131 }
15132 run_test 130f "FIEMAP (unstriped file)"
15133
15134 test_130g() {
15135         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15136                 skip "Need MDS version with at least 2.12.53 for overstriping"
15137         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15138         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15139         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15140                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15141
15142         local file=$DIR/$tfile
15143         local nr=$((OSTCOUNT * 100))
15144
15145         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
15146
15147         stack_trap "rm -f $file"
15148         dd if=/dev/zero of=$file count=$nr bs=1M
15149         sync
15150         nr=$($LFS getstripe -c $file)
15151
15152         local extents=$(filefrag -v $file |
15153                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15154
15155         echo "filefrag list $extents extents in file with stripecount $nr"
15156         if (( extents < nr )); then
15157                 $LFS getstripe $file
15158                 filefrag -v $file
15159                 error "filefrag printed $extents < $nr extents"
15160         fi
15161 }
15162 run_test 130g "FIEMAP (overstripe file)"
15163
15164 # Test for writev/readv
15165 test_131a() {
15166         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15167                 error "writev test failed"
15168         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15169                 error "readv failed"
15170         rm -f $DIR/$tfile
15171 }
15172 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15173
15174 test_131b() {
15175         local fsize=$((524288 + 1048576 + 1572864))
15176         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15177                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15178                         error "append writev test failed"
15179
15180         ((fsize += 1572864 + 1048576))
15181         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15182                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15183                         error "append writev test failed"
15184         rm -f $DIR/$tfile
15185 }
15186 run_test 131b "test append writev"
15187
15188 test_131c() {
15189         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15190         error "NOT PASS"
15191 }
15192 run_test 131c "test read/write on file w/o objects"
15193
15194 test_131d() {
15195         rwv -f $DIR/$tfile -w -n 1 1572864
15196         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15197         if [ "$NOB" != 1572864 ]; then
15198                 error "Short read filed: read $NOB bytes instead of 1572864"
15199         fi
15200         rm -f $DIR/$tfile
15201 }
15202 run_test 131d "test short read"
15203
15204 test_131e() {
15205         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15206         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15207         error "read hitting hole failed"
15208         rm -f $DIR/$tfile
15209 }
15210 run_test 131e "test read hitting hole"
15211
15212 check_stats() {
15213         local facet=$1
15214         local op=$2
15215         local want=${3:-0}
15216         local res
15217
15218         # open             11 samples [usecs] 468 4793 13658 35791898
15219         case $facet in
15220         mds*) res=($(do_facet $facet \
15221                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15222                  ;;
15223         ost*) res=($(do_facet $facet \
15224                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15225                  ;;
15226         *) error "Wrong facet '$facet'" ;;
15227         esac
15228         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15229         # if $want is zero, it means any stat increment is ok.
15230         if (( $want > 0 )); then
15231                 local count=${res[1]}
15232
15233                 if (( $count != $want )); then
15234                         if [[ $facet =~ "mds" ]]; then
15235                                 do_nodes $(comma_list $(mdts_nodes)) \
15236                                         $LCTL get_param mdt.*.md_stats
15237                         else
15238                                 do_nodes $(comma_list $(osts-nodes)) \
15239                                         $LCTL get_param obdfilter.*.stats
15240                         fi
15241                         error "The $op counter on $facet is $count, not $want"
15242                 fi
15243         fi
15244 }
15245
15246 test_133a() {
15247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15248         remote_ost_nodsh && skip "remote OST with nodsh"
15249         remote_mds_nodsh && skip "remote MDS with nodsh"
15250         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15251                 skip_env "MDS doesn't support rename stats"
15252
15253         local testdir=$DIR/${tdir}/stats_testdir
15254
15255         mkdir -p $DIR/${tdir}
15256
15257         # clear stats.
15258         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15259         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15260
15261         # verify mdt stats first.
15262         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15263         check_stats $SINGLEMDS "mkdir" 1
15264
15265         # clear "open" from "lfs mkdir" above
15266         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15267         touch ${testdir}/${tfile} || error "touch failed"
15268         check_stats $SINGLEMDS "open" 1
15269         check_stats $SINGLEMDS "close" 1
15270         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15271                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15272                 check_stats $SINGLEMDS "mknod" 2
15273         }
15274         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15275         check_stats $SINGLEMDS "unlink" 1
15276         rm -f ${testdir}/${tfile} || error "file remove failed"
15277         check_stats $SINGLEMDS "unlink" 2
15278
15279         # remove working dir and check mdt stats again.
15280         rmdir ${testdir} || error "rmdir failed"
15281         check_stats $SINGLEMDS "rmdir" 1
15282
15283         local testdir1=$DIR/${tdir}/stats_testdir1
15284         mkdir_on_mdt0 -p ${testdir}
15285         mkdir_on_mdt0 -p ${testdir1}
15286         touch ${testdir1}/test1
15287         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15288         check_stats $SINGLEMDS "crossdir_rename" 1
15289
15290         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15291         check_stats $SINGLEMDS "samedir_rename" 1
15292
15293         rm -rf $DIR/${tdir}
15294 }
15295 run_test 133a "Verifying MDT stats ========================================"
15296
15297 test_133b() {
15298         local res
15299
15300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15301         remote_ost_nodsh && skip "remote OST with nodsh"
15302         remote_mds_nodsh && skip "remote MDS with nodsh"
15303
15304         local testdir=$DIR/${tdir}/stats_testdir
15305
15306         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15307         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15308         touch ${testdir}/${tfile} || error "touch failed"
15309         cancel_lru_locks mdc
15310
15311         # clear stats.
15312         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15313         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15314
15315         # extra mdt stats verification.
15316         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15317         check_stats $SINGLEMDS "setattr" 1
15318         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15319         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15320         then            # LU-1740
15321                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15322                 check_stats $SINGLEMDS "getattr" 1
15323         fi
15324         rm -rf $DIR/${tdir}
15325
15326         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15327         # so the check below is not reliable
15328         [ $MDSCOUNT -eq 1 ] || return 0
15329
15330         # Sleep to avoid a cached response.
15331         #define OBD_STATFS_CACHE_SECONDS 1
15332         sleep 2
15333         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15334         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15335         $LFS df || error "lfs failed"
15336         check_stats $SINGLEMDS "statfs" 1
15337
15338         # check aggregated statfs (LU-10018)
15339         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15340                 return 0
15341         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15342                 return 0
15343         sleep 2
15344         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15345         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15346         df $DIR
15347         check_stats $SINGLEMDS "statfs" 1
15348
15349         # We want to check that the client didn't send OST_STATFS to
15350         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15351         # extra care is needed here.
15352         if remote_mds; then
15353                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15354                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15355
15356                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15357                 [ "$res" ] && error "OST got STATFS"
15358         fi
15359
15360         return 0
15361 }
15362 run_test 133b "Verifying extra MDT stats =================================="
15363
15364 test_133c() {
15365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15366         remote_ost_nodsh && skip "remote OST with nodsh"
15367         remote_mds_nodsh && skip "remote MDS with nodsh"
15368
15369         local testdir=$DIR/$tdir/stats_testdir
15370
15371         test_mkdir -p $testdir
15372
15373         # verify obdfilter stats.
15374         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15375         sync
15376         cancel_lru_locks osc
15377         wait_delete_completed
15378
15379         # clear stats.
15380         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15381         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15382
15383         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15384                 error "dd failed"
15385         sync
15386         cancel_lru_locks osc
15387         check_stats ost1 "write" 1
15388
15389         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15390         check_stats ost1 "read" 1
15391
15392         > $testdir/$tfile || error "truncate failed"
15393         check_stats ost1 "punch" 1
15394
15395         rm -f $testdir/$tfile || error "file remove failed"
15396         wait_delete_completed
15397         check_stats ost1 "destroy" 1
15398
15399         rm -rf $DIR/$tdir
15400 }
15401 run_test 133c "Verifying OST stats ========================================"
15402
15403 order_2() {
15404         local value=$1
15405         local orig=$value
15406         local order=1
15407
15408         while [ $value -ge 2 ]; do
15409                 order=$((order*2))
15410                 value=$((value/2))
15411         done
15412
15413         if [ $orig -gt $order ]; then
15414                 order=$((order*2))
15415         fi
15416         echo $order
15417 }
15418
15419 size_in_KMGT() {
15420     local value=$1
15421     local size=('K' 'M' 'G' 'T');
15422     local i=0
15423     local size_string=$value
15424
15425     while [ $value -ge 1024 ]; do
15426         if [ $i -gt 3 ]; then
15427             #T is the biggest unit we get here, if that is bigger,
15428             #just return XXXT
15429             size_string=${value}T
15430             break
15431         fi
15432         value=$((value >> 10))
15433         if [ $value -lt 1024 ]; then
15434             size_string=${value}${size[$i]}
15435             break
15436         fi
15437         i=$((i + 1))
15438     done
15439
15440     echo $size_string
15441 }
15442
15443 get_rename_size() {
15444         local size=$1
15445         local context=${2:-.}
15446         local sample=$(do_facet $SINGLEMDS $LCTL \
15447                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15448                 grep -A1 $context |
15449                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15450         echo $sample
15451 }
15452
15453 test_133d() {
15454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15455         remote_ost_nodsh && skip "remote OST with nodsh"
15456         remote_mds_nodsh && skip "remote MDS with nodsh"
15457         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15458                 skip_env "MDS doesn't support rename stats"
15459
15460         local testdir1=$DIR/${tdir}/stats_testdir1
15461         local testdir2=$DIR/${tdir}/stats_testdir2
15462         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15463
15464         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15465
15466         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15467         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15468
15469         createmany -o $testdir1/test 512 || error "createmany failed"
15470
15471         # check samedir rename size
15472         mv ${testdir1}/test0 ${testdir1}/test_0
15473
15474         local testdir1_size=$(ls -l $DIR/${tdir} |
15475                 awk '/stats_testdir1/ {print $5}')
15476         local testdir2_size=$(ls -l $DIR/${tdir} |
15477                 awk '/stats_testdir2/ {print $5}')
15478
15479         testdir1_size=$(order_2 $testdir1_size)
15480         testdir2_size=$(order_2 $testdir2_size)
15481
15482         testdir1_size=$(size_in_KMGT $testdir1_size)
15483         testdir2_size=$(size_in_KMGT $testdir2_size)
15484
15485         echo "source rename dir size: ${testdir1_size}"
15486         echo "target rename dir size: ${testdir2_size}"
15487
15488         local cmd="do_facet $SINGLEMDS $LCTL "
15489         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15490
15491         eval $cmd || error "$cmd failed"
15492         local samedir=$($cmd | grep 'same_dir')
15493         local same_sample=$(get_rename_size $testdir1_size)
15494         [ -z "$samedir" ] && error "samedir_rename_size count error"
15495         [[ $same_sample -eq 1 ]] ||
15496                 error "samedir_rename_size error $same_sample"
15497         echo "Check same dir rename stats success"
15498
15499         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15500
15501         # check crossdir rename size
15502         mv ${testdir1}/test_0 ${testdir2}/test_0
15503
15504         testdir1_size=$(ls -l $DIR/${tdir} |
15505                 awk '/stats_testdir1/ {print $5}')
15506         testdir2_size=$(ls -l $DIR/${tdir} |
15507                 awk '/stats_testdir2/ {print $5}')
15508
15509         testdir1_size=$(order_2 $testdir1_size)
15510         testdir2_size=$(order_2 $testdir2_size)
15511
15512         testdir1_size=$(size_in_KMGT $testdir1_size)
15513         testdir2_size=$(size_in_KMGT $testdir2_size)
15514
15515         echo "source rename dir size: ${testdir1_size}"
15516         echo "target rename dir size: ${testdir2_size}"
15517
15518         eval $cmd || error "$cmd failed"
15519         local crossdir=$($cmd | grep 'crossdir')
15520         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15521         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15522         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15523         [[ $src_sample -eq 1 ]] ||
15524                 error "crossdir_rename_size error $src_sample"
15525         [[ $tgt_sample -eq 1 ]] ||
15526                 error "crossdir_rename_size error $tgt_sample"
15527         echo "Check cross dir rename stats success"
15528         rm -rf $DIR/${tdir}
15529 }
15530 run_test 133d "Verifying rename_stats ========================================"
15531
15532 test_133e() {
15533         remote_mds_nodsh && skip "remote MDS with nodsh"
15534         remote_ost_nodsh && skip "remote OST with nodsh"
15535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15536
15537         local testdir=$DIR/${tdir}/stats_testdir
15538         local ctr f0 f1 bs=32768 count=42 sum
15539
15540         mkdir -p ${testdir} || error "mkdir failed"
15541
15542         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15543
15544         for ctr in {write,read}_bytes; do
15545                 sync
15546                 cancel_lru_locks osc
15547
15548                 do_facet ost1 $LCTL set_param -n \
15549                         "obdfilter.*.exports.clear=clear"
15550
15551                 if [ $ctr = write_bytes ]; then
15552                         f0=/dev/zero
15553                         f1=${testdir}/${tfile}
15554                 else
15555                         f0=${testdir}/${tfile}
15556                         f1=/dev/null
15557                 fi
15558
15559                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15560                         error "dd failed"
15561                 sync
15562                 cancel_lru_locks osc
15563
15564                 sum=$(do_facet ost1 $LCTL get_param \
15565                         "obdfilter.*.exports.*.stats" |
15566                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15567                                 $1 == ctr { sum += $7 }
15568                                 END { printf("%0.0f", sum) }')
15569
15570                 if ((sum != bs * count)); then
15571                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15572                 fi
15573         done
15574
15575         rm -rf $DIR/${tdir}
15576 }
15577 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15578
15579 test_133f() {
15580         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15581                 skip "too old lustre for get_param -R ($facet_ver)"
15582
15583         # verifying readability.
15584         $LCTL get_param -R '*' &> /dev/null
15585
15586         # Verifing writability with badarea_io.
15587         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15588         local skipped_params='force_lbug|changelog_mask|daemon_file'
15589         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15590                 egrep -v "$skipped_params" |
15591                 xargs -n 1 find $proc_dirs -name |
15592                 xargs -n 1 badarea_io ||
15593                 error "client badarea_io failed"
15594
15595         # remount the FS in case writes/reads /proc break the FS
15596         cleanup || error "failed to unmount"
15597         setup || error "failed to setup"
15598 }
15599 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15600
15601 test_133g() {
15602         remote_mds_nodsh && skip "remote MDS with nodsh"
15603         remote_ost_nodsh && skip "remote OST with nodsh"
15604
15605         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15606         local proc_dirs_str=$(eval echo $proc_dirs)
15607         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15608         local facet
15609         for facet in mds1 ost1; do
15610                 local facet_ver=$(lustre_version_code $facet)
15611                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15612                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15613                 else
15614                         log "$facet: too old lustre for get_param -R"
15615                 fi
15616                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15617                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15618                                 tr -d = | egrep -v $skipped_params |
15619                                 xargs -n 1 find $proc_dirs_str -name |
15620                                 xargs -n 1 badarea_io" ||
15621                                         error "$facet badarea_io failed"
15622                 else
15623                         skip_noexit "$facet: too old lustre for get_param -R"
15624                 fi
15625         done
15626
15627         # remount the FS in case writes/reads /proc break the FS
15628         cleanup || error "failed to unmount"
15629         setup || error "failed to setup"
15630 }
15631 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15632
15633 test_133h() {
15634         remote_mds_nodsh && skip "remote MDS with nodsh"
15635         remote_ost_nodsh && skip "remote OST with nodsh"
15636         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15637                 skip "Need MDS version at least 2.9.54"
15638
15639         local facet
15640         for facet in client mds1 ost1; do
15641                 # Get the list of files that are missing the terminating newline
15642                 local plist=$(do_facet $facet
15643                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15644                 local ent
15645                 for ent in $plist; do
15646                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15647                                 awk -v FS='\v' -v RS='\v\v' \
15648                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15649                                         print FILENAME}'" 2>/dev/null)
15650                         [ -z $missing ] || {
15651                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15652                                 error "file does not end with newline: $facet-$ent"
15653                         }
15654                 done
15655         done
15656 }
15657 run_test 133h "Proc files should end with newlines"
15658
15659 test_134a() {
15660         remote_mds_nodsh && skip "remote MDS with nodsh"
15661         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15662                 skip "Need MDS version at least 2.7.54"
15663
15664         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15665         cancel_lru_locks mdc
15666
15667         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15668         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15669         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15670
15671         local nr=1000
15672         createmany -o $DIR/$tdir/f $nr ||
15673                 error "failed to create $nr files in $DIR/$tdir"
15674         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15675
15676         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15677         do_facet mds1 $LCTL set_param fail_loc=0x327
15678         do_facet mds1 $LCTL set_param fail_val=500
15679         touch $DIR/$tdir/m
15680
15681         echo "sleep 10 seconds ..."
15682         sleep 10
15683         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15684
15685         do_facet mds1 $LCTL set_param fail_loc=0
15686         do_facet mds1 $LCTL set_param fail_val=0
15687         [ $lck_cnt -lt $unused ] ||
15688                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15689
15690         rm $DIR/$tdir/m
15691         unlinkmany $DIR/$tdir/f $nr
15692 }
15693 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15694
15695 test_134b() {
15696         remote_mds_nodsh && skip "remote MDS with nodsh"
15697         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15698                 skip "Need MDS version at least 2.7.54"
15699
15700         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15701         cancel_lru_locks mdc
15702
15703         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15704                         ldlm.lock_reclaim_threshold_mb)
15705         # disable reclaim temporarily
15706         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15707
15708         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15709         do_facet mds1 $LCTL set_param fail_loc=0x328
15710         do_facet mds1 $LCTL set_param fail_val=500
15711
15712         $LCTL set_param debug=+trace
15713
15714         local nr=600
15715         createmany -o $DIR/$tdir/f $nr &
15716         local create_pid=$!
15717
15718         echo "Sleep $TIMEOUT seconds ..."
15719         sleep $TIMEOUT
15720         if ! ps -p $create_pid  > /dev/null 2>&1; then
15721                 do_facet mds1 $LCTL set_param fail_loc=0
15722                 do_facet mds1 $LCTL set_param fail_val=0
15723                 do_facet mds1 $LCTL set_param \
15724                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15725                 error "createmany finished incorrectly!"
15726         fi
15727         do_facet mds1 $LCTL set_param fail_loc=0
15728         do_facet mds1 $LCTL set_param fail_val=0
15729         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15730         wait $create_pid || return 1
15731
15732         unlinkmany $DIR/$tdir/f $nr
15733 }
15734 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15735
15736 test_135() {
15737         remote_mds_nodsh && skip "remote MDS with nodsh"
15738         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15739                 skip "Need MDS version at least 2.13.50"
15740         local fname
15741
15742         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15743
15744 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15745         #set only one record at plain llog
15746         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15747
15748         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15749
15750         #fill already existed plain llog each 64767
15751         #wrapping whole catalog
15752         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15753
15754         createmany -o $DIR/$tdir/$tfile_ 64700
15755         for (( i = 0; i < 64700; i = i + 2 ))
15756         do
15757                 rm $DIR/$tdir/$tfile_$i &
15758                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15759                 local pid=$!
15760                 wait $pid
15761         done
15762
15763         #waiting osp synchronization
15764         wait_delete_completed
15765 }
15766 run_test 135 "Race catalog processing"
15767
15768 test_136() {
15769         remote_mds_nodsh && skip "remote MDS with nodsh"
15770         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15771                 skip "Need MDS version at least 2.13.50"
15772         local fname
15773
15774         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15775         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15776         #set only one record at plain llog
15777 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15778         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15779
15780         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15781
15782         #fill already existed 2 plain llogs each 64767
15783         #wrapping whole catalog
15784         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15785         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15786         wait_delete_completed
15787
15788         createmany -o $DIR/$tdir/$tfile_ 10
15789         sleep 25
15790
15791         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15792         for (( i = 0; i < 10; i = i + 3 ))
15793         do
15794                 rm $DIR/$tdir/$tfile_$i &
15795                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15796                 local pid=$!
15797                 wait $pid
15798                 sleep 7
15799                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15800         done
15801
15802         #waiting osp synchronization
15803         wait_delete_completed
15804 }
15805 run_test 136 "Race catalog processing 2"
15806
15807 test_140() { #bug-17379
15808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15809
15810         test_mkdir $DIR/$tdir
15811         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15812         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15813
15814         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15815         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15816         local i=0
15817         while i=$((i + 1)); do
15818                 test_mkdir $i
15819                 cd $i || error "Changing to $i"
15820                 ln -s ../stat stat || error "Creating stat symlink"
15821                 # Read the symlink until ELOOP present,
15822                 # not LBUGing the system is considered success,
15823                 # we didn't overrun the stack.
15824                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15825                 if [ $ret -ne 0 ]; then
15826                         if [ $ret -eq 40 ]; then
15827                                 break  # -ELOOP
15828                         else
15829                                 error "Open stat symlink"
15830                                         return
15831                         fi
15832                 fi
15833         done
15834         i=$((i - 1))
15835         echo "The symlink depth = $i"
15836         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15837                 error "Invalid symlink depth"
15838
15839         # Test recursive symlink
15840         ln -s symlink_self symlink_self
15841         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15842         echo "open symlink_self returns $ret"
15843         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15844 }
15845 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15846
15847 test_150a() {
15848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15849
15850         local TF="$TMP/$tfile"
15851
15852         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15853         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15854         cp $TF $DIR/$tfile
15855         cancel_lru_locks $OSC
15856         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15857         remount_client $MOUNT
15858         df -P $MOUNT
15859         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15860
15861         $TRUNCATE $TF 6000
15862         $TRUNCATE $DIR/$tfile 6000
15863         cancel_lru_locks $OSC
15864         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15865
15866         echo "12345" >>$TF
15867         echo "12345" >>$DIR/$tfile
15868         cancel_lru_locks $OSC
15869         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15870
15871         echo "12345" >>$TF
15872         echo "12345" >>$DIR/$tfile
15873         cancel_lru_locks $OSC
15874         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15875 }
15876 run_test 150a "truncate/append tests"
15877
15878 test_150b() {
15879         check_set_fallocate_or_skip
15880         local out
15881
15882         touch $DIR/$tfile
15883         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15884         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15885                 skip_eopnotsupp "$out|check_fallocate failed"
15886 }
15887 run_test 150b "Verify fallocate (prealloc) functionality"
15888
15889 test_150bb() {
15890         check_set_fallocate_or_skip
15891
15892         touch $DIR/$tfile
15893         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15894         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15895         > $DIR/$tfile
15896         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15897         # precomputed md5sum for 20MB of zeroes
15898         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15899         local sum=($(md5sum $DIR/$tfile))
15900
15901         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15902
15903         check_set_fallocate 1
15904
15905         > $DIR/$tfile
15906         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15907         sum=($(md5sum $DIR/$tfile))
15908
15909         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15910 }
15911 run_test 150bb "Verify fallocate modes both zero space"
15912
15913 test_150c() {
15914         check_set_fallocate_or_skip
15915         local striping="-c2"
15916
15917         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15918         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15919         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15920         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15921         local want=$((OSTCOUNT * 1048576))
15922
15923         # Must allocate all requested space, not more than 5% extra
15924         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15925                 error "bytes $bytes is not $want"
15926
15927         rm -f $DIR/$tfile
15928
15929         echo "verify fallocate on PFL file"
15930
15931         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15932
15933         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15934                 error "Create $DIR/$tfile failed"
15935         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15936         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15937         want=$((512 * 1048576))
15938
15939         # Must allocate all requested space, not more than 5% extra
15940         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15941                 error "bytes $bytes is not $want"
15942 }
15943 run_test 150c "Verify fallocate Size and Blocks"
15944
15945 test_150d() {
15946         check_set_fallocate_or_skip
15947         local striping="-c2"
15948
15949         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15950
15951         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15952         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15953                 error "setstripe failed"
15954         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15955         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15956         local want=$((OSTCOUNT * 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 150d "Verify fallocate Size and Blocks - Non zero start"
15963
15964 test_150e() {
15965         check_set_fallocate_or_skip
15966
15967         echo "df before:"
15968         $LFS df
15969         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15970         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15971                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15972
15973         # Find OST with Minimum Size
15974         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15975                        sort -un | head -1)
15976
15977         # Get 100MB per OST of the available space to reduce run time
15978         # else 60% of the available space if we are running SLOW tests
15979         if [ $SLOW == "no" ]; then
15980                 local space=$((1024 * 100 * OSTCOUNT))
15981         else
15982                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15983         fi
15984
15985         fallocate -l${space}k $DIR/$tfile ||
15986                 error "fallocate ${space}k $DIR/$tfile failed"
15987         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15988
15989         # get size immediately after fallocate. This should be correctly
15990         # updated
15991         local size=$(stat -c '%s' $DIR/$tfile)
15992         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15993
15994         # Sleep for a while for statfs to get updated. And not pull from cache.
15995         sleep 2
15996
15997         echo "df after fallocate:"
15998         $LFS df
15999
16000         (( size / 1024 == space )) || error "size $size != requested $space"
16001         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16002                 error "used $used < space $space"
16003
16004         rm $DIR/$tfile || error "rm failed"
16005         sync
16006         wait_delete_completed
16007
16008         echo "df after unlink:"
16009         $LFS df
16010 }
16011 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16012
16013 test_150f() {
16014         local size
16015         local blocks
16016         local want_size_before=20480 # in bytes
16017         local want_blocks_before=40 # 512 sized blocks
16018         local want_blocks_after=24  # 512 sized blocks
16019         local length=$(((want_blocks_before - want_blocks_after) * 512))
16020
16021         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16022                 skip "need at least 2.14.0 for fallocate punch"
16023
16024         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16025                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16026         fi
16027
16028         check_set_fallocate_or_skip
16029         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16030
16031         [[ "x$DOM" == "xyes" ]] &&
16032                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16033
16034         echo "Verify fallocate punch: Range within the file range"
16035         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16036                 error "dd failed for bs 4096 and count 5"
16037
16038         # Call fallocate with punch range which is within the file range
16039         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16040                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16041         # client must see changes immediately after fallocate
16042         size=$(stat -c '%s' $DIR/$tfile)
16043         blocks=$(stat -c '%b' $DIR/$tfile)
16044
16045         # Verify punch worked.
16046         (( blocks == want_blocks_after )) ||
16047                 error "punch failed: blocks $blocks != $want_blocks_after"
16048
16049         (( size == want_size_before )) ||
16050                 error "punch failed: size $size != $want_size_before"
16051
16052         # Verify there is hole in file
16053         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16054         # precomputed md5sum
16055         local expect="4a9a834a2db02452929c0a348273b4aa"
16056
16057         cksum=($(md5sum $DIR/$tfile))
16058         [[ "${cksum[0]}" == "$expect" ]] ||
16059                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16060
16061         # Start second sub-case for fallocate punch.
16062         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16063         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16064                 error "dd failed for bs 4096 and count 5"
16065
16066         # Punch range less than block size will have no change in block count
16067         want_blocks_after=40  # 512 sized blocks
16068
16069         # Punch overlaps two blocks and less than blocksize
16070         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16071                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16072         size=$(stat -c '%s' $DIR/$tfile)
16073         blocks=$(stat -c '%b' $DIR/$tfile)
16074
16075         # Verify punch worked.
16076         (( blocks == want_blocks_after )) ||
16077                 error "punch failed: blocks $blocks != $want_blocks_after"
16078
16079         (( size == want_size_before )) ||
16080                 error "punch failed: size $size != $want_size_before"
16081
16082         # Verify if range is really zero'ed out. We expect Zeros.
16083         # precomputed md5sum
16084         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16085         cksum=($(md5sum $DIR/$tfile))
16086         [[ "${cksum[0]}" == "$expect" ]] ||
16087                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16088 }
16089 run_test 150f "Verify fallocate punch functionality"
16090
16091 test_150g() {
16092         local space
16093         local size
16094         local blocks
16095         local blocks_after
16096         local size_after
16097         local BS=4096 # Block size in bytes
16098
16099         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16100                 skip "need at least 2.14.0 for fallocate punch"
16101
16102         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16103                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16104         fi
16105
16106         check_set_fallocate_or_skip
16107         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16108
16109         if [[ "x$DOM" == "xyes" ]]; then
16110                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16111                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16112         else
16113                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16114                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16115         fi
16116
16117         # Get 100MB per OST of the available space to reduce run time
16118         # else 60% of the available space if we are running SLOW tests
16119         if [ $SLOW == "no" ]; then
16120                 space=$((1024 * 100 * OSTCOUNT))
16121         else
16122                 # Find OST with Minimum Size
16123                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16124                         sort -un | head -1)
16125                 echo "min size OST: $space"
16126                 space=$(((space * 60)/100 * OSTCOUNT))
16127         fi
16128         # space in 1k units, round to 4k blocks
16129         local blkcount=$((space * 1024 / $BS))
16130
16131         echo "Verify fallocate punch: Very large Range"
16132         fallocate -l${space}k $DIR/$tfile ||
16133                 error "fallocate ${space}k $DIR/$tfile failed"
16134         # write 1M at the end, start and in the middle
16135         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16136                 error "dd failed: bs $BS count 256"
16137         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16138                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16139         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16140                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16141
16142         # Gather stats.
16143         size=$(stat -c '%s' $DIR/$tfile)
16144
16145         # gather punch length.
16146         local punch_size=$((size - (BS * 2)))
16147
16148         echo "punch_size = $punch_size"
16149         echo "size - punch_size: $((size - punch_size))"
16150         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16151
16152         # Call fallocate to punch all except 2 blocks. We leave the
16153         # first and the last block
16154         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16155         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16156                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16157
16158         size_after=$(stat -c '%s' $DIR/$tfile)
16159         blocks_after=$(stat -c '%b' $DIR/$tfile)
16160
16161         # Verify punch worked.
16162         # Size should be kept
16163         (( size == size_after )) ||
16164                 error "punch failed: size $size != $size_after"
16165
16166         # two 4k data blocks to remain plus possible 1 extra extent block
16167         (( blocks_after <= ((BS / 512) * 3) )) ||
16168                 error "too many blocks remains: $blocks_after"
16169
16170         # Verify that file has hole between the first and the last blocks
16171         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16172         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16173
16174         echo "Hole at [$hole_start, $hole_end)"
16175         (( hole_start == BS )) ||
16176                 error "no hole at offset $BS after punch"
16177
16178         (( hole_end == BS + punch_size )) ||
16179                 error "data at offset $hole_end < $((BS + punch_size))"
16180 }
16181 run_test 150g "Verify fallocate punch on large range"
16182
16183 test_150h() {
16184         local file=$DIR/$tfile
16185         local size
16186
16187         check_set_fallocate_or_skip
16188         statx_supported || skip_env "Test must be statx() syscall supported"
16189
16190         # fallocate() does not update the size information on the MDT
16191         fallocate -l 16K $file || error "failed to fallocate $file"
16192         cancel_lru_locks $OSC
16193         # STATX with cached-always mode will not send glimpse RPCs to OST,
16194         # it uses the caching attrs on the client side as much as possible.
16195         size=$($STATX --cached=always -c %s $file)
16196         [ $size == 16384 ] ||
16197                 error "size after fallocate() is $size, expected 16384"
16198 }
16199 run_test 150h "Verify extend fallocate updates the file size"
16200
16201 #LU-2902 roc_hit was not able to read all values from lproc
16202 function roc_hit_init() {
16203         local list=$(comma_list $(osts_nodes))
16204         local dir=$DIR/$tdir-check
16205         local file=$dir/$tfile
16206         local BEFORE
16207         local AFTER
16208         local idx
16209
16210         test_mkdir $dir
16211         #use setstripe to do a write to every ost
16212         for i in $(seq 0 $((OSTCOUNT-1))); do
16213                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16214                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16215                 idx=$(printf %04x $i)
16216                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16217                         awk '$1 == "cache_access" {sum += $7}
16218                                 END { printf("%0.0f", sum) }')
16219
16220                 cancel_lru_locks osc
16221                 cat $file >/dev/null
16222
16223                 AFTER=$(get_osd_param $list *OST*$idx stats |
16224                         awk '$1 == "cache_access" {sum += $7}
16225                                 END { printf("%0.0f", sum) }')
16226
16227                 echo BEFORE:$BEFORE AFTER:$AFTER
16228                 if ! let "AFTER - BEFORE == 4"; then
16229                         rm -rf $dir
16230                         error "roc_hit is not safe to use"
16231                 fi
16232                 rm $file
16233         done
16234
16235         rm -rf $dir
16236 }
16237
16238 function roc_hit() {
16239         local list=$(comma_list $(osts_nodes))
16240         echo $(get_osd_param $list '' stats |
16241                 awk '$1 == "cache_hit" {sum += $7}
16242                         END { printf("%0.0f", sum) }')
16243 }
16244
16245 function set_cache() {
16246         local on=1
16247
16248         if [ "$2" == "off" ]; then
16249                 on=0;
16250         fi
16251         local list=$(comma_list $(osts_nodes))
16252         set_osd_param $list '' $1_cache_enable $on
16253
16254         cancel_lru_locks osc
16255 }
16256
16257 test_151() {
16258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16259         remote_ost_nodsh && skip "remote OST with nodsh"
16260         (( CLIENT_VERSION == OST1_VERSION )) ||
16261                 skip "LU-13081: no interop testing for OSS cache"
16262
16263         local CPAGES=3
16264         local list=$(comma_list $(osts_nodes))
16265
16266         # check whether obdfilter is cache capable at all
16267         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16268                 skip "not cache-capable obdfilter"
16269         fi
16270
16271         # check cache is enabled on all obdfilters
16272         if get_osd_param $list '' read_cache_enable | grep 0; then
16273                 skip "oss cache is disabled"
16274         fi
16275
16276         set_osd_param $list '' writethrough_cache_enable 1
16277
16278         # check write cache is enabled on all obdfilters
16279         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16280                 skip "oss write cache is NOT enabled"
16281         fi
16282
16283         roc_hit_init
16284
16285         #define OBD_FAIL_OBD_NO_LRU  0x609
16286         do_nodes $list $LCTL set_param fail_loc=0x609
16287
16288         # pages should be in the case right after write
16289         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16290                 error "dd failed"
16291
16292         local BEFORE=$(roc_hit)
16293         cancel_lru_locks osc
16294         cat $DIR/$tfile >/dev/null
16295         local AFTER=$(roc_hit)
16296
16297         do_nodes $list $LCTL set_param fail_loc=0
16298
16299         if ! let "AFTER - BEFORE == CPAGES"; then
16300                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16301         fi
16302
16303         cancel_lru_locks osc
16304         # invalidates OST cache
16305         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16306         set_osd_param $list '' read_cache_enable 0
16307         cat $DIR/$tfile >/dev/null
16308
16309         # now data shouldn't be found in the cache
16310         BEFORE=$(roc_hit)
16311         cancel_lru_locks osc
16312         cat $DIR/$tfile >/dev/null
16313         AFTER=$(roc_hit)
16314         if let "AFTER - BEFORE != 0"; then
16315                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16316         fi
16317
16318         set_osd_param $list '' read_cache_enable 1
16319         rm -f $DIR/$tfile
16320 }
16321 run_test 151 "test cache on oss and controls ==============================="
16322
16323 test_152() {
16324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16325
16326         local TF="$TMP/$tfile"
16327
16328         # simulate ENOMEM during write
16329 #define OBD_FAIL_OST_NOMEM      0x226
16330         lctl set_param fail_loc=0x80000226
16331         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16332         cp $TF $DIR/$tfile
16333         sync || error "sync failed"
16334         lctl set_param fail_loc=0
16335
16336         # discard client's cache
16337         cancel_lru_locks osc
16338
16339         # simulate ENOMEM during read
16340         lctl set_param fail_loc=0x80000226
16341         cmp $TF $DIR/$tfile || error "cmp failed"
16342         lctl set_param fail_loc=0
16343
16344         rm -f $TF
16345 }
16346 run_test 152 "test read/write with enomem ============================"
16347
16348 test_153() {
16349         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16350 }
16351 run_test 153 "test if fdatasync does not crash ======================="
16352
16353 dot_lustre_fid_permission_check() {
16354         local fid=$1
16355         local ffid=$MOUNT/.lustre/fid/$fid
16356         local test_dir=$2
16357
16358         echo "stat fid $fid"
16359         stat $ffid || error "stat $ffid failed."
16360         echo "touch fid $fid"
16361         touch $ffid || error "touch $ffid failed."
16362         echo "write to fid $fid"
16363         cat /etc/hosts > $ffid || error "write $ffid failed."
16364         echo "read fid $fid"
16365         diff /etc/hosts $ffid || error "read $ffid failed."
16366         echo "append write to fid $fid"
16367         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16368         echo "rename fid $fid"
16369         mv $ffid $test_dir/$tfile.1 &&
16370                 error "rename $ffid to $tfile.1 should fail."
16371         touch $test_dir/$tfile.1
16372         mv $test_dir/$tfile.1 $ffid &&
16373                 error "rename $tfile.1 to $ffid should fail."
16374         rm -f $test_dir/$tfile.1
16375         echo "truncate fid $fid"
16376         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16377         echo "link fid $fid"
16378         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16379         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16380                 id $USER0 || skip_env "missing user $USER0"
16381                 echo "setfacl fid $fid"
16382                 setfacl -R -m u:$USER0:rwx $ffid ||
16383                         error "setfacl $ffid failed"
16384                 echo "getfacl fid $fid"
16385                 getfacl $ffid || error "getfacl $ffid failed."
16386         fi
16387         echo "unlink fid $fid"
16388         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16389         echo "mknod fid $fid"
16390         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16391
16392         fid=[0xf00000400:0x1:0x0]
16393         ffid=$MOUNT/.lustre/fid/$fid
16394
16395         echo "stat non-exist fid $fid"
16396         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16397         echo "write to non-exist fid $fid"
16398         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16399         echo "link new fid $fid"
16400         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16401
16402         mkdir -p $test_dir/$tdir
16403         touch $test_dir/$tdir/$tfile
16404         fid=$($LFS path2fid $test_dir/$tdir)
16405         rc=$?
16406         [ $rc -ne 0 ] &&
16407                 error "error: could not get fid for $test_dir/$dir/$tfile."
16408
16409         ffid=$MOUNT/.lustre/fid/$fid
16410
16411         echo "ls $fid"
16412         ls $ffid || error "ls $ffid failed."
16413         echo "touch $fid/$tfile.1"
16414         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16415
16416         echo "touch $MOUNT/.lustre/fid/$tfile"
16417         touch $MOUNT/.lustre/fid/$tfile && \
16418                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16419
16420         echo "setxattr to $MOUNT/.lustre/fid"
16421         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16422
16423         echo "listxattr for $MOUNT/.lustre/fid"
16424         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16425
16426         echo "delxattr from $MOUNT/.lustre/fid"
16427         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16428
16429         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16430         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16431                 error "touch invalid fid should fail."
16432
16433         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16434         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16435                 error "touch non-normal fid should fail."
16436
16437         echo "rename $tdir to $MOUNT/.lustre/fid"
16438         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16439                 error "rename to $MOUNT/.lustre/fid should fail."
16440
16441         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16442         then            # LU-3547
16443                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16444                 local new_obf_mode=777
16445
16446                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16447                 chmod $new_obf_mode $DIR/.lustre/fid ||
16448                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16449
16450                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16451                 [ $obf_mode -eq $new_obf_mode ] ||
16452                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16453
16454                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16455                 chmod $old_obf_mode $DIR/.lustre/fid ||
16456                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16457         fi
16458
16459         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16460         fid=$($LFS path2fid $test_dir/$tfile-2)
16461
16462         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16463         then # LU-5424
16464                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16465                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16466                         error "create lov data thru .lustre failed"
16467         fi
16468         echo "cp /etc/passwd $test_dir/$tfile-2"
16469         cp /etc/passwd $test_dir/$tfile-2 ||
16470                 error "copy to $test_dir/$tfile-2 failed."
16471         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16472         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16473                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16474
16475         rm -rf $test_dir/tfile.lnk
16476         rm -rf $test_dir/$tfile-2
16477 }
16478
16479 test_154A() {
16480         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16481                 skip "Need MDS version at least 2.4.1"
16482
16483         local tf=$DIR/$tfile
16484         touch $tf
16485
16486         local fid=$($LFS path2fid $tf)
16487         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16488
16489         # check that we get the same pathname back
16490         local rootpath
16491         local found
16492         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16493                 echo "$rootpath $fid"
16494                 found=$($LFS fid2path $rootpath "$fid")
16495                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16496                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16497         done
16498
16499         # check wrong root path format
16500         rootpath=$MOUNT"_wrong"
16501         found=$($LFS fid2path $rootpath "$fid")
16502         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16503 }
16504 run_test 154A "lfs path2fid and fid2path basic checks"
16505
16506 test_154B() {
16507         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16508                 skip "Need MDS version at least 2.4.1"
16509
16510         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16511         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16512         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16513         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16514
16515         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16516         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16517
16518         # check that we get the same pathname
16519         echo "PFID: $PFID, name: $name"
16520         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16521         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16522         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16523                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16524
16525         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16526 }
16527 run_test 154B "verify the ll_decode_linkea tool"
16528
16529 test_154a() {
16530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16531         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16532         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16533                 skip "Need MDS version at least 2.2.51"
16534         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16535
16536         cp /etc/hosts $DIR/$tfile
16537
16538         fid=$($LFS path2fid $DIR/$tfile)
16539         rc=$?
16540         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16541
16542         dot_lustre_fid_permission_check "$fid" $DIR ||
16543                 error "dot lustre permission check $fid failed"
16544
16545         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16546
16547         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16548
16549         touch $MOUNT/.lustre/file &&
16550                 error "creation is not allowed under .lustre"
16551
16552         mkdir $MOUNT/.lustre/dir &&
16553                 error "mkdir is not allowed under .lustre"
16554
16555         rm -rf $DIR/$tfile
16556 }
16557 run_test 154a "Open-by-FID"
16558
16559 test_154b() {
16560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16561         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16563         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16564                 skip "Need MDS version at least 2.2.51"
16565
16566         local remote_dir=$DIR/$tdir/remote_dir
16567         local MDTIDX=1
16568         local rc=0
16569
16570         mkdir -p $DIR/$tdir
16571         $LFS mkdir -i $MDTIDX $remote_dir ||
16572                 error "create remote directory failed"
16573
16574         cp /etc/hosts $remote_dir/$tfile
16575
16576         fid=$($LFS path2fid $remote_dir/$tfile)
16577         rc=$?
16578         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16579
16580         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16581                 error "dot lustre permission check $fid failed"
16582         rm -rf $DIR/$tdir
16583 }
16584 run_test 154b "Open-by-FID for remote directory"
16585
16586 test_154c() {
16587         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16588                 skip "Need MDS version at least 2.4.1"
16589
16590         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16591         local FID1=$($LFS path2fid $DIR/$tfile.1)
16592         local FID2=$($LFS path2fid $DIR/$tfile.2)
16593         local FID3=$($LFS path2fid $DIR/$tfile.3)
16594
16595         local N=1
16596         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16597                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16598                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16599                 local want=FID$N
16600                 [ "$FID" = "${!want}" ] ||
16601                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16602                 N=$((N + 1))
16603         done
16604
16605         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16606         do
16607                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16608                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16609                 N=$((N + 1))
16610         done
16611 }
16612 run_test 154c "lfs path2fid and fid2path multiple arguments"
16613
16614 test_154d() {
16615         remote_mds_nodsh && skip "remote MDS with nodsh"
16616         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16617                 skip "Need MDS version at least 2.5.53"
16618
16619         if remote_mds; then
16620                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16621         else
16622                 nid="0@lo"
16623         fi
16624         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16625         local fd
16626         local cmd
16627
16628         rm -f $DIR/$tfile
16629         touch $DIR/$tfile
16630
16631         local fid=$($LFS path2fid $DIR/$tfile)
16632         # Open the file
16633         fd=$(free_fd)
16634         cmd="exec $fd<$DIR/$tfile"
16635         eval $cmd
16636         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16637         echo "$fid_list" | grep "$fid"
16638         rc=$?
16639
16640         cmd="exec $fd>/dev/null"
16641         eval $cmd
16642         if [ $rc -ne 0 ]; then
16643                 error "FID $fid not found in open files list $fid_list"
16644         fi
16645 }
16646 run_test 154d "Verify open file fid"
16647
16648 test_154e()
16649 {
16650         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16651                 skip "Need MDS version at least 2.6.50"
16652
16653         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16654                 error ".lustre returned by readdir"
16655         fi
16656 }
16657 run_test 154e ".lustre is not returned by readdir"
16658
16659 test_154f() {
16660         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16661
16662         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16663         mkdir_on_mdt0 $DIR/$tdir
16664         # test dirs inherit from its stripe
16665         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16666         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16667         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16668         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16669         touch $DIR/f
16670
16671         # get fid of parents
16672         local FID0=$($LFS path2fid $DIR/$tdir)
16673         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16674         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16675         local FID3=$($LFS path2fid $DIR)
16676
16677         # check that path2fid --parents returns expected <parent_fid>/name
16678         # 1) test for a directory (single parent)
16679         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16680         [ "$parent" == "$FID0/foo1" ] ||
16681                 error "expected parent: $FID0/foo1, got: $parent"
16682
16683         # 2) test for a file with nlink > 1 (multiple parents)
16684         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16685         echo "$parent" | grep -F "$FID1/$tfile" ||
16686                 error "$FID1/$tfile not returned in parent list"
16687         echo "$parent" | grep -F "$FID2/link" ||
16688                 error "$FID2/link not returned in parent list"
16689
16690         # 3) get parent by fid
16691         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16692         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16693         echo "$parent" | grep -F "$FID1/$tfile" ||
16694                 error "$FID1/$tfile not returned in parent list (by fid)"
16695         echo "$parent" | grep -F "$FID2/link" ||
16696                 error "$FID2/link not returned in parent list (by fid)"
16697
16698         # 4) test for entry in root directory
16699         parent=$($LFS path2fid --parents $DIR/f)
16700         echo "$parent" | grep -F "$FID3/f" ||
16701                 error "$FID3/f not returned in parent list"
16702
16703         # 5) test it on root directory
16704         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16705                 error "$MOUNT should not have parents"
16706
16707         # enable xattr caching and check that linkea is correctly updated
16708         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16709         save_lustre_params client "llite.*.xattr_cache" > $save
16710         lctl set_param llite.*.xattr_cache 1
16711
16712         # 6.1) linkea update on rename
16713         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16714
16715         # get parents by fid
16716         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16717         # foo1 should no longer be returned in parent list
16718         echo "$parent" | grep -F "$FID1" &&
16719                 error "$FID1 should no longer be in parent list"
16720         # the new path should appear
16721         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16722                 error "$FID2/$tfile.moved is not in parent list"
16723
16724         # 6.2) linkea update on unlink
16725         rm -f $DIR/$tdir/foo2/link
16726         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16727         # foo2/link should no longer be returned in parent list
16728         echo "$parent" | grep -F "$FID2/link" &&
16729                 error "$FID2/link should no longer be in parent list"
16730         true
16731
16732         rm -f $DIR/f
16733         restore_lustre_params < $save
16734         rm -f $save
16735 }
16736 run_test 154f "get parent fids by reading link ea"
16737
16738 test_154g()
16739 {
16740         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16741            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16742                 skip "Need MDS version at least 2.6.92"
16743
16744         mkdir_on_mdt0 $DIR/$tdir
16745         llapi_fid_test -d $DIR/$tdir
16746 }
16747 run_test 154g "various llapi FID tests"
16748
16749 test_154h()
16750 {
16751         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16752                 skip "Need client at least version 2.15.55.1"
16753
16754         # Create an empty file
16755         touch $DIR/$tfile
16756
16757         # Get FID (interactive mode) and save under $TMP/$tfile.log
16758         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16759                 path2fid $DIR/$tfile
16760         EOF
16761
16762         fid=$(cat $TMP/$tfile.log)
16763         # $fid should not be empty
16764         [[ ! -z $fid ]] || error "FID is empty"
16765         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16766 }
16767 run_test 154h "Verify interactive path2fid"
16768
16769 test_155_small_load() {
16770     local temp=$TMP/$tfile
16771     local file=$DIR/$tfile
16772
16773     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16774         error "dd of=$temp bs=6096 count=1 failed"
16775     cp $temp $file
16776     cancel_lru_locks $OSC
16777     cmp $temp $file || error "$temp $file differ"
16778
16779     $TRUNCATE $temp 6000
16780     $TRUNCATE $file 6000
16781     cmp $temp $file || error "$temp $file differ (truncate1)"
16782
16783     echo "12345" >>$temp
16784     echo "12345" >>$file
16785     cmp $temp $file || error "$temp $file differ (append1)"
16786
16787     echo "12345" >>$temp
16788     echo "12345" >>$file
16789     cmp $temp $file || error "$temp $file differ (append2)"
16790
16791     rm -f $temp $file
16792     true
16793 }
16794
16795 test_155_big_load() {
16796         remote_ost_nodsh && skip "remote OST with nodsh"
16797
16798         local temp=$TMP/$tfile
16799         local file=$DIR/$tfile
16800
16801         free_min_max
16802         local cache_size=$(do_facet ost$((MAXI+1)) \
16803                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16804
16805         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16806         # pre-set value
16807         if [ -z "$cache_size" ]; then
16808                 cache_size=256
16809         fi
16810         local large_file_size=$((cache_size * 2))
16811
16812         echo "OSS cache size: $cache_size KB"
16813         echo "Large file size: $large_file_size KB"
16814
16815         [ $MAXV -le $large_file_size ] &&
16816                 skip_env "max available OST size needs > $large_file_size KB"
16817
16818         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16819
16820         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16821                 error "dd of=$temp bs=$large_file_size count=1k failed"
16822         cp $temp $file
16823         ls -lh $temp $file
16824         cancel_lru_locks osc
16825         cmp $temp $file || error "$temp $file differ"
16826
16827         rm -f $temp $file
16828         true
16829 }
16830
16831 save_writethrough() {
16832         local facets=$(get_facets OST)
16833
16834         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16835 }
16836
16837 test_155a() {
16838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16839
16840         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16841
16842         save_writethrough $p
16843
16844         set_cache read on
16845         set_cache writethrough on
16846         test_155_small_load
16847         restore_lustre_params < $p
16848         rm -f $p
16849 }
16850 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16851
16852 test_155b() {
16853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16854
16855         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16856
16857         save_writethrough $p
16858
16859         set_cache read on
16860         set_cache writethrough off
16861         test_155_small_load
16862         restore_lustre_params < $p
16863         rm -f $p
16864 }
16865 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16866
16867 test_155c() {
16868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16869
16870         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16871
16872         save_writethrough $p
16873
16874         set_cache read off
16875         set_cache writethrough on
16876         test_155_small_load
16877         restore_lustre_params < $p
16878         rm -f $p
16879 }
16880 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16881
16882 test_155d() {
16883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16884
16885         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16886
16887         save_writethrough $p
16888
16889         set_cache read off
16890         set_cache writethrough off
16891         test_155_small_load
16892         restore_lustre_params < $p
16893         rm -f $p
16894 }
16895 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16896
16897 test_155e() {
16898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16899
16900         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16901
16902         save_writethrough $p
16903
16904         set_cache read on
16905         set_cache writethrough on
16906         test_155_big_load
16907         restore_lustre_params < $p
16908         rm -f $p
16909 }
16910 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16911
16912 test_155f() {
16913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16914
16915         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16916
16917         save_writethrough $p
16918
16919         set_cache read on
16920         set_cache writethrough off
16921         test_155_big_load
16922         restore_lustre_params < $p
16923         rm -f $p
16924 }
16925 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16926
16927 test_155g() {
16928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16929
16930         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16931
16932         save_writethrough $p
16933
16934         set_cache read off
16935         set_cache writethrough on
16936         test_155_big_load
16937         restore_lustre_params < $p
16938         rm -f $p
16939 }
16940 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16941
16942 test_155h() {
16943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16944
16945         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16946
16947         save_writethrough $p
16948
16949         set_cache read off
16950         set_cache writethrough off
16951         test_155_big_load
16952         restore_lustre_params < $p
16953         rm -f $p
16954 }
16955 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16956
16957 test_156() {
16958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16959         remote_ost_nodsh && skip "remote OST with nodsh"
16960         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16961                 skip "stats not implemented on old servers"
16962         [ "$ost1_FSTYPE" = "zfs" ] &&
16963                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16964         (( CLIENT_VERSION == OST1_VERSION )) ||
16965                 skip "LU-13081: no interop testing for OSS cache"
16966
16967         local CPAGES=3
16968         local BEFORE
16969         local AFTER
16970         local file="$DIR/$tfile"
16971         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16972
16973         save_writethrough $p
16974         roc_hit_init
16975
16976         log "Turn on read and write cache"
16977         set_cache read on
16978         set_cache writethrough on
16979
16980         log "Write data and read it back."
16981         log "Read should be satisfied from the cache."
16982         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16983         BEFORE=$(roc_hit)
16984         cancel_lru_locks osc
16985         cat $file >/dev/null
16986         AFTER=$(roc_hit)
16987         if ! let "AFTER - BEFORE == CPAGES"; then
16988                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16989         else
16990                 log "cache hits: before: $BEFORE, after: $AFTER"
16991         fi
16992
16993         log "Read again; it should be satisfied from the cache."
16994         BEFORE=$AFTER
16995         cancel_lru_locks osc
16996         cat $file >/dev/null
16997         AFTER=$(roc_hit)
16998         if ! let "AFTER - BEFORE == CPAGES"; then
16999                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17000         else
17001                 log "cache hits:: before: $BEFORE, after: $AFTER"
17002         fi
17003
17004         log "Turn off the read cache and turn on the write cache"
17005         set_cache read off
17006         set_cache writethrough on
17007
17008         log "Read again; it should be satisfied from the cache."
17009         BEFORE=$(roc_hit)
17010         cancel_lru_locks osc
17011         cat $file >/dev/null
17012         AFTER=$(roc_hit)
17013         if ! let "AFTER - BEFORE == CPAGES"; then
17014                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17015         else
17016                 log "cache hits:: before: $BEFORE, after: $AFTER"
17017         fi
17018
17019         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17020                 # > 2.12.56 uses pagecache if cached
17021                 log "Read again; it should not be satisfied from the cache."
17022                 BEFORE=$AFTER
17023                 cancel_lru_locks osc
17024                 cat $file >/dev/null
17025                 AFTER=$(roc_hit)
17026                 if ! let "AFTER - BEFORE == 0"; then
17027                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17028                 else
17029                         log "cache hits:: before: $BEFORE, after: $AFTER"
17030                 fi
17031         fi
17032
17033         log "Write data and read it back."
17034         log "Read should be satisfied from the cache."
17035         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17036         BEFORE=$(roc_hit)
17037         cancel_lru_locks osc
17038         cat $file >/dev/null
17039         AFTER=$(roc_hit)
17040         if ! let "AFTER - BEFORE == CPAGES"; then
17041                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17042         else
17043                 log "cache hits:: before: $BEFORE, after: $AFTER"
17044         fi
17045
17046         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17047                 # > 2.12.56 uses pagecache if cached
17048                 log "Read again; it should not be satisfied from the cache."
17049                 BEFORE=$AFTER
17050                 cancel_lru_locks osc
17051                 cat $file >/dev/null
17052                 AFTER=$(roc_hit)
17053                 if ! let "AFTER - BEFORE == 0"; then
17054                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17055                 else
17056                         log "cache hits:: before: $BEFORE, after: $AFTER"
17057                 fi
17058         fi
17059
17060         log "Turn off read and write cache"
17061         set_cache read off
17062         set_cache writethrough off
17063
17064         log "Write data and read it back"
17065         log "It should not be satisfied from the cache."
17066         rm -f $file
17067         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17068         cancel_lru_locks osc
17069         BEFORE=$(roc_hit)
17070         cat $file >/dev/null
17071         AFTER=$(roc_hit)
17072         if ! let "AFTER - BEFORE == 0"; then
17073                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17074         else
17075                 log "cache hits:: before: $BEFORE, after: $AFTER"
17076         fi
17077
17078         log "Turn on the read cache and turn off the write cache"
17079         set_cache read on
17080         set_cache writethrough off
17081
17082         log "Write data and read it back"
17083         log "It should not be satisfied from the cache."
17084         rm -f $file
17085         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17086         BEFORE=$(roc_hit)
17087         cancel_lru_locks osc
17088         cat $file >/dev/null
17089         AFTER=$(roc_hit)
17090         if ! let "AFTER - BEFORE == 0"; then
17091                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17092         else
17093                 log "cache hits:: before: $BEFORE, after: $AFTER"
17094         fi
17095
17096         log "Read again; it should be satisfied from the cache."
17097         BEFORE=$(roc_hit)
17098         cancel_lru_locks osc
17099         cat $file >/dev/null
17100         AFTER=$(roc_hit)
17101         if ! let "AFTER - BEFORE == CPAGES"; then
17102                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17103         else
17104                 log "cache hits:: before: $BEFORE, after: $AFTER"
17105         fi
17106
17107         restore_lustre_params < $p
17108         rm -f $p $file
17109 }
17110 run_test 156 "Verification of tunables"
17111
17112 test_160a() {
17113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17114         remote_mds_nodsh && skip "remote MDS with nodsh"
17115         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17116                 skip "Need MDS version at least 2.2.0"
17117
17118         changelog_register || error "changelog_register failed"
17119         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17120         changelog_users $SINGLEMDS | grep -q $cl_user ||
17121                 error "User $cl_user not found in changelog_users"
17122
17123         mkdir_on_mdt0 $DIR/$tdir
17124
17125         # change something
17126         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17127         changelog_clear 0 || error "changelog_clear failed"
17128         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17129         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17130         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17131         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17132         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17133         rm $DIR/$tdir/pics/desktop.jpg
17134
17135         echo "verifying changelog mask"
17136         changelog_chmask "-MKDIR"
17137         changelog_chmask "-CLOSE"
17138
17139         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17140         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17141
17142         changelog_chmask "+MKDIR"
17143         changelog_chmask "+CLOSE"
17144
17145         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17146         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17147
17148         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17149         CLOSES=$(changelog_dump | grep -c "CLOSE")
17150         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17151         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17152
17153         # verify contents
17154         echo "verifying target fid"
17155         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17156         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17157         [ "$fidc" == "$fidf" ] ||
17158                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17159         echo "verifying parent fid"
17160         # The FID returned from the Changelog may be the directory shard on
17161         # a different MDT, and not the FID returned by path2fid on the parent.
17162         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17163         # since this is what will matter when recreating this file in the tree.
17164         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17165         local pathp=$($LFS fid2path $MOUNT "$fidp")
17166         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17167                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17168
17169         echo "getting records for $cl_user"
17170         changelog_users $SINGLEMDS
17171         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17172         local nclr=3
17173         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17174                 error "changelog_clear failed"
17175         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17176         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17177         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17178                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17179
17180         local min0_rec=$(changelog_users $SINGLEMDS |
17181                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17182         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17183                           awk '{ print $1; exit; }')
17184
17185         changelog_dump | tail -n 5
17186         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17187         [ $first_rec == $((min0_rec + 1)) ] ||
17188                 error "first index should be $min0_rec + 1 not $first_rec"
17189
17190         # LU-3446 changelog index reset on MDT restart
17191         local cur_rec1=$(changelog_users $SINGLEMDS |
17192                          awk '/^current.index:/ { print $NF }')
17193         changelog_clear 0 ||
17194                 error "clear all changelog records for $cl_user failed"
17195         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17196         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17197                 error "Fail to start $SINGLEMDS"
17198         local cur_rec2=$(changelog_users $SINGLEMDS |
17199                          awk '/^current.index:/ { print $NF }')
17200         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17201         [ $cur_rec1 == $cur_rec2 ] ||
17202                 error "current index should be $cur_rec1 not $cur_rec2"
17203
17204         echo "verifying users from this test are deregistered"
17205         changelog_deregister || error "changelog_deregister failed"
17206         changelog_users $SINGLEMDS | grep -q $cl_user &&
17207                 error "User '$cl_user' still in changelog_users"
17208
17209         # lctl get_param -n mdd.*.changelog_users
17210         # current_index: 144
17211         # ID    index (idle seconds)
17212         # cl3   144   (2) mask=<list>
17213         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17214                 # this is the normal case where all users were deregistered
17215                 # make sure no new records are added when no users are present
17216                 local last_rec1=$(changelog_users $SINGLEMDS |
17217                                   awk '/^current.index:/ { print $NF }')
17218                 touch $DIR/$tdir/chloe
17219                 local last_rec2=$(changelog_users $SINGLEMDS |
17220                                   awk '/^current.index:/ { print $NF }')
17221                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17222                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17223         else
17224                 # any changelog users must be leftovers from a previous test
17225                 changelog_users $SINGLEMDS
17226                 echo "other changelog users; can't verify off"
17227         fi
17228 }
17229 run_test 160a "changelog sanity"
17230
17231 test_160b() { # LU-3587
17232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17233         remote_mds_nodsh && skip "remote MDS with nodsh"
17234         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17235                 skip "Need MDS version at least 2.2.0"
17236
17237         changelog_register || error "changelog_register failed"
17238         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17239         changelog_users $SINGLEMDS | grep -q $cl_user ||
17240                 error "User '$cl_user' not found in changelog_users"
17241
17242         local longname1=$(str_repeat a 255)
17243         local longname2=$(str_repeat b 255)
17244
17245         cd $DIR
17246         echo "creating very long named file"
17247         touch $longname1 || error "create of '$longname1' failed"
17248         echo "renaming very long named file"
17249         mv $longname1 $longname2
17250
17251         changelog_dump | grep RENME | tail -n 5
17252         rm -f $longname2
17253 }
17254 run_test 160b "Verify that very long rename doesn't crash in changelog"
17255
17256 test_160c() {
17257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17258         remote_mds_nodsh && skip "remote MDS with nodsh"
17259
17260         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17261                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17262                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17263                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17264
17265         local rc=0
17266
17267         # Registration step
17268         changelog_register || error "changelog_register failed"
17269
17270         rm -rf $DIR/$tdir
17271         mkdir -p $DIR/$tdir
17272         $MCREATE $DIR/$tdir/foo_160c
17273         changelog_chmask "-TRUNC"
17274         $TRUNCATE $DIR/$tdir/foo_160c 200
17275         changelog_chmask "+TRUNC"
17276         $TRUNCATE $DIR/$tdir/foo_160c 199
17277         changelog_dump | tail -n 5
17278         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17279         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17280 }
17281 run_test 160c "verify that changelog log catch the truncate event"
17282
17283 test_160d() {
17284         remote_mds_nodsh && skip "remote MDS with nodsh"
17285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17287         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17288                 skip "Need MDS version at least 2.7.60"
17289
17290         # Registration step
17291         changelog_register || error "changelog_register failed"
17292
17293         mkdir -p $DIR/$tdir/migrate_dir
17294         changelog_clear 0 || error "changelog_clear failed"
17295
17296         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17297         changelog_dump | tail -n 5
17298         local migrates=$(changelog_dump | grep -c "MIGRT")
17299         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17300 }
17301 run_test 160d "verify that changelog log catch the migrate event"
17302
17303 test_160e() {
17304         remote_mds_nodsh && skip "remote MDS with nodsh"
17305
17306         # Create a user
17307         changelog_register || error "changelog_register failed"
17308
17309         local MDT0=$(facet_svc $SINGLEMDS)
17310         local rc
17311
17312         # No user (expect fail)
17313         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17314         rc=$?
17315         if [ $rc -eq 0 ]; then
17316                 error "Should fail without user"
17317         elif [ $rc -ne 4 ]; then
17318                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17319         fi
17320
17321         # Delete a future user (expect fail)
17322         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17323         rc=$?
17324         if [ $rc -eq 0 ]; then
17325                 error "Deleted non-existant user cl77"
17326         elif [ $rc -ne 2 ]; then
17327                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17328         fi
17329
17330         # Clear to a bad index (1 billion should be safe)
17331         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17332         rc=$?
17333
17334         if [ $rc -eq 0 ]; then
17335                 error "Successfully cleared to invalid CL index"
17336         elif [ $rc -ne 22 ]; then
17337                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17338         fi
17339 }
17340 run_test 160e "changelog negative testing (should return errors)"
17341
17342 test_160f() {
17343         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17344         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17345                 skip "Need MDS version at least 2.10.56"
17346
17347         local mdts=$(comma_list $(mdts_nodes))
17348
17349         # Create a user
17350         changelog_register || error "first changelog_register failed"
17351         changelog_register || error "second changelog_register failed"
17352         local cl_users
17353         declare -A cl_user1
17354         declare -A cl_user2
17355         local user_rec1
17356         local user_rec2
17357         local i
17358
17359         # generate some changelog records to accumulate on each MDT
17360         # use all_char because created files should be evenly distributed
17361         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17362                 error "test_mkdir $tdir failed"
17363         log "$(date +%s): creating first files"
17364         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17365                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17366                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17367         done
17368
17369         # check changelogs have been generated
17370         local start=$SECONDS
17371         local idle_time=$((MDSCOUNT * 5 + 5))
17372         local nbcl=$(changelog_dump | wc -l)
17373         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17374
17375         for param in "changelog_max_idle_time=$idle_time" \
17376                      "changelog_gc=1" \
17377                      "changelog_min_gc_interval=2" \
17378                      "changelog_min_free_cat_entries=3"; do
17379                 local MDT0=$(facet_svc $SINGLEMDS)
17380                 local var="${param%=*}"
17381                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17382
17383                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17384                 do_nodes $mdts $LCTL set_param mdd.*.$param
17385         done
17386
17387         # force cl_user2 to be idle (1st part), but also cancel the
17388         # cl_user1 records so that it is not evicted later in the test.
17389         local sleep1=$((idle_time / 2))
17390         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17391         sleep $sleep1
17392
17393         # simulate changelog catalog almost full
17394         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17395         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17396
17397         for i in $(seq $MDSCOUNT); do
17398                 cl_users=(${CL_USERS[mds$i]})
17399                 cl_user1[mds$i]="${cl_users[0]}"
17400                 cl_user2[mds$i]="${cl_users[1]}"
17401
17402                 [ -n "${cl_user1[mds$i]}" ] ||
17403                         error "mds$i: no user registered"
17404                 [ -n "${cl_user2[mds$i]}" ] ||
17405                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17406
17407                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17408                 [ -n "$user_rec1" ] ||
17409                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17410                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17411                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17412                 [ -n "$user_rec2" ] ||
17413                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17414                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17415                      "$user_rec1 + 2 == $user_rec2"
17416                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17417                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17418                               "$user_rec1 + 2, but is $user_rec2"
17419                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17420                 [ -n "$user_rec2" ] ||
17421                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17422                 [ $user_rec1 == $user_rec2 ] ||
17423                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17424                               "$user_rec1, but is $user_rec2"
17425         done
17426
17427         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17428         local sleep2=$((idle_time - (SECONDS - start) + 1))
17429         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17430         sleep $sleep2
17431
17432         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17433         # cl_user1 should be OK because it recently processed records.
17434         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17435         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17436                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17437                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17438         done
17439
17440         # ensure gc thread is done
17441         for i in $(mdts_nodes); do
17442                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17443                         error "$i: GC-thread not done"
17444         done
17445
17446         local first_rec
17447         for (( i = 1; i <= MDSCOUNT; i++ )); do
17448                 # check cl_user1 still registered
17449                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17450                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17451                 # check cl_user2 unregistered
17452                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17453                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17454
17455                 # check changelogs are present and starting at $user_rec1 + 1
17456                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17457                 [ -n "$user_rec1" ] ||
17458                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17459                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17460                             awk '{ print $1; exit; }')
17461
17462                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17463                 [ $((user_rec1 + 1)) == $first_rec ] ||
17464                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17465         done
17466 }
17467 run_test 160f "changelog garbage collect (timestamped users)"
17468
17469 test_160g() {
17470         remote_mds_nodsh && skip "remote MDS with nodsh"
17471         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17472                 skip "Need MDS version at least 2.14.55"
17473
17474         local mdts=$(comma_list $(mdts_nodes))
17475
17476         # Create a user
17477         changelog_register || error "first changelog_register failed"
17478         changelog_register || error "second changelog_register failed"
17479         local cl_users
17480         declare -A cl_user1
17481         declare -A cl_user2
17482         local user_rec1
17483         local user_rec2
17484         local i
17485
17486         # generate some changelog records to accumulate on each MDT
17487         # use all_char because created files should be evenly distributed
17488         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17489                 error "test_mkdir $tdir failed"
17490         for ((i = 0; i < MDSCOUNT; i++)); do
17491                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17492                         error "create $DIR/$tdir/d$i.1 failed"
17493         done
17494
17495         # check changelogs have been generated
17496         local nbcl=$(changelog_dump | wc -l)
17497         (( $nbcl > 0 )) || error "no changelogs found"
17498
17499         # reduce the max_idle_indexes value to make sure we exceed it
17500         for param in "changelog_max_idle_indexes=2" \
17501                      "changelog_gc=1" \
17502                      "changelog_min_gc_interval=2"; do
17503                 local MDT0=$(facet_svc $SINGLEMDS)
17504                 local var="${param%=*}"
17505                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17506
17507                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17508                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17509                         error "unable to set mdd.*.$param"
17510         done
17511
17512         local start=$SECONDS
17513         for i in $(seq $MDSCOUNT); do
17514                 cl_users=(${CL_USERS[mds$i]})
17515                 cl_user1[mds$i]="${cl_users[0]}"
17516                 cl_user2[mds$i]="${cl_users[1]}"
17517
17518                 [ -n "${cl_user1[mds$i]}" ] ||
17519                         error "mds$i: user1 is not registered"
17520                 [ -n "${cl_user2[mds$i]}" ] ||
17521                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17522
17523                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17524                 [ -n "$user_rec1" ] ||
17525                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17526                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17527                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17528                 [ -n "$user_rec2" ] ||
17529                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17530                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17531                      "$user_rec1 + 2 == $user_rec2"
17532                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17533                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17534                               "expected $user_rec1 + 2, but is $user_rec2"
17535                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17536                 [ -n "$user_rec2" ] ||
17537                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17538                 [ $user_rec1 == $user_rec2 ] ||
17539                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17540                               "expected $user_rec1, but is $user_rec2"
17541         done
17542
17543         # ensure we are past the previous changelog_min_gc_interval set above
17544         local sleep2=$((start + 2 - SECONDS))
17545         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17546         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17547         # cl_user1 should be OK because it recently processed records.
17548         for ((i = 0; i < MDSCOUNT; i++)); do
17549                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17550                         error "create $DIR/$tdir/d$i.3 failed"
17551         done
17552
17553         # ensure gc thread is done
17554         for i in $(mdts_nodes); do
17555                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17556                         error "$i: GC-thread not done"
17557         done
17558
17559         local first_rec
17560         for (( i = 1; i <= MDSCOUNT; i++ )); do
17561                 # check cl_user1 still registered
17562                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17563                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17564                 # check cl_user2 unregistered
17565                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17566                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17567
17568                 # check changelogs are present and starting at $user_rec1 + 1
17569                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17570                 [ -n "$user_rec1" ] ||
17571                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17572                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17573                             awk '{ print $1; exit; }')
17574
17575                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17576                 [ $((user_rec1 + 1)) == $first_rec ] ||
17577                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17578         done
17579 }
17580 run_test 160g "changelog garbage collect on idle records"
17581
17582 test_160h() {
17583         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17584         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17585                 skip "Need MDS version at least 2.10.56"
17586
17587         local mdts=$(comma_list $(mdts_nodes))
17588
17589         # Create a user
17590         changelog_register || error "first changelog_register failed"
17591         changelog_register || error "second changelog_register failed"
17592         local cl_users
17593         declare -A cl_user1
17594         declare -A cl_user2
17595         local user_rec1
17596         local user_rec2
17597         local i
17598
17599         # generate some changelog records to accumulate on each MDT
17600         # use all_char because created files should be evenly distributed
17601         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17602                 error "test_mkdir $tdir failed"
17603         for ((i = 0; i < MDSCOUNT; i++)); do
17604                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17605                         error "create $DIR/$tdir/d$i.1 failed"
17606         done
17607
17608         # check changelogs have been generated
17609         local nbcl=$(changelog_dump | wc -l)
17610         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17611
17612         for param in "changelog_max_idle_time=10" \
17613                      "changelog_gc=1" \
17614                      "changelog_min_gc_interval=2"; do
17615                 local MDT0=$(facet_svc $SINGLEMDS)
17616                 local var="${param%=*}"
17617                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17618
17619                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17620                 do_nodes $mdts $LCTL set_param mdd.*.$param
17621         done
17622
17623         # force cl_user2 to be idle (1st part)
17624         sleep 9
17625
17626         for i in $(seq $MDSCOUNT); do
17627                 cl_users=(${CL_USERS[mds$i]})
17628                 cl_user1[mds$i]="${cl_users[0]}"
17629                 cl_user2[mds$i]="${cl_users[1]}"
17630
17631                 [ -n "${cl_user1[mds$i]}" ] ||
17632                         error "mds$i: no user registered"
17633                 [ -n "${cl_user2[mds$i]}" ] ||
17634                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17635
17636                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17637                 [ -n "$user_rec1" ] ||
17638                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17639                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17640                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17641                 [ -n "$user_rec2" ] ||
17642                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17643                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17644                      "$user_rec1 + 2 == $user_rec2"
17645                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17646                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17647                               "$user_rec1 + 2, but is $user_rec2"
17648                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17649                 [ -n "$user_rec2" ] ||
17650                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17651                 [ $user_rec1 == $user_rec2 ] ||
17652                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17653                               "$user_rec1, but is $user_rec2"
17654         done
17655
17656         # force cl_user2 to be idle (2nd part) and to reach
17657         # changelog_max_idle_time
17658         sleep 2
17659
17660         # force each GC-thread start and block then
17661         # one per MDT/MDD, set fail_val accordingly
17662         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17663         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17664
17665         # generate more changelogs to trigger fail_loc
17666         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17667                 error "create $DIR/$tdir/${tfile}bis failed"
17668
17669         # stop MDT to stop GC-thread, should be done in back-ground as it will
17670         # block waiting for the thread to be released and exit
17671         declare -A stop_pids
17672         for i in $(seq $MDSCOUNT); do
17673                 stop mds$i &
17674                 stop_pids[mds$i]=$!
17675         done
17676
17677         for i in $(mdts_nodes); do
17678                 local facet
17679                 local nb=0
17680                 local facets=$(facets_up_on_host $i)
17681
17682                 for facet in ${facets//,/ }; do
17683                         if [[ $facet == mds* ]]; then
17684                                 nb=$((nb + 1))
17685                         fi
17686                 done
17687                 # ensure each MDS's gc threads are still present and all in "R"
17688                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17689                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17690                         error "$i: expected $nb GC-thread"
17691                 wait_update $i \
17692                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17693                         "R" 20 ||
17694                         error "$i: GC-thread not found in R-state"
17695                 # check umounts of each MDT on MDS have reached kthread_stop()
17696                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17697                         error "$i: expected $nb umount"
17698                 wait_update $i \
17699                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17700                         error "$i: umount not found in D-state"
17701         done
17702
17703         # release all GC-threads
17704         do_nodes $mdts $LCTL set_param fail_loc=0
17705
17706         # wait for MDT stop to complete
17707         for i in $(seq $MDSCOUNT); do
17708                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17709         done
17710
17711         # XXX
17712         # may try to check if any orphan changelog records are present
17713         # via ldiskfs/zfs and llog_reader...
17714
17715         # re-start/mount MDTs
17716         for i in $(seq $MDSCOUNT); do
17717                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17718                         error "Fail to start mds$i"
17719         done
17720
17721         local first_rec
17722         for i in $(seq $MDSCOUNT); do
17723                 # check cl_user1 still registered
17724                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17725                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17726                 # check cl_user2 unregistered
17727                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17728                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17729
17730                 # check changelogs are present and starting at $user_rec1 + 1
17731                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17732                 [ -n "$user_rec1" ] ||
17733                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17734                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17735                             awk '{ print $1; exit; }')
17736
17737                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17738                 [ $((user_rec1 + 1)) == $first_rec ] ||
17739                         error "mds$i: first index should be $user_rec1 + 1, " \
17740                               "but is $first_rec"
17741         done
17742 }
17743 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17744               "during mount"
17745
17746 test_160i() {
17747
17748         local mdts=$(comma_list $(mdts_nodes))
17749
17750         changelog_register || error "first changelog_register failed"
17751
17752         # generate some changelog records to accumulate on each MDT
17753         # use all_char because created files should be evenly distributed
17754         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17755                 error "test_mkdir $tdir failed"
17756         for ((i = 0; i < MDSCOUNT; i++)); do
17757                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17758                         error "create $DIR/$tdir/d$i.1 failed"
17759         done
17760
17761         # check changelogs have been generated
17762         local nbcl=$(changelog_dump | wc -l)
17763         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17764
17765         # simulate race between register and unregister
17766         # XXX as fail_loc is set per-MDS, with DNE configs the race
17767         # simulation will only occur for one MDT per MDS and for the
17768         # others the normal race scenario will take place
17769         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17770         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17771         do_nodes $mdts $LCTL set_param fail_val=1
17772
17773         # unregister 1st user
17774         changelog_deregister &
17775         local pid1=$!
17776         # wait some time for deregister work to reach race rdv
17777         sleep 2
17778         # register 2nd user
17779         changelog_register || error "2nd user register failed"
17780
17781         wait $pid1 || error "1st user deregister failed"
17782
17783         local i
17784         local last_rec
17785         declare -A LAST_REC
17786         for i in $(seq $MDSCOUNT); do
17787                 if changelog_users mds$i | grep "^cl"; then
17788                         # make sure new records are added with one user present
17789                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17790                                           awk '/^current.index:/ { print $NF }')
17791                 else
17792                         error "mds$i has no user registered"
17793                 fi
17794         done
17795
17796         # generate more changelog records to accumulate on each MDT
17797         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17798                 error "create $DIR/$tdir/${tfile}bis failed"
17799
17800         for i in $(seq $MDSCOUNT); do
17801                 last_rec=$(changelog_users $SINGLEMDS |
17802                            awk '/^current.index:/ { print $NF }')
17803                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17804                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17805                         error "changelogs are off on mds$i"
17806         done
17807 }
17808 run_test 160i "changelog user register/unregister race"
17809
17810 test_160j() {
17811         remote_mds_nodsh && skip "remote MDS with nodsh"
17812         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17813                 skip "Need MDS version at least 2.12.56"
17814
17815         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17816         stack_trap "umount $MOUNT2" EXIT
17817
17818         changelog_register || error "first changelog_register failed"
17819         stack_trap "changelog_deregister" EXIT
17820
17821         # generate some changelog
17822         # use all_char because created files should be evenly distributed
17823         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17824                 error "mkdir $tdir failed"
17825         for ((i = 0; i < MDSCOUNT; i++)); do
17826                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17827                         error "create $DIR/$tdir/d$i.1 failed"
17828         done
17829
17830         # open the changelog device
17831         exec 3>/dev/changelog-$FSNAME-MDT0000
17832         stack_trap "exec 3>&-" EXIT
17833         exec 4</dev/changelog-$FSNAME-MDT0000
17834         stack_trap "exec 4<&-" EXIT
17835
17836         # umount the first lustre mount
17837         umount $MOUNT
17838         stack_trap "mount_client $MOUNT" EXIT
17839
17840         # read changelog, which may or may not fail, but should not crash
17841         cat <&4 >/dev/null
17842
17843         # clear changelog
17844         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17845         changelog_users $SINGLEMDS | grep -q $cl_user ||
17846                 error "User $cl_user not found in changelog_users"
17847
17848         printf 'clear:'$cl_user':0' >&3
17849 }
17850 run_test 160j "client can be umounted while its chanangelog is being used"
17851
17852 test_160k() {
17853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17854         remote_mds_nodsh && skip "remote MDS with nodsh"
17855
17856         mkdir -p $DIR/$tdir/1/1
17857
17858         changelog_register || error "changelog_register failed"
17859         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17860
17861         changelog_users $SINGLEMDS | grep -q $cl_user ||
17862                 error "User '$cl_user' not found in changelog_users"
17863 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17864         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17865         rmdir $DIR/$tdir/1/1 & sleep 1
17866         mkdir $DIR/$tdir/2
17867         touch $DIR/$tdir/2/2
17868         rm -rf $DIR/$tdir/2
17869
17870         wait
17871         sleep 4
17872
17873         changelog_dump | grep rmdir || error "rmdir not recorded"
17874 }
17875 run_test 160k "Verify that changelog records are not lost"
17876
17877 # Verifies that a file passed as a parameter has recently had an operation
17878 # performed on it that has generated an MTIME changelog which contains the
17879 # correct parent FID. As files might reside on a different MDT from the
17880 # parent directory in DNE configurations, the FIDs are translated to paths
17881 # before being compared, which should be identical
17882 compare_mtime_changelog() {
17883         local file="${1}"
17884         local mdtidx
17885         local mtime
17886         local cl_fid
17887         local pdir
17888         local dir
17889
17890         mdtidx=$($LFS getstripe --mdt-index $file)
17891         mdtidx=$(printf "%04x" $mdtidx)
17892
17893         # Obtain the parent FID from the MTIME changelog
17894         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17895         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17896
17897         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17898         [ -z "$cl_fid" ] && error "parent FID not present"
17899
17900         # Verify that the path for the parent FID is the same as the path for
17901         # the test directory
17902         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17903
17904         dir=$(dirname $1)
17905
17906         [[ "${pdir%/}" == "$dir" ]] ||
17907                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17908 }
17909
17910 test_160l() {
17911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17912
17913         remote_mds_nodsh && skip "remote MDS with nodsh"
17914         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17915                 skip "Need MDS version at least 2.13.55"
17916
17917         local cl_user
17918
17919         changelog_register || error "changelog_register failed"
17920         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17921
17922         changelog_users $SINGLEMDS | grep -q $cl_user ||
17923                 error "User '$cl_user' not found in changelog_users"
17924
17925         # Clear some types so that MTIME changelogs are generated
17926         changelog_chmask "-CREAT"
17927         changelog_chmask "-CLOSE"
17928
17929         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17930
17931         # Test CL_MTIME during setattr
17932         touch $DIR/$tdir/$tfile
17933         compare_mtime_changelog $DIR/$tdir/$tfile
17934
17935         # Test CL_MTIME during close
17936         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17937         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17938 }
17939 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17940
17941 test_160m() {
17942         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17943         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17944                 skip "Need MDS version at least 2.14.51"
17945         local cl_users
17946         local cl_user1
17947         local cl_user2
17948         local pid1
17949
17950         # Create a user
17951         changelog_register || error "first changelog_register failed"
17952         changelog_register || error "second changelog_register failed"
17953
17954         cl_users=(${CL_USERS[mds1]})
17955         cl_user1="${cl_users[0]}"
17956         cl_user2="${cl_users[1]}"
17957         # generate some changelog records to accumulate on MDT0
17958         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17959         createmany -m $DIR/$tdir/$tfile 50 ||
17960                 error "create $DIR/$tdir/$tfile failed"
17961         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17962         rm -f $DIR/$tdir
17963
17964         # check changelogs have been generated
17965         local nbcl=$(changelog_dump | wc -l)
17966         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17967
17968 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17969         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17970
17971         __changelog_clear mds1 $cl_user1 +10
17972         __changelog_clear mds1 $cl_user2 0 &
17973         pid1=$!
17974         sleep 2
17975         __changelog_clear mds1 $cl_user1 0 ||
17976                 error "fail to cancel record for $cl_user1"
17977         wait $pid1
17978         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17979 }
17980 run_test 160m "Changelog clear race"
17981
17982 test_160n() {
17983         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17984         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17985                 skip "Need MDS version at least 2.14.51"
17986         local cl_users
17987         local cl_user1
17988         local cl_user2
17989         local pid1
17990         local first_rec
17991         local last_rec=0
17992
17993         # Create a user
17994         changelog_register || error "first changelog_register failed"
17995
17996         cl_users=(${CL_USERS[mds1]})
17997         cl_user1="${cl_users[0]}"
17998
17999         # generate some changelog records to accumulate on MDT0
18000         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18001         first_rec=$(changelog_users $SINGLEMDS |
18002                         awk '/^current.index:/ { print $NF }')
18003         while (( last_rec < (( first_rec + 65000)) )); do
18004                 createmany -m $DIR/$tdir/$tfile 10000 ||
18005                         error "create $DIR/$tdir/$tfile failed"
18006
18007                 for i in $(seq 0 10000); do
18008                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18009                                 > /dev/null
18010                 done
18011
18012                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18013                         error "unlinkmany failed unlink"
18014                 last_rec=$(changelog_users $SINGLEMDS |
18015                         awk '/^current.index:/ { print $NF }')
18016                 echo last record $last_rec
18017                 (( last_rec == 0 )) && error "no changelog found"
18018         done
18019
18020 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18021         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18022
18023         __changelog_clear mds1 $cl_user1 0 &
18024         pid1=$!
18025         sleep 2
18026         __changelog_clear mds1 $cl_user1 0 ||
18027                 error "fail to cancel record for $cl_user1"
18028         wait $pid1
18029         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18030 }
18031 run_test 160n "Changelog destroy race"
18032
18033 test_160o() {
18034         local mdt="$(facet_svc $SINGLEMDS)"
18035
18036         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18037         remote_mds_nodsh && skip "remote MDS with nodsh"
18038         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18039                 skip "Need MDS version at least 2.14.52"
18040
18041         changelog_register --user test_160o -m unlnk+close+open ||
18042                 error "changelog_register failed"
18043
18044         do_facet $SINGLEMDS $LCTL --device $mdt \
18045                                 changelog_register -u "Tt3_-#" &&
18046                 error "bad symbols in name should fail"
18047
18048         do_facet $SINGLEMDS $LCTL --device $mdt \
18049                                 changelog_register -u test_160o &&
18050                 error "the same name registration should fail"
18051
18052         do_facet $SINGLEMDS $LCTL --device $mdt \
18053                         changelog_register -u test_160toolongname &&
18054                 error "too long name registration should fail"
18055
18056         changelog_chmask "MARK+HSM"
18057         lctl get_param mdd.*.changelog*mask
18058         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18059         changelog_users $SINGLEMDS | grep -q $cl_user ||
18060                 error "User $cl_user not found in changelog_users"
18061         #verify username
18062         echo $cl_user | grep -q test_160o ||
18063                 error "User $cl_user has no specific name 'test160o'"
18064
18065         # change something
18066         changelog_clear 0 || error "changelog_clear failed"
18067         # generate some changelog records to accumulate on MDT0
18068         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18069         touch $DIR/$tdir/$tfile                 # open 1
18070
18071         OPENS=$(changelog_dump | grep -c "OPEN")
18072         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18073
18074         # must be no MKDIR it wasn't set as user mask
18075         MKDIR=$(changelog_dump | grep -c "MKDIR")
18076         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18077
18078         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18079                                 mdd.$mdt.changelog_current_mask -n)
18080         # register maskless user
18081         changelog_register || error "changelog_register failed"
18082         # effective mask should be not changed because it is not minimal
18083         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18084                                 mdd.$mdt.changelog_current_mask -n)
18085         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18086         # set server mask to minimal value
18087         changelog_chmask "MARK"
18088         # check effective mask again, should be treated as DEFMASK now
18089         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18090                                 mdd.$mdt.changelog_current_mask -n)
18091         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18092
18093         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18094                 # set server mask back to some value
18095                 changelog_chmask "CLOSE,UNLNK"
18096                 # check effective mask again, should not remain as DEFMASK
18097                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18098                                 mdd.$mdt.changelog_current_mask -n)
18099                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18100         fi
18101
18102         do_facet $SINGLEMDS $LCTL --device $mdt \
18103                                 changelog_deregister -u test_160o ||
18104                 error "cannot deregister by name"
18105 }
18106 run_test 160o "changelog user name and mask"
18107
18108 test_160p() {
18109         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18110         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18111                 skip "Need MDS version at least 2.14.51"
18112         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18113         local cl_users
18114         local cl_user1
18115         local entry_count
18116
18117         # Create a user
18118         changelog_register || error "first changelog_register failed"
18119
18120         cl_users=(${CL_USERS[mds1]})
18121         cl_user1="${cl_users[0]}"
18122
18123         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18124         createmany -m $DIR/$tdir/$tfile 50 ||
18125                 error "create $DIR/$tdir/$tfile failed"
18126         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18127         rm -rf $DIR/$tdir
18128
18129         # check changelogs have been generated
18130         entry_count=$(changelog_dump | wc -l)
18131         ((entry_count != 0)) || error "no changelog entries found"
18132
18133         # remove changelog_users and check that orphan entries are removed
18134         stop mds1
18135         local dev=$(mdsdevname 1)
18136         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18137         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18138         entry_count=$(changelog_dump | wc -l)
18139         ((entry_count == 0)) ||
18140                 error "found $entry_count changelog entries, expected none"
18141 }
18142 run_test 160p "Changelog orphan cleanup with no users"
18143
18144 test_160q() {
18145         local mdt="$(facet_svc $SINGLEMDS)"
18146         local clu
18147
18148         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18149         remote_mds_nodsh && skip "remote MDS with nodsh"
18150         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18151                 skip "Need MDS version at least 2.14.54"
18152
18153         # set server mask to minimal value like server init does
18154         changelog_chmask "MARK"
18155         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18156                 error "changelog_register failed"
18157         # check effective mask again, should be treated as DEFMASK now
18158         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18159                                 mdd.$mdt.changelog_current_mask -n)
18160         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18161                 error "changelog_deregister failed"
18162         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18163 }
18164 run_test 160q "changelog effective mask is DEFMASK if not set"
18165
18166 test_160s() {
18167         remote_mds_nodsh && skip "remote MDS with nodsh"
18168         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18169                 skip "Need MDS version at least 2.14.55"
18170
18171         local mdts=$(comma_list $(mdts_nodes))
18172
18173         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18174         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18175                                        fail_val=$((24 * 3600 * 10))
18176
18177         # Create a user which is 10 days old
18178         changelog_register || error "first changelog_register failed"
18179         local cl_users
18180         declare -A cl_user1
18181         local i
18182
18183         # generate some changelog records to accumulate on each MDT
18184         # use all_char because created files should be evenly distributed
18185         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18186                 error "test_mkdir $tdir failed"
18187         for ((i = 0; i < MDSCOUNT; i++)); do
18188                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18189                         error "create $DIR/$tdir/d$i.1 failed"
18190         done
18191
18192         # check changelogs have been generated
18193         local nbcl=$(changelog_dump | wc -l)
18194         (( nbcl > 0 )) || error "no changelogs found"
18195
18196         # reduce the max_idle_indexes value to make sure we exceed it
18197         for param in "changelog_max_idle_indexes=2097446912" \
18198                      "changelog_max_idle_time=2592000" \
18199                      "changelog_gc=1" \
18200                      "changelog_min_gc_interval=2"; do
18201                 local MDT0=$(facet_svc $SINGLEMDS)
18202                 local var="${param%=*}"
18203                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18204
18205                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18206                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18207                         error "unable to set mdd.*.$param"
18208         done
18209
18210         local start=$SECONDS
18211         for i in $(seq $MDSCOUNT); do
18212                 cl_users=(${CL_USERS[mds$i]})
18213                 cl_user1[mds$i]="${cl_users[0]}"
18214
18215                 [[ -n "${cl_user1[mds$i]}" ]] ||
18216                         error "mds$i: no user registered"
18217         done
18218
18219         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18220         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18221
18222         # ensure we are past the previous changelog_min_gc_interval set above
18223         local sleep2=$((start + 2 - SECONDS))
18224         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18225
18226         # Generate one more changelog to trigger GC
18227         for ((i = 0; i < MDSCOUNT; i++)); do
18228                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18229                         error "create $DIR/$tdir/d$i.3 failed"
18230         done
18231
18232         # ensure gc thread is done
18233         for node in $(mdts_nodes); do
18234                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18235                         error "$node: GC-thread not done"
18236         done
18237
18238         do_nodes $mdts $LCTL set_param fail_loc=0
18239
18240         for (( i = 1; i <= MDSCOUNT; i++ )); do
18241                 # check cl_user1 is purged
18242                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18243                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18244         done
18245         return 0
18246 }
18247 run_test 160s "changelog garbage collect on idle records * time"
18248
18249 test_160t() {
18250         remote_mds_nodsh && skip "remote MDS with nodsh"
18251         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18252                 skip "Need MDS version at least 2.15.50"
18253
18254         local MDT0=$(facet_svc $SINGLEMDS)
18255         local cl_users
18256         local cl_user1
18257         local cl_user2
18258         local start
18259
18260         changelog_register --user user1 -m all ||
18261                 error "user1 failed to register"
18262
18263         mkdir_on_mdt0 $DIR/$tdir
18264         # create default overstripe to maximize changelog size
18265         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18266         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18267         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18268
18269         # user2 consumes less records so less space
18270         changelog_register --user user2 || error "user2 failed to register"
18271         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18272         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18273
18274         # check changelogs have been generated
18275         local nbcl=$(changelog_dump | wc -l)
18276         (( nbcl > 0 )) || error "no changelogs found"
18277
18278         # reduce the changelog_min_gc_interval to force check
18279         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18280                 local var="${param%=*}"
18281                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18282
18283                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18284                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18285                         error "unable to set mdd.*.$param"
18286         done
18287
18288         start=$SECONDS
18289         cl_users=(${CL_USERS[mds1]})
18290         cl_user1="${cl_users[0]}"
18291         cl_user2="${cl_users[1]}"
18292
18293         [[ -n $cl_user1 ]] ||
18294                 error "mds1: user #1 isn't registered"
18295         [[ -n $cl_user2 ]] ||
18296                 error "mds1: user #2 isn't registered"
18297
18298         # ensure we are past the previous changelog_min_gc_interval set above
18299         local sleep2=$((start + 2 - SECONDS))
18300         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18301
18302         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18303         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18304                         fail_val=$(((llog_size1 + llog_size2) / 2))
18305
18306         # Generate more changelog to trigger GC
18307         createmany -o $DIR/$tdir/u3_ 4 ||
18308                 error "create failed for more files"
18309
18310         # ensure gc thread is done
18311         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18312                 error "mds1: GC-thread not done"
18313
18314         do_facet mds1 $LCTL set_param fail_loc=0
18315
18316         # check cl_user1 is purged
18317         changelog_users mds1 | grep -q "$cl_user1" &&
18318                 error "User $cl_user1 is registered"
18319         # check cl_user2 is not purged
18320         changelog_users mds1 | grep -q "$cl_user2" ||
18321                 error "User $cl_user2 is not registered"
18322 }
18323 run_test 160t "changelog garbage collect on lack of space"
18324
18325 test_161a() {
18326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18327
18328         test_mkdir -c1 $DIR/$tdir
18329         cp /etc/hosts $DIR/$tdir/$tfile
18330         test_mkdir -c1 $DIR/$tdir/foo1
18331         test_mkdir -c1 $DIR/$tdir/foo2
18332         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18333         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18334         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18335         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18336         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18337         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18338                 $LFS fid2path $DIR $FID
18339                 error "bad link ea"
18340         fi
18341         # middle
18342         rm $DIR/$tdir/foo2/zachary
18343         # last
18344         rm $DIR/$tdir/foo2/thor
18345         # first
18346         rm $DIR/$tdir/$tfile
18347         # rename
18348         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18349         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18350                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18351         rm $DIR/$tdir/foo2/maggie
18352
18353         # overflow the EA
18354         local longname=$tfile.avg_len_is_thirty_two_
18355         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18356                 error_noexit 'failed to unlink many hardlinks'" EXIT
18357         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18358                 error "failed to hardlink many files"
18359         links=$($LFS fid2path $DIR $FID | wc -l)
18360         echo -n "${links}/1000 links in link EA"
18361         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18362 }
18363 run_test 161a "link ea sanity"
18364
18365 test_161b() {
18366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18367         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18368
18369         local MDTIDX=1
18370         local remote_dir=$DIR/$tdir/remote_dir
18371
18372         mkdir -p $DIR/$tdir
18373         $LFS mkdir -i $MDTIDX $remote_dir ||
18374                 error "create remote directory failed"
18375
18376         cp /etc/hosts $remote_dir/$tfile
18377         mkdir -p $remote_dir/foo1
18378         mkdir -p $remote_dir/foo2
18379         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18380         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18381         ln $remote_dir/$tfile $remote_dir/foo1/luna
18382         ln $remote_dir/$tfile $remote_dir/foo2/thor
18383
18384         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18385                      tr -d ']')
18386         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18387                 $LFS fid2path $DIR $FID
18388                 error "bad link ea"
18389         fi
18390         # middle
18391         rm $remote_dir/foo2/zachary
18392         # last
18393         rm $remote_dir/foo2/thor
18394         # first
18395         rm $remote_dir/$tfile
18396         # rename
18397         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18398         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18399         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18400                 $LFS fid2path $DIR $FID
18401                 error "bad link rename"
18402         fi
18403         rm $remote_dir/foo2/maggie
18404
18405         # overflow the EA
18406         local longname=filename_avg_len_is_thirty_two_
18407         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18408                 error "failed to hardlink many files"
18409         links=$($LFS fid2path $DIR $FID | wc -l)
18410         echo -n "${links}/1000 links in link EA"
18411         [[ ${links} -gt 60 ]] ||
18412                 error "expected at least 60 links in link EA"
18413         unlinkmany $remote_dir/foo2/$longname 1000 ||
18414         error "failed to unlink many hardlinks"
18415 }
18416 run_test 161b "link ea sanity under remote directory"
18417
18418 test_161c() {
18419         remote_mds_nodsh && skip "remote MDS with nodsh"
18420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18421         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18422                 skip "Need MDS version at least 2.1.5"
18423
18424         # define CLF_RENAME_LAST 0x0001
18425         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18426         changelog_register || error "changelog_register failed"
18427
18428         rm -rf $DIR/$tdir
18429         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18430         touch $DIR/$tdir/foo_161c
18431         touch $DIR/$tdir/bar_161c
18432         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18433         changelog_dump | grep RENME | tail -n 5
18434         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18435         changelog_clear 0 || error "changelog_clear failed"
18436         if [ x$flags != "x0x1" ]; then
18437                 error "flag $flags is not 0x1"
18438         fi
18439
18440         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18441         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18442         touch $DIR/$tdir/foo_161c
18443         touch $DIR/$tdir/bar_161c
18444         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18445         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18446         changelog_dump | grep RENME | tail -n 5
18447         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18448         changelog_clear 0 || error "changelog_clear failed"
18449         if [ x$flags != "x0x0" ]; then
18450                 error "flag $flags is not 0x0"
18451         fi
18452         echo "rename overwrite a target having nlink > 1," \
18453                 "changelog record has flags of $flags"
18454
18455         # rename doesn't overwrite a target (changelog flag 0x0)
18456         touch $DIR/$tdir/foo_161c
18457         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18458         changelog_dump | grep RENME | tail -n 5
18459         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18460         changelog_clear 0 || error "changelog_clear failed"
18461         if [ x$flags != "x0x0" ]; then
18462                 error "flag $flags is not 0x0"
18463         fi
18464         echo "rename doesn't overwrite a target," \
18465                 "changelog record has flags of $flags"
18466
18467         # define CLF_UNLINK_LAST 0x0001
18468         # unlink a file having nlink = 1 (changelog flag 0x1)
18469         rm -f $DIR/$tdir/foo2_161c
18470         changelog_dump | grep UNLNK | tail -n 5
18471         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18472         changelog_clear 0 || error "changelog_clear failed"
18473         if [ x$flags != "x0x1" ]; then
18474                 error "flag $flags is not 0x1"
18475         fi
18476         echo "unlink a file having nlink = 1," \
18477                 "changelog record has flags of $flags"
18478
18479         # unlink a file having nlink > 1 (changelog flag 0x0)
18480         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18481         rm -f $DIR/$tdir/foobar_161c
18482         changelog_dump | grep UNLNK | tail -n 5
18483         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18484         changelog_clear 0 || error "changelog_clear failed"
18485         if [ x$flags != "x0x0" ]; then
18486                 error "flag $flags is not 0x0"
18487         fi
18488         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18489 }
18490 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18491
18492 test_161d() {
18493         remote_mds_nodsh && skip "remote MDS with nodsh"
18494         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18495
18496         local pid
18497         local fid
18498
18499         changelog_register || error "changelog_register failed"
18500
18501         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18502         # interfer with $MOUNT/.lustre/fid/ access
18503         mkdir $DIR/$tdir
18504         [[ $? -eq 0 ]] || error "mkdir failed"
18505
18506         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18507         $LCTL set_param fail_loc=0x8000140c
18508         # 5s pause
18509         $LCTL set_param fail_val=5
18510
18511         # create file
18512         echo foofoo > $DIR/$tdir/$tfile &
18513         pid=$!
18514
18515         # wait for create to be delayed
18516         sleep 2
18517
18518         ps -p $pid
18519         [[ $? -eq 0 ]] || error "create should be blocked"
18520
18521         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18522         stack_trap "rm -f $tempfile"
18523         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18524         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18525         # some delay may occur during ChangeLog publishing and file read just
18526         # above, that could allow file write to happen finally
18527         [[ -s $tempfile ]] && echo "file should be empty"
18528
18529         $LCTL set_param fail_loc=0
18530
18531         wait $pid
18532         [[ $? -eq 0 ]] || error "create failed"
18533 }
18534 run_test 161d "create with concurrent .lustre/fid access"
18535
18536 check_path() {
18537         local expected="$1"
18538         shift
18539         local fid="$2"
18540
18541         local path
18542         path=$($LFS fid2path "$@")
18543         local rc=$?
18544
18545         if [ $rc -ne 0 ]; then
18546                 error "path looked up of '$expected' failed: rc=$rc"
18547         elif [ "$path" != "$expected" ]; then
18548                 error "path looked up '$path' instead of '$expected'"
18549         else
18550                 echo "FID '$fid' resolves to path '$path' as expected"
18551         fi
18552 }
18553
18554 test_162a() { # was test_162
18555         test_mkdir -p -c1 $DIR/$tdir/d2
18556         touch $DIR/$tdir/d2/$tfile
18557         touch $DIR/$tdir/d2/x1
18558         touch $DIR/$tdir/d2/x2
18559         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18560         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18561         # regular file
18562         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18563         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18564
18565         # softlink
18566         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18567         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18568         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18569
18570         # softlink to wrong file
18571         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18572         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18573         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18574
18575         # hardlink
18576         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18577         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18578         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18579         # fid2path dir/fsname should both work
18580         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18581         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18582
18583         # hardlink count: check that there are 2 links
18584         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18585         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18586
18587         # hardlink indexing: remove the first link
18588         rm $DIR/$tdir/d2/p/q/r/hlink
18589         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18590 }
18591 run_test 162a "path lookup sanity"
18592
18593 test_162b() {
18594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18596
18597         mkdir $DIR/$tdir
18598         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18599                                 error "create striped dir failed"
18600
18601         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18602                                         tail -n 1 | awk '{print $2}')
18603         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18604
18605         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18606         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18607
18608         # regular file
18609         for ((i=0;i<5;i++)); do
18610                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18611                         error "get fid for f$i failed"
18612                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18613
18614                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18615                         error "get fid for d$i failed"
18616                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18617         done
18618
18619         return 0
18620 }
18621 run_test 162b "striped directory path lookup sanity"
18622
18623 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18624 test_162c() {
18625         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18626                 skip "Need MDS version at least 2.7.51"
18627
18628         local lpath=$tdir.local
18629         local rpath=$tdir.remote
18630
18631         test_mkdir $DIR/$lpath
18632         test_mkdir $DIR/$rpath
18633
18634         for ((i = 0; i <= 101; i++)); do
18635                 lpath="$lpath/$i"
18636                 mkdir $DIR/$lpath
18637                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18638                         error "get fid for local directory $DIR/$lpath failed"
18639                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18640
18641                 rpath="$rpath/$i"
18642                 test_mkdir $DIR/$rpath
18643                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18644                         error "get fid for remote directory $DIR/$rpath failed"
18645                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18646         done
18647
18648         return 0
18649 }
18650 run_test 162c "fid2path works with paths 100 or more directories deep"
18651
18652 oalr_event_count() {
18653         local event="${1}"
18654         local trace="${2}"
18655
18656         awk -v name="${FSNAME}-OST0000" \
18657             -v event="${event}" \
18658             '$1 == "TRACE" && $2 == event && $3 == name' \
18659             "${trace}" |
18660         wc -l
18661 }
18662
18663 oalr_expect_event_count() {
18664         local event="${1}"
18665         local trace="${2}"
18666         local expect="${3}"
18667         local count
18668
18669         count=$(oalr_event_count "${event}" "${trace}")
18670         if ((count == expect)); then
18671                 return 0
18672         fi
18673
18674         error_noexit "${event} event count was '${count}', expected ${expect}"
18675         cat "${trace}" >&2
18676         exit 1
18677 }
18678
18679 cleanup_165() {
18680         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18681         stop ost1
18682         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18683 }
18684
18685 setup_165() {
18686         sync # Flush previous IOs so we can count log entries.
18687         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18688         stack_trap cleanup_165 EXIT
18689 }
18690
18691 test_165a() {
18692         local trace="/tmp/${tfile}.trace"
18693         local rc
18694         local count
18695
18696         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18697                 skip "OFD access log unsupported"
18698
18699         setup_165
18700         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18701         sleep 5
18702
18703         do_facet ost1 ofd_access_log_reader --list
18704         stop ost1
18705
18706         do_facet ost1 killall -TERM ofd_access_log_reader
18707         wait
18708         rc=$?
18709
18710         if ((rc != 0)); then
18711                 error "ofd_access_log_reader exited with rc = '${rc}'"
18712         fi
18713
18714         # Parse trace file for discovery events:
18715         oalr_expect_event_count alr_log_add "${trace}" 1
18716         oalr_expect_event_count alr_log_eof "${trace}" 1
18717         oalr_expect_event_count alr_log_free "${trace}" 1
18718 }
18719 run_test 165a "ofd access log discovery"
18720
18721 test_165b() {
18722         local trace="/tmp/${tfile}.trace"
18723         local file="${DIR}/${tfile}"
18724         local pfid1
18725         local pfid2
18726         local -a entry
18727         local rc
18728         local count
18729         local size
18730         local flags
18731
18732         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18733                 skip "OFD access log unsupported"
18734
18735         setup_165
18736         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18737         sleep 5
18738
18739         do_facet ost1 ofd_access_log_reader --list
18740
18741         lfs setstripe -c 1 -i 0 "${file}"
18742         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18743                 error "cannot create '${file}'"
18744
18745         sleep 5
18746         do_facet ost1 killall -TERM ofd_access_log_reader
18747         wait
18748         rc=$?
18749
18750         if ((rc != 0)); then
18751                 error "ofd_access_log_reader exited with rc = '${rc}'"
18752         fi
18753
18754         oalr_expect_event_count alr_log_entry "${trace}" 1
18755
18756         pfid1=$($LFS path2fid "${file}")
18757
18758         # 1     2             3   4    5     6   7    8    9     10
18759         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18760         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18761
18762         echo "entry = '${entry[*]}'" >&2
18763
18764         pfid2=${entry[4]}
18765         if [[ "${pfid1}" != "${pfid2}" ]]; then
18766                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18767         fi
18768
18769         size=${entry[8]}
18770         if ((size != 1048576)); then
18771                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18772         fi
18773
18774         flags=${entry[10]}
18775         if [[ "${flags}" != "w" ]]; then
18776                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18777         fi
18778
18779         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18780         sleep 5
18781
18782         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18783                 error "cannot read '${file}'"
18784         sleep 5
18785
18786         do_facet ost1 killall -TERM ofd_access_log_reader
18787         wait
18788         rc=$?
18789
18790         if ((rc != 0)); then
18791                 error "ofd_access_log_reader exited with rc = '${rc}'"
18792         fi
18793
18794         oalr_expect_event_count alr_log_entry "${trace}" 1
18795
18796         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18797         echo "entry = '${entry[*]}'" >&2
18798
18799         pfid2=${entry[4]}
18800         if [[ "${pfid1}" != "${pfid2}" ]]; then
18801                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18802         fi
18803
18804         size=${entry[8]}
18805         if ((size != 524288)); then
18806                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18807         fi
18808
18809         flags=${entry[10]}
18810         if [[ "${flags}" != "r" ]]; then
18811                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18812         fi
18813 }
18814 run_test 165b "ofd access log entries are produced and consumed"
18815
18816 test_165c() {
18817         local trace="/tmp/${tfile}.trace"
18818         local file="${DIR}/${tdir}/${tfile}"
18819
18820         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18821                 skip "OFD access log unsupported"
18822
18823         test_mkdir "${DIR}/${tdir}"
18824
18825         setup_165
18826         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18827         sleep 5
18828
18829         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18830
18831         # 4096 / 64 = 64. Create twice as many entries.
18832         for ((i = 0; i < 128; i++)); do
18833                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18834                         error "cannot create file"
18835         done
18836
18837         sync
18838
18839         do_facet ost1 killall -TERM ofd_access_log_reader
18840         wait
18841         rc=$?
18842         if ((rc != 0)); then
18843                 error "ofd_access_log_reader exited with rc = '${rc}'"
18844         fi
18845
18846         unlinkmany  "${file}-%d" 128
18847 }
18848 run_test 165c "full ofd access logs do not block IOs"
18849
18850 oal_get_read_count() {
18851         local stats="$1"
18852
18853         # STATS lustre-OST0001 alr_read_count 1
18854
18855         do_facet ost1 cat "${stats}" |
18856         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18857              END { print count; }'
18858 }
18859
18860 oal_expect_read_count() {
18861         local stats="$1"
18862         local count
18863         local expect="$2"
18864
18865         # Ask ofd_access_log_reader to write stats.
18866         do_facet ost1 killall -USR1 ofd_access_log_reader
18867
18868         # Allow some time for things to happen.
18869         sleep 1
18870
18871         count=$(oal_get_read_count "${stats}")
18872         if ((count == expect)); then
18873                 return 0
18874         fi
18875
18876         error_noexit "bad read count, got ${count}, expected ${expect}"
18877         do_facet ost1 cat "${stats}" >&2
18878         exit 1
18879 }
18880
18881 test_165d() {
18882         local stats="/tmp/${tfile}.stats"
18883         local file="${DIR}/${tdir}/${tfile}"
18884         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18885
18886         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18887                 skip "OFD access log unsupported"
18888
18889         test_mkdir "${DIR}/${tdir}"
18890
18891         setup_165
18892         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18893         sleep 5
18894
18895         lfs setstripe -c 1 -i 0 "${file}"
18896
18897         do_facet ost1 lctl set_param "${param}=rw"
18898         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18899                 error "cannot create '${file}'"
18900         oal_expect_read_count "${stats}" 1
18901
18902         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18903                 error "cannot read '${file}'"
18904         oal_expect_read_count "${stats}" 2
18905
18906         do_facet ost1 lctl set_param "${param}=r"
18907         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18908                 error "cannot create '${file}'"
18909         oal_expect_read_count "${stats}" 2
18910
18911         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18912                 error "cannot read '${file}'"
18913         oal_expect_read_count "${stats}" 3
18914
18915         do_facet ost1 lctl set_param "${param}=w"
18916         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18917                 error "cannot create '${file}'"
18918         oal_expect_read_count "${stats}" 4
18919
18920         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18921                 error "cannot read '${file}'"
18922         oal_expect_read_count "${stats}" 4
18923
18924         do_facet ost1 lctl set_param "${param}=0"
18925         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18926                 error "cannot create '${file}'"
18927         oal_expect_read_count "${stats}" 4
18928
18929         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18930                 error "cannot read '${file}'"
18931         oal_expect_read_count "${stats}" 4
18932
18933         do_facet ost1 killall -TERM ofd_access_log_reader
18934         wait
18935         rc=$?
18936         if ((rc != 0)); then
18937                 error "ofd_access_log_reader exited with rc = '${rc}'"
18938         fi
18939 }
18940 run_test 165d "ofd_access_log mask works"
18941
18942 test_165e() {
18943         local stats="/tmp/${tfile}.stats"
18944         local file0="${DIR}/${tdir}-0/${tfile}"
18945         local file1="${DIR}/${tdir}-1/${tfile}"
18946
18947         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18948                 skip "OFD access log unsupported"
18949
18950         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18951
18952         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18953         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18954
18955         lfs setstripe -c 1 -i 0 "${file0}"
18956         lfs setstripe -c 1 -i 0 "${file1}"
18957
18958         setup_165
18959         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18960         sleep 5
18961
18962         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18963                 error "cannot create '${file0}'"
18964         sync
18965         oal_expect_read_count "${stats}" 0
18966
18967         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18968                 error "cannot create '${file1}'"
18969         sync
18970         oal_expect_read_count "${stats}" 1
18971
18972         do_facet ost1 killall -TERM ofd_access_log_reader
18973         wait
18974         rc=$?
18975         if ((rc != 0)); then
18976                 error "ofd_access_log_reader exited with rc = '${rc}'"
18977         fi
18978 }
18979 run_test 165e "ofd_access_log MDT index filter works"
18980
18981 test_165f() {
18982         local trace="/tmp/${tfile}.trace"
18983         local rc
18984         local count
18985
18986         setup_165
18987         do_facet ost1 timeout 60 ofd_access_log_reader \
18988                 --exit-on-close --debug=- --trace=- > "${trace}" &
18989         sleep 5
18990         stop ost1
18991
18992         wait
18993         rc=$?
18994
18995         if ((rc != 0)); then
18996                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18997                 cat "${trace}"
18998                 exit 1
18999         fi
19000 }
19001 run_test 165f "ofd_access_log_reader --exit-on-close works"
19002
19003 test_169() {
19004         # do directio so as not to populate the page cache
19005         log "creating a 10 Mb file"
19006         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19007                 error "multiop failed while creating a file"
19008         log "starting reads"
19009         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19010         log "truncating the file"
19011         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19012                 error "multiop failed while truncating the file"
19013         log "killing dd"
19014         kill %+ || true # reads might have finished
19015         echo "wait until dd is finished"
19016         wait
19017         log "removing the temporary file"
19018         rm -rf $DIR/$tfile || error "tmp file removal failed"
19019 }
19020 run_test 169 "parallel read and truncate should not deadlock"
19021
19022 test_170() {
19023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19024
19025         $LCTL clear     # bug 18514
19026         $LCTL debug_daemon start $TMP/${tfile}_log_good
19027         touch $DIR/$tfile
19028         $LCTL debug_daemon stop
19029         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19030                 error "sed failed to read log_good"
19031
19032         $LCTL debug_daemon start $TMP/${tfile}_log_good
19033         rm -rf $DIR/$tfile
19034         $LCTL debug_daemon stop
19035
19036         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19037                error "lctl df log_bad failed"
19038
19039         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19040         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19041
19042         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19043         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19044
19045         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19046                 error "bad_line good_line1 good_line2 are empty"
19047
19048         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19049         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19050         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19051
19052         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19053         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19054         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19055
19056         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19057                 error "bad_line_new good_line_new are empty"
19058
19059         local expected_good=$((good_line1 + good_line2*2))
19060
19061         rm -f $TMP/${tfile}*
19062         # LU-231, short malformed line may not be counted into bad lines
19063         if [ $bad_line -ne $bad_line_new ] &&
19064                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19065                 error "expected $bad_line bad lines, but got $bad_line_new"
19066                 return 1
19067         fi
19068
19069         if [ $expected_good -ne $good_line_new ]; then
19070                 error "expected $expected_good good lines, but got $good_line_new"
19071                 return 2
19072         fi
19073         true
19074 }
19075 run_test 170 "test lctl df to handle corrupted log ====================="
19076
19077 test_171() { # bug20592
19078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19079
19080         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19081         $LCTL set_param fail_loc=0x50e
19082         $LCTL set_param fail_val=3000
19083         multiop_bg_pause $DIR/$tfile O_s || true
19084         local MULTIPID=$!
19085         kill -USR1 $MULTIPID
19086         # cause log dump
19087         sleep 3
19088         wait $MULTIPID
19089         if dmesg | grep "recursive fault"; then
19090                 error "caught a recursive fault"
19091         fi
19092         $LCTL set_param fail_loc=0
19093         true
19094 }
19095 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19096
19097 test_172() {
19098
19099         #define OBD_FAIL_OBD_CLEANUP  0x60e
19100         $LCTL set_param fail_loc=0x60e
19101         umount $MOUNT || error "umount $MOUNT failed"
19102         stack_trap "mount_client $MOUNT"
19103
19104         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19105                 error "no client OBDs are remained"
19106
19107         $LCTL dl | while read devno state type name foo; do
19108                 case $type in
19109                 lov|osc|lmv|mdc)
19110                         $LCTL --device $name cleanup
19111                         $LCTL --device $name detach
19112                         ;;
19113                 *)
19114                         # skip server devices
19115                         ;;
19116                 esac
19117         done
19118
19119         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19120                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19121                 error "some client OBDs are still remained"
19122         fi
19123
19124 }
19125 run_test 172 "manual device removal with lctl cleanup/detach ======"
19126
19127 # it would be good to share it with obdfilter-survey/iokit-libecho code
19128 setup_obdecho_osc () {
19129         local rc=0
19130         local ost_nid=$1
19131         local obdfilter_name=$2
19132         echo "Creating new osc for $obdfilter_name on $ost_nid"
19133         # make sure we can find loopback nid
19134         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19135
19136         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19137                            ${obdfilter_name}_osc_UUID || rc=2; }
19138         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19139                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19140         return $rc
19141 }
19142
19143 cleanup_obdecho_osc () {
19144         local obdfilter_name=$1
19145         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19146         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19147         return 0
19148 }
19149
19150 obdecho_test() {
19151         local OBD=$1
19152         local node=$2
19153         local pages=${3:-64}
19154         local rc=0
19155         local id
19156
19157         local count=10
19158         local obd_size=$(get_obd_size $node $OBD)
19159         local page_size=$(get_page_size $node)
19160         if [[ -n "$obd_size" ]]; then
19161                 local new_count=$((obd_size / (pages * page_size / 1024)))
19162                 [[ $new_count -ge $count ]] || count=$new_count
19163         fi
19164
19165         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19166         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19167                            rc=2; }
19168         if [ $rc -eq 0 ]; then
19169             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19170             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19171         fi
19172         echo "New object id is $id"
19173         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19174                            rc=4; }
19175         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19176                            "test_brw $count w v $pages $id" || rc=4; }
19177         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19178                            rc=4; }
19179         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19180                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19181         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19182                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19183         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19184         return $rc
19185 }
19186
19187 test_180a() {
19188         skip "obdecho on osc is no longer supported"
19189 }
19190 run_test 180a "test obdecho on osc"
19191
19192 test_180b() {
19193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19194         remote_ost_nodsh && skip "remote OST with nodsh"
19195
19196         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19197                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19198                 error "failed to load module obdecho"
19199
19200         local target=$(do_facet ost1 $LCTL dl |
19201                        awk '/obdfilter/ { print $4; exit; }')
19202
19203         if [ -n "$target" ]; then
19204                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19205         else
19206                 do_facet ost1 $LCTL dl
19207                 error "there is no obdfilter target on ost1"
19208         fi
19209 }
19210 run_test 180b "test obdecho directly on obdfilter"
19211
19212 test_180c() { # LU-2598
19213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19214         remote_ost_nodsh && skip "remote OST with nodsh"
19215         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19216                 skip "Need MDS version at least 2.4.0"
19217
19218         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19219                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19220                 error "failed to load module obdecho"
19221
19222         local target=$(do_facet ost1 $LCTL dl |
19223                        awk '/obdfilter/ { print $4; exit; }')
19224
19225         if [ -n "$target" ]; then
19226                 local pages=16384 # 64MB bulk I/O RPC size
19227
19228                 obdecho_test "$target" ost1 "$pages" ||
19229                         error "obdecho_test with pages=$pages failed with $?"
19230         else
19231                 do_facet ost1 $LCTL dl
19232                 error "there is no obdfilter target on ost1"
19233         fi
19234 }
19235 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19236
19237 test_181() { # bug 22177
19238         test_mkdir $DIR/$tdir
19239         # create enough files to index the directory
19240         createmany -o $DIR/$tdir/foobar 4000
19241         # print attributes for debug purpose
19242         lsattr -d .
19243         # open dir
19244         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19245         MULTIPID=$!
19246         # remove the files & current working dir
19247         unlinkmany $DIR/$tdir/foobar 4000
19248         rmdir $DIR/$tdir
19249         kill -USR1 $MULTIPID
19250         wait $MULTIPID
19251         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19252         return 0
19253 }
19254 run_test 181 "Test open-unlinked dir ========================"
19255
19256 test_182a() {
19257         local fcount=1000
19258         local tcount=10
19259
19260         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19261
19262         $LCTL set_param mdc.*.rpc_stats=clear
19263
19264         for (( i = 0; i < $tcount; i++ )) ; do
19265                 mkdir $DIR/$tdir/$i
19266         done
19267
19268         for (( i = 0; i < $tcount; i++ )) ; do
19269                 createmany -o $DIR/$tdir/$i/f- $fcount &
19270         done
19271         wait
19272
19273         for (( i = 0; i < $tcount; i++ )) ; do
19274                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19275         done
19276         wait
19277
19278         $LCTL get_param mdc.*.rpc_stats
19279
19280         rm -rf $DIR/$tdir
19281 }
19282 run_test 182a "Test parallel modify metadata operations from mdc"
19283
19284 test_182b() {
19285         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19286         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19287         local dcount=1000
19288         local tcount=10
19289         local stime
19290         local etime
19291         local delta
19292
19293         do_facet mds1 $LCTL list_param \
19294                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19295                 skip "MDS lacks parallel RPC handling"
19296
19297         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19298
19299         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19300                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19301
19302         stime=$(date +%s)
19303         createmany -i 0 -d $DIR/$tdir/t- $tcount
19304
19305         for (( i = 0; i < $tcount; i++ )) ; do
19306                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19307         done
19308         wait
19309         etime=$(date +%s)
19310         delta=$((etime - stime))
19311         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19312
19313         stime=$(date +%s)
19314         for (( i = 0; i < $tcount; i++ )) ; do
19315                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19316         done
19317         wait
19318         etime=$(date +%s)
19319         delta=$((etime - stime))
19320         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19321
19322         rm -rf $DIR/$tdir
19323
19324         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19325
19326         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19327
19328         stime=$(date +%s)
19329         createmany -i 0 -d $DIR/$tdir/t- $tcount
19330
19331         for (( i = 0; i < $tcount; i++ )) ; do
19332                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19333         done
19334         wait
19335         etime=$(date +%s)
19336         delta=$((etime - stime))
19337         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19338
19339         stime=$(date +%s)
19340         for (( i = 0; i < $tcount; i++ )) ; do
19341                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19342         done
19343         wait
19344         etime=$(date +%s)
19345         delta=$((etime - stime))
19346         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19347
19348         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19349 }
19350 run_test 182b "Test parallel modify metadata operations from osp"
19351
19352 test_183() { # LU-2275
19353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19354         remote_mds_nodsh && skip "remote MDS with nodsh"
19355         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19356                 skip "Need MDS version at least 2.3.56"
19357
19358         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19359         echo aaa > $DIR/$tdir/$tfile
19360
19361 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19362         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19363
19364         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19365         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19366
19367         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19368
19369         # Flush negative dentry cache
19370         touch $DIR/$tdir/$tfile
19371
19372         # We are not checking for any leaked references here, they'll
19373         # become evident next time we do cleanup with module unload.
19374         rm -rf $DIR/$tdir
19375 }
19376 run_test 183 "No crash or request leak in case of strange dispositions ========"
19377
19378 # test suite 184 is for LU-2016, LU-2017
19379 test_184a() {
19380         check_swap_layouts_support
19381
19382         dir0=$DIR/$tdir/$testnum
19383         test_mkdir -p -c1 $dir0
19384         ref1=/etc/passwd
19385         ref2=/etc/group
19386         file1=$dir0/f1
19387         file2=$dir0/f2
19388         $LFS setstripe -c1 $file1
19389         cp $ref1 $file1
19390         $LFS setstripe -c2 $file2
19391         cp $ref2 $file2
19392         gen1=$($LFS getstripe -g $file1)
19393         gen2=$($LFS getstripe -g $file2)
19394
19395         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19396         gen=$($LFS getstripe -g $file1)
19397         [[ $gen1 != $gen ]] ||
19398                 error "Layout generation on $file1 does not change"
19399         gen=$($LFS getstripe -g $file2)
19400         [[ $gen2 != $gen ]] ||
19401                 error "Layout generation on $file2 does not change"
19402
19403         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19404         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19405
19406         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19407 }
19408 run_test 184a "Basic layout swap"
19409
19410 test_184b() {
19411         check_swap_layouts_support
19412
19413         dir0=$DIR/$tdir/$testnum
19414         mkdir -p $dir0 || error "creating dir $dir0"
19415         file1=$dir0/f1
19416         file2=$dir0/f2
19417         file3=$dir0/f3
19418         dir1=$dir0/d1
19419         dir2=$dir0/d2
19420         mkdir $dir1 $dir2
19421         $LFS setstripe -c1 $file1
19422         $LFS setstripe -c2 $file2
19423         $LFS setstripe -c1 $file3
19424         chown $RUNAS_ID $file3
19425         gen1=$($LFS getstripe -g $file1)
19426         gen2=$($LFS getstripe -g $file2)
19427
19428         $LFS swap_layouts $dir1 $dir2 &&
19429                 error "swap of directories layouts should fail"
19430         $LFS swap_layouts $dir1 $file1 &&
19431                 error "swap of directory and file layouts should fail"
19432         $RUNAS $LFS swap_layouts $file1 $file2 &&
19433                 error "swap of file we cannot write should fail"
19434         $LFS swap_layouts $file1 $file3 &&
19435                 error "swap of file with different owner should fail"
19436         /bin/true # to clear error code
19437 }
19438 run_test 184b "Forbidden layout swap (will generate errors)"
19439
19440 test_184c() {
19441         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19442         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19443         check_swap_layouts_support
19444         check_swap_layout_no_dom $DIR
19445
19446         local dir0=$DIR/$tdir/$testnum
19447         mkdir -p $dir0 || error "creating dir $dir0"
19448
19449         local ref1=$dir0/ref1
19450         local ref2=$dir0/ref2
19451         local file1=$dir0/file1
19452         local file2=$dir0/file2
19453         # create a file large enough for the concurrent test
19454         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19455         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19456         echo "ref file size: ref1($(stat -c %s $ref1))," \
19457              "ref2($(stat -c %s $ref2))"
19458
19459         cp $ref2 $file2
19460         dd if=$ref1 of=$file1 bs=16k &
19461         local DD_PID=$!
19462
19463         # Make sure dd starts to copy file, but wait at most 5 seconds
19464         local loops=0
19465         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19466
19467         $LFS swap_layouts $file1 $file2
19468         local rc=$?
19469         wait $DD_PID
19470         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19471         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19472
19473         # how many bytes copied before swapping layout
19474         local copied=$(stat -c %s $file2)
19475         local remaining=$(stat -c %s $ref1)
19476         remaining=$((remaining - copied))
19477         echo "Copied $copied bytes before swapping layout..."
19478
19479         cmp -n $copied $file1 $ref2 | grep differ &&
19480                 error "Content mismatch [0, $copied) of ref2 and file1"
19481         cmp -n $copied $file2 $ref1 ||
19482                 error "Content mismatch [0, $copied) of ref1 and file2"
19483         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19484                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19485
19486         # clean up
19487         rm -f $ref1 $ref2 $file1 $file2
19488 }
19489 run_test 184c "Concurrent write and layout swap"
19490
19491 test_184d() {
19492         check_swap_layouts_support
19493         check_swap_layout_no_dom $DIR
19494         [ -z "$(which getfattr 2>/dev/null)" ] &&
19495                 skip_env "no getfattr command"
19496
19497         local file1=$DIR/$tdir/$tfile-1
19498         local file2=$DIR/$tdir/$tfile-2
19499         local file3=$DIR/$tdir/$tfile-3
19500         local lovea1
19501         local lovea2
19502
19503         mkdir -p $DIR/$tdir
19504         touch $file1 || error "create $file1 failed"
19505         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19506                 error "create $file2 failed"
19507         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19508                 error "create $file3 failed"
19509         lovea1=$(get_layout_param $file1)
19510
19511         $LFS swap_layouts $file2 $file3 ||
19512                 error "swap $file2 $file3 layouts failed"
19513         $LFS swap_layouts $file1 $file2 ||
19514                 error "swap $file1 $file2 layouts failed"
19515
19516         lovea2=$(get_layout_param $file2)
19517         echo "$lovea1"
19518         echo "$lovea2"
19519         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19520
19521         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19522         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19523 }
19524 run_test 184d "allow stripeless layouts swap"
19525
19526 test_184e() {
19527         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19528                 skip "Need MDS version at least 2.6.94"
19529         check_swap_layouts_support
19530         check_swap_layout_no_dom $DIR
19531         [ -z "$(which getfattr 2>/dev/null)" ] &&
19532                 skip_env "no getfattr command"
19533
19534         local file1=$DIR/$tdir/$tfile-1
19535         local file2=$DIR/$tdir/$tfile-2
19536         local file3=$DIR/$tdir/$tfile-3
19537         local lovea
19538
19539         mkdir -p $DIR/$tdir
19540         touch $file1 || error "create $file1 failed"
19541         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19542                 error "create $file2 failed"
19543         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19544                 error "create $file3 failed"
19545
19546         $LFS swap_layouts $file1 $file2 ||
19547                 error "swap $file1 $file2 layouts failed"
19548
19549         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19550         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19551
19552         echo 123 > $file1 || error "Should be able to write into $file1"
19553
19554         $LFS swap_layouts $file1 $file3 ||
19555                 error "swap $file1 $file3 layouts failed"
19556
19557         echo 123 > $file1 || error "Should be able to write into $file1"
19558
19559         rm -rf $file1 $file2 $file3
19560 }
19561 run_test 184e "Recreate layout after stripeless layout swaps"
19562
19563 test_184f() {
19564         # Create a file with name longer than sizeof(struct stat) ==
19565         # 144 to see if we can get chars from the file name to appear
19566         # in the returned striping. Note that 'f' == 0x66.
19567         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19568
19569         mkdir -p $DIR/$tdir
19570         mcreate $DIR/$tdir/$file
19571         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19572                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19573         fi
19574 }
19575 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19576
19577 test_185() { # LU-2441
19578         # LU-3553 - no volatile file support in old servers
19579         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19580                 skip "Need MDS version at least 2.3.60"
19581
19582         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19583         touch $DIR/$tdir/spoo
19584         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19585         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19586                 error "cannot create/write a volatile file"
19587         [ "$FILESET" == "" ] &&
19588         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19589                 error "FID is still valid after close"
19590
19591         multiop_bg_pause $DIR/$tdir Vw4096_c
19592         local multi_pid=$!
19593
19594         local OLD_IFS=$IFS
19595         IFS=":"
19596         local fidv=($fid)
19597         IFS=$OLD_IFS
19598         # assume that the next FID for this client is sequential, since stdout
19599         # is unfortunately eaten by multiop_bg_pause
19600         local n=$((${fidv[1]} + 1))
19601         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19602         if [ "$FILESET" == "" ]; then
19603                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19604                         error "FID is missing before close"
19605         fi
19606         kill -USR1 $multi_pid
19607         # 1 second delay, so if mtime change we will see it
19608         sleep 1
19609         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19610         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19611 }
19612 run_test 185 "Volatile file support"
19613
19614 function create_check_volatile() {
19615         local idx=$1
19616         local tgt
19617
19618         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19619         local PID=$!
19620         sleep 1
19621         local FID=$(cat /tmp/${tfile}.fid)
19622         [ "$FID" == "" ] && error "can't get FID for volatile"
19623         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19624         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19625         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19626         kill -USR1 $PID
19627         wait
19628         sleep 1
19629         cancel_lru_locks mdc # flush opencache
19630         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19631         return 0
19632 }
19633
19634 test_185a(){
19635         # LU-12516 - volatile creation via .lustre
19636         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19637                 skip "Need MDS version at least 2.3.55"
19638
19639         create_check_volatile 0
19640         [ $MDSCOUNT -lt 2 ] && return 0
19641
19642         # DNE case
19643         create_check_volatile 1
19644
19645         return 0
19646 }
19647 run_test 185a "Volatile file creation in .lustre/fid/"
19648
19649 test_187a() {
19650         remote_mds_nodsh && skip "remote MDS with nodsh"
19651         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19652                 skip "Need MDS version at least 2.3.0"
19653
19654         local dir0=$DIR/$tdir/$testnum
19655         mkdir -p $dir0 || error "creating dir $dir0"
19656
19657         local file=$dir0/file1
19658         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19659         stack_trap "rm -f $file"
19660         local dv1=$($LFS data_version $file)
19661         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19662         local dv2=$($LFS data_version $file)
19663         [[ $dv1 != $dv2 ]] ||
19664                 error "data version did not change on write $dv1 == $dv2"
19665 }
19666 run_test 187a "Test data version change"
19667
19668 test_187b() {
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         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19677         [[ ${DV[0]} != ${DV[1]} ]] ||
19678                 error "data version did not change on write"\
19679                       " ${DV[0]} == ${DV[1]}"
19680
19681         # clean up
19682         rm -f $file1
19683 }
19684 run_test 187b "Test data version change on volatile file"
19685
19686 test_200() {
19687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19688         remote_mgs_nodsh && skip "remote MGS with nodsh"
19689         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19690
19691         local POOL=${POOL:-cea1}
19692         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19693         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19694         # Pool OST targets
19695         local first_ost=0
19696         local last_ost=$(($OSTCOUNT - 1))
19697         local ost_step=2
19698         local ost_list=$(seq $first_ost $ost_step $last_ost)
19699         local ost_range="$first_ost $last_ost $ost_step"
19700         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19701         local file_dir=$POOL_ROOT/file_tst
19702         local subdir=$test_path/subdir
19703         local rc=0
19704
19705         while : ; do
19706                 # former test_200a test_200b
19707                 pool_add $POOL                          || { rc=$? ; break; }
19708                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19709                 # former test_200c test_200d
19710                 mkdir -p $test_path
19711                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19712                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19713                 mkdir -p $subdir
19714                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19715                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19716                                                         || { rc=$? ; break; }
19717                 # former test_200e test_200f
19718                 local files=$((OSTCOUNT*3))
19719                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19720                                                         || { rc=$? ; break; }
19721                 pool_create_files $POOL $file_dir $files "$ost_list" \
19722                                                         || { rc=$? ; break; }
19723                 # former test_200g test_200h
19724                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19725                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19726
19727                 # former test_201a test_201b test_201c
19728                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19729
19730                 local f=$test_path/$tfile
19731                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19732                 pool_remove $POOL $f                    || { rc=$? ; break; }
19733                 break
19734         done
19735
19736         destroy_test_pools
19737
19738         return $rc
19739 }
19740 run_test 200 "OST pools"
19741
19742 # usage: default_attr <count | size | offset>
19743 default_attr() {
19744         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19745 }
19746
19747 # usage: check_default_stripe_attr
19748 check_default_stripe_attr() {
19749         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19750         case $1 in
19751         --stripe-count|-c)
19752                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19753         --stripe-size|-S)
19754                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19755         --stripe-index|-i)
19756                 EXPECTED=-1;;
19757         *)
19758                 error "unknown getstripe attr '$1'"
19759         esac
19760
19761         [ $ACTUAL == $EXPECTED ] ||
19762                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19763 }
19764
19765 test_204a() {
19766         test_mkdir $DIR/$tdir
19767         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19768
19769         check_default_stripe_attr --stripe-count
19770         check_default_stripe_attr --stripe-size
19771         check_default_stripe_attr --stripe-index
19772 }
19773 run_test 204a "Print default stripe attributes"
19774
19775 test_204b() {
19776         test_mkdir $DIR/$tdir
19777         $LFS setstripe --stripe-count 1 $DIR/$tdir
19778
19779         check_default_stripe_attr --stripe-size
19780         check_default_stripe_attr --stripe-index
19781 }
19782 run_test 204b "Print default stripe size and offset"
19783
19784 test_204c() {
19785         test_mkdir $DIR/$tdir
19786         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19787
19788         check_default_stripe_attr --stripe-count
19789         check_default_stripe_attr --stripe-index
19790 }
19791 run_test 204c "Print default stripe count and offset"
19792
19793 test_204d() {
19794         test_mkdir $DIR/$tdir
19795         $LFS setstripe --stripe-index 0 $DIR/$tdir
19796
19797         check_default_stripe_attr --stripe-count
19798         check_default_stripe_attr --stripe-size
19799 }
19800 run_test 204d "Print default stripe count and size"
19801
19802 test_204e() {
19803         test_mkdir $DIR/$tdir
19804         $LFS setstripe -d $DIR/$tdir
19805
19806         # LU-16904 check if root is set as PFL layout
19807         local numcomp=$($LFS getstripe --component-count $MOUNT)
19808
19809         if [[ $numcomp -gt 0 ]]; then
19810                 check_default_stripe_attr --stripe-count
19811         else
19812                 check_default_stripe_attr --stripe-count --raw
19813         fi
19814         check_default_stripe_attr --stripe-size --raw
19815         check_default_stripe_attr --stripe-index --raw
19816 }
19817 run_test 204e "Print raw stripe attributes"
19818
19819 test_204f() {
19820         test_mkdir $DIR/$tdir
19821         $LFS setstripe --stripe-count 1 $DIR/$tdir
19822
19823         check_default_stripe_attr --stripe-size --raw
19824         check_default_stripe_attr --stripe-index --raw
19825 }
19826 run_test 204f "Print raw stripe size and offset"
19827
19828 test_204g() {
19829         test_mkdir $DIR/$tdir
19830         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19831
19832         check_default_stripe_attr --stripe-count --raw
19833         check_default_stripe_attr --stripe-index --raw
19834 }
19835 run_test 204g "Print raw stripe count and offset"
19836
19837 test_204h() {
19838         test_mkdir $DIR/$tdir
19839         $LFS setstripe --stripe-index 0 $DIR/$tdir
19840
19841         check_default_stripe_attr --stripe-count --raw
19842         check_default_stripe_attr --stripe-size --raw
19843 }
19844 run_test 204h "Print raw stripe count and size"
19845
19846 # Figure out which job scheduler is being used, if any,
19847 # or use a fake one
19848 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19849         JOBENV=SLURM_JOB_ID
19850 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19851         JOBENV=LSB_JOBID
19852 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19853         JOBENV=PBS_JOBID
19854 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19855         JOBENV=LOADL_STEP_ID
19856 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19857         JOBENV=JOB_ID
19858 else
19859         $LCTL list_param jobid_name > /dev/null 2>&1
19860         if [ $? -eq 0 ]; then
19861                 JOBENV=nodelocal
19862         else
19863                 JOBENV=FAKE_JOBID
19864         fi
19865 fi
19866 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19867
19868 verify_jobstats() {
19869         local cmd=($1)
19870         shift
19871         local facets="$@"
19872
19873 # we don't really need to clear the stats for this test to work, since each
19874 # command has a unique jobid, but it makes debugging easier if needed.
19875 #       for facet in $facets; do
19876 #               local dev=$(convert_facet2label $facet)
19877 #               # clear old jobstats
19878 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19879 #       done
19880
19881         # use a new JobID for each test, or we might see an old one
19882         [ "$JOBENV" = "FAKE_JOBID" ] &&
19883                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19884
19885         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19886
19887         [ "$JOBENV" = "nodelocal" ] && {
19888                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19889                 $LCTL set_param jobid_name=$FAKE_JOBID
19890                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19891         }
19892
19893         log "Test: ${cmd[*]}"
19894         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19895
19896         if [ $JOBENV = "FAKE_JOBID" ]; then
19897                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19898         else
19899                 ${cmd[*]}
19900         fi
19901
19902         # all files are created on OST0000
19903         for facet in $facets; do
19904                 local stats="*.$(convert_facet2label $facet).job_stats"
19905
19906                 # strip out libtool wrappers for in-tree executables
19907                 if (( $(do_facet $facet lctl get_param $stats |
19908                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19909                         do_facet $facet lctl get_param $stats
19910                         error "No jobstats for $JOBVAL found on $facet::$stats"
19911                 fi
19912         done
19913 }
19914
19915 jobstats_set() {
19916         local new_jobenv=$1
19917
19918         set_persistent_param_and_check client "jobid_var" \
19919                 "$FSNAME.sys.jobid_var" $new_jobenv
19920 }
19921
19922 test_205a() { # Job stats
19923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19924         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19925                 skip "Need MDS version with at least 2.7.1"
19926         remote_mgs_nodsh && skip "remote MGS with nodsh"
19927         remote_mds_nodsh && skip "remote MDS with nodsh"
19928         remote_ost_nodsh && skip "remote OST with nodsh"
19929         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19930                 skip "Server doesn't support jobstats"
19931         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19932
19933         local old_jobenv=$($LCTL get_param -n jobid_var)
19934         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19935         stack_trap "jobstats_set $old_jobenv" EXIT
19936
19937         changelog_register
19938
19939         local old_jobid_name=$($LCTL get_param jobid_name)
19940         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19941
19942         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19943                                 mdt.*.job_cleanup_interval | head -n 1)
19944         local new_interval=5
19945         do_facet $SINGLEMDS \
19946                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19947         stack_trap "do_facet $SINGLEMDS \
19948                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19949         local start=$SECONDS
19950
19951         local cmd
19952         # mkdir
19953         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19954         verify_jobstats "$cmd" "$SINGLEMDS"
19955         # rmdir
19956         cmd="rmdir $DIR/$tdir"
19957         verify_jobstats "$cmd" "$SINGLEMDS"
19958         # mkdir on secondary MDT
19959         if [ $MDSCOUNT -gt 1 ]; then
19960                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19961                 verify_jobstats "$cmd" "mds2"
19962         fi
19963         # mknod
19964         cmd="mknod $DIR/$tfile c 1 3"
19965         verify_jobstats "$cmd" "$SINGLEMDS"
19966         # unlink
19967         cmd="rm -f $DIR/$tfile"
19968         verify_jobstats "$cmd" "$SINGLEMDS"
19969         # create all files on OST0000 so verify_jobstats can find OST stats
19970         # open & close
19971         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19972         verify_jobstats "$cmd" "$SINGLEMDS"
19973         # setattr
19974         cmd="touch $DIR/$tfile"
19975         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19976         # write
19977         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19978         verify_jobstats "$cmd" "ost1"
19979         # read
19980         cancel_lru_locks osc
19981         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19982         verify_jobstats "$cmd" "ost1"
19983         # truncate
19984         cmd="$TRUNCATE $DIR/$tfile 0"
19985         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19986         # rename
19987         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19988         verify_jobstats "$cmd" "$SINGLEMDS"
19989         # jobstats expiry - sleep until old stats should be expired
19990         local left=$((new_interval + 5 - (SECONDS - start)))
19991         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19992                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19993                         "0" $left
19994         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19995         verify_jobstats "$cmd" "$SINGLEMDS"
19996         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19997             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19998
19999         # Ensure that jobid are present in changelog (if supported by MDS)
20000         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20001                 changelog_dump | tail -10
20002                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20003                 [ $jobids -eq 9 ] ||
20004                         error "Wrong changelog jobid count $jobids != 9"
20005
20006                 # LU-5862
20007                 JOBENV="disable"
20008                 jobstats_set $JOBENV
20009                 touch $DIR/$tfile
20010                 changelog_dump | grep $tfile
20011                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20012                 [ $jobids -eq 0 ] ||
20013                         error "Unexpected jobids when jobid_var=$JOBENV"
20014         fi
20015
20016         # test '%j' access to environment variable - if supported
20017         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20018                 JOBENV="JOBCOMPLEX"
20019                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20020
20021                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20022         fi
20023
20024         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20025                 JOBENV="JOBCOMPLEX"
20026                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20027
20028                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20029         fi
20030
20031         # test '%j' access to per-session jobid - if supported
20032         if lctl list_param jobid_this_session > /dev/null 2>&1
20033         then
20034                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20035                 lctl set_param jobid_this_session=$USER
20036
20037                 JOBENV="JOBCOMPLEX"
20038                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20039
20040                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20041         fi
20042 }
20043 run_test 205a "Verify job stats"
20044
20045 # LU-13117, LU-13597, LU-16599
20046 test_205b() {
20047         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20048                 skip "Need MDS version at least 2.13.54.91"
20049
20050         local job_stats="mdt.*.job_stats"
20051         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20052
20053         do_facet mds1 $LCTL set_param $job_stats=clear
20054
20055         # Setting jobid_var to USER might not be supported
20056         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20057         $LCTL set_param jobid_var=USER || true
20058         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20059         $LCTL set_param jobid_name="%j.%e.%u"
20060
20061         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20062         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20063                 { do_facet mds1 $LCTL get_param $job_stats;
20064                   error "Unexpected jobid found"; }
20065         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20066                 { do_facet mds1 $LCTL get_param $job_stats;
20067                   error "wrong job_stats format found"; }
20068
20069         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20070                 echo "MDS does not yet escape jobid" && return 0
20071
20072         mkdir_on_mdt0 $DIR/$tdir
20073         $LCTL set_param jobid_var=TEST205b
20074         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20075         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20076                       awk '/has\\x20sp/ {print $3}')
20077         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20078                   error "jobid not escaped"; }
20079
20080         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20081                 # need to run such a command on mds1:
20082                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20083                 #
20084                 # there might be multiple MDTs on single mds server, so need to
20085                 # specifiy MDT0000. Or the command will fail due to other MDTs
20086                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20087                         error "cannot clear escaped jobid in job_stats";
20088         else
20089                 echo "MDS does not support clearing escaped jobid"
20090         fi
20091 }
20092 run_test 205b "Verify job stats jobid and output format"
20093
20094 # LU-13733
20095 test_205c() {
20096         $LCTL set_param llite.*.stats=0
20097         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20098         $LCTL get_param llite.*.stats
20099         $LCTL get_param llite.*.stats | grep \
20100                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20101                         error "wrong client stats format found"
20102 }
20103 run_test 205c "Verify client stats format"
20104
20105 test_205d() {
20106         local file=$DIR/$tdir/$tfile
20107
20108         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20109                 skip "need lustre >= 2.15.53 for lljobstat"
20110         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20111                 skip "need lustre >= 2.15.53 for lljobstat"
20112         verify_yaml_available || skip_env "YAML verification not installed"
20113
20114         test_mkdir -i 0 $DIR/$tdir
20115         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20116         stack_trap "rm -rf $DIR/$tdir"
20117
20118         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20119                 error "failed to write data to $file"
20120         mv $file $file.2
20121
20122         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20123         echo -n 'verify rename_stats...'
20124         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20125                 verify_yaml || error "rename_stats is not valid YAML"
20126         echo " OK"
20127
20128         echo -n 'verify mdt job_stats...'
20129         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20130                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20131         echo " OK"
20132
20133         echo -n 'verify ost job_stats...'
20134         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20135                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20136         echo " OK"
20137 }
20138 run_test 205d "verify the format of some stats files"
20139
20140 test_205e() {
20141         local ops_comma
20142         local file=$DIR/$tdir/$tfile
20143         local -a cli_params
20144
20145         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20146                 skip "need lustre >= 2.15.53 for lljobstat"
20147         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20148                 skip "need lustre >= 2.15.53 for lljobstat"
20149         verify_yaml_available || skip_env "YAML verification not installed"
20150
20151         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20152         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20153         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20154
20155         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20156         stack_trap "rm -rf $DIR/$tdir"
20157
20158         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20159                 error "failed to create $file on ost1"
20160         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20161                 error "failed to write data to $file"
20162
20163         do_facet mds1 "$LCTL get_param *.*.job_stats"
20164         do_facet ost1 "$LCTL get_param *.*.job_stats"
20165
20166         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20167         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20168                 error "The output of lljobstat is not an valid YAML"
20169
20170         # verify that job dd.0 does exist and has some ops on ost1
20171         # typically this line is like:
20172         # - 205e.dd.0:            {ops: 20, ...}
20173         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20174                     awk '$2=="205e.dd.0:" {print $4}')
20175
20176         (( ${ops_comma%,} >= 10 )) ||
20177                 error "cannot find job 205e.dd.0 with ops >= 10"
20178 }
20179 run_test 205e "verify the output of lljobstat"
20180
20181 test_205f() {
20182         verify_yaml_available || skip_env "YAML verification not installed"
20183
20184         # check both qos_ost_weights and qos_mdt_weights
20185         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20186         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20187                 error "qos_ost_weights is not valid YAML"
20188 }
20189 run_test 205f "verify qos_ost_weights YAML format "
20190
20191 __test_205_jobstats_dump() {
20192         local -a pids
20193         local nbr_instance=$1
20194
20195         while true; do
20196                 if (( ${#pids[@]} >= nbr_instance )); then
20197                         wait ${pids[@]}
20198                         pids=()
20199                 fi
20200
20201                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20202                 pids+=( $! )
20203         done
20204 }
20205
20206 __test_205_cleanup() {
20207         kill $@
20208         # Clear all job entries
20209         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20210 }
20211
20212 test_205g() {
20213         local -a mds1_params
20214         local -a cli_params
20215         local pids
20216         local interval=5
20217
20218         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20219         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20220         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20221
20222         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20223         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20224         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20225
20226         # start jobs loop
20227         export TEST205G_ID=205g
20228         stack_trap "unset TEST205G_ID" EXIT
20229         while true; do
20230                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20231         done & pids="$! "
20232
20233         __test_205_jobstats_dump 4 & pids+="$! "
20234         stack_trap "__test_205_cleanup $pids" EXIT INT
20235
20236         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20237 }
20238 run_test 205g "stress test for job_stats procfile"
20239
20240 test_205h() {
20241         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20242
20243         local dir=$DIR/$tdir
20244         local f=$dir/$tfile
20245         local f2=$dir/$tfile-2
20246         local f3=$dir/$tfile-3
20247         local subdir=$DIR/dir
20248         local val
20249
20250         local mdts=$(comma_list $(mdts_nodes))
20251         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20252         local client_saved=$($LCTL get_param -n jobid_var)
20253
20254         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20255         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20256
20257         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20258                 error "failed to set job_xattr parameter to user.job"
20259         $LCTL set_param jobid_var=procname.uid ||
20260                 error "failed to set jobid_var parameter"
20261
20262         test_mkdir $dir
20263
20264         touch $f
20265         val=$(getfattr -n user.job $f | grep user.job)
20266         [[ $val = user.job=\"touch.0\" ]] ||
20267                 error "expected user.job=\"touch.0\", got '$val'"
20268
20269         mkdir $subdir
20270         val=$(getfattr -n user.job $subdir | grep user.job)
20271         [[ $val = user.job=\"mkdir.0\" ]] ||
20272                 error "expected user.job=\"mkdir.0\", got '$val'"
20273
20274         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20275                 error "failed to set job_xattr parameter to NONE"
20276
20277         touch $f2
20278         val=$(getfattr -d $f2)
20279         [[ -z $val ]] ||
20280                 error "expected no user xattr, got '$val'"
20281
20282         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20283                 error "failed to set job_xattr parameter to trusted.job"
20284
20285         touch $f3
20286         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20287         [[ $val = trusted.job=\"touch.0\" ]] ||
20288                 error "expected trusted.job=\"touch.0\", got '$val'"
20289 }
20290 run_test 205h "check jobid xattr is stored correctly"
20291
20292 test_205i() {
20293         local mdts=$(comma_list $(mdts_nodes))
20294         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20295
20296         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20297
20298         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20299                 error "failed to set mdt.*.job_xattr to user.1234567"
20300
20301         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20302                 error "failed to reject too long job_xattr name"
20303
20304         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20305                 error "failed to reject job_xattr name in bad format"
20306
20307         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20308                 error "failed to reject job_xattr name with invalid character"
20309
20310         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20311                         xargs $LCTL set_param" &&
20312                 error "failed to reject job_xattr name with non-ascii character"
20313
20314         return 0
20315 }
20316 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20317
20318 # LU-1480, LU-1773 and LU-1657
20319 test_206() {
20320         mkdir -p $DIR/$tdir
20321         $LFS setstripe -c -1 $DIR/$tdir
20322 #define OBD_FAIL_LOV_INIT 0x1403
20323         $LCTL set_param fail_loc=0xa0001403
20324         $LCTL set_param fail_val=1
20325         touch $DIR/$tdir/$tfile || true
20326 }
20327 run_test 206 "fail lov_init_raid0() doesn't lbug"
20328
20329 test_207a() {
20330         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20331         local fsz=`stat -c %s $DIR/$tfile`
20332         cancel_lru_locks mdc
20333
20334         # do not return layout in getattr intent
20335 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20336         $LCTL set_param fail_loc=0x170
20337         local sz=`stat -c %s $DIR/$tfile`
20338
20339         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20340
20341         rm -rf $DIR/$tfile
20342 }
20343 run_test 207a "can refresh layout at glimpse"
20344
20345 test_207b() {
20346         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20347         local cksum=`md5sum $DIR/$tfile`
20348         local fsz=`stat -c %s $DIR/$tfile`
20349         cancel_lru_locks mdc
20350         cancel_lru_locks osc
20351
20352         # do not return layout in getattr intent
20353 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20354         $LCTL set_param fail_loc=0x171
20355
20356         # it will refresh layout after the file is opened but before read issues
20357         echo checksum is "$cksum"
20358         echo "$cksum" |md5sum -c --quiet || error "file differs"
20359
20360         rm -rf $DIR/$tfile
20361 }
20362 run_test 207b "can refresh layout at open"
20363
20364 test_208() {
20365         # FIXME: in this test suite, only RD lease is used. This is okay
20366         # for now as only exclusive open is supported. After generic lease
20367         # is done, this test suite should be revised. - Jinshan
20368
20369         remote_mds_nodsh && skip "remote MDS with nodsh"
20370         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20371                 skip "Need MDS version at least 2.4.52"
20372
20373         echo "==== test 1: verify get lease work"
20374         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20375
20376         echo "==== test 2: verify lease can be broken by upcoming open"
20377         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20378         local PID=$!
20379         sleep 2
20380
20381         $MULTIOP $DIR/$tfile oO_RDWR:c
20382         kill -USR1 $PID && wait $PID || error "break lease error"
20383
20384         echo "==== test 3: verify lease can't be granted if an open already exists"
20385         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20386         local PID=$!
20387         sleep 2
20388
20389         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20390         kill -USR1 $PID && wait $PID || error "open file error"
20391
20392         echo "==== test 4: lease can sustain over recovery"
20393         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20394         PID=$!
20395         sleep 2
20396
20397         fail mds1
20398
20399         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20400
20401         echo "==== test 5: lease broken can't be regained by replay"
20402         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20403         PID=$!
20404         sleep 2
20405
20406         # open file to break lease and then recovery
20407         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20408         fail mds1
20409
20410         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20411
20412         rm -f $DIR/$tfile
20413 }
20414 run_test 208 "Exclusive open"
20415
20416 test_209() {
20417         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20418                 skip_env "must have disp_stripe"
20419
20420         touch $DIR/$tfile
20421         sync; sleep 5; sync;
20422
20423         echo 3 > /proc/sys/vm/drop_caches
20424         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20425                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20426         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20427
20428         # open/close 500 times
20429         for i in $(seq 500); do
20430                 cat $DIR/$tfile
20431         done
20432
20433         echo 3 > /proc/sys/vm/drop_caches
20434         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20435                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20436         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20437
20438         echo "before: $req_before, after: $req_after"
20439         [ $((req_after - req_before)) -ge 300 ] &&
20440                 error "open/close requests are not freed"
20441         return 0
20442 }
20443 run_test 209 "read-only open/close requests should be freed promptly"
20444
20445 test_210() {
20446         local pid
20447
20448         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20449         pid=$!
20450         sleep 1
20451
20452         $LFS getstripe $DIR/$tfile
20453         kill -USR1 $pid
20454         wait $pid || error "multiop failed"
20455
20456         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20457         pid=$!
20458         sleep 1
20459
20460         $LFS getstripe $DIR/$tfile
20461         kill -USR1 $pid
20462         wait $pid || error "multiop failed"
20463 }
20464 run_test 210 "lfs getstripe does not break leases"
20465
20466 function test_211() {
20467         local PID
20468         local id
20469         local rc
20470
20471         stack_trap "rm -f $DIR/$tfile" EXIT
20472         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20473                 error "can't create file"
20474         $LFS mirror extend -N $DIR/$tfile ||
20475                 error "can't create a replica"
20476         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20477         $LFS getstripe $DIR/$tfile
20478         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20479         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20480
20481         $MULTIOP $DIR/$tfile OeW_E+eUc &
20482         PID=$!
20483         sleep 0.3
20484
20485         id=$($LFS getstripe $DIR/$tfile |
20486                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20487         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20488                 error "removed last in-sync replica?"
20489
20490         kill -USR1 $PID
20491         wait $PID
20492         (( $? == 0 )) || error "failed split broke the lease"
20493 }
20494 run_test 211 "failed mirror split doesn't break write lease"
20495
20496 test_212() {
20497         size=`date +%s`
20498         size=$((size % 8192 + 1))
20499         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20500         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20501         rm -f $DIR/f212 $DIR/f212.xyz
20502 }
20503 run_test 212 "Sendfile test ============================================"
20504
20505 test_213() {
20506         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20507         cancel_lru_locks osc
20508         lctl set_param fail_loc=0x8000040f
20509         # generate a read lock
20510         cat $DIR/$tfile > /dev/null
20511         # write to the file, it will try to cancel the above read lock.
20512         cat /etc/hosts >> $DIR/$tfile
20513 }
20514 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20515
20516 test_214() { # for bug 20133
20517         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20518         for (( i=0; i < 340; i++ )) ; do
20519                 touch $DIR/$tdir/d214c/a$i
20520         done
20521
20522         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20523         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20524         ls $DIR/d214c || error "ls $DIR/d214c failed"
20525         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20526         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20527 }
20528 run_test 214 "hash-indexed directory test - bug 20133"
20529
20530 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20531 create_lnet_proc_files() {
20532         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20533 }
20534
20535 # counterpart of create_lnet_proc_files
20536 remove_lnet_proc_files() {
20537         rm -f $TMP/lnet_$1.sys
20538 }
20539
20540 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20541 # 3rd arg as regexp for body
20542 check_lnet_proc_stats() {
20543         local l=$(cat "$TMP/lnet_$1" |wc -l)
20544         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20545
20546         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20547 }
20548
20549 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20550 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20551 # optional and can be regexp for 2nd line (lnet.routes case)
20552 check_lnet_proc_entry() {
20553         local blp=2          # blp stands for 'position of 1st line of body'
20554         [ -z "$5" ] || blp=3 # lnet.routes case
20555
20556         local l=$(cat "$TMP/lnet_$1" |wc -l)
20557         # subtracting one from $blp because the body can be empty
20558         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20559
20560         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20561                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20562
20563         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20564                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20565
20566         # bail out if any unexpected line happened
20567         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20568         [ "$?" != 0 ] || error "$2 misformatted"
20569 }
20570
20571 test_215() { # for bugs 18102, 21079, 21517
20572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20573
20574         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20575         local P='[1-9][0-9]*'           # positive numeric
20576         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20577         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20578         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20579         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20580
20581         local L1 # regexp for 1st line
20582         local L2 # regexp for 2nd line (optional)
20583         local BR # regexp for the rest (body)
20584
20585         # lnet.stats should look as 11 space-separated non-negative numerics
20586         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20587         create_lnet_proc_files "stats"
20588         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20589         remove_lnet_proc_files "stats"
20590
20591         # lnet.routes should look like this:
20592         # Routing disabled/enabled
20593         # net hops priority state router
20594         # where net is a string like tcp0, hops > 0, priority >= 0,
20595         # state is up/down,
20596         # router is a string like 192.168.1.1@tcp2
20597         L1="^Routing (disabled|enabled)$"
20598         L2="^net +hops +priority +state +router$"
20599         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20600         create_lnet_proc_files "routes"
20601         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20602         remove_lnet_proc_files "routes"
20603
20604         # lnet.routers should look like this:
20605         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20606         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20607         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20608         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20609         L1="^ref +rtr_ref +alive +router$"
20610         BR="^$P +$P +(up|down) +$NID$"
20611         create_lnet_proc_files "routers"
20612         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20613         remove_lnet_proc_files "routers"
20614
20615         # lnet.peers should look like this:
20616         # nid refs state last max rtr min tx min queue
20617         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20618         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20619         # numeric (0 or >0 or <0), queue >= 0.
20620         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20621         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20622         create_lnet_proc_files "peers"
20623         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20624         remove_lnet_proc_files "peers"
20625
20626         # lnet.buffers  should look like this:
20627         # pages count credits min
20628         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20629         L1="^pages +count +credits +min$"
20630         BR="^ +$N +$N +$I +$I$"
20631         create_lnet_proc_files "buffers"
20632         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20633         remove_lnet_proc_files "buffers"
20634
20635         # lnet.nis should look like this:
20636         # nid status alive refs peer rtr max tx min
20637         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20638         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20639         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20640         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20641         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20642         create_lnet_proc_files "nis"
20643         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20644         remove_lnet_proc_files "nis"
20645
20646         # can we successfully write to lnet.stats?
20647         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20648 }
20649 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20650
20651 test_216() { # bug 20317
20652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20653         remote_ost_nodsh && skip "remote OST with nodsh"
20654
20655         local node
20656         local facets=$(get_facets OST)
20657         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20658
20659         save_lustre_params client "osc.*.contention_seconds" > $p
20660         save_lustre_params $facets \
20661                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20662         save_lustre_params $facets \
20663                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20664         save_lustre_params $facets \
20665                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20666         clear_stats osc.*.osc_stats
20667
20668         # agressive lockless i/o settings
20669         do_nodes $(comma_list $(osts_nodes)) \
20670                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20671                         ldlm.namespaces.filter-*.contended_locks=0 \
20672                         ldlm.namespaces.filter-*.contention_seconds=60"
20673         lctl set_param -n osc.*.contention_seconds=60
20674
20675         $DIRECTIO write $DIR/$tfile 0 10 4096
20676         $CHECKSTAT -s 40960 $DIR/$tfile
20677
20678         # disable lockless i/o
20679         do_nodes $(comma_list $(osts_nodes)) \
20680                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20681                         ldlm.namespaces.filter-*.contended_locks=32 \
20682                         ldlm.namespaces.filter-*.contention_seconds=0"
20683         lctl set_param -n osc.*.contention_seconds=0
20684         clear_stats osc.*.osc_stats
20685
20686         dd if=/dev/zero of=$DIR/$tfile count=0
20687         $CHECKSTAT -s 0 $DIR/$tfile
20688
20689         restore_lustre_params <$p
20690         rm -f $p
20691         rm $DIR/$tfile
20692 }
20693 run_test 216 "check lockless direct write updates file size and kms correctly"
20694
20695 test_217() { # bug 22430
20696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20697
20698         local node
20699
20700         for node in $(nodes_list); do
20701                 local nid=$(host_nids_address $node $NETTYPE)
20702                 local node_ip=$(do_node $node getent ahostsv4 $node |
20703                                 awk '{ print $1; exit; }')
20704
20705                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20706                 # if hostname matches any NID, use hostname for better testing
20707                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20708                         echo "lctl ping node $node@$NETTYPE"
20709                         lctl ping $node@$NETTYPE
20710                 else # otherwise, at least test 'lctl ping' is working
20711                         echo "lctl ping nid $(h2nettype $nid)"
20712                         lctl ping $(h2nettype $nid)
20713                         echo "skipping $node (no hyphen detected)"
20714                 fi
20715         done
20716 }
20717 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20718
20719 test_218() {
20720         # do directio so as not to populate the page cache
20721         log "creating a 10 Mb file"
20722         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20723                 error "multiop failed while creating a file"
20724         log "starting reads"
20725         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20726         log "truncating the file"
20727         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20728                 error "multiop failed while truncating the file"
20729         log "killing dd"
20730         kill %+ || true # reads might have finished
20731         echo "wait until dd is finished"
20732         wait
20733         log "removing the temporary file"
20734         rm -rf $DIR/$tfile || error "tmp file removal failed"
20735 }
20736 run_test 218 "parallel read and truncate should not deadlock"
20737
20738 test_219() {
20739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20740
20741         # write one partial page
20742         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20743         # set no grant so vvp_io_commit_write will do sync write
20744         $LCTL set_param fail_loc=0x411
20745         # write a full page at the end of file
20746         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20747
20748         $LCTL set_param fail_loc=0
20749         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20750         $LCTL set_param fail_loc=0x411
20751         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20752
20753         # LU-4201
20754         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20755         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20756 }
20757 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20758
20759 test_220() { #LU-325
20760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20761         remote_ost_nodsh && skip "remote OST with nodsh"
20762         remote_mds_nodsh && skip "remote MDS with nodsh"
20763         remote_mgs_nodsh && skip "remote MGS with nodsh"
20764
20765         local OSTIDX=0
20766
20767         # create on MDT0000 so the last_id and next_id are correct
20768         mkdir_on_mdt0 $DIR/$tdir
20769         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20770         OST=${OST%_UUID}
20771
20772         # on the mdt's osc
20773         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20774         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20775                         osp.$mdtosc_proc1.prealloc_last_id)
20776         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20777                         osp.$mdtosc_proc1.prealloc_next_id)
20778
20779         $LFS df -i
20780
20781         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20782         #define OBD_FAIL_OST_ENOINO              0x229
20783         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20784         create_pool $FSNAME.$TESTNAME || return 1
20785         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20786
20787         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20788
20789         MDSOBJS=$((last_id - next_id))
20790         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20791
20792         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20793         echo "OST still has $count kbytes free"
20794
20795         echo "create $MDSOBJS files @next_id..."
20796         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20797
20798         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20799                         osp.$mdtosc_proc1.prealloc_last_id)
20800         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20801                         osp.$mdtosc_proc1.prealloc_next_id)
20802
20803         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20804         $LFS df -i
20805
20806         echo "cleanup..."
20807
20808         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20809         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20810
20811         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20812                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20813         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20814                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20815         echo "unlink $MDSOBJS files @$next_id..."
20816         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20817 }
20818 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20819
20820 test_221() {
20821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20822
20823         dd if=`which date` of=$MOUNT/date oflag=sync
20824         chmod +x $MOUNT/date
20825
20826         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20827         $LCTL set_param fail_loc=0x80001401
20828
20829         $MOUNT/date > /dev/null
20830         rm -f $MOUNT/date
20831 }
20832 run_test 221 "make sure fault and truncate race to not cause OOM"
20833
20834 test_222a () {
20835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20836
20837         rm -rf $DIR/$tdir
20838         test_mkdir $DIR/$tdir
20839         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20840         createmany -o $DIR/$tdir/$tfile 10
20841         cancel_lru_locks mdc
20842         cancel_lru_locks osc
20843         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20844         $LCTL set_param fail_loc=0x31a
20845         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20846         $LCTL set_param fail_loc=0
20847         rm -r $DIR/$tdir
20848 }
20849 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20850
20851 test_222b () {
20852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20853
20854         rm -rf $DIR/$tdir
20855         test_mkdir $DIR/$tdir
20856         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20857         createmany -o $DIR/$tdir/$tfile 10
20858         cancel_lru_locks mdc
20859         cancel_lru_locks osc
20860         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20861         $LCTL set_param fail_loc=0x31a
20862         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20863         $LCTL set_param fail_loc=0
20864 }
20865 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20866
20867 test_223 () {
20868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20869
20870         rm -rf $DIR/$tdir
20871         test_mkdir $DIR/$tdir
20872         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20873         createmany -o $DIR/$tdir/$tfile 10
20874         cancel_lru_locks mdc
20875         cancel_lru_locks osc
20876         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20877         $LCTL set_param fail_loc=0x31b
20878         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20879         $LCTL set_param fail_loc=0
20880         rm -r $DIR/$tdir
20881 }
20882 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20883
20884 test_224a() { # LU-1039, MRP-303
20885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20886         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20887         $LCTL set_param fail_loc=0x508
20888         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20889         $LCTL set_param fail_loc=0
20890         df $DIR
20891 }
20892 run_test 224a "Don't panic on bulk IO failure"
20893
20894 test_224bd_sub() { # LU-1039, MRP-303
20895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20896         local timeout=$1
20897
20898         shift
20899         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20900
20901         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20902
20903         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20904         cancel_lru_locks osc
20905         set_checksums 0
20906         stack_trap "set_checksums $ORIG_CSUM" EXIT
20907         local at_max_saved=0
20908
20909         # adaptive timeouts may prevent seeing the issue
20910         if at_is_enabled; then
20911                 at_max_saved=$(at_max_get mds)
20912                 at_max_set 0 mds client
20913                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20914         fi
20915
20916         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20917         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20918         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20919
20920         do_facet ost1 $LCTL set_param fail_loc=0
20921         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20922         df $DIR
20923 }
20924
20925 test_224b() {
20926         test_224bd_sub 3 error "dd failed"
20927 }
20928 run_test 224b "Don't panic on bulk IO failure"
20929
20930 test_224c() { # LU-6441
20931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20932         remote_mds_nodsh && skip "remote MDS with nodsh"
20933
20934         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20935         save_writethrough $p
20936         set_cache writethrough on
20937
20938         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20939         local at_max=$($LCTL get_param -n at_max)
20940         local timeout=$($LCTL get_param -n timeout)
20941         local test_at="at_max"
20942         local param_at="$FSNAME.sys.at_max"
20943         local test_timeout="timeout"
20944         local param_timeout="$FSNAME.sys.timeout"
20945
20946         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20947
20948         set_persistent_param_and_check client "$test_at" "$param_at" 0
20949         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20950
20951         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20952         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20953         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20954         stack_trap "rm -f $DIR/$tfile"
20955         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20956         sync
20957         do_facet ost1 "$LCTL set_param fail_loc=0"
20958
20959         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20960         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20961                 $timeout
20962
20963         $LCTL set_param -n $pages_per_rpc
20964         restore_lustre_params < $p
20965         rm -f $p
20966 }
20967 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20968
20969 test_224d() { # LU-11169
20970         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20971 }
20972 run_test 224d "Don't corrupt data on bulk IO timeout"
20973
20974 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20975 test_225a () {
20976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20977         if [ -z ${MDSSURVEY} ]; then
20978                 skip_env "mds-survey not found"
20979         fi
20980         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20981                 skip "Need MDS version at least 2.2.51"
20982
20983         local mds=$(facet_host $SINGLEMDS)
20984         local target=$(do_nodes $mds 'lctl dl' |
20985                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20986
20987         local cmd1="file_count=1000 thrhi=4"
20988         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20989         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20990         local cmd="$cmd1 $cmd2 $cmd3"
20991
20992         rm -f ${TMP}/mds_survey*
20993         echo + $cmd
20994         eval $cmd || error "mds-survey with zero-stripe failed"
20995         cat ${TMP}/mds_survey*
20996         rm -f ${TMP}/mds_survey*
20997 }
20998 run_test 225a "Metadata survey sanity with zero-stripe"
20999
21000 test_225b () {
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         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21007         remote_mds_nodsh && skip "remote MDS with nodsh"
21008         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21009                 skip_env "Need to mount OST to test"
21010         fi
21011
21012         local mds=$(facet_host $SINGLEMDS)
21013         local target=$(do_nodes $mds 'lctl dl' |
21014                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21015
21016         local cmd1="file_count=1000 thrhi=4"
21017         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21018         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21019         local cmd="$cmd1 $cmd2 $cmd3"
21020
21021         rm -f ${TMP}/mds_survey*
21022         echo + $cmd
21023         eval $cmd || error "mds-survey with stripe_count failed"
21024         cat ${TMP}/mds_survey*
21025         rm -f ${TMP}/mds_survey*
21026 }
21027 run_test 225b "Metadata survey sanity with stripe_count = 1"
21028
21029 mcreate_path2fid () {
21030         local mode=$1
21031         local major=$2
21032         local minor=$3
21033         local name=$4
21034         local desc=$5
21035         local path=$DIR/$tdir/$name
21036         local fid
21037         local rc
21038         local fid_path
21039
21040         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21041                 error "cannot create $desc"
21042
21043         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21044         rc=$?
21045         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21046
21047         fid_path=$($LFS fid2path $MOUNT $fid)
21048         rc=$?
21049         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21050
21051         [ "$path" == "$fid_path" ] ||
21052                 error "fid2path returned $fid_path, expected $path"
21053
21054         echo "pass with $path and $fid"
21055 }
21056
21057 test_226a () {
21058         rm -rf $DIR/$tdir
21059         mkdir -p $DIR/$tdir
21060
21061         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21062         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21063         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21064         mcreate_path2fid 0040666 0 0 dir "directory"
21065         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21066         mcreate_path2fid 0100666 0 0 file "regular file"
21067         mcreate_path2fid 0120666 0 0 link "symbolic link"
21068         mcreate_path2fid 0140666 0 0 sock "socket"
21069 }
21070 run_test 226a "call path2fid and fid2path on files of all type"
21071
21072 test_226b () {
21073         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21074
21075         local MDTIDX=1
21076
21077         rm -rf $DIR/$tdir
21078         mkdir -p $DIR/$tdir
21079         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21080                 error "create remote directory failed"
21081         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21082         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21083                                 "character special file (null)"
21084         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21085                                 "character special file (no device)"
21086         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21087         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21088                                 "block special file (loop)"
21089         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21090         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21091         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21092 }
21093 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21094
21095 test_226c () {
21096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21097         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21098                 skip "Need MDS version at least 2.13.55"
21099
21100         local submnt=/mnt/submnt
21101         local srcfile=/etc/passwd
21102         local dstfile=$submnt/passwd
21103         local path
21104         local fid
21105
21106         rm -rf $DIR/$tdir
21107         rm -rf $submnt
21108         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21109                 error "create remote directory failed"
21110         mkdir -p $submnt || error "create $submnt failed"
21111         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21112                 error "mount $submnt failed"
21113         stack_trap "umount $submnt" EXIT
21114
21115         cp $srcfile $dstfile
21116         fid=$($LFS path2fid $dstfile)
21117         path=$($LFS fid2path $submnt "$fid")
21118         [ "$path" = "$dstfile" ] ||
21119                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21120 }
21121 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21122
21123 test_226d () {
21124         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21125                 skip "Need client at least version 2.15.57"
21126
21127         # Define First test dataset
21128         local testdirs_01=$DIR/$tdir
21129         local testdata_01=$testdirs_01/${tdir}_01
21130         local testresult_01=${tdir}_01
21131         # Define Second test dataset
21132         local testdirs_02=$DIR/$tdir/$tdir
21133         local testdata_02=$testdirs_02/${tdir}_02
21134         local testresult_02=${tdir}_02
21135         # Define third test dataset (top level)
21136         local testdata_03=$DIR/${tdir}_03
21137         local testresult_03=${tdir}_03
21138
21139         # Create first test dataset
21140         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21141         touch $testdata_01 || error "cannot create file $testdata_01"
21142
21143         # Create second test dataset
21144         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21145         touch $testdata_02 || error "cannot create file $testdata_02"
21146
21147         # Create third test dataset
21148         touch $testdata_03 || error "cannot create file $testdata_03"
21149
21150         local fid01=$($LFS getstripe -F "$testdata_01") ||
21151                 error "getstripe failed on $testdata_01"
21152         local fid02=$($LFS getstripe -F "$testdata_02") ||
21153                 error "getstripe failed on $testdata_01"
21154         local fid03=$($LFS getstripe -F "$testdata_03") ||
21155                 error "getstripe failed on $testdata_03"
21156
21157         # Verify only -n option
21158         local out1=$($LFS fid2path -n $DIR $fid01) ||
21159                 error "fid2path failed on $fid01"
21160         local out2=$($LFS fid2path -n $DIR $fid02) ||
21161                 error "fid2path failed on $fid02"
21162         local out3=$($LFS fid2path -n $DIR $fid03) ||
21163                 error "fid2path failed on $fid03"
21164
21165         [[ "$out1" == "$testresult_01" ]] ||
21166                 error "fid2path failed: Expected $testresult_01 got $out1"
21167         [[ "$out2" == "$testresult_02" ]] ||
21168                 error "fid2path failed: Expected $testresult_02 got $out2"
21169         [[ "$out3" == "$testresult_03" ]] ||
21170                 error "fid2path failed: Expected $testresult_03 got $out3"
21171
21172         # Verify with option -fn together
21173         out1=$($LFS fid2path -fn $DIR $fid01) ||
21174                 error "fid2path -fn failed on $fid01"
21175         out2=$($LFS fid2path -fn $DIR $fid02) ||
21176                 error "fid2path -fn failed on $fid02"
21177         out3=$($LFS fid2path -fn $DIR $fid03) ||
21178                 error "fid2path -fn failed on $fid03"
21179
21180         local tmpout=$(echo $out1 | cut -d" " -f2)
21181         [[ "$tmpout" == "$testresult_01" ]] ||
21182                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21183
21184         tmpout=$(echo $out2 | cut -d" " -f2)
21185         [[ "$tmpout" == "$testresult_02" ]] ||
21186                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21187
21188         tmpout=$(echo $out3 | cut -d" " -f2)
21189         [[ "$tmpout" == "$testresult_03" ]] ||
21190                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21191 }
21192 run_test 226d "verify fid2path with -n and -fn option"
21193
21194 test_226e () {
21195         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21196                 skip "Need client at least version 2.15.56"
21197
21198         # Define filename with 'newline' and a space
21199         local testfile="Test"$'\n'"file 01"
21200         # Define link name with multiple 'newline' and a space
21201         local linkfile="Link"$'\n'"file "$'\n'"01"
21202         # Remove prior hard link
21203         rm -f $DIR/"$linkfile"
21204
21205         # Create file
21206         touch $DIR/"$testfile"
21207         # Create link
21208         ln $DIR/"$testfile" $DIR/"$linkfile"
21209
21210         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21211                 error "getstripe failed on $DIR/$testfile"
21212
21213         # Call with -0 option
21214         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21215                 echo "FILE:" | grep -c "FILE:")
21216
21217         # With -0 option the output should be exactly 2 lines.
21218         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21219 }
21220 run_test 226e "Verify path2fid -0 option with newline and space"
21221
21222 # LU-1299 Executing or running ldd on a truncated executable does not
21223 # cause an out-of-memory condition.
21224 test_227() {
21225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21226         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21227
21228         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21229         chmod +x $MOUNT/date
21230
21231         $MOUNT/date > /dev/null
21232         ldd $MOUNT/date > /dev/null
21233         rm -f $MOUNT/date
21234 }
21235 run_test 227 "running truncated executable does not cause OOM"
21236
21237 # LU-1512 try to reuse idle OI blocks
21238 test_228a() {
21239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21240         remote_mds_nodsh && skip "remote MDS with nodsh"
21241         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21242
21243         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21244         local myDIR=$DIR/$tdir
21245
21246         mkdir -p $myDIR
21247         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21248         $LCTL set_param fail_loc=0x80001002
21249         createmany -o $myDIR/t- 10000
21250         $LCTL set_param fail_loc=0
21251         # The guard is current the largest FID holder
21252         touch $myDIR/guard
21253         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21254                     tr -d '[')
21255         local IDX=$(($SEQ % 64))
21256
21257         do_facet $SINGLEMDS sync
21258         # Make sure journal flushed.
21259         sleep 6
21260         local blk1=$(do_facet $SINGLEMDS \
21261                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21262                      grep Blockcount | awk '{print $4}')
21263
21264         # Remove old files, some OI blocks will become idle.
21265         unlinkmany $myDIR/t- 10000
21266         # Create new files, idle OI blocks should be reused.
21267         createmany -o $myDIR/t- 2000
21268         do_facet $SINGLEMDS sync
21269         # Make sure journal flushed.
21270         sleep 6
21271         local blk2=$(do_facet $SINGLEMDS \
21272                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21273                      grep Blockcount | awk '{print $4}')
21274
21275         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21276 }
21277 run_test 228a "try to reuse idle OI blocks"
21278
21279 test_228b() {
21280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21281         remote_mds_nodsh && skip "remote MDS with nodsh"
21282         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21283
21284         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21285         local myDIR=$DIR/$tdir
21286
21287         mkdir -p $myDIR
21288         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21289         $LCTL set_param fail_loc=0x80001002
21290         createmany -o $myDIR/t- 10000
21291         $LCTL set_param fail_loc=0
21292         # The guard is current the largest FID holder
21293         touch $myDIR/guard
21294         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21295                     tr -d '[')
21296         local IDX=$(($SEQ % 64))
21297
21298         do_facet $SINGLEMDS sync
21299         # Make sure journal flushed.
21300         sleep 6
21301         local blk1=$(do_facet $SINGLEMDS \
21302                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21303                      grep Blockcount | awk '{print $4}')
21304
21305         # Remove old files, some OI blocks will become idle.
21306         unlinkmany $myDIR/t- 10000
21307
21308         # stop the MDT
21309         stop $SINGLEMDS || error "Fail to stop MDT."
21310         # remount the MDT
21311         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21312                 error "Fail to start MDT."
21313
21314         client_up || error "Fail to df."
21315         # Create new files, idle OI blocks should be reused.
21316         createmany -o $myDIR/t- 2000
21317         do_facet $SINGLEMDS sync
21318         # Make sure journal flushed.
21319         sleep 6
21320         local blk2=$(do_facet $SINGLEMDS \
21321                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21322                      grep Blockcount | awk '{print $4}')
21323
21324         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21325 }
21326 run_test 228b "idle OI blocks can be reused after MDT restart"
21327
21328 #LU-1881
21329 test_228c() {
21330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21331         remote_mds_nodsh && skip "remote MDS with nodsh"
21332         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21333
21334         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21335         local myDIR=$DIR/$tdir
21336
21337         mkdir -p $myDIR
21338         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21339         $LCTL set_param fail_loc=0x80001002
21340         # 20000 files can guarantee there are index nodes in the OI file
21341         createmany -o $myDIR/t- 20000
21342         $LCTL set_param fail_loc=0
21343         # The guard is current the largest FID holder
21344         touch $myDIR/guard
21345         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21346                     tr -d '[')
21347         local IDX=$(($SEQ % 64))
21348
21349         do_facet $SINGLEMDS sync
21350         # Make sure journal flushed.
21351         sleep 6
21352         local blk1=$(do_facet $SINGLEMDS \
21353                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21354                      grep Blockcount | awk '{print $4}')
21355
21356         # Remove old files, some OI blocks will become idle.
21357         unlinkmany $myDIR/t- 20000
21358         rm -f $myDIR/guard
21359         # The OI file should become empty now
21360
21361         # Create new files, idle OI blocks should be reused.
21362         createmany -o $myDIR/t- 2000
21363         do_facet $SINGLEMDS sync
21364         # Make sure journal flushed.
21365         sleep 6
21366         local blk2=$(do_facet $SINGLEMDS \
21367                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21368                      grep Blockcount | awk '{print $4}')
21369
21370         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21371 }
21372 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21373
21374 test_229() { # LU-2482, LU-3448
21375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21376         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21377         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21378                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21379
21380         rm -f $DIR/$tfile
21381
21382         # Create a file with a released layout and stripe count 2.
21383         $MULTIOP $DIR/$tfile H2c ||
21384                 error "failed to create file with released layout"
21385
21386         $LFS getstripe -v $DIR/$tfile
21387
21388         local pattern=$($LFS getstripe -L $DIR/$tfile)
21389         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21390
21391         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21392                 error "getstripe"
21393         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21394         stat $DIR/$tfile || error "failed to stat released file"
21395
21396         chown $RUNAS_ID $DIR/$tfile ||
21397                 error "chown $RUNAS_ID $DIR/$tfile failed"
21398
21399         chgrp $RUNAS_ID $DIR/$tfile ||
21400                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21401
21402         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21403         rm $DIR/$tfile || error "failed to remove released file"
21404 }
21405 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21406
21407 test_230a() {
21408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21409         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21410         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21411                 skip "Need MDS version at least 2.11.52"
21412
21413         local MDTIDX=1
21414
21415         test_mkdir $DIR/$tdir
21416         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21417         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21418         [ $mdt_idx -ne 0 ] &&
21419                 error "create local directory on wrong MDT $mdt_idx"
21420
21421         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21422                         error "create remote directory failed"
21423         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21424         [ $mdt_idx -ne $MDTIDX ] &&
21425                 error "create remote directory on wrong MDT $mdt_idx"
21426
21427         createmany -o $DIR/$tdir/test_230/t- 10 ||
21428                 error "create files on remote directory failed"
21429         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21430         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21431         rm -r $DIR/$tdir || error "unlink remote directory failed"
21432 }
21433 run_test 230a "Create remote directory and files under the remote directory"
21434
21435 test_230b() {
21436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21438         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21439                 skip "Need MDS version at least 2.11.52"
21440
21441         local MDTIDX=1
21442         local mdt_index
21443         local i
21444         local file
21445         local pid
21446         local stripe_count
21447         local migrate_dir=$DIR/$tdir/migrate_dir
21448         local other_dir=$DIR/$tdir/other_dir
21449
21450         test_mkdir $DIR/$tdir
21451         test_mkdir -i0 -c1 $migrate_dir
21452         test_mkdir -i0 -c1 $other_dir
21453         for ((i=0; i<10; i++)); do
21454                 mkdir -p $migrate_dir/dir_${i}
21455                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21456                         error "create files under remote dir failed $i"
21457         done
21458
21459         cp /etc/passwd $migrate_dir/$tfile
21460         cp /etc/passwd $other_dir/$tfile
21461         chattr +SAD $migrate_dir
21462         chattr +SAD $migrate_dir/$tfile
21463
21464         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21465         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21466         local old_dir_mode=$(stat -c%f $migrate_dir)
21467         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21468
21469         mkdir -p $migrate_dir/dir_default_stripe2
21470         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21471         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21472
21473         mkdir -p $other_dir
21474         ln $migrate_dir/$tfile $other_dir/luna
21475         ln $migrate_dir/$tfile $migrate_dir/sofia
21476         ln $other_dir/$tfile $migrate_dir/david
21477         ln -s $migrate_dir/$tfile $other_dir/zachary
21478         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21479         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21480
21481         local len
21482         local lnktgt
21483
21484         # inline symlink
21485         for len in 58 59 60; do
21486                 lnktgt=$(str_repeat 'l' $len)
21487                 touch $migrate_dir/$lnktgt
21488                 ln -s $lnktgt $migrate_dir/${len}char_ln
21489         done
21490
21491         # PATH_MAX
21492         for len in 4094 4095; do
21493                 lnktgt=$(str_repeat 'l' $len)
21494                 ln -s $lnktgt $migrate_dir/${len}char_ln
21495         done
21496
21497         # NAME_MAX
21498         for len in 254 255; do
21499                 touch $migrate_dir/$(str_repeat 'l' $len)
21500         done
21501
21502         $LFS migrate -m $MDTIDX $migrate_dir ||
21503                 error "fails on migrating remote dir to MDT1"
21504
21505         echo "migratate to MDT1, then checking.."
21506         for ((i = 0; i < 10; i++)); do
21507                 for file in $(find $migrate_dir/dir_${i}); do
21508                         mdt_index=$($LFS getstripe -m $file)
21509                         # broken symlink getstripe will fail
21510                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21511                                 error "$file is not on MDT${MDTIDX}"
21512                 done
21513         done
21514
21515         # the multiple link file should still in MDT0
21516         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21517         [ $mdt_index == 0 ] ||
21518                 error "$file is not on MDT${MDTIDX}"
21519
21520         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21521         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21522                 error " expect $old_dir_flag get $new_dir_flag"
21523
21524         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21525         [ "$old_file_flag" = "$new_file_flag" ] ||
21526                 error " expect $old_file_flag get $new_file_flag"
21527
21528         local new_dir_mode=$(stat -c%f $migrate_dir)
21529         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21530                 error "expect mode $old_dir_mode get $new_dir_mode"
21531
21532         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21533         [ "$old_file_mode" = "$new_file_mode" ] ||
21534                 error "expect mode $old_file_mode get $new_file_mode"
21535
21536         diff /etc/passwd $migrate_dir/$tfile ||
21537                 error "$tfile different after migration"
21538
21539         diff /etc/passwd $other_dir/luna ||
21540                 error "luna different after migration"
21541
21542         diff /etc/passwd $migrate_dir/sofia ||
21543                 error "sofia different after migration"
21544
21545         diff /etc/passwd $migrate_dir/david ||
21546                 error "david different after migration"
21547
21548         diff /etc/passwd $other_dir/zachary ||
21549                 error "zachary different after migration"
21550
21551         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21552                 error "${tfile}_ln different after migration"
21553
21554         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21555                 error "${tfile}_ln_other different after migration"
21556
21557         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21558         [ $stripe_count = 2 ] ||
21559                 error "dir strpe_count $d != 2 after migration."
21560
21561         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21562         [ $stripe_count = 2 ] ||
21563                 error "file strpe_count $d != 2 after migration."
21564
21565         #migrate back to MDT0
21566         MDTIDX=0
21567
21568         $LFS migrate -m $MDTIDX $migrate_dir ||
21569                 error "fails on migrating remote dir to MDT0"
21570
21571         echo "migrate back to MDT0, checking.."
21572         for file in $(find $migrate_dir); do
21573                 mdt_index=$($LFS getstripe -m $file)
21574                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21575                         error "$file is not on MDT${MDTIDX}"
21576         done
21577
21578         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21579         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21580                 error " expect $old_dir_flag get $new_dir_flag"
21581
21582         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21583         [ "$old_file_flag" = "$new_file_flag" ] ||
21584                 error " expect $old_file_flag get $new_file_flag"
21585
21586         local new_dir_mode=$(stat -c%f $migrate_dir)
21587         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21588                 error "expect mode $old_dir_mode get $new_dir_mode"
21589
21590         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21591         [ "$old_file_mode" = "$new_file_mode" ] ||
21592                 error "expect mode $old_file_mode get $new_file_mode"
21593
21594         diff /etc/passwd ${migrate_dir}/$tfile ||
21595                 error "$tfile different after migration"
21596
21597         diff /etc/passwd ${other_dir}/luna ||
21598                 error "luna different after migration"
21599
21600         diff /etc/passwd ${migrate_dir}/sofia ||
21601                 error "sofia different after migration"
21602
21603         diff /etc/passwd ${other_dir}/zachary ||
21604                 error "zachary different after migration"
21605
21606         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21607                 error "${tfile}_ln different after migration"
21608
21609         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21610                 error "${tfile}_ln_other different after migration"
21611
21612         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21613         [ $stripe_count = 2 ] ||
21614                 error "dir strpe_count $d != 2 after migration."
21615
21616         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21617         [ $stripe_count = 2 ] ||
21618                 error "file strpe_count $d != 2 after migration."
21619
21620         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21621 }
21622 run_test 230b "migrate directory"
21623
21624 test_230c() {
21625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21626         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21627         remote_mds_nodsh && skip "remote MDS with nodsh"
21628         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21629                 skip "Need MDS version at least 2.11.52"
21630
21631         local MDTIDX=1
21632         local total=3
21633         local mdt_index
21634         local file
21635         local migrate_dir=$DIR/$tdir/migrate_dir
21636
21637         #If migrating directory fails in the middle, all entries of
21638         #the directory is still accessiable.
21639         test_mkdir $DIR/$tdir
21640         test_mkdir -i0 -c1 $migrate_dir
21641         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21642         stat $migrate_dir
21643         createmany -o $migrate_dir/f $total ||
21644                 error "create files under ${migrate_dir} failed"
21645
21646         # fail after migrating top dir, and this will fail only once, so the
21647         # first sub file migration will fail (currently f3), others succeed.
21648         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21649         do_facet mds1 lctl set_param fail_loc=0x1801
21650         local t=$(ls $migrate_dir | wc -l)
21651         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21652                 error "migrate should fail"
21653         local u=$(ls $migrate_dir | wc -l)
21654         [ "$u" == "$t" ] || error "$u != $t during migration"
21655
21656         # add new dir/file should succeed
21657         mkdir $migrate_dir/dir ||
21658                 error "mkdir failed under migrating directory"
21659         touch $migrate_dir/file ||
21660                 error "create file failed under migrating directory"
21661
21662         # add file with existing name should fail
21663         for file in $migrate_dir/f*; do
21664                 stat $file > /dev/null || error "stat $file failed"
21665                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21666                         error "open(O_CREAT|O_EXCL) $file should fail"
21667                 $MULTIOP $file m && error "create $file should fail"
21668                 touch $DIR/$tdir/remote_dir/$tfile ||
21669                         error "touch $tfile failed"
21670                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21671                         error "link $file should fail"
21672                 mdt_index=$($LFS getstripe -m $file)
21673                 if [ $mdt_index == 0 ]; then
21674                         # file failed to migrate is not allowed to rename to
21675                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21676                                 error "rename to $file should fail"
21677                 else
21678                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21679                                 error "rename to $file failed"
21680                 fi
21681                 echo hello >> $file || error "write $file failed"
21682         done
21683
21684         # resume migration with different options should fail
21685         $LFS migrate -m 0 $migrate_dir &&
21686                 error "migrate -m 0 $migrate_dir should fail"
21687
21688         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21689                 error "migrate -c 2 $migrate_dir should fail"
21690
21691         # resume migration should succeed
21692         $LFS migrate -m $MDTIDX $migrate_dir ||
21693                 error "migrate $migrate_dir failed"
21694
21695         echo "Finish migration, then checking.."
21696         for file in $(find $migrate_dir); do
21697                 mdt_index=$($LFS getstripe -m $file)
21698                 [ $mdt_index == $MDTIDX ] ||
21699                         error "$file is not on MDT${MDTIDX}"
21700         done
21701
21702         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21703 }
21704 run_test 230c "check directory accessiblity if migration failed"
21705
21706 test_230d() {
21707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21709         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21710                 skip "Need MDS version at least 2.11.52"
21711         # LU-11235
21712         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21713
21714         local migrate_dir=$DIR/$tdir/migrate_dir
21715         local old_index
21716         local new_index
21717         local old_count
21718         local new_count
21719         local new_hash
21720         local mdt_index
21721         local i
21722         local j
21723
21724         old_index=$((RANDOM % MDSCOUNT))
21725         old_count=$((MDSCOUNT - old_index))
21726         new_index=$((RANDOM % MDSCOUNT))
21727         new_count=$((MDSCOUNT - new_index))
21728         new_hash=1 # for all_char
21729
21730         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21731         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21732
21733         test_mkdir $DIR/$tdir
21734         test_mkdir -i $old_index -c $old_count $migrate_dir
21735
21736         for ((i=0; i<100; i++)); do
21737                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21738                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21739                         error "create files under remote dir failed $i"
21740         done
21741
21742         echo -n "Migrate from MDT$old_index "
21743         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21744         echo -n "to MDT$new_index"
21745         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21746         echo
21747
21748         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21749         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21750                 error "migrate remote dir error"
21751
21752         echo "Finish migration, then checking.."
21753         for file in $(find $migrate_dir -maxdepth 1); do
21754                 mdt_index=$($LFS getstripe -m $file)
21755                 if [ $mdt_index -lt $new_index ] ||
21756                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21757                         error "$file is on MDT$mdt_index"
21758                 fi
21759         done
21760
21761         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21762 }
21763 run_test 230d "check migrate big directory"
21764
21765 test_230e() {
21766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21767         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21768         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21769                 skip "Need MDS version at least 2.11.52"
21770
21771         local i
21772         local j
21773         local a_fid
21774         local b_fid
21775
21776         mkdir_on_mdt0 $DIR/$tdir
21777         mkdir $DIR/$tdir/migrate_dir
21778         mkdir $DIR/$tdir/other_dir
21779         touch $DIR/$tdir/migrate_dir/a
21780         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21781         ls $DIR/$tdir/other_dir
21782
21783         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21784                 error "migrate dir fails"
21785
21786         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21787         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21788
21789         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21790         [ $mdt_index == 0 ] || error "a is not on MDT0"
21791
21792         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21793                 error "migrate dir fails"
21794
21795         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21796         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21797
21798         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21799         [ $mdt_index == 1 ] || error "a is not on MDT1"
21800
21801         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21802         [ $mdt_index == 1 ] || error "b is not on MDT1"
21803
21804         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21805         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21806
21807         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21808
21809         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21810 }
21811 run_test 230e "migrate mulitple local link files"
21812
21813 test_230f() {
21814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21816         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21817                 skip "Need MDS version at least 2.11.52"
21818
21819         local a_fid
21820         local ln_fid
21821
21822         mkdir -p $DIR/$tdir
21823         mkdir $DIR/$tdir/migrate_dir
21824         $LFS mkdir -i1 $DIR/$tdir/other_dir
21825         touch $DIR/$tdir/migrate_dir/a
21826         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21827         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21828         ls $DIR/$tdir/other_dir
21829
21830         # a should be migrated to MDT1, since no other links on MDT0
21831         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21832                 error "#1 migrate dir fails"
21833         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21834         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21835         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21836         [ $mdt_index == 1 ] || error "a is not on MDT1"
21837
21838         # a should stay on MDT1, because it is a mulitple link file
21839         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21840                 error "#2 migrate dir fails"
21841         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21842         [ $mdt_index == 1 ] || error "a is not on MDT1"
21843
21844         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21845                 error "#3 migrate dir fails"
21846
21847         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21848         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21849         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21850
21851         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21852         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21853
21854         # a should be migrated to MDT0, since no other links on MDT1
21855         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21856                 error "#4 migrate dir fails"
21857         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21858         [ $mdt_index == 0 ] || error "a is not on MDT0"
21859
21860         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21861 }
21862 run_test 230f "migrate mulitple remote link files"
21863
21864 test_230g() {
21865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21866         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21867         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21868                 skip "Need MDS version at least 2.11.52"
21869
21870         mkdir -p $DIR/$tdir/migrate_dir
21871
21872         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21873                 error "migrating dir to non-exist MDT succeeds"
21874         true
21875 }
21876 run_test 230g "migrate dir to non-exist MDT"
21877
21878 test_230h() {
21879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21880         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21881         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21882                 skip "Need MDS version at least 2.11.52"
21883
21884         local mdt_index
21885
21886         mkdir -p $DIR/$tdir/migrate_dir
21887
21888         $LFS migrate -m1 $DIR &&
21889                 error "migrating mountpoint1 should fail"
21890
21891         $LFS migrate -m1 $DIR/$tdir/.. &&
21892                 error "migrating mountpoint2 should fail"
21893
21894         # same as mv
21895         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21896                 error "migrating $tdir/migrate_dir/.. should fail"
21897
21898         true
21899 }
21900 run_test 230h "migrate .. and root"
21901
21902 test_230i() {
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         mkdir -p $DIR/$tdir/migrate_dir
21909
21910         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21911                 error "migration fails with a tailing slash"
21912
21913         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21914                 error "migration fails with two tailing slashes"
21915 }
21916 run_test 230i "lfs migrate -m tolerates trailing slashes"
21917
21918 test_230j() {
21919         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21920         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21921                 skip "Need MDS version at least 2.11.52"
21922
21923         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21924         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21925                 error "create $tfile failed"
21926         cat /etc/passwd > $DIR/$tdir/$tfile
21927
21928         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21929
21930         cmp /etc/passwd $DIR/$tdir/$tfile ||
21931                 error "DoM file mismatch after migration"
21932 }
21933 run_test 230j "DoM file data not changed after dir migration"
21934
21935 test_230k() {
21936         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21937         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21938                 skip "Need MDS version at least 2.11.56"
21939
21940         local total=20
21941         local files_on_starting_mdt=0
21942
21943         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21944         $LFS getdirstripe $DIR/$tdir
21945         for i in $(seq $total); do
21946                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21947                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21948                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21949         done
21950
21951         echo "$files_on_starting_mdt files on MDT0"
21952
21953         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21954         $LFS getdirstripe $DIR/$tdir
21955
21956         files_on_starting_mdt=0
21957         for i in $(seq $total); do
21958                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21959                         error "file $tfile.$i mismatch after migration"
21960                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21961                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21962         done
21963
21964         echo "$files_on_starting_mdt files on MDT1 after migration"
21965         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21966
21967         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21968         $LFS getdirstripe $DIR/$tdir
21969
21970         files_on_starting_mdt=0
21971         for i in $(seq $total); do
21972                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21973                         error "file $tfile.$i mismatch after 2nd migration"
21974                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21975                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21976         done
21977
21978         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21979         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21980
21981         true
21982 }
21983 run_test 230k "file data not changed after dir migration"
21984
21985 test_230l() {
21986         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21987         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21988                 skip "Need MDS version at least 2.11.56"
21989
21990         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21991         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21992                 error "create files under remote dir failed $i"
21993         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21994 }
21995 run_test 230l "readdir between MDTs won't crash"
21996
21997 test_230m() {
21998         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21999         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22000                 skip "Need MDS version at least 2.11.56"
22001
22002         local MDTIDX=1
22003         local mig_dir=$DIR/$tdir/migrate_dir
22004         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22005         local shortstr="b"
22006         local val
22007
22008         echo "Creating files and dirs with xattrs"
22009         test_mkdir $DIR/$tdir
22010         test_mkdir -i0 -c1 $mig_dir
22011         mkdir $mig_dir/dir
22012         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22013                 error "cannot set xattr attr1 on dir"
22014         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22015                 error "cannot set xattr attr2 on dir"
22016         touch $mig_dir/dir/f0
22017         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22018                 error "cannot set xattr attr1 on file"
22019         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22020                 error "cannot set xattr attr2 on file"
22021         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22022         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22023         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22024         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22025         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22026         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22027         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22028         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22029         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22030
22031         echo "Migrating to MDT1"
22032         $LFS migrate -m $MDTIDX $mig_dir ||
22033                 error "fails on migrating dir to MDT1"
22034
22035         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22036         echo "Checking xattrs"
22037         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22038         [ "$val" = $longstr ] ||
22039                 error "expecting xattr1 $longstr on dir, found $val"
22040         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22041         [ "$val" = $shortstr ] ||
22042                 error "expecting xattr2 $shortstr on dir, found $val"
22043         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22044         [ "$val" = $longstr ] ||
22045                 error "expecting xattr1 $longstr on file, found $val"
22046         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22047         [ "$val" = $shortstr ] ||
22048                 error "expecting xattr2 $shortstr on file, found $val"
22049 }
22050 run_test 230m "xattrs not changed after dir migration"
22051
22052 test_230n() {
22053         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22054         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22055                 skip "Need MDS version at least 2.13.53"
22056
22057         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22058         cat /etc/hosts > $DIR/$tdir/$tfile
22059         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22060         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22061
22062         cmp /etc/hosts $DIR/$tdir/$tfile ||
22063                 error "File data mismatch after migration"
22064 }
22065 run_test 230n "Dir migration with mirrored file"
22066
22067 test_230o() {
22068         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22069         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22070                 skip "Need MDS version at least 2.13.52"
22071
22072         local mdts=$(comma_list $(mdts_nodes))
22073         local timeout=100
22074         local restripe_status
22075         local delta
22076         local i
22077
22078         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22079
22080         # in case "crush" hash type is not set
22081         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22082
22083         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22084                            mdt.*MDT0000.enable_dir_restripe)
22085         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22086         stack_trap "do_nodes $mdts $LCTL set_param \
22087                     mdt.*.enable_dir_restripe=$restripe_status"
22088
22089         mkdir $DIR/$tdir
22090         createmany -m $DIR/$tdir/f 100 ||
22091                 error "create files under remote dir failed $i"
22092         createmany -d $DIR/$tdir/d 100 ||
22093                 error "create dirs under remote dir failed $i"
22094
22095         for i in $(seq 2 $MDSCOUNT); do
22096                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22097                 $LFS setdirstripe -c $i $DIR/$tdir ||
22098                         error "split -c $i $tdir failed"
22099                 wait_update $HOSTNAME \
22100                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22101                         error "dir split not finished"
22102                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22103                         awk '/migrate/ {sum += $2} END { print sum }')
22104                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22105                 # delta is around total_files/stripe_count
22106                 (( $delta < 200 / (i - 1) + 4 )) ||
22107                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22108         done
22109 }
22110 run_test 230o "dir split"
22111
22112 test_230p() {
22113         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22114         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22115                 skip "Need MDS version at least 2.13.52"
22116
22117         local mdts=$(comma_list $(mdts_nodes))
22118         local timeout=100
22119         local restripe_status
22120         local delta
22121         local c
22122
22123         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22124
22125         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22126
22127         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22128                            mdt.*MDT0000.enable_dir_restripe)
22129         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22130         stack_trap "do_nodes $mdts $LCTL set_param \
22131                     mdt.*.enable_dir_restripe=$restripe_status"
22132
22133         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22134         createmany -m $DIR/$tdir/f 100 ||
22135                 error "create files under remote dir failed"
22136         createmany -d $DIR/$tdir/d 100 ||
22137                 error "create dirs under remote dir failed"
22138
22139         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22140                 local mdt_hash="crush"
22141
22142                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22143                 $LFS setdirstripe -c $c $DIR/$tdir ||
22144                         error "split -c $c $tdir failed"
22145                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22146                         mdt_hash="$mdt_hash,fixed"
22147                 elif [ $c -eq 1 ]; then
22148                         mdt_hash="none"
22149                 fi
22150                 wait_update $HOSTNAME \
22151                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22152                         error "dir merge not finished"
22153                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22154                         awk '/migrate/ {sum += $2} END { print sum }')
22155                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22156                 # delta is around total_files/stripe_count
22157                 (( delta < 200 / c + 4 )) ||
22158                         error "$delta files migrated >= $((200 / c + 4))"
22159         done
22160 }
22161 run_test 230p "dir merge"
22162
22163 test_230q() {
22164         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22165         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22166                 skip "Need MDS version at least 2.13.52"
22167
22168         local mdts=$(comma_list $(mdts_nodes))
22169         local saved_threshold=$(do_facet mds1 \
22170                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22171         local saved_delta=$(do_facet mds1 \
22172                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22173         local threshold=100
22174         local delta=2
22175         local total=0
22176         local stripe_count=0
22177         local stripe_index
22178         local nr_files
22179         local create
22180
22181         # test with fewer files on ZFS
22182         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22183
22184         stack_trap "do_nodes $mdts $LCTL set_param \
22185                     mdt.*.dir_split_count=$saved_threshold"
22186         stack_trap "do_nodes $mdts $LCTL set_param \
22187                     mdt.*.dir_split_delta=$saved_delta"
22188         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22189         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22190         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22191         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22192         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22193         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22194
22195         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22196         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22197
22198         create=$((threshold * 3 / 2))
22199         while [ $stripe_count -lt $MDSCOUNT ]; do
22200                 createmany -m $DIR/$tdir/f $total $create ||
22201                         error "create sub files failed"
22202                 stat $DIR/$tdir > /dev/null
22203                 total=$((total + create))
22204                 stripe_count=$((stripe_count + delta))
22205                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22206
22207                 wait_update $HOSTNAME \
22208                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22209                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22210
22211                 wait_update $HOSTNAME \
22212                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22213                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22214
22215                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22216                 echo "$nr_files/$total files on MDT$stripe_index after split"
22217                 # allow 10% margin of imbalance with crush hash
22218                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22219                         error "$nr_files files on MDT$stripe_index after split"
22220
22221                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22222                 [ $nr_files -eq $total ] ||
22223                         error "total sub files $nr_files != $total"
22224         done
22225
22226         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22227
22228         echo "fixed layout directory won't auto split"
22229         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22230         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22231                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22232         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22233                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22234 }
22235 run_test 230q "dir auto split"
22236
22237 test_230r() {
22238         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22239         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22240         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22241                 skip "Need MDS version at least 2.13.54"
22242
22243         # maximum amount of local locks:
22244         # parent striped dir - 2 locks
22245         # new stripe in parent to migrate to - 1 lock
22246         # source and target - 2 locks
22247         # Total 5 locks for regular file
22248         mkdir -p $DIR/$tdir
22249         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22250         touch $DIR/$tdir/dir1/eee
22251
22252         # create 4 hardlink for 4 more locks
22253         # Total: 9 locks > RS_MAX_LOCKS (8)
22254         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22255         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22256         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22257         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22258         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22259         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22260         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22261         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22262
22263         cancel_lru_locks mdc
22264
22265         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22266                 error "migrate dir fails"
22267
22268         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22269 }
22270 run_test 230r "migrate with too many local locks"
22271
22272 test_230s() {
22273         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22274                 skip "Need MDS version at least 2.14.52"
22275
22276         local mdts=$(comma_list $(mdts_nodes))
22277         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22278                                 mdt.*MDT0000.enable_dir_restripe)
22279
22280         stack_trap "do_nodes $mdts $LCTL set_param \
22281                     mdt.*.enable_dir_restripe=$restripe_status"
22282
22283         local st
22284         for st in 0 1; do
22285                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22286                 test_mkdir $DIR/$tdir
22287                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22288                         error "$LFS mkdir should return EEXIST if target exists"
22289                 rmdir $DIR/$tdir
22290         done
22291 }
22292 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22293
22294 test_230t()
22295 {
22296         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22297         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22298                 skip "Need MDS version at least 2.14.50"
22299
22300         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22301         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22302         $LFS project -p 1 -s $DIR/$tdir ||
22303                 error "set $tdir project id failed"
22304         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22305                 error "set subdir project id failed"
22306         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22307 }
22308 run_test 230t "migrate directory with project ID set"
22309
22310 test_230u()
22311 {
22312         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22313         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22314                 skip "Need MDS version at least 2.14.53"
22315
22316         local count
22317
22318         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22319         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22320         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22321         for i in $(seq 0 $((MDSCOUNT - 1))); do
22322                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22323                 echo "$count dirs migrated to MDT$i"
22324         done
22325         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22326         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22327 }
22328 run_test 230u "migrate directory by QOS"
22329
22330 test_230v()
22331 {
22332         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22333         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22334                 skip "Need MDS version at least 2.14.53"
22335
22336         local count
22337
22338         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22339         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22340         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22341         for i in $(seq 0 $((MDSCOUNT - 1))); do
22342                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22343                 echo "$count subdirs migrated to MDT$i"
22344                 (( i == 3 )) && (( count > 0 )) &&
22345                         error "subdir shouldn't be migrated to MDT3"
22346         done
22347         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22348         (( count == 3 )) || error "dirs migrated to $count MDTs"
22349 }
22350 run_test 230v "subdir migrated to the MDT where its parent is located"
22351
22352 test_230w() {
22353         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22354         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22355                 skip "Need MDS version at least 2.15.0"
22356
22357         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22358         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22359         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22360
22361         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22362                 error "migrate failed"
22363
22364         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22365                 error "$tdir stripe count mismatch"
22366
22367         for i in $(seq 0 9); do
22368                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22369                         error "d$i is striped"
22370         done
22371 }
22372 run_test 230w "non-recursive mode dir migration"
22373
22374 test_230x() {
22375         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22376         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22377                 skip "Need MDS version at least 2.15.0"
22378
22379         mkdir -p $DIR/$tdir || error "mkdir failed"
22380         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22381
22382         local mdt_name=$(mdtname_from_index 0)
22383         local low=$(do_facet mds2 $LCTL get_param -n \
22384                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22385         local high=$(do_facet mds2 $LCTL get_param -n \
22386                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22387         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22388         local maxage=$(do_facet mds2 $LCTL get_param -n \
22389                 osp.*$mdt_name-osp-MDT0001.maxage)
22390
22391         stack_trap "do_facet mds2 $LCTL set_param -n \
22392                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22393                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22394         stack_trap "do_facet mds2 $LCTL set_param -n \
22395                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22396
22397         do_facet mds2 $LCTL set_param -n \
22398                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22399         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22400         sleep 4
22401         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22402                 error "migrate $tdir should fail"
22403
22404         do_facet mds2 $LCTL set_param -n \
22405                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22406         do_facet mds2 $LCTL set_param -n \
22407                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22408         sleep 4
22409         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22410                 error "migrate failed"
22411         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22412                 error "$tdir stripe count mismatch"
22413 }
22414 run_test 230x "dir migration check space"
22415
22416 test_230y() {
22417         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22418         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22419                 skip "Need MDS version at least 2.15.55.45"
22420
22421         local pid
22422
22423         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22424         $LFS getdirstripe $DIR/$tdir
22425         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22426         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22427         pid=$!
22428         sleep 1
22429
22430         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22431         do_facet mds2 lctl set_param fail_loc=0x1802
22432
22433         wait $pid
22434         do_facet mds2 lctl set_param fail_loc=0
22435         $LFS getdirstripe $DIR/$tdir
22436         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22437         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22438 }
22439 run_test 230y "unlink dir with bad hash type"
22440
22441 test_230z() {
22442         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22443         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22444                 skip "Need MDS version at least 2.15.55.45"
22445
22446         local pid
22447
22448         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22449         $LFS getdirstripe $DIR/$tdir
22450         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22451         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22452         pid=$!
22453         sleep 1
22454
22455         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22456         do_facet mds2 lctl set_param fail_loc=0x1802
22457
22458         wait $pid
22459         do_facet mds2 lctl set_param fail_loc=0
22460         $LFS getdirstripe $DIR/$tdir
22461
22462         # resume migration
22463         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22464                 error "resume migration failed"
22465         $LFS getdirstripe $DIR/$tdir
22466         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22467                 error "migration is not finished"
22468 }
22469 run_test 230z "resume dir migration with bad hash type"
22470
22471 test_231a()
22472 {
22473         # For simplicity this test assumes that max_pages_per_rpc
22474         # is the same across all OSCs
22475         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22476         local bulk_size=$((max_pages * PAGE_SIZE))
22477         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22478                                        head -n 1)
22479
22480         mkdir -p $DIR/$tdir
22481         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22482                 error "failed to set stripe with -S ${brw_size}M option"
22483         stack_trap "rm -rf $DIR/$tdir"
22484
22485         # clear the OSC stats
22486         $LCTL set_param osc.*.stats=0 &>/dev/null
22487         stop_writeback
22488
22489         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22491                 oflag=direct &>/dev/null || error "dd failed"
22492
22493         sync; sleep 1; sync # just to be safe
22494         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22495         if [ x$nrpcs != "x1" ]; then
22496                 $LCTL get_param osc.*.stats
22497                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22498         fi
22499
22500         start_writeback
22501         # Drop the OSC cache, otherwise we will read from it
22502         cancel_lru_locks osc
22503
22504         # clear the OSC stats
22505         $LCTL set_param osc.*.stats=0 &>/dev/null
22506
22507         # Client reads $bulk_size.
22508         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22509                 iflag=direct &>/dev/null || error "dd failed"
22510
22511         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22512         if [ x$nrpcs != "x1" ]; then
22513                 $LCTL get_param osc.*.stats
22514                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22515         fi
22516 }
22517 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22518
22519 test_231b() {
22520         mkdir -p $DIR/$tdir
22521         stack_trap "rm -rf $DIR/$tdir"
22522         local i
22523         for i in {0..1023}; do
22524                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22525                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22526                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22527         done
22528         sync
22529 }
22530 run_test 231b "must not assert on fully utilized OST request buffer"
22531
22532 test_232a() {
22533         mkdir -p $DIR/$tdir
22534         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22535
22536         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22537         do_facet ost1 $LCTL set_param fail_loc=0x31c
22538
22539         # ignore dd failure
22540         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22541         stack_trap "rm -f $DIR/$tdir/$tfile"
22542
22543         do_facet ost1 $LCTL set_param fail_loc=0
22544         umount_client $MOUNT || error "umount failed"
22545         mount_client $MOUNT || error "mount failed"
22546         stop ost1 || error "cannot stop ost1"
22547         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22548 }
22549 run_test 232a "failed lock should not block umount"
22550
22551 test_232b() {
22552         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22553                 skip "Need MDS version at least 2.10.58"
22554
22555         mkdir -p $DIR/$tdir
22556         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22558         stack_trap "rm -f $DIR/$tdir/$tfile"
22559         sync
22560         cancel_lru_locks osc
22561
22562         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22563         do_facet ost1 $LCTL set_param fail_loc=0x31c
22564
22565         # ignore failure
22566         $LFS data_version $DIR/$tdir/$tfile || true
22567
22568         do_facet ost1 $LCTL set_param fail_loc=0
22569         umount_client $MOUNT || error "umount failed"
22570         mount_client $MOUNT || error "mount failed"
22571         stop ost1 || error "cannot stop ost1"
22572         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22573 }
22574 run_test 232b "failed data version lock should not block umount"
22575
22576 test_233a() {
22577         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22578                 skip "Need MDS version at least 2.3.64"
22579         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22580
22581         local fid=$($LFS path2fid $MOUNT)
22582
22583         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22584                 error "cannot access $MOUNT using its FID '$fid'"
22585 }
22586 run_test 233a "checking that OBF of the FS root succeeds"
22587
22588 test_233b() {
22589         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22590                 skip "Need MDS version at least 2.5.90"
22591         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22592
22593         local fid=$($LFS path2fid $MOUNT/.lustre)
22594
22595         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22596                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22597
22598         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22599         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22600                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22601 }
22602 run_test 233b "checking that OBF of the FS .lustre succeeds"
22603
22604 test_234() {
22605         local p="$TMP/sanityN-$TESTNAME.parameters"
22606         save_lustre_params client "llite.*.xattr_cache" > $p
22607         lctl set_param llite.*.xattr_cache 1 ||
22608                 skip_env "xattr cache is not supported"
22609
22610         mkdir -p $DIR/$tdir || error "mkdir failed"
22611         touch $DIR/$tdir/$tfile || error "touch failed"
22612         # OBD_FAIL_LLITE_XATTR_ENOMEM
22613         $LCTL set_param fail_loc=0x1405
22614         getfattr -n user.attr $DIR/$tdir/$tfile &&
22615                 error "getfattr should have failed with ENOMEM"
22616         $LCTL set_param fail_loc=0x0
22617         rm -rf $DIR/$tdir
22618
22619         restore_lustre_params < $p
22620         rm -f $p
22621 }
22622 run_test 234 "xattr cache should not crash on ENOMEM"
22623
22624 test_235() {
22625         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22626                 skip "Need MDS version at least 2.4.52"
22627
22628         flock_deadlock $DIR/$tfile
22629         local RC=$?
22630         case $RC in
22631                 0)
22632                 ;;
22633                 124) error "process hangs on a deadlock"
22634                 ;;
22635                 *) error "error executing flock_deadlock $DIR/$tfile"
22636                 ;;
22637         esac
22638 }
22639 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22640
22641 #LU-2935
22642 test_236() {
22643         check_swap_layouts_support
22644
22645         local ref1=/etc/passwd
22646         local ref2=/etc/group
22647         local file1=$DIR/$tdir/f1
22648         local file2=$DIR/$tdir/f2
22649
22650         test_mkdir -c1 $DIR/$tdir
22651         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22652         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22653         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22654         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22655         local fd=$(free_fd)
22656         local cmd="exec $fd<>$file2"
22657         eval $cmd
22658         rm $file2
22659         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22660                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22661         cmd="exec $fd>&-"
22662         eval $cmd
22663         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22664
22665         #cleanup
22666         rm -rf $DIR/$tdir
22667 }
22668 run_test 236 "Layout swap on open unlinked file"
22669
22670 # LU-4659 linkea consistency
22671 test_238() {
22672         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22673                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22674                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22675                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22676
22677         touch $DIR/$tfile
22678         ln $DIR/$tfile $DIR/$tfile.lnk
22679         touch $DIR/$tfile.new
22680         mv $DIR/$tfile.new $DIR/$tfile
22681         local fid1=$($LFS path2fid $DIR/$tfile)
22682         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22683         local path1=$($LFS fid2path $FSNAME "$fid1")
22684         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22685         local path2=$($LFS fid2path $FSNAME "$fid2")
22686         [ $tfile.lnk == $path2 ] ||
22687                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22688         rm -f $DIR/$tfile*
22689 }
22690 run_test 238 "Verify linkea consistency"
22691
22692 test_239A() { # was test_239
22693         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22694                 skip "Need MDS version at least 2.5.60"
22695
22696         local list=$(comma_list $(mdts_nodes))
22697
22698         mkdir -p $DIR/$tdir
22699         createmany -o $DIR/$tdir/f- 5000
22700         unlinkmany $DIR/$tdir/f- 5000
22701         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22702                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22703         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22704                         osp.*MDT*.sync_in_flight" | calc_sum)
22705         [ "$changes" -eq 0 ] || error "$changes not synced"
22706 }
22707 run_test 239A "osp_sync test"
22708
22709 test_239a() { #LU-5297
22710         remote_mds_nodsh && skip "remote MDS with nodsh"
22711
22712         touch $DIR/$tfile
22713         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22714         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22715         chgrp $RUNAS_GID $DIR/$tfile
22716         wait_delete_completed
22717 }
22718 run_test 239a "process invalid osp sync record correctly"
22719
22720 test_239b() { #LU-5297
22721         remote_mds_nodsh && skip "remote MDS with nodsh"
22722
22723         touch $DIR/$tfile1
22724         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22725         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22726         chgrp $RUNAS_GID $DIR/$tfile1
22727         wait_delete_completed
22728         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22729         touch $DIR/$tfile2
22730         chgrp $RUNAS_GID $DIR/$tfile2
22731         wait_delete_completed
22732 }
22733 run_test 239b "process osp sync record with ENOMEM error correctly"
22734
22735 test_240() {
22736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22737         remote_mds_nodsh && skip "remote MDS with nodsh"
22738
22739         mkdir -p $DIR/$tdir
22740
22741         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22742                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22743         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22744                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22745
22746         umount_client $MOUNT || error "umount failed"
22747         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22748         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22749         mount_client $MOUNT || error "failed to mount client"
22750
22751         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22752         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22753 }
22754 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22755
22756 test_241_bio() {
22757         local count=$1
22758         local bsize=$2
22759
22760         for LOOP in $(seq $count); do
22761                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22762                 cancel_lru_locks $OSC || true
22763         done
22764 }
22765
22766 test_241_dio() {
22767         local count=$1
22768         local bsize=$2
22769
22770         for LOOP in $(seq $1); do
22771                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22772                         2>/dev/null
22773         done
22774 }
22775
22776 test_241a() { # was test_241
22777         local bsize=$PAGE_SIZE
22778
22779         (( bsize < 40960 )) && bsize=40960
22780         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22781         ls -la $DIR/$tfile
22782         cancel_lru_locks $OSC
22783         test_241_bio 1000 $bsize &
22784         PID=$!
22785         test_241_dio 1000 $bsize
22786         wait $PID
22787 }
22788 run_test 241a "bio vs dio"
22789
22790 test_241b() {
22791         local bsize=$PAGE_SIZE
22792
22793         (( bsize < 40960 )) && bsize=40960
22794         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22795         ls -la $DIR/$tfile
22796         test_241_dio 1000 $bsize &
22797         PID=$!
22798         test_241_dio 1000 $bsize
22799         wait $PID
22800 }
22801 run_test 241b "dio vs dio"
22802
22803 test_242() {
22804         remote_mds_nodsh && skip "remote MDS with nodsh"
22805
22806         mkdir_on_mdt0 $DIR/$tdir
22807         touch $DIR/$tdir/$tfile
22808
22809         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22810         do_facet mds1 lctl set_param fail_loc=0x105
22811         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22812
22813         do_facet mds1 lctl set_param fail_loc=0
22814         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22815 }
22816 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22817
22818 test_243()
22819 {
22820         test_mkdir $DIR/$tdir
22821         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22822 }
22823 run_test 243 "various group lock tests"
22824
22825 test_244a()
22826 {
22827         test_mkdir $DIR/$tdir
22828         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22829         sendfile_grouplock $DIR/$tdir/$tfile || \
22830                 error "sendfile+grouplock failed"
22831         rm -rf $DIR/$tdir
22832 }
22833 run_test 244a "sendfile with group lock tests"
22834
22835 test_244b()
22836 {
22837         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22838
22839         local threads=50
22840         local size=$((1024*1024))
22841
22842         test_mkdir $DIR/$tdir
22843         for i in $(seq 1 $threads); do
22844                 local file=$DIR/$tdir/file_$((i / 10))
22845                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22846                 local pids[$i]=$!
22847         done
22848         for i in $(seq 1 $threads); do
22849                 wait ${pids[$i]}
22850         done
22851 }
22852 run_test 244b "multi-threaded write with group lock"
22853
22854 test_245a() {
22855         local flagname="multi_mod_rpcs"
22856         local connect_data_name="max_mod_rpcs"
22857         local out
22858
22859         # check if multiple modify RPCs flag is set
22860         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22861                 grep "connect_flags:")
22862         echo "$out"
22863
22864         echo "$out" | grep -qw $flagname
22865         if [ $? -ne 0 ]; then
22866                 echo "connect flag $flagname is not set"
22867                 return
22868         fi
22869
22870         # check if multiple modify RPCs data is set
22871         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22872         echo "$out"
22873
22874         echo "$out" | grep -qw $connect_data_name ||
22875                 error "import should have connect data $connect_data_name"
22876 }
22877 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22878
22879 test_245b() {
22880         local flagname="multi_mod_rpcs"
22881         local connect_data_name="max_mod_rpcs"
22882         local out
22883
22884         remote_mds_nodsh && skip "remote MDS with nodsh"
22885         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22886
22887         # check if multiple modify RPCs flag is set
22888         out=$(do_facet mds1 \
22889               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22890               grep "connect_flags:")
22891         echo "$out"
22892
22893         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22894
22895         # check if multiple modify RPCs data is set
22896         out=$(do_facet mds1 \
22897               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22898
22899         [[ "$out" =~ $connect_data_name ]] ||
22900                 {
22901                         echo "$out"
22902                         error "missing connect data $connect_data_name"
22903                 }
22904 }
22905 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22906
22907 cleanup_247() {
22908         local submount=$1
22909
22910         trap 0
22911         umount_client $submount
22912         rmdir $submount
22913 }
22914
22915 test_247a() {
22916         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22917                 grep -q subtree ||
22918                 skip_env "Fileset feature is not supported"
22919
22920         local submount=${MOUNT}_$tdir
22921
22922         mkdir $MOUNT/$tdir
22923         mkdir -p $submount || error "mkdir $submount failed"
22924         FILESET="$FILESET/$tdir" mount_client $submount ||
22925                 error "mount $submount failed"
22926         trap "cleanup_247 $submount" EXIT
22927         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22928         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22929                 error "read $MOUNT/$tdir/$tfile failed"
22930         cleanup_247 $submount
22931 }
22932 run_test 247a "mount subdir as fileset"
22933
22934 test_247b() {
22935         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22936                 skip_env "Fileset feature is not supported"
22937
22938         local submount=${MOUNT}_$tdir
22939
22940         rm -rf $MOUNT/$tdir
22941         mkdir -p $submount || error "mkdir $submount failed"
22942         SKIP_FILESET=1
22943         FILESET="$FILESET/$tdir" mount_client $submount &&
22944                 error "mount $submount should fail"
22945         rmdir $submount
22946 }
22947 run_test 247b "mount subdir that dose not exist"
22948
22949 test_247c() {
22950         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22951                 skip_env "Fileset feature is not supported"
22952
22953         local submount=${MOUNT}_$tdir
22954
22955         mkdir -p $MOUNT/$tdir/dir1
22956         mkdir -p $submount || error "mkdir $submount failed"
22957         trap "cleanup_247 $submount" EXIT
22958         FILESET="$FILESET/$tdir" mount_client $submount ||
22959                 error "mount $submount failed"
22960         local fid=$($LFS path2fid $MOUNT/)
22961         $LFS fid2path $submount $fid && error "fid2path should fail"
22962         cleanup_247 $submount
22963 }
22964 run_test 247c "running fid2path outside subdirectory root"
22965
22966 test_247d() {
22967         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22968                 skip "Fileset feature is not supported"
22969
22970         local submount=${MOUNT}_$tdir
22971
22972         mkdir -p $MOUNT/$tdir/dir1
22973         mkdir -p $submount || error "mkdir $submount failed"
22974         FILESET="$FILESET/$tdir" mount_client $submount ||
22975                 error "mount $submount failed"
22976         trap "cleanup_247 $submount" EXIT
22977
22978         local td=$submount/dir1
22979         local fid=$($LFS path2fid $td)
22980         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22981
22982         # check that we get the same pathname back
22983         local rootpath
22984         local found
22985         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22986                 echo "$rootpath $fid"
22987                 found=$($LFS fid2path $rootpath "$fid")
22988                 [ -n "$found" ] || error "fid2path should succeed"
22989                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22990         done
22991         # check wrong root path format
22992         rootpath=$submount"_wrong"
22993         found=$($LFS fid2path $rootpath "$fid")
22994         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22995
22996         cleanup_247 $submount
22997 }
22998 run_test 247d "running fid2path inside subdirectory root"
22999
23000 # LU-8037
23001 test_247e() {
23002         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23003                 grep -q subtree ||
23004                 skip "Fileset feature is not supported"
23005
23006         local submount=${MOUNT}_$tdir
23007
23008         mkdir $MOUNT/$tdir
23009         mkdir -p $submount || error "mkdir $submount failed"
23010         FILESET="$FILESET/.." mount_client $submount &&
23011                 error "mount $submount should fail"
23012         rmdir $submount
23013 }
23014 run_test 247e "mount .. as fileset"
23015
23016 test_247f() {
23017         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23018         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23019                 skip "Need at least version 2.14.50.162"
23020         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23021                 skip "Fileset feature is not supported"
23022
23023         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23024         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23025                 error "mkdir remote failed"
23026         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23027                 error "mkdir remote/subdir failed"
23028         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23029                 error "mkdir striped failed"
23030         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23031
23032         local submount=${MOUNT}_$tdir
23033
23034         mkdir -p $submount || error "mkdir $submount failed"
23035         stack_trap "rmdir $submount"
23036
23037         local dir
23038         local fileset=$FILESET
23039         local mdts=$(comma_list $(mdts_nodes))
23040
23041         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23042         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23043                 $tdir/striped/subdir $tdir/striped/.; do
23044                 FILESET="$fileset/$dir" mount_client $submount ||
23045                         error "mount $dir failed"
23046                 umount_client $submount
23047         done
23048 }
23049 run_test 247f "mount striped or remote directory as fileset"
23050
23051 test_subdir_mount_lock()
23052 {
23053         local testdir=$1
23054         local submount=${MOUNT}_$(basename $testdir)
23055
23056         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23057
23058         mkdir -p $submount || error "mkdir $submount failed"
23059         stack_trap "rmdir $submount"
23060
23061         FILESET="$fileset/$testdir" mount_client $submount ||
23062                 error "mount $FILESET failed"
23063         stack_trap "umount $submount"
23064
23065         local mdts=$(comma_list $(mdts_nodes))
23066
23067         local nrpcs
23068
23069         stat $submount > /dev/null || error "stat $submount failed"
23070         cancel_lru_locks $MDC
23071         stat $submount > /dev/null || error "stat $submount failed"
23072         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23073         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23074         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23075         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23076                 awk '/getattr/ {sum += $2} END {print sum}')
23077
23078         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23079 }
23080
23081 test_247g() {
23082         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23083
23084         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23085                 error "mkdir $tdir failed"
23086         test_subdir_mount_lock $tdir
23087 }
23088 run_test 247g "striped directory submount revalidate ROOT from cache"
23089
23090 test_247h() {
23091         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23092         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23093                 skip "Need MDS version at least 2.15.51"
23094
23095         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23096         test_subdir_mount_lock $tdir
23097         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23098         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23099                 error "mkdir $tdir.1 failed"
23100         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23101 }
23102 run_test 247h "remote directory submount revalidate ROOT from cache"
23103
23104 test_248a() {
23105         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23106         [ -z "$fast_read_sav" ] && skip "no fast read support"
23107
23108         # create a large file for fast read verification
23109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23110
23111         # make sure the file is created correctly
23112         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23113                 { rm -f $DIR/$tfile; skip "file creation error"; }
23114
23115         echo "Test 1: verify that fast read is 4 times faster on cache read"
23116
23117         # small read with fast read enabled
23118         $LCTL set_param -n llite.*.fast_read=1
23119         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23120                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23121                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23122         # small read with fast read disabled
23123         $LCTL set_param -n llite.*.fast_read=0
23124         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23125                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23126                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23127
23128         # verify that fast read is 4 times faster for cache read
23129         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23130                 error_not_in_vm "fast read was not 4 times faster: " \
23131                            "$t_fast vs $t_slow"
23132
23133         echo "Test 2: verify the performance between big and small read"
23134         $LCTL set_param -n llite.*.fast_read=1
23135
23136         # 1k non-cache read
23137         cancel_lru_locks osc
23138         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23139                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23140                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23141
23142         # 1M non-cache read
23143         cancel_lru_locks osc
23144         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23145                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23146                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23147
23148         # verify that big IO is not 4 times faster than small IO
23149         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23150                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23151
23152         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23153         rm -f $DIR/$tfile
23154 }
23155 run_test 248a "fast read verification"
23156
23157 test_248b() {
23158         # Default short_io_bytes=16384, try both smaller and larger sizes.
23159         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23160         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23161         echo "bs=53248 count=113 normal buffered write"
23162         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23163                 error "dd of initial data file failed"
23164         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23165
23166         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23167         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23168                 error "dd with sync normal writes failed"
23169         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23170
23171         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23172         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23173                 error "dd with sync small writes failed"
23174         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23175
23176         cancel_lru_locks osc
23177
23178         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23179         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23180         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23181         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23182                 iflag=direct || error "dd with O_DIRECT small read failed"
23183         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23184         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23185                 error "compare $TMP/$tfile.1 failed"
23186
23187         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23188         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23189
23190         # just to see what the maximum tunable value is, and test parsing
23191         echo "test invalid parameter 2MB"
23192         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23193                 error "too-large short_io_bytes allowed"
23194         echo "test maximum parameter 512KB"
23195         # if we can set a larger short_io_bytes, run test regardless of version
23196         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23197                 # older clients may not allow setting it this large, that's OK
23198                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23199                         skip "Need at least client version 2.13.50"
23200                 error "medium short_io_bytes failed"
23201         fi
23202         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23203         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23204
23205         echo "test large parameter 64KB"
23206         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23207         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23208
23209         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23210         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23211                 error "dd with sync large writes failed"
23212         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23213
23214         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23215         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23216         num=$((113 * 4096 / PAGE_SIZE))
23217         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23218         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23219                 error "dd with O_DIRECT large writes failed"
23220         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23221                 error "compare $DIR/$tfile.3 failed"
23222
23223         cancel_lru_locks osc
23224
23225         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23226         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23227                 error "dd with O_DIRECT large read failed"
23228         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23229                 error "compare $TMP/$tfile.2 failed"
23230
23231         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23232         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23233                 error "dd with O_DIRECT large read failed"
23234         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23235                 error "compare $TMP/$tfile.3 failed"
23236 }
23237 run_test 248b "test short_io read and write for both small and large sizes"
23238
23239 test_249() { # LU-7890
23240         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23241                 skip "Need at least version 2.8.54"
23242
23243         rm -f $DIR/$tfile
23244         $LFS setstripe -c 1 $DIR/$tfile
23245         # Offset 2T == 4k * 512M
23246         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23247                 error "dd to 2T offset failed"
23248 }
23249 run_test 249 "Write above 2T file size"
23250
23251 test_250() {
23252         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23253          && skip "no 16TB file size limit on ZFS"
23254
23255         $LFS setstripe -c 1 $DIR/$tfile
23256         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23257         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23258         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23259         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23260                 conv=notrunc,fsync && error "append succeeded"
23261         return 0
23262 }
23263 run_test 250 "Write above 16T limit"
23264
23265 test_251() {
23266         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23267
23268         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23269         #Skip once - writing the first stripe will succeed
23270         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23271         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23272                 error "short write happened"
23273
23274         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23275         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23276                 error "short read happened"
23277
23278         rm -f $DIR/$tfile
23279 }
23280 run_test 251 "Handling short read and write correctly"
23281
23282 test_252() {
23283         remote_mds_nodsh && skip "remote MDS with nodsh"
23284         remote_ost_nodsh && skip "remote OST with nodsh"
23285         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23286                 skip_env "ldiskfs only test"
23287         fi
23288
23289         local tgt
23290         local dev
23291         local out
23292         local uuid
23293         local num
23294         local gen
23295
23296         # check lr_reader on OST0000
23297         tgt=ost1
23298         dev=$(facet_device $tgt)
23299         out=$(do_facet $tgt $LR_READER $dev)
23300         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23301         echo "$out"
23302         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23303         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23304                 error "Invalid uuid returned by $LR_READER on target $tgt"
23305         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23306
23307         # check lr_reader -c on MDT0000
23308         tgt=mds1
23309         dev=$(facet_device $tgt)
23310         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23311                 skip "$LR_READER does not support additional options"
23312         fi
23313         out=$(do_facet $tgt $LR_READER -c $dev)
23314         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23315         echo "$out"
23316         num=$(echo "$out" | grep -c "mdtlov")
23317         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23318                 error "Invalid number of mdtlov clients returned by $LR_READER"
23319         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23320
23321         # check lr_reader -cr on MDT0000
23322         out=$(do_facet $tgt $LR_READER -cr $dev)
23323         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23324         echo "$out"
23325         echo "$out" | grep -q "^reply_data:$" ||
23326                 error "$LR_READER should have returned 'reply_data' section"
23327         num=$(echo "$out" | grep -c "client_generation")
23328         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23329 }
23330 run_test 252 "check lr_reader tool"
23331
23332 test_253() {
23333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23334         remote_mds_nodsh && skip "remote MDS with nodsh"
23335         remote_mgs_nodsh && skip "remote MGS with nodsh"
23336
23337         local ostidx=0
23338         local rc=0
23339         local ost_name=$(ostname_from_index $ostidx)
23340
23341         # on the mdt's osc
23342         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23343         do_facet $SINGLEMDS $LCTL get_param -n \
23344                 osp.$mdtosc_proc1.reserved_mb_high ||
23345                 skip  "remote MDS does not support reserved_mb_high"
23346
23347         rm -rf $DIR/$tdir
23348         wait_mds_ost_sync
23349         wait_delete_completed
23350         mkdir $DIR/$tdir
23351         stack_trap "rm -rf $DIR/$tdir"
23352
23353         pool_add $TESTNAME || error "Pool creation failed"
23354         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23355
23356         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23357                 error "Setstripe failed"
23358
23359         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23360
23361         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23362                     grep "watermarks")
23363         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23364
23365         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23366                         osp.$mdtosc_proc1.prealloc_status)
23367         echo "prealloc_status $oa_status"
23368
23369         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23370                 error "File creation should fail"
23371
23372         #object allocation was stopped, but we still able to append files
23373         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23374                 oflag=append || error "Append failed"
23375
23376         rm -f $DIR/$tdir/$tfile.0
23377
23378         # For this test, we want to delete the files we created to go out of
23379         # space but leave the watermark, so we remain nearly out of space
23380         ost_watermarks_enospc_delete_files $tfile $ostidx
23381
23382         wait_delete_completed
23383
23384         sleep_maxage
23385
23386         for i in $(seq 10 12); do
23387                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23388                         2>/dev/null || error "File creation failed after rm"
23389         done
23390
23391         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23392                         osp.$mdtosc_proc1.prealloc_status)
23393         echo "prealloc_status $oa_status"
23394
23395         if (( oa_status != 0 )); then
23396                 error "Object allocation still disable after rm"
23397         fi
23398 }
23399 run_test 253 "Check object allocation limit"
23400
23401 test_254() {
23402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23403         remote_mds_nodsh && skip "remote MDS with nodsh"
23404
23405         local mdt=$(facet_svc $SINGLEMDS)
23406
23407         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23408                 skip "MDS does not support changelog_size"
23409
23410         local cl_user
23411
23412         changelog_register || error "changelog_register failed"
23413
23414         changelog_clear 0 || error "changelog_clear failed"
23415
23416         local size1=$(do_facet $SINGLEMDS \
23417                       $LCTL get_param -n mdd.$mdt.changelog_size)
23418         echo "Changelog size $size1"
23419
23420         rm -rf $DIR/$tdir
23421         $LFS mkdir -i 0 $DIR/$tdir
23422         # change something
23423         mkdir -p $DIR/$tdir/pics/2008/zachy
23424         touch $DIR/$tdir/pics/2008/zachy/timestamp
23425         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23426         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23427         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23428         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23429         rm $DIR/$tdir/pics/desktop.jpg
23430
23431         local size2=$(do_facet $SINGLEMDS \
23432                       $LCTL get_param -n mdd.$mdt.changelog_size)
23433         echo "Changelog size after work $size2"
23434
23435         (( $size2 > $size1 )) ||
23436                 error "new Changelog size=$size2 less than old size=$size1"
23437 }
23438 run_test 254 "Check changelog size"
23439
23440 ladvise_no_type()
23441 {
23442         local type=$1
23443         local file=$2
23444
23445         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23446                 awk -F: '{print $2}' | grep $type > /dev/null
23447         if [ $? -ne 0 ]; then
23448                 return 0
23449         fi
23450         return 1
23451 }
23452
23453 ladvise_no_ioctl()
23454 {
23455         local file=$1
23456
23457         lfs ladvise -a willread $file > /dev/null 2>&1
23458         if [ $? -eq 0 ]; then
23459                 return 1
23460         fi
23461
23462         lfs ladvise -a willread $file 2>&1 |
23463                 grep "Inappropriate ioctl for device" > /dev/null
23464         if [ $? -eq 0 ]; then
23465                 return 0
23466         fi
23467         return 1
23468 }
23469
23470 percent() {
23471         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23472 }
23473
23474 # run a random read IO workload
23475 # usage: random_read_iops <filename> <filesize> <iosize>
23476 random_read_iops() {
23477         local file=$1
23478         local fsize=$2
23479         local iosize=${3:-4096}
23480
23481         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23482                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23483 }
23484
23485 drop_file_oss_cache() {
23486         local file="$1"
23487         local nodes="$2"
23488
23489         $LFS ladvise -a dontneed $file 2>/dev/null ||
23490                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23491 }
23492
23493 ladvise_willread_performance()
23494 {
23495         local repeat=10
23496         local average_origin=0
23497         local average_cache=0
23498         local average_ladvise=0
23499
23500         for ((i = 1; i <= $repeat; i++)); do
23501                 echo "Iter $i/$repeat: reading without willread hint"
23502                 cancel_lru_locks osc
23503                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23504                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23505                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23506                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23507
23508                 cancel_lru_locks osc
23509                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23510                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23511                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23512
23513                 cancel_lru_locks osc
23514                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23515                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23516                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23517                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23518                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23519         done
23520         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23521         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23522         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23523
23524         speedup_cache=$(percent $average_cache $average_origin)
23525         speedup_ladvise=$(percent $average_ladvise $average_origin)
23526
23527         echo "Average uncached read: $average_origin"
23528         echo "Average speedup with OSS cached read: " \
23529                 "$average_cache = +$speedup_cache%"
23530         echo "Average speedup with ladvise willread: " \
23531                 "$average_ladvise = +$speedup_ladvise%"
23532
23533         local lowest_speedup=20
23534         if (( ${average_cache%.*} < $lowest_speedup )); then
23535                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23536                      " got $average_cache%. Skipping ladvise willread check."
23537                 return 0
23538         fi
23539
23540         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23541         # it is still good to run until then to exercise 'ladvise willread'
23542         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23543                 [ "$ost1_FSTYPE" = "zfs" ] &&
23544                 echo "osd-zfs does not support dontneed or drop_caches" &&
23545                 return 0
23546
23547         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23548         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23549                 error_not_in_vm "Speedup with willread is less than " \
23550                         "$lowest_speedup%, got $average_ladvise%"
23551 }
23552
23553 test_255a() {
23554         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23555                 skip "lustre < 2.8.54 does not support ladvise "
23556         remote_ost_nodsh && skip "remote OST with nodsh"
23557
23558         stack_trap "rm -f $DIR/$tfile"
23559         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23560
23561         ladvise_no_type willread $DIR/$tfile &&
23562                 skip "willread ladvise is not supported"
23563
23564         ladvise_no_ioctl $DIR/$tfile &&
23565                 skip "ladvise ioctl is not supported"
23566
23567         local size_mb=100
23568         local size=$((size_mb * 1048576))
23569         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23570                 error "dd to $DIR/$tfile failed"
23571
23572         lfs ladvise -a willread $DIR/$tfile ||
23573                 error "Ladvise failed with no range argument"
23574
23575         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23576                 error "Ladvise failed with no -l or -e argument"
23577
23578         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23579                 error "Ladvise failed with only -e argument"
23580
23581         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23582                 error "Ladvise failed with only -l argument"
23583
23584         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23585                 error "End offset should not be smaller than start offset"
23586
23587         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23588                 error "End offset should not be equal to start offset"
23589
23590         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23591                 error "Ladvise failed with overflowing -s argument"
23592
23593         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23594                 error "Ladvise failed with overflowing -e argument"
23595
23596         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23597                 error "Ladvise failed with overflowing -l argument"
23598
23599         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23600                 error "Ladvise succeeded with conflicting -l and -e arguments"
23601
23602         echo "Synchronous ladvise should wait"
23603         local delay=8
23604 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23605         do_nodes $(comma_list $(osts_nodes)) \
23606                 $LCTL set_param fail_val=$delay fail_loc=0x237
23607         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23608                 $LCTL set_param fail_loc=0"
23609
23610         local start_ts=$SECONDS
23611         lfs ladvise -a willread $DIR/$tfile ||
23612                 error "Ladvise failed with no range argument"
23613         local end_ts=$SECONDS
23614         local inteval_ts=$((end_ts - start_ts))
23615
23616         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23617                 error "Synchronous advice didn't wait reply"
23618         fi
23619
23620         echo "Asynchronous ladvise shouldn't wait"
23621         local start_ts=$SECONDS
23622         lfs ladvise -a willread -b $DIR/$tfile ||
23623                 error "Ladvise failed with no range argument"
23624         local end_ts=$SECONDS
23625         local inteval_ts=$((end_ts - start_ts))
23626
23627         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23628                 error "Asynchronous advice blocked"
23629         fi
23630
23631         ladvise_willread_performance
23632 }
23633 run_test 255a "check 'lfs ladvise -a willread'"
23634
23635 facet_meminfo() {
23636         local facet=$1
23637         local info=$2
23638
23639         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23640 }
23641
23642 test_255b() {
23643         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23644                 skip "lustre < 2.8.54 does not support ladvise "
23645         remote_ost_nodsh && skip "remote OST with nodsh"
23646
23647         stack_trap "rm -f $DIR/$tfile"
23648         lfs setstripe -c 1 -i 0 $DIR/$tfile
23649
23650         ladvise_no_type dontneed $DIR/$tfile &&
23651                 skip "dontneed ladvise is not supported"
23652
23653         ladvise_no_ioctl $DIR/$tfile &&
23654                 skip "ladvise ioctl is not supported"
23655
23656         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23657                 [ "$ost1_FSTYPE" = "zfs" ] &&
23658                 skip "zfs-osd does not support 'ladvise dontneed'"
23659
23660         local size_mb=100
23661         local size=$((size_mb * 1048576))
23662         # In order to prevent disturbance of other processes, only check 3/4
23663         # of the memory usage
23664         local kibibytes=$((size_mb * 1024 * 3 / 4))
23665
23666         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23667                 error "dd to $DIR/$tfile failed"
23668
23669         #force write to complete before dropping OST cache & checking memory
23670         sync
23671
23672         local total=$(facet_meminfo ost1 MemTotal)
23673         echo "Total memory: $total KiB"
23674
23675         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23676         local before_read=$(facet_meminfo ost1 Cached)
23677         echo "Cache used before read: $before_read KiB"
23678
23679         lfs ladvise -a willread $DIR/$tfile ||
23680                 error "Ladvise willread failed"
23681         local after_read=$(facet_meminfo ost1 Cached)
23682         echo "Cache used after read: $after_read KiB"
23683
23684         lfs ladvise -a dontneed $DIR/$tfile ||
23685                 error "Ladvise dontneed again failed"
23686         local no_read=$(facet_meminfo ost1 Cached)
23687         echo "Cache used after dontneed ladvise: $no_read KiB"
23688
23689         if [ $total -lt $((before_read + kibibytes)) ]; then
23690                 echo "Memory is too small, abort checking"
23691                 return 0
23692         fi
23693
23694         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23695                 error "Ladvise willread should use more memory" \
23696                         "than $kibibytes KiB"
23697         fi
23698
23699         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23700                 error "Ladvise dontneed should release more memory" \
23701                         "than $kibibytes KiB"
23702         fi
23703 }
23704 run_test 255b "check 'lfs ladvise -a dontneed'"
23705
23706 test_255c() {
23707         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23708                 skip "lustre < 2.10.50 does not support lockahead"
23709
23710         local ost1_imp=$(get_osc_import_name client ost1)
23711         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23712                          cut -d'.' -f2)
23713         local count
23714         local new_count
23715         local difference
23716         local i
23717         local rc
23718
23719         test_mkdir -p $DIR/$tdir
23720         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23721
23722         #test 10 returns only success/failure
23723         i=10
23724         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23725         rc=$?
23726         if [ $rc -eq 255 ]; then
23727                 error "Ladvise test${i} failed, ${rc}"
23728         fi
23729
23730         #test 11 counts lock enqueue requests, all others count new locks
23731         i=11
23732         count=$(do_facet ost1 \
23733                 $LCTL get_param -n ost.OSS.ost.stats)
23734         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23735
23736         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23737         rc=$?
23738         if [ $rc -eq 255 ]; then
23739                 error "Ladvise test${i} failed, ${rc}"
23740         fi
23741
23742         new_count=$(do_facet ost1 \
23743                 $LCTL get_param -n ost.OSS.ost.stats)
23744         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23745                    awk '{ print $2 }')
23746
23747         difference="$((new_count - count))"
23748         if [ $difference -ne $rc ]; then
23749                 error "Ladvise test${i}, bad enqueue count, returned " \
23750                       "${rc}, actual ${difference}"
23751         fi
23752
23753         for i in $(seq 12 21); do
23754                 # If we do not do this, we run the risk of having too many
23755                 # locks and starting lock cancellation while we are checking
23756                 # lock counts.
23757                 cancel_lru_locks osc
23758
23759                 count=$($LCTL get_param -n \
23760                        ldlm.namespaces.$imp_name.lock_unused_count)
23761
23762                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23763                 rc=$?
23764                 if [ $rc -eq 255 ]; then
23765                         error "Ladvise test ${i} failed, ${rc}"
23766                 fi
23767
23768                 new_count=$($LCTL get_param -n \
23769                        ldlm.namespaces.$imp_name.lock_unused_count)
23770                 difference="$((new_count - count))"
23771
23772                 # Test 15 output is divided by 100 to map down to valid return
23773                 if [ $i -eq 15 ]; then
23774                         rc="$((rc * 100))"
23775                 fi
23776
23777                 if [ $difference -ne $rc ]; then
23778                         error "Ladvise test ${i}, bad lock count, returned " \
23779                               "${rc}, actual ${difference}"
23780                 fi
23781         done
23782
23783         #test 22 returns only success/failure
23784         i=22
23785         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23786         rc=$?
23787         if [ $rc -eq 255 ]; then
23788                 error "Ladvise test${i} failed, ${rc}"
23789         fi
23790 }
23791 run_test 255c "suite of ladvise lockahead tests"
23792
23793 test_256() {
23794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23795         remote_mds_nodsh && skip "remote MDS with nodsh"
23796         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23797         changelog_users $SINGLEMDS | grep "^cl" &&
23798                 skip "active changelog user"
23799
23800         local cl_user
23801         local cat_sl
23802         local mdt_dev
23803
23804         mdt_dev=$(facet_device $SINGLEMDS)
23805         echo $mdt_dev
23806
23807         changelog_register || error "changelog_register failed"
23808
23809         rm -rf $DIR/$tdir
23810         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23811
23812         changelog_clear 0 || error "changelog_clear failed"
23813
23814         # change something
23815         touch $DIR/$tdir/{1..10}
23816
23817         # stop the MDT
23818         stop $SINGLEMDS || error "Fail to stop MDT"
23819
23820         # remount the MDT
23821         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23822                 error "Fail to start MDT"
23823
23824         #after mount new plainllog is used
23825         touch $DIR/$tdir/{11..19}
23826         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23827         stack_trap "rm -f $tmpfile"
23828         cat_sl=$(do_facet $SINGLEMDS "sync; \
23829                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23830                  llog_reader $tmpfile | grep -c type=1064553b")
23831         do_facet $SINGLEMDS llog_reader $tmpfile
23832
23833         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23834
23835         changelog_clear 0 || error "changelog_clear failed"
23836
23837         cat_sl=$(do_facet $SINGLEMDS "sync; \
23838                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23839                  llog_reader $tmpfile | grep -c type=1064553b")
23840
23841         if (( cat_sl == 2 )); then
23842                 error "Empty plain llog was not deleted from changelog catalog"
23843         elif (( cat_sl != 1 )); then
23844                 error "Active plain llog shouldn't be deleted from catalog"
23845         fi
23846 }
23847 run_test 256 "Check llog delete for empty and not full state"
23848
23849 test_257() {
23850         remote_mds_nodsh && skip "remote MDS with nodsh"
23851         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23852                 skip "Need MDS version at least 2.8.55"
23853
23854         test_mkdir $DIR/$tdir
23855
23856         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23857                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23858         stat $DIR/$tdir
23859
23860 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23861         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23862         local facet=mds$((mdtidx + 1))
23863         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23864         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23865
23866         stop $facet || error "stop MDS failed"
23867         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23868                 error "start MDS fail"
23869         wait_recovery_complete $facet
23870 }
23871 run_test 257 "xattr locks are not lost"
23872
23873 # Verify we take the i_mutex when security requires it
23874 test_258a() {
23875 #define OBD_FAIL_IMUTEX_SEC 0x141c
23876         $LCTL set_param fail_loc=0x141c
23877         touch $DIR/$tfile
23878         chmod u+s $DIR/$tfile
23879         chmod a+rwx $DIR/$tfile
23880         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23881         RC=$?
23882         if [ $RC -ne 0 ]; then
23883                 error "error, failed to take i_mutex, rc=$?"
23884         fi
23885         rm -f $DIR/$tfile
23886 }
23887 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23888
23889 # Verify we do NOT take the i_mutex in the normal case
23890 test_258b() {
23891 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23892         $LCTL set_param fail_loc=0x141d
23893         touch $DIR/$tfile
23894         chmod a+rwx $DIR
23895         chmod a+rw $DIR/$tfile
23896         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23897         RC=$?
23898         if [ $RC -ne 0 ]; then
23899                 error "error, took i_mutex unnecessarily, rc=$?"
23900         fi
23901         rm -f $DIR/$tfile
23902
23903 }
23904 run_test 258b "verify i_mutex security behavior"
23905
23906 test_259() {
23907         local file=$DIR/$tfile
23908         local before
23909         local after
23910
23911         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23912
23913         stack_trap "rm -f $file" EXIT
23914
23915         wait_delete_completed
23916         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23917         echo "before: $before"
23918
23919         $LFS setstripe -i 0 -c 1 $file
23920         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23921         sync_all_data
23922         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23923         echo "after write: $after"
23924
23925 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23926         do_facet ost1 $LCTL set_param fail_loc=0x2301
23927         $TRUNCATE $file 0
23928         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23929         echo "after truncate: $after"
23930
23931         stop ost1
23932         do_facet ost1 $LCTL set_param fail_loc=0
23933         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23934         sleep 2
23935         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23936         echo "after restart: $after"
23937         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23938                 error "missing truncate?"
23939
23940         return 0
23941 }
23942 run_test 259 "crash at delayed truncate"
23943
23944 test_260() {
23945 #define OBD_FAIL_MDC_CLOSE               0x806
23946         $LCTL set_param fail_loc=0x80000806
23947         touch $DIR/$tfile
23948
23949 }
23950 run_test 260 "Check mdc_close fail"
23951
23952 ### Data-on-MDT sanity tests ###
23953 test_270a() {
23954         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23955                 skip "Need MDS version at least 2.10.55 for DoM"
23956
23957         # create DoM file
23958         local dom=$DIR/$tdir/dom_file
23959         local tmp=$DIR/$tdir/tmp_file
23960
23961         mkdir_on_mdt0 $DIR/$tdir
23962
23963         # basic checks for DoM component creation
23964         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23965                 error "Can set MDT layout to non-first entry"
23966
23967         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23968                 error "Can define multiple entries as MDT layout"
23969
23970         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23971
23972         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23973         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23974         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23975
23976         local mdtidx=$($LFS getstripe -m $dom)
23977         local mdtname=MDT$(printf %04x $mdtidx)
23978         local facet=mds$((mdtidx + 1))
23979         local space_check=1
23980
23981         # Skip free space checks with ZFS
23982         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23983
23984         # write
23985         sync
23986         local size_tmp=$((65536 * 3))
23987         local mdtfree1=$(do_facet $facet \
23988                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23989
23990         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23991         # check also direct IO along write
23992         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23993         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23994         sync
23995         cmp $tmp $dom || error "file data is different"
23996         [ $(stat -c%s $dom) == $size_tmp ] ||
23997                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23998         if [ $space_check == 1 ]; then
23999                 local mdtfree2=$(do_facet $facet \
24000                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24001
24002                 # increase in usage from by $size_tmp
24003                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24004                         error "MDT free space wrong after write: " \
24005                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24006         fi
24007
24008         # truncate
24009         local size_dom=10000
24010
24011         $TRUNCATE $dom $size_dom
24012         [ $(stat -c%s $dom) == $size_dom ] ||
24013                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24014         if [ $space_check == 1 ]; then
24015                 mdtfree1=$(do_facet $facet \
24016                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24017                 # decrease in usage from $size_tmp to new $size_dom
24018                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24019                   $(((size_tmp - size_dom) / 1024)) ] ||
24020                         error "MDT free space is wrong after truncate: " \
24021                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24022         fi
24023
24024         # append
24025         cat $tmp >> $dom
24026         sync
24027         size_dom=$((size_dom + size_tmp))
24028         [ $(stat -c%s $dom) == $size_dom ] ||
24029                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24030         if [ $space_check == 1 ]; then
24031                 mdtfree2=$(do_facet $facet \
24032                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24033                 # increase in usage by $size_tmp from previous
24034                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24035                         error "MDT free space is wrong after append: " \
24036                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24037         fi
24038
24039         # delete
24040         rm $dom
24041         if [ $space_check == 1 ]; then
24042                 mdtfree1=$(do_facet $facet \
24043                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24044                 # decrease in usage by $size_dom from previous
24045                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24046                         error "MDT free space is wrong after removal: " \
24047                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24048         fi
24049
24050         # combined striping
24051         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24052                 error "Can't create DoM + OST striping"
24053
24054         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24055         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24056         # check also direct IO along write
24057         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24058         sync
24059         cmp $tmp $dom || error "file data is different"
24060         [ $(stat -c%s $dom) == $size_tmp ] ||
24061                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24062         rm $dom $tmp
24063
24064         return 0
24065 }
24066 run_test 270a "DoM: basic functionality tests"
24067
24068 test_270b() {
24069         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24070                 skip "Need MDS version at least 2.10.55"
24071
24072         local dom=$DIR/$tdir/dom_file
24073         local max_size=1048576
24074
24075         mkdir -p $DIR/$tdir
24076         $LFS setstripe -E $max_size -L mdt $dom
24077
24078         # truncate over the limit
24079         $TRUNCATE $dom $(($max_size + 1)) &&
24080                 error "successful truncate over the maximum size"
24081         # write over the limit
24082         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24083                 error "successful write over the maximum size"
24084         # append over the limit
24085         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24086         echo "12345" >> $dom && error "successful append over the maximum size"
24087         rm $dom
24088
24089         return 0
24090 }
24091 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24092
24093 test_270c() {
24094         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24095                 skip "Need MDS version at least 2.10.55"
24096
24097         mkdir -p $DIR/$tdir
24098         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24099
24100         # check files inherit DoM EA
24101         touch $DIR/$tdir/first
24102         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24103                 error "bad pattern"
24104         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24105                 error "bad stripe count"
24106         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24107                 error "bad stripe size"
24108
24109         # check directory inherits DoM EA and uses it as default
24110         mkdir $DIR/$tdir/subdir
24111         touch $DIR/$tdir/subdir/second
24112         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24113                 error "bad pattern in sub-directory"
24114         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24115                 error "bad stripe count in sub-directory"
24116         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24117                 error "bad stripe size in sub-directory"
24118         return 0
24119 }
24120 run_test 270c "DoM: DoM EA inheritance tests"
24121
24122 test_270d() {
24123         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24124                 skip "Need MDS version at least 2.10.55"
24125
24126         mkdir -p $DIR/$tdir
24127         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24128
24129         # inherit default DoM striping
24130         mkdir $DIR/$tdir/subdir
24131         touch $DIR/$tdir/subdir/f1
24132
24133         # change default directory striping
24134         $LFS setstripe -c 1 $DIR/$tdir/subdir
24135         touch $DIR/$tdir/subdir/f2
24136         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24137                 error "wrong default striping in file 2"
24138         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24139                 error "bad pattern in file 2"
24140         return 0
24141 }
24142 run_test 270d "DoM: change striping from DoM to RAID0"
24143
24144 test_270e() {
24145         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24146                 skip "Need MDS version at least 2.10.55"
24147
24148         mkdir -p $DIR/$tdir/dom
24149         mkdir -p $DIR/$tdir/norm
24150         DOMFILES=20
24151         NORMFILES=10
24152         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24153         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24154
24155         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24156         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24157
24158         # find DoM files by layout
24159         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24160         [ $NUM -eq  $DOMFILES ] ||
24161                 error "lfs find -L: found $NUM, expected $DOMFILES"
24162         echo "Test 1: lfs find 20 DOM files by layout: OK"
24163
24164         # there should be 1 dir with default DOM striping
24165         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24166         [ $NUM -eq  1 ] ||
24167                 error "lfs find -L: found $NUM, expected 1 dir"
24168         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24169
24170         # find DoM files by stripe size
24171         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24172         [ $NUM -eq  $DOMFILES ] ||
24173                 error "lfs find -S: found $NUM, expected $DOMFILES"
24174         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24175
24176         # find files by stripe offset except DoM files
24177         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24178         [ $NUM -eq  $NORMFILES ] ||
24179                 error "lfs find -i: found $NUM, expected $NORMFILES"
24180         echo "Test 5: lfs find no DOM files by stripe index: OK"
24181         return 0
24182 }
24183 run_test 270e "DoM: lfs find with DoM files test"
24184
24185 test_270f() {
24186         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24187                 skip "Need MDS version at least 2.10.55"
24188
24189         local mdtname=${FSNAME}-MDT0000-mdtlov
24190         local dom=$DIR/$tdir/dom_file
24191         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24192                                                 lod.$mdtname.dom_stripesize)
24193         local dom_limit=131072
24194
24195         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24196         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24197                                                 lod.$mdtname.dom_stripesize)
24198         [ ${dom_limit} -eq ${dom_current} ] ||
24199                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24200
24201         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24202         $LFS setstripe -d $DIR/$tdir
24203         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24204                 error "Can't set directory default striping"
24205
24206         # exceed maximum stripe size
24207         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24208                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24209         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24210                 error "Able to create DoM component size more than LOD limit"
24211
24212         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24213         dom_current=$(do_facet mds1 $LCTL get_param -n \
24214                                                 lod.$mdtname.dom_stripesize)
24215         [ 0 -eq ${dom_current} ] ||
24216                 error "Can't set zero DoM stripe limit"
24217         rm $dom
24218
24219         # attempt to create DoM file on server with disabled DoM should
24220         # remove DoM entry from layout and be succeed
24221         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24222                 error "Can't create DoM file (DoM is disabled)"
24223         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24224                 error "File has DoM component while DoM is disabled"
24225         rm $dom
24226
24227         # attempt to create DoM file with only DoM stripe should return error
24228         $LFS setstripe -E $dom_limit -L mdt $dom &&
24229                 error "Able to create DoM-only file while DoM is disabled"
24230
24231         # too low values to be aligned with smallest stripe size 64K
24232         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24233         dom_current=$(do_facet mds1 $LCTL get_param -n \
24234                                                 lod.$mdtname.dom_stripesize)
24235         [ 30000 -eq ${dom_current} ] &&
24236                 error "Can set too small DoM stripe limit"
24237
24238         # 64K is a minimal stripe size in Lustre, expect limit of that size
24239         [ 65536 -eq ${dom_current} ] ||
24240                 error "Limit is not set to 64K but ${dom_current}"
24241
24242         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24243         dom_current=$(do_facet mds1 $LCTL get_param -n \
24244                                                 lod.$mdtname.dom_stripesize)
24245         echo $dom_current
24246         [ 2147483648 -eq ${dom_current} ] &&
24247                 error "Can set too large DoM stripe limit"
24248
24249         do_facet mds1 $LCTL set_param -n \
24250                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24251         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24252                 error "Can't create DoM component size after limit change"
24253         do_facet mds1 $LCTL set_param -n \
24254                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24255         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24256                 error "Can't create DoM file after limit decrease"
24257         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24258                 error "Can create big DoM component after limit decrease"
24259         touch ${dom}_def ||
24260                 error "Can't create file with old default layout"
24261
24262         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24263         return 0
24264 }
24265 run_test 270f "DoM: maximum DoM stripe size checks"
24266
24267 test_270g() {
24268         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24269                 skip "Need MDS version at least 2.13.52"
24270         local dom=$DIR/$tdir/$tfile
24271
24272         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24273         local lodname=${FSNAME}-MDT0000-mdtlov
24274
24275         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24276         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24277         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24278         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24279
24280         local dom_limit=1024
24281         local dom_threshold="50%"
24282
24283         $LFS setstripe -d $DIR/$tdir
24284         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24285                 error "Can't set directory default striping"
24286
24287         do_facet mds1 $LCTL set_param -n \
24288                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24289         # set 0 threshold and create DOM file to change tunable stripesize
24290         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24291         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24292                 error "Failed to create $dom file"
24293         # now tunable dom_cur_stripesize should reach maximum
24294         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24295                                         lod.${lodname}.dom_stripesize_cur_kb)
24296         [[ $dom_current == $dom_limit ]] ||
24297                 error "Current DOM stripesize is not maximum"
24298         rm $dom
24299
24300         # set threshold for further tests
24301         do_facet mds1 $LCTL set_param -n \
24302                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24303         echo "DOM threshold is $dom_threshold free space"
24304         local dom_def
24305         local dom_set
24306         # Spoof bfree to exceed threshold
24307         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24308         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24309         for spfree in 40 20 0 15 30 55; do
24310                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24311                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24312                         error "Failed to create $dom file"
24313                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24314                                         lod.${lodname}.dom_stripesize_cur_kb)
24315                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24316                 [[ $dom_def != $dom_current ]] ||
24317                         error "Default stripe size was not changed"
24318                 if (( spfree > 0 )) ; then
24319                         dom_set=$($LFS getstripe -S $dom)
24320                         (( dom_set == dom_def * 1024 )) ||
24321                                 error "DOM component size is still old"
24322                 else
24323                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24324                                 error "DoM component is set with no free space"
24325                 fi
24326                 rm $dom
24327                 dom_current=$dom_def
24328         done
24329 }
24330 run_test 270g "DoM: default DoM stripe size depends on free space"
24331
24332 test_270h() {
24333         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24334                 skip "Need MDS version at least 2.13.53"
24335
24336         local mdtname=${FSNAME}-MDT0000-mdtlov
24337         local dom=$DIR/$tdir/$tfile
24338         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24339
24340         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24341         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24342
24343         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24344         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24345                 error "can't create OST file"
24346         # mirrored file with DOM entry in the second mirror
24347         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24348                 error "can't create mirror with DoM component"
24349
24350         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24351
24352         # DOM component in the middle and has other enries in the same mirror,
24353         # should succeed but lost DoM component
24354         $LFS setstripe --copy=${dom}_1 $dom ||
24355                 error "Can't create file from OST|DOM mirror layout"
24356         # check new file has no DoM layout after all
24357         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24358                 error "File has DoM component while DoM is disabled"
24359 }
24360 run_test 270h "DoM: DoM stripe removal when disabled on server"
24361
24362 test_270i() {
24363         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24364                 skip "Need MDS version at least 2.14.54"
24365
24366         mkdir $DIR/$tdir
24367         # DoM with plain layout
24368         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24369                 error "default plain layout with DoM must fail"
24370         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24371                 error "setstripe plain file layout with DoM must fail"
24372         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24373                 error "default DoM layout with bad striping must fail"
24374         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24375                 error "setstripe to DoM layout with bad striping must fail"
24376         return 0
24377 }
24378 run_test 270i "DoM: setting invalid DoM striping should fail"
24379
24380 test_270j() {
24381         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24382                 skip "Need MDS version at least 2.15.55.203"
24383
24384         local dom=$DIR/$tdir/$tfile
24385         local odv
24386         local ndv
24387
24388         mkdir -p $DIR/$tdir
24389
24390         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24391
24392         odv=$($LFS data_version $dom)
24393         chmod 666 $dom
24394         mv $dom ${dom}_moved
24395         link ${dom}_moved $dom
24396         setfattr -n user.attrx -v "some_attr" $dom
24397         ndv=$($LFS data_version $dom)
24398         (( $ndv == $odv )) ||
24399                 error "data version was changed by metadata operations"
24400
24401         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24402                 error "failed to write data into $dom"
24403         cancel_lru_locks mdc
24404         ndv=$($LFS data_version $dom)
24405         (( $ndv != $odv )) ||
24406                 error "data version wasn't changed on write"
24407
24408         odv=$ndv
24409         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24410         ndv=$($LFS data_version $dom)
24411         (( $ndv != $odv )) ||
24412                 error "data version wasn't changed on truncate down"
24413
24414         odv=$ndv
24415         $TRUNCATE $dom 25000
24416         ndv=$($LFS data_version $dom)
24417         (( $ndv != $odv )) ||
24418                 error "data version wasn't changed on truncate up"
24419
24420         # check also fallocate for ldiskfs
24421         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24422                 odv=$ndv
24423                 fallocate -l 1048576 $dom
24424                 ndv=$($LFS data_version $dom)
24425                 (( $ndv != $odv )) ||
24426                         error "data version wasn't changed on fallocate"
24427
24428                 odv=$ndv
24429                 fallocate -p --offset 4096 -l 4096 $dom
24430                 ndv=$($LFS data_version $dom)
24431                 (( $ndv != $odv )) ||
24432                         error "data version wasn't changed on fallocate punch"
24433         fi
24434 }
24435 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24436
24437 test_271a() {
24438         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24439                 skip "Need MDS version at least 2.10.55"
24440
24441         local dom=$DIR/$tdir/dom
24442
24443         mkdir -p $DIR/$tdir
24444
24445         $LFS setstripe -E 1024K -L mdt $dom
24446
24447         lctl set_param -n mdc.*.stats=clear
24448         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24449         cat $dom > /dev/null
24450         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24451         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24452         ls $dom
24453         rm -f $dom
24454 }
24455 run_test 271a "DoM: data is cached for read after write"
24456
24457 test_271b() {
24458         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24459                 skip "Need MDS version at least 2.10.55"
24460
24461         local dom=$DIR/$tdir/dom
24462
24463         mkdir -p $DIR/$tdir
24464
24465         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24466
24467         lctl set_param -n mdc.*.stats=clear
24468         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24469         cancel_lru_locks mdc
24470         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24471         # second stat to check size is cached on client
24472         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24473         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24474         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24475         rm -f $dom
24476 }
24477 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24478
24479 test_271ba() {
24480         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24481                 skip "Need MDS version at least 2.10.55"
24482
24483         local dom=$DIR/$tdir/dom
24484
24485         mkdir -p $DIR/$tdir
24486
24487         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24488
24489         lctl set_param -n mdc.*.stats=clear
24490         lctl set_param -n osc.*.stats=clear
24491         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24492         cancel_lru_locks mdc
24493         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24494         # second stat to check size is cached on client
24495         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24496         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24497         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24498         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24499         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24500         rm -f $dom
24501 }
24502 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24503
24504
24505 get_mdc_stats() {
24506         local mdtidx=$1
24507         local param=$2
24508         local mdt=MDT$(printf %04x $mdtidx)
24509
24510         if [ -z $param ]; then
24511                 lctl get_param -n mdc.*$mdt*.stats
24512         else
24513                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24514         fi
24515 }
24516
24517 test_271c() {
24518         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24519                 skip "Need MDS version at least 2.10.55"
24520
24521         local dom=$DIR/$tdir/dom
24522
24523         mkdir -p $DIR/$tdir
24524
24525         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24526
24527         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24528         local facet=mds$((mdtidx + 1))
24529
24530         cancel_lru_locks mdc
24531         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24532         createmany -o $dom 1000
24533         lctl set_param -n mdc.*.stats=clear
24534         smalliomany -w $dom 1000 200
24535         get_mdc_stats $mdtidx
24536         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24537         # Each file has 1 open, 1 IO enqueues, total 2000
24538         # but now we have also +1 getxattr for security.capability, total 3000
24539         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24540         unlinkmany $dom 1000
24541
24542         cancel_lru_locks mdc
24543         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24544         createmany -o $dom 1000
24545         lctl set_param -n mdc.*.stats=clear
24546         smalliomany -w $dom 1000 200
24547         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24548         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24549         # for OPEN and IO lock.
24550         [ $((enq - enq_2)) -ge 1000 ] ||
24551                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24552         unlinkmany $dom 1000
24553         return 0
24554 }
24555 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24556
24557 cleanup_271def_tests() {
24558         trap 0
24559         rm -f $1
24560 }
24561
24562 test_271d() {
24563         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24564                 skip "Need MDS version at least 2.10.57"
24565
24566         local dom=$DIR/$tdir/dom
24567         local tmp=$TMP/$tfile
24568         trap "cleanup_271def_tests $tmp" EXIT
24569
24570         mkdir -p $DIR/$tdir
24571
24572         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24573
24574         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24575
24576         cancel_lru_locks mdc
24577         dd if=/dev/urandom of=$tmp bs=1000 count=1
24578         dd if=$tmp of=$dom bs=1000 count=1
24579         cancel_lru_locks mdc
24580
24581         cat /etc/hosts >> $tmp
24582         lctl set_param -n mdc.*.stats=clear
24583
24584         # append data to the same file it should update local page
24585         echo "Append to the same page"
24586         cat /etc/hosts >> $dom
24587         local num=$(get_mdc_stats $mdtidx ost_read)
24588         local ra=$(get_mdc_stats $mdtidx req_active)
24589         local rw=$(get_mdc_stats $mdtidx req_waittime)
24590
24591         [ -z $num ] || error "$num READ RPC occured"
24592         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24593         echo "... DONE"
24594
24595         # compare content
24596         cmp $tmp $dom || error "file miscompare"
24597
24598         cancel_lru_locks mdc
24599         lctl set_param -n mdc.*.stats=clear
24600
24601         echo "Open and read file"
24602         cat $dom > /dev/null
24603         local num=$(get_mdc_stats $mdtidx ost_read)
24604         local ra=$(get_mdc_stats $mdtidx req_active)
24605         local rw=$(get_mdc_stats $mdtidx req_waittime)
24606
24607         [ -z $num ] || error "$num READ RPC occured"
24608         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24609         echo "... DONE"
24610
24611         # compare content
24612         cmp $tmp $dom || error "file miscompare"
24613
24614         return 0
24615 }
24616 run_test 271d "DoM: read on open (1K file in reply buffer)"
24617
24618 test_271f() {
24619         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24620                 skip "Need MDS version at least 2.10.57"
24621
24622         local dom=$DIR/$tdir/dom
24623         local tmp=$TMP/$tfile
24624         trap "cleanup_271def_tests $tmp" EXIT
24625
24626         mkdir -p $DIR/$tdir
24627
24628         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24629
24630         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24631
24632         cancel_lru_locks mdc
24633         dd if=/dev/urandom of=$tmp bs=265000 count=1
24634         dd if=$tmp of=$dom bs=265000 count=1
24635         cancel_lru_locks mdc
24636         cat /etc/hosts >> $tmp
24637         lctl set_param -n mdc.*.stats=clear
24638
24639         echo "Append to the same page"
24640         cat /etc/hosts >> $dom
24641         local num=$(get_mdc_stats $mdtidx ost_read)
24642         local ra=$(get_mdc_stats $mdtidx req_active)
24643         local rw=$(get_mdc_stats $mdtidx req_waittime)
24644
24645         [ -z $num ] || error "$num READ RPC occured"
24646         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24647         echo "... DONE"
24648
24649         # compare content
24650         cmp $tmp $dom || error "file miscompare"
24651
24652         cancel_lru_locks mdc
24653         lctl set_param -n mdc.*.stats=clear
24654
24655         echo "Open and read file"
24656         cat $dom > /dev/null
24657         local num=$(get_mdc_stats $mdtidx ost_read)
24658         local ra=$(get_mdc_stats $mdtidx req_active)
24659         local rw=$(get_mdc_stats $mdtidx req_waittime)
24660
24661         [ -z $num ] && num=0
24662         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24663         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24664         echo "... DONE"
24665
24666         # compare content
24667         cmp $tmp $dom || error "file miscompare"
24668
24669         return 0
24670 }
24671 run_test 271f "DoM: read on open (200K file and read tail)"
24672
24673 test_271g() {
24674         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24675                 skip "Skipping due to old client or server version"
24676
24677         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24678         # to get layout
24679         $CHECKSTAT -t file $DIR1/$tfile
24680
24681         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24682         MULTIOP_PID=$!
24683         sleep 1
24684         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24685         $LCTL set_param fail_loc=0x80000314
24686         rm $DIR1/$tfile || error "Unlink fails"
24687         RC=$?
24688         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24689         [ $RC -eq 0 ] || error "Failed write to stale object"
24690 }
24691 run_test 271g "Discard DoM data vs client flush race"
24692
24693 test_272a() {
24694         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24695                 skip "Need MDS version at least 2.11.50"
24696
24697         local dom=$DIR/$tdir/dom
24698         mkdir -p $DIR/$tdir
24699
24700         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24701         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24702                 error "failed to write data into $dom"
24703         local old_md5=$(md5sum $dom)
24704
24705         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24706                 error "failed to migrate to the same DoM component"
24707
24708         local new_md5=$(md5sum $dom)
24709
24710         [ "$old_md5" == "$new_md5" ] ||
24711                 error "md5sum differ: $old_md5, $new_md5"
24712
24713         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24714                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24715 }
24716 run_test 272a "DoM migration: new layout with the same DOM component"
24717
24718 test_272b() {
24719         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24720                 skip "Need MDS version at least 2.11.50"
24721
24722         local dom=$DIR/$tdir/dom
24723         mkdir -p $DIR/$tdir
24724         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24725         stack_trap "rm -rf $DIR/$tdir"
24726
24727         local mdtidx=$($LFS getstripe -m $dom)
24728         local mdtname=MDT$(printf %04x $mdtidx)
24729         local facet=mds$((mdtidx + 1))
24730
24731         local mdtfree1=$(do_facet $facet \
24732                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24733         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24734                 error "failed to write data into $dom"
24735         local old_md5=$(md5sum $dom)
24736         cancel_lru_locks mdc
24737         local mdtfree1=$(do_facet $facet \
24738                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24739
24740         $LFS migrate -c2 $dom ||
24741                 error "failed to migrate to the new composite layout"
24742         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24743                 error "MDT stripe was not removed"
24744         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24745                 error "$dir1 shouldn't have DATAVER EA"
24746
24747         cancel_lru_locks mdc
24748         local new_md5=$(md5sum $dom)
24749         [ "$old_md5" == "$new_md5" ] ||
24750                 error "$old_md5 != $new_md5"
24751
24752         # Skip free space checks with ZFS
24753         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24754                 local mdtfree2=$(do_facet $facet \
24755                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24756                 [ $mdtfree2 -gt $mdtfree1 ] ||
24757                         error "MDT space is not freed after migration"
24758         fi
24759         return 0
24760 }
24761 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24762
24763 test_272c() {
24764         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24765                 skip "Need MDS version at least 2.11.50"
24766
24767         local dom=$DIR/$tdir/$tfile
24768         mkdir -p $DIR/$tdir
24769         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24770         stack_trap "rm -rf $DIR/$tdir"
24771
24772         local mdtidx=$($LFS getstripe -m $dom)
24773         local mdtname=MDT$(printf %04x $mdtidx)
24774         local facet=mds$((mdtidx + 1))
24775
24776         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24777                 error "failed to write data into $dom"
24778         local old_md5=$(md5sum $dom)
24779         cancel_lru_locks mdc
24780         local mdtfree1=$(do_facet $facet \
24781                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24782
24783         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24784                 error "failed to migrate to the new composite layout"
24785         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24786                 error "MDT stripe was not removed"
24787
24788         cancel_lru_locks mdc
24789         local new_md5=$(md5sum $dom)
24790         [ "$old_md5" == "$new_md5" ] ||
24791                 error "$old_md5 != $new_md5"
24792
24793         # Skip free space checks with ZFS
24794         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24795                 local mdtfree2=$(do_facet $facet \
24796                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24797                 [ $mdtfree2 -gt $mdtfree1 ] ||
24798                         error "MDS space is not freed after migration"
24799         fi
24800         return 0
24801 }
24802 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24803
24804 test_272d() {
24805         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24806                 skip "Need MDS version at least 2.12.55"
24807
24808         local dom=$DIR/$tdir/$tfile
24809         mkdir -p $DIR/$tdir
24810         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24811
24812         local mdtidx=$($LFS getstripe -m $dom)
24813         local mdtname=MDT$(printf %04x $mdtidx)
24814         local facet=mds$((mdtidx + 1))
24815
24816         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24817                 error "failed to write data into $dom"
24818         local old_md5=$(md5sum $dom)
24819         cancel_lru_locks mdc
24820         local mdtfree1=$(do_facet $facet \
24821                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24822
24823         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24824                 error "failed mirroring to the new composite layout"
24825         $LFS mirror resync $dom ||
24826                 error "failed mirror resync"
24827         $LFS mirror split --mirror-id 1 -d $dom ||
24828                 error "failed mirror split"
24829
24830         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24831                 error "MDT stripe was not removed"
24832
24833         cancel_lru_locks mdc
24834         local new_md5=$(md5sum $dom)
24835         [ "$old_md5" == "$new_md5" ] ||
24836                 error "$old_md5 != $new_md5"
24837
24838         # Skip free space checks with ZFS
24839         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24840                 local mdtfree2=$(do_facet $facet \
24841                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24842                 [ $mdtfree2 -gt $mdtfree1 ] ||
24843                         error "MDS space is not freed after DOM mirror deletion"
24844         fi
24845         return 0
24846 }
24847 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24848
24849 test_272e() {
24850         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24851                 skip "Need MDS version at least 2.12.55"
24852
24853         local dom=$DIR/$tdir/$tfile
24854         mkdir -p $DIR/$tdir
24855         $LFS setstripe -c 2 $dom
24856
24857         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24858                 error "failed to write data into $dom"
24859         local old_md5=$(md5sum $dom)
24860         cancel_lru_locks
24861
24862         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24863                 error "failed mirroring to the DOM layout"
24864         $LFS mirror resync $dom ||
24865                 error "failed mirror resync"
24866         $LFS mirror split --mirror-id 1 -d $dom ||
24867                 error "failed mirror split"
24868
24869         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24870                 error "MDT stripe wasn't set"
24871
24872         cancel_lru_locks
24873         local new_md5=$(md5sum $dom)
24874         [ "$old_md5" == "$new_md5" ] ||
24875                 error "$old_md5 != $new_md5"
24876
24877         return 0
24878 }
24879 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24880
24881 test_272f() {
24882         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24883                 skip "Need MDS version at least 2.12.55"
24884
24885         local dom=$DIR/$tdir/$tfile
24886         mkdir -p $DIR/$tdir
24887         $LFS setstripe -c 2 $dom
24888
24889         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24890                 error "failed to write data into $dom"
24891         local old_md5=$(md5sum $dom)
24892         cancel_lru_locks
24893
24894         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24895                 error "failed migrating to the DOM file"
24896
24897         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24898                 error "MDT stripe wasn't set"
24899
24900         cancel_lru_locks
24901         local new_md5=$(md5sum $dom)
24902         [ "$old_md5" != "$new_md5" ] &&
24903                 error "$old_md5 != $new_md5"
24904
24905         return 0
24906 }
24907 run_test 272f "DoM migration: OST-striped file to DOM file"
24908
24909 test_273a() {
24910         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24911                 skip "Need MDS version at least 2.11.50"
24912
24913         # Layout swap cannot be done if either file has DOM component,
24914         # this will never be supported, migration should be used instead
24915
24916         local dom=$DIR/$tdir/$tfile
24917         mkdir -p $DIR/$tdir
24918
24919         $LFS setstripe -c2 ${dom}_plain
24920         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24921         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24922                 error "can swap layout with DoM component"
24923         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24924                 error "can swap layout with DoM component"
24925
24926         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24927         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24928                 error "can swap layout with DoM component"
24929         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24930                 error "can swap layout with DoM component"
24931         return 0
24932 }
24933 run_test 273a "DoM: layout swapping should fail with DOM"
24934
24935 test_273b() {
24936         mkdir -p $DIR/$tdir
24937         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24938
24939 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24940         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24941
24942         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24943 }
24944 run_test 273b "DoM: race writeback and object destroy"
24945
24946 test_273c() {
24947         mkdir -p $DIR/$tdir
24948         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24949
24950         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24951         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24952
24953         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24954 }
24955 run_test 273c "race writeback and object destroy"
24956
24957 test_275() {
24958         remote_ost_nodsh && skip "remote OST with nodsh"
24959         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24960                 skip "Need OST version >= 2.10.57"
24961
24962         local file=$DIR/$tfile
24963         local oss
24964
24965         oss=$(comma_list $(osts_nodes))
24966
24967         dd if=/dev/urandom of=$file bs=1M count=2 ||
24968                 error "failed to create a file"
24969         stack_trap "rm -f $file"
24970         cancel_lru_locks osc
24971
24972         #lock 1
24973         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24974                 error "failed to read a file"
24975
24976 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24977         $LCTL set_param fail_loc=0x8000031f
24978
24979         cancel_lru_locks osc &
24980         sleep 1
24981
24982 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24983         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24984         #IO takes another lock, but matches the PENDING one
24985         #and places it to the IO RPC
24986         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24987                 error "failed to read a file with PENDING lock"
24988 }
24989 run_test 275 "Read on a canceled duplicate lock"
24990
24991 test_276() {
24992         remote_ost_nodsh && skip "remote OST with nodsh"
24993         local pid
24994
24995         do_facet ost1 "(while true; do \
24996                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24997                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24998         pid=$!
24999
25000         for LOOP in $(seq 20); do
25001                 stop ost1
25002                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25003         done
25004         kill -9 $pid
25005         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25006                 rm $TMP/sanity_276_pid"
25007 }
25008 run_test 276 "Race between mount and obd_statfs"
25009
25010 test_277() {
25011         $LCTL set_param ldlm.namespaces.*.lru_size=0
25012         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25013         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25014                           awk '/^used_mb/ { print $2 }')
25015         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25016         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25017                 oflag=direct conv=notrunc
25018         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25019                     awk '/^used_mb/ { print $2 }')
25020         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25021 }
25022 run_test 277 "Direct IO shall drop page cache"
25023
25024 test_278() {
25025         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25026         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25027         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25028                 skip "needs the same host for mdt1 mdt2" && return
25029
25030         local pid1
25031         local pid2
25032
25033 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25034         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25035         stop mds2 &
25036         pid2=$!
25037
25038         stop mds1
25039
25040         echo "Starting MDTs"
25041         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25042         wait $pid2
25043 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25044 #will return NULL
25045         do_facet mds2 $LCTL set_param fail_loc=0
25046
25047         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25048         wait_recovery_complete mds2
25049 }
25050 run_test 278 "Race starting MDS between MDTs stop/start"
25051
25052 test_280() {
25053         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25054                 skip "Need MGS version at least 2.13.52"
25055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25056         combined_mgs_mds || skip "needs combined MGS/MDT"
25057
25058         umount_client $MOUNT
25059 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25060         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25061
25062         mount_client $MOUNT &
25063         sleep 1
25064         stop mgs || error "stop mgs failed"
25065         #for a race mgs would crash
25066         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25067         # make sure we unmount client before remounting
25068         wait
25069         umount_client $MOUNT
25070         mount_client $MOUNT || error "mount client failed"
25071 }
25072 run_test 280 "Race between MGS umount and client llog processing"
25073
25074 cleanup_test_300() {
25075         trap 0
25076         umask $SAVE_UMASK
25077 }
25078 test_striped_dir() {
25079         local mdt_index=$1
25080         local stripe_count
25081         local stripe_index
25082
25083         mkdir -p $DIR/$tdir
25084
25085         SAVE_UMASK=$(umask)
25086         trap cleanup_test_300 RETURN EXIT
25087
25088         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25089                                                 $DIR/$tdir/striped_dir ||
25090                 error "set striped dir error"
25091
25092         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25093         [ "$mode" = "755" ] || error "expect 755 got $mode"
25094
25095         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25096                 error "getdirstripe failed"
25097         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25098         if [ "$stripe_count" != "2" ]; then
25099                 error "1:stripe_count is $stripe_count, expect 2"
25100         fi
25101         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25102         if [ "$stripe_count" != "2" ]; then
25103                 error "2:stripe_count is $stripe_count, expect 2"
25104         fi
25105
25106         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25107         if [ "$stripe_index" != "$mdt_index" ]; then
25108                 error "stripe_index is $stripe_index, expect $mdt_index"
25109         fi
25110
25111         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25112                 error "nlink error after create striped dir"
25113
25114         mkdir $DIR/$tdir/striped_dir/a
25115         mkdir $DIR/$tdir/striped_dir/b
25116
25117         stat $DIR/$tdir/striped_dir/a ||
25118                 error "create dir under striped dir failed"
25119         stat $DIR/$tdir/striped_dir/b ||
25120                 error "create dir under striped dir failed"
25121
25122         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25123                 error "nlink error after mkdir"
25124
25125         rmdir $DIR/$tdir/striped_dir/a
25126         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25127                 error "nlink error after rmdir"
25128
25129         rmdir $DIR/$tdir/striped_dir/b
25130         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25131                 error "nlink error after rmdir"
25132
25133         chattr +i $DIR/$tdir/striped_dir
25134         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25135                 error "immutable flags not working under striped dir!"
25136         chattr -i $DIR/$tdir/striped_dir
25137
25138         rmdir $DIR/$tdir/striped_dir ||
25139                 error "rmdir striped dir error"
25140
25141         cleanup_test_300
25142
25143         true
25144 }
25145
25146 test_300a() {
25147         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25148                 skip "skipped for lustre < 2.7.0"
25149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25151
25152         test_striped_dir 0 || error "failed on striped dir on MDT0"
25153         test_striped_dir 1 || error "failed on striped dir on MDT0"
25154 }
25155 run_test 300a "basic striped dir sanity test"
25156
25157 test_300b() {
25158         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25159                 skip "skipped for lustre < 2.7.0"
25160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25161         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25162
25163         local i
25164         local mtime1
25165         local mtime2
25166         local mtime3
25167
25168         test_mkdir $DIR/$tdir || error "mkdir fail"
25169         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25170                 error "set striped dir error"
25171         for i in {0..9}; do
25172                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25173                 sleep 1
25174                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25175                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25176                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25177                 sleep 1
25178                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25179                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25180                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25181         done
25182         true
25183 }
25184 run_test 300b "check ctime/mtime for striped dir"
25185
25186 test_300c() {
25187         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25188                 skip "skipped for lustre < 2.7.0"
25189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25191
25192         local file_count
25193
25194         mkdir_on_mdt0 $DIR/$tdir
25195         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25196                 error "set striped dir error"
25197
25198         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25199                 error "chown striped dir failed"
25200
25201         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25202                 error "create 5k files failed"
25203
25204         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25205
25206         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25207
25208         rm -rf $DIR/$tdir
25209 }
25210 run_test 300c "chown && check ls under striped directory"
25211
25212 test_300d() {
25213         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25214                 skip "skipped for lustre < 2.7.0"
25215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25217
25218         local stripe_count
25219         local file
25220
25221         mkdir -p $DIR/$tdir
25222         $LFS setstripe -c 2 $DIR/$tdir
25223
25224         #local striped directory
25225         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25226                 error "set striped dir error"
25227         #look at the directories for debug purposes
25228         ls -l $DIR/$tdir
25229         $LFS getdirstripe $DIR/$tdir
25230         ls -l $DIR/$tdir/striped_dir
25231         $LFS getdirstripe $DIR/$tdir/striped_dir
25232         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25233                 error "create 10 files failed"
25234
25235         #remote striped directory
25236         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25237                 error "set striped dir error"
25238         #look at the directories for debug purposes
25239         ls -l $DIR/$tdir
25240         $LFS getdirstripe $DIR/$tdir
25241         ls -l $DIR/$tdir/remote_striped_dir
25242         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25243         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25244                 error "create 10 files failed"
25245
25246         for file in $(find $DIR/$tdir); do
25247                 stripe_count=$($LFS getstripe -c $file)
25248                 [ $stripe_count -eq 2 ] ||
25249                         error "wrong stripe $stripe_count for $file"
25250         done
25251
25252         rm -rf $DIR/$tdir
25253 }
25254 run_test 300d "check default stripe under striped directory"
25255
25256 test_300e() {
25257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25258                 skip "Need MDS version at least 2.7.55"
25259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25261
25262         local stripe_count
25263         local file
25264
25265         mkdir -p $DIR/$tdir
25266
25267         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25268                 error "set striped dir error"
25269
25270         touch $DIR/$tdir/striped_dir/a
25271         touch $DIR/$tdir/striped_dir/b
25272         touch $DIR/$tdir/striped_dir/c
25273
25274         mkdir $DIR/$tdir/striped_dir/dir_a
25275         mkdir $DIR/$tdir/striped_dir/dir_b
25276         mkdir $DIR/$tdir/striped_dir/dir_c
25277
25278         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25279                 error "set striped adir under striped dir error"
25280
25281         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25282                 error "set striped bdir under striped dir error"
25283
25284         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25285                 error "set striped cdir under striped dir error"
25286
25287         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25288                 error "rename dir under striped dir fails"
25289
25290         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25291                 error "rename dir under different stripes fails"
25292
25293         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25294                 error "rename file under striped dir should succeed"
25295
25296         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25297                 error "rename dir under striped dir should succeed"
25298
25299         rm -rf $DIR/$tdir
25300 }
25301 run_test 300e "check rename under striped directory"
25302
25303 test_300f() {
25304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25306         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25307                 skip "Need MDS version at least 2.7.55"
25308
25309         local stripe_count
25310         local file
25311
25312         rm -rf $DIR/$tdir
25313         mkdir -p $DIR/$tdir
25314
25315         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25316                 error "set striped dir error"
25317
25318         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25319                 error "set striped dir error"
25320
25321         touch $DIR/$tdir/striped_dir/a
25322         mkdir $DIR/$tdir/striped_dir/dir_a
25323         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25324                 error "create striped dir under striped dir fails"
25325
25326         touch $DIR/$tdir/striped_dir1/b
25327         mkdir $DIR/$tdir/striped_dir1/dir_b
25328         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25329                 error "create striped dir under striped dir fails"
25330
25331         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25332                 error "rename dir under different striped dir should fail"
25333
25334         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25335                 error "rename striped dir under diff striped dir should fail"
25336
25337         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25338                 error "rename file under diff striped dirs fails"
25339
25340         rm -rf $DIR/$tdir
25341 }
25342 run_test 300f "check rename cross striped directory"
25343
25344 test_300_check_default_striped_dir()
25345 {
25346         local dirname=$1
25347         local default_count=$2
25348         local default_index=$3
25349         local stripe_count
25350         local stripe_index
25351         local dir_stripe_index
25352         local dir
25353
25354         echo "checking $dirname $default_count $default_index"
25355         $LFS setdirstripe -D -c $default_count -i $default_index \
25356                                 -H all_char $DIR/$tdir/$dirname ||
25357                 error "set default stripe on striped dir error"
25358         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25359         [ $stripe_count -eq $default_count ] ||
25360                 error "expect $default_count get $stripe_count for $dirname"
25361
25362         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25363         [ $stripe_index -eq $default_index ] ||
25364                 error "expect $default_index get $stripe_index for $dirname"
25365
25366         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25367                                                 error "create dirs failed"
25368
25369         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25370         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25371         for dir in $(find $DIR/$tdir/$dirname/*); do
25372                 stripe_count=$($LFS getdirstripe -c $dir)
25373                 (( $stripe_count == $default_count )) ||
25374                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25375                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25376                 error "stripe count $default_count != $stripe_count for $dir"
25377
25378                 stripe_index=$($LFS getdirstripe -i $dir)
25379                 [ $default_index -eq -1 ] ||
25380                         [ $stripe_index -eq $default_index ] ||
25381                         error "$stripe_index != $default_index for $dir"
25382
25383                 #check default stripe
25384                 stripe_count=$($LFS getdirstripe -D -c $dir)
25385                 [ $stripe_count -eq $default_count ] ||
25386                 error "default count $default_count != $stripe_count for $dir"
25387
25388                 stripe_index=$($LFS getdirstripe -D -i $dir)
25389                 [ $stripe_index -eq $default_index ] ||
25390                 error "default index $default_index != $stripe_index for $dir"
25391         done
25392         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25393 }
25394
25395 test_300g() {
25396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25397         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25398                 skip "Need MDS version at least 2.7.55"
25399
25400         local dir
25401         local stripe_count
25402         local stripe_index
25403
25404         mkdir_on_mdt0 $DIR/$tdir
25405         mkdir $DIR/$tdir/normal_dir
25406
25407         #Checking when client cache stripe index
25408         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25409         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25410                 error "create striped_dir failed"
25411
25412         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25413                 error "create dir0 fails"
25414         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25415         [ $stripe_index -eq 0 ] ||
25416                 error "dir0 expect index 0 got $stripe_index"
25417
25418         mkdir $DIR/$tdir/striped_dir/dir1 ||
25419                 error "create dir1 fails"
25420         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25421         [ $stripe_index -eq 1 ] ||
25422                 error "dir1 expect index 1 got $stripe_index"
25423
25424         #check default stripe count/stripe index
25425         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25426         test_300_check_default_striped_dir normal_dir 1 0
25427         test_300_check_default_striped_dir normal_dir -1 1
25428         test_300_check_default_striped_dir normal_dir 2 -1
25429
25430         #delete default stripe information
25431         echo "delete default stripeEA"
25432         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25433                 error "set default stripe on striped dir error"
25434
25435         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25436         for dir in $(find $DIR/$tdir/normal_dir/*); do
25437                 stripe_count=$($LFS getdirstripe -c $dir)
25438                 [ $stripe_count -eq 0 ] ||
25439                         error "expect 1 get $stripe_count for $dir"
25440         done
25441 }
25442 run_test 300g "check default striped directory for normal directory"
25443
25444 test_300h() {
25445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25446         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25447                 skip "Need MDS version at least 2.7.55"
25448
25449         local dir
25450         local stripe_count
25451
25452         mkdir $DIR/$tdir
25453         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25454                 error "set striped dir error"
25455
25456         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25457         test_300_check_default_striped_dir striped_dir 1 0
25458         test_300_check_default_striped_dir striped_dir -1 1
25459         test_300_check_default_striped_dir striped_dir 2 -1
25460
25461         #delete default stripe information
25462         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25463                 error "set default stripe on striped dir error"
25464
25465         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25466         for dir in $(find $DIR/$tdir/striped_dir/*); do
25467                 stripe_count=$($LFS getdirstripe -c $dir)
25468                 [ $stripe_count -eq 0 ] ||
25469                         error "expect 1 get $stripe_count for $dir"
25470         done
25471 }
25472 run_test 300h "check default striped directory for striped directory"
25473
25474 test_300i() {
25475         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25476         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25477         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25478                 skip "Need MDS version at least 2.7.55"
25479
25480         local stripe_count
25481         local file
25482
25483         mkdir $DIR/$tdir
25484
25485         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25486                 error "set striped dir error"
25487
25488         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25489                 error "create files under striped dir failed"
25490
25491         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25492                 error "set striped hashdir error"
25493
25494         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25495                 error "create dir0 under hash dir failed"
25496         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25497                 error "create dir1 under hash dir failed"
25498         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25499                 error "create dir2 under hash dir failed"
25500
25501         # unfortunately, we need to umount to clear dir layout cache for now
25502         # once we fully implement dir layout, we can drop this
25503         umount_client $MOUNT || error "umount failed"
25504         mount_client $MOUNT || error "mount failed"
25505
25506         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25507         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25508         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25509
25510         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25511                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25512                         error "create crush2 dir $tdir/hashdir/d3 failed"
25513                 $LFS find -H crush2 $DIR/$tdir/hashdir
25514                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25515                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25516
25517                 # mkdir with an invalid hash type (hash=fail_val) from client
25518                 # should be replaced on MDS with a valid (default) hash type
25519                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25520                 $LCTL set_param fail_loc=0x1901 fail_val=99
25521                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25522
25523                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25524                 local expect=$(do_facet mds1 \
25525                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25526                 [[ $hash == $expect ]] ||
25527                         error "d99 hash '$hash' != expected hash '$expect'"
25528         fi
25529
25530         #set the stripe to be unknown hash type on read
25531         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25532         $LCTL set_param fail_loc=0x1901 fail_val=99
25533         for ((i = 0; i < 10; i++)); do
25534                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25535                         error "stat f-$i failed"
25536                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25537         done
25538
25539         touch $DIR/$tdir/striped_dir/f0 &&
25540                 error "create under striped dir with unknown hash should fail"
25541
25542         $LCTL set_param fail_loc=0
25543
25544         umount_client $MOUNT || error "umount failed"
25545         mount_client $MOUNT || error "mount failed"
25546
25547         return 0
25548 }
25549 run_test 300i "client handle unknown hash type striped directory"
25550
25551 test_300j() {
25552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25554         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25555                 skip "Need MDS version at least 2.7.55"
25556
25557         local stripe_count
25558         local file
25559
25560         mkdir $DIR/$tdir
25561
25562         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25563         $LCTL set_param fail_loc=0x1702
25564         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25565                 error "set striped dir error"
25566
25567         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25568                 error "create files under striped dir failed"
25569
25570         $LCTL set_param fail_loc=0
25571
25572         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25573
25574         return 0
25575 }
25576 run_test 300j "test large update record"
25577
25578 test_300k() {
25579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25581         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25582                 skip "Need MDS version at least 2.7.55"
25583
25584         # this test needs a huge transaction
25585         local kb
25586         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25587              osd*.$FSNAME-MDT0000.kbytestotal")
25588         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25589
25590         local stripe_count
25591         local file
25592
25593         mkdir $DIR/$tdir
25594
25595         #define OBD_FAIL_LARGE_STRIPE   0x1703
25596         $LCTL set_param fail_loc=0x1703
25597         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25598                 error "set striped dir error"
25599         $LCTL set_param fail_loc=0
25600
25601         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25602                 error "getstripeddir fails"
25603         rm -rf $DIR/$tdir/striped_dir ||
25604                 error "unlink striped dir fails"
25605
25606         return 0
25607 }
25608 run_test 300k "test large striped directory"
25609
25610 test_300l() {
25611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25613         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25614                 skip "Need MDS version at least 2.7.55"
25615
25616         local stripe_index
25617
25618         test_mkdir -p $DIR/$tdir/striped_dir
25619         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25620                         error "chown $RUNAS_ID failed"
25621         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25622                 error "set default striped dir failed"
25623
25624         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25625         $LCTL set_param fail_loc=0x80000158
25626         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25627
25628         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25629         [ $stripe_index -eq 1 ] ||
25630                 error "expect 1 get $stripe_index for $dir"
25631 }
25632 run_test 300l "non-root user to create dir under striped dir with stale layout"
25633
25634 test_300m() {
25635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25636         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25637         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25638                 skip "Need MDS version at least 2.7.55"
25639
25640         mkdir -p $DIR/$tdir/striped_dir
25641         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25642                 error "set default stripes dir error"
25643
25644         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25645
25646         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25647         [ $stripe_count -eq 0 ] ||
25648                         error "expect 0 get $stripe_count for a"
25649
25650         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25651                 error "set default stripes dir error"
25652
25653         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25654
25655         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25656         [ $stripe_count -eq 0 ] ||
25657                         error "expect 0 get $stripe_count for b"
25658
25659         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25660                 error "set default stripes dir error"
25661
25662         mkdir $DIR/$tdir/striped_dir/c &&
25663                 error "default stripe_index is invalid, mkdir c should fails"
25664
25665         rm -rf $DIR/$tdir || error "rmdir fails"
25666 }
25667 run_test 300m "setstriped directory on single MDT FS"
25668
25669 cleanup_300n() {
25670         local list=$(comma_list $(mdts_nodes))
25671
25672         trap 0
25673         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25674 }
25675
25676 test_300n() {
25677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25679         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25680                 skip "Need MDS version at least 2.7.55"
25681         remote_mds_nodsh && skip "remote MDS with nodsh"
25682
25683         local stripe_index
25684         local list=$(comma_list $(mdts_nodes))
25685
25686         trap cleanup_300n RETURN EXIT
25687         mkdir -p $DIR/$tdir
25688         chmod 777 $DIR/$tdir
25689         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25690                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25691                 error "create striped dir succeeds with gid=0"
25692
25693         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25694         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25695                 error "create striped dir fails with gid=-1"
25696
25697         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25698         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25699                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25700                 error "set default striped dir succeeds with gid=0"
25701
25702
25703         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25704         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25705                 error "set default striped dir fails with gid=-1"
25706
25707
25708         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25709         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25710                                         error "create test_dir fails"
25711         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25712                                         error "create test_dir1 fails"
25713         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25714                                         error "create test_dir2 fails"
25715         cleanup_300n
25716 }
25717 run_test 300n "non-root user to create dir under striped dir with default EA"
25718
25719 test_300o() {
25720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25721         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25722         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25723                 skip "Need MDS version at least 2.7.55"
25724
25725         local numfree1
25726         local numfree2
25727
25728         mkdir -p $DIR/$tdir
25729
25730         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25731         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25732         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25733                 skip "not enough free inodes $numfree1 $numfree2"
25734         fi
25735
25736         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25737         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25738         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25739                 skip "not enough free space $numfree1 $numfree2"
25740         fi
25741
25742         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25743                 error "setdirstripe fails"
25744
25745         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25746                 error "create dirs fails"
25747
25748         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25749         ls $DIR/$tdir/striped_dir > /dev/null ||
25750                 error "ls striped dir fails"
25751         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25752                 error "unlink big striped dir fails"
25753 }
25754 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25755
25756 test_300p() {
25757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25759         remote_mds_nodsh && skip "remote MDS with nodsh"
25760
25761         mkdir_on_mdt0 $DIR/$tdir
25762
25763         #define OBD_FAIL_OUT_ENOSPC     0x1704
25764         do_facet mds2 lctl set_param fail_loc=0x80001704
25765         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25766                  && error "create striped directory should fail"
25767
25768         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25769
25770         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25771         true
25772 }
25773 run_test 300p "create striped directory without space"
25774
25775 test_300q() {
25776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25777         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25778
25779         local fd=$(free_fd)
25780         local cmd="exec $fd<$tdir"
25781         cd $DIR
25782         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25783         eval $cmd
25784         cmd="exec $fd<&-"
25785         trap "eval $cmd" EXIT
25786         cd $tdir || error "cd $tdir fails"
25787         rmdir  ../$tdir || error "rmdir $tdir fails"
25788         mkdir local_dir && error "create dir succeeds"
25789         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25790         eval $cmd
25791         return 0
25792 }
25793 run_test 300q "create remote directory under orphan directory"
25794
25795 test_300r() {
25796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25797                 skip "Need MDS version at least 2.7.55" && return
25798         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25799
25800         mkdir $DIR/$tdir
25801
25802         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25803                 error "set striped dir error"
25804
25805         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25806                 error "getstripeddir fails"
25807
25808         local stripe_count
25809         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25810                       awk '/lmv_stripe_count:/ { print $2 }')
25811
25812         [ $MDSCOUNT -ne $stripe_count ] &&
25813                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25814
25815         rm -rf $DIR/$tdir/striped_dir ||
25816                 error "unlink striped dir fails"
25817 }
25818 run_test 300r "test -1 striped directory"
25819
25820 test_300s_helper() {
25821         local count=$1
25822
25823         local stripe_dir=$DIR/$tdir/striped_dir.$count
25824
25825         $LFS mkdir -c $count $stripe_dir ||
25826                 error "lfs mkdir -c error"
25827
25828         $LFS getdirstripe $stripe_dir ||
25829                 error "lfs getdirstripe fails"
25830
25831         local stripe_count
25832         stripe_count=$($LFS getdirstripe $stripe_dir |
25833                       awk '/lmv_stripe_count:/ { print $2 }')
25834
25835         [ $count -ne $stripe_count ] &&
25836                 error_noexit "bad stripe count $stripe_count expected $count"
25837
25838         local dupe_stripes
25839         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25840                 awk '/0x/ {count[$1] += 1}; END {
25841                         for (idx in count) {
25842                                 if (count[idx]>1) {
25843                                         print "index " idx " count " count[idx]
25844                                 }
25845                         }
25846                 }')
25847
25848         if [[ -n "$dupe_stripes" ]] ; then
25849                 lfs getdirstripe $stripe_dir
25850                 error_noexit "Dupe MDT above: $dupe_stripes "
25851         fi
25852
25853         rm -rf $stripe_dir ||
25854                 error_noexit "unlink $stripe_dir fails"
25855 }
25856
25857 test_300s() {
25858         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25859                 skip "Need MDS version at least 2.7.55" && return
25860         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25861
25862         mkdir $DIR/$tdir
25863         for count in $(seq 2 $MDSCOUNT); do
25864                 test_300s_helper $count
25865         done
25866 }
25867 run_test 300s "test lfs mkdir -c without -i"
25868
25869 test_300t() {
25870         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25871                 skip "need MDS 2.14.55 or later"
25872         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25873
25874         local testdir="$DIR/$tdir/striped_dir"
25875         local dir1=$testdir/dir1
25876         local dir2=$testdir/dir2
25877
25878         mkdir -p $testdir
25879
25880         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25881                 error "failed to set default stripe count for $testdir"
25882
25883         mkdir $dir1
25884         local stripe_count=$($LFS getdirstripe -c $dir1)
25885
25886         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25887
25888         local max_count=$((MDSCOUNT - 1))
25889         local mdts=$(comma_list $(mdts_nodes))
25890
25891         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25892         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25893
25894         mkdir $dir2
25895         stripe_count=$($LFS getdirstripe -c $dir2)
25896
25897         (( $stripe_count == $max_count )) || error "wrong stripe count"
25898 }
25899 run_test 300t "test max_mdt_stripecount"
25900
25901 prepare_remote_file() {
25902         mkdir $DIR/$tdir/src_dir ||
25903                 error "create remote source failed"
25904
25905         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25906                  error "cp to remote source failed"
25907         touch $DIR/$tdir/src_dir/a
25908
25909         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25910                 error "create remote target dir failed"
25911
25912         touch $DIR/$tdir/tgt_dir/b
25913
25914         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25915                 error "rename dir cross MDT failed!"
25916
25917         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25918                 error "src_child still exists after rename"
25919
25920         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25921                 error "missing file(a) after rename"
25922
25923         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25924                 error "diff after rename"
25925 }
25926
25927 test_310a() {
25928         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25930
25931         local remote_file=$DIR/$tdir/tgt_dir/b
25932
25933         mkdir -p $DIR/$tdir
25934
25935         prepare_remote_file || error "prepare remote file failed"
25936
25937         #open-unlink file
25938         $OPENUNLINK $remote_file $remote_file ||
25939                 error "openunlink $remote_file failed"
25940         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25941 }
25942 run_test 310a "open unlink remote file"
25943
25944 test_310b() {
25945         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25947
25948         local remote_file=$DIR/$tdir/tgt_dir/b
25949
25950         mkdir -p $DIR/$tdir
25951
25952         prepare_remote_file || error "prepare remote file failed"
25953
25954         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25955         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25956         $CHECKSTAT -t file $remote_file || error "check file failed"
25957 }
25958 run_test 310b "unlink remote file with multiple links while open"
25959
25960 test_310c() {
25961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25962         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25963
25964         local remote_file=$DIR/$tdir/tgt_dir/b
25965
25966         mkdir -p $DIR/$tdir
25967
25968         prepare_remote_file || error "prepare remote file failed"
25969
25970         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25971         multiop_bg_pause $remote_file O_uc ||
25972                         error "mulitop failed for remote file"
25973         MULTIPID=$!
25974         $MULTIOP $DIR/$tfile Ouc
25975         kill -USR1 $MULTIPID
25976         wait $MULTIPID
25977 }
25978 run_test 310c "open-unlink remote file with multiple links"
25979
25980 #LU-4825
25981 test_311() {
25982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25983         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25984         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25985                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25986         remote_mds_nodsh && skip "remote MDS with nodsh"
25987
25988         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25989         local mdts=$(comma_list $(mdts_nodes))
25990
25991         mkdir -p $DIR/$tdir
25992         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25993         createmany -o $DIR/$tdir/$tfile. 1000
25994
25995         # statfs data is not real time, let's just calculate it
25996         old_iused=$((old_iused + 1000))
25997
25998         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25999                         osp.*OST0000*MDT0000.create_count")
26000         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26001                                 osp.*OST0000*MDT0000.max_create_count")
26002         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26003
26004         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26005         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26006         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26007
26008         unlinkmany $DIR/$tdir/$tfile. 1000
26009
26010         do_nodes $mdts "$LCTL set_param -n \
26011                         osp.*OST0000*.max_create_count=$max_count"
26012         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26013                 do_nodes $mdts "$LCTL set_param -n \
26014                                 osp.*OST0000*.create_count=$count"
26015         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26016                         grep "=0" && error "create_count is zero"
26017
26018         local new_iused
26019         for i in $(seq 120); do
26020                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26021                 # system may be too busy to destroy all objs in time, use
26022                 # a somewhat small value to not fail autotest
26023                 [ $((old_iused - new_iused)) -gt 400 ] && break
26024                 sleep 1
26025         done
26026
26027         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26028         [ $((old_iused - new_iused)) -gt 400 ] ||
26029                 error "objs not destroyed after unlink"
26030 }
26031 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26032
26033 zfs_get_objid()
26034 {
26035         local ost=$1
26036         local tf=$2
26037         local fid=($($LFS getstripe $tf | grep 0x))
26038         local seq=${fid[3]#0x}
26039         local objid=${fid[1]}
26040
26041         local vdevdir=$(dirname $(facet_vdevice $ost))
26042         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26043         local zfs_zapid=$(do_facet $ost $cmd |
26044                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26045                           awk '/Object/{getline; print $1}')
26046         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26047                           awk "/$objid = /"'{printf $3}')
26048
26049         echo $zfs_objid
26050 }
26051
26052 zfs_object_blksz() {
26053         local ost=$1
26054         local objid=$2
26055
26056         local vdevdir=$(dirname $(facet_vdevice $ost))
26057         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26058         local blksz=$(do_facet $ost $cmd $objid |
26059                       awk '/dblk/{getline; printf $4}')
26060
26061         case "${blksz: -1}" in
26062                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26063                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26064                 *) ;;
26065         esac
26066
26067         echo $blksz
26068 }
26069
26070 test_312() { # LU-4856
26071         remote_ost_nodsh && skip "remote OST with nodsh"
26072         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26073
26074         local max_blksz=$(do_facet ost1 \
26075                           $ZFS get -p recordsize $(facet_device ost1) |
26076                           awk '!/VALUE/{print $3}')
26077         local tf=$DIR/$tfile
26078
26079         $LFS setstripe -c1 $tf
26080         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26081
26082         # Get ZFS object id
26083         local zfs_objid=$(zfs_get_objid $facet $tf)
26084         # block size change by sequential overwrite
26085         local bs
26086
26087         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26088                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26089
26090                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26091                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26092         done
26093         rm -f $tf
26094
26095         $LFS setstripe -c1 $tf
26096         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26097
26098         # block size change by sequential append write
26099         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26100         zfs_objid=$(zfs_get_objid $facet $tf)
26101         local count
26102
26103         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26104                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26105                         oflag=sync conv=notrunc
26106
26107                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26108                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26109                         error "blksz error, actual $blksz, " \
26110                                 "expected: 2 * $count * $PAGE_SIZE"
26111         done
26112         rm -f $tf
26113
26114         # random write
26115         $LFS setstripe -c1 $tf
26116         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26117         zfs_objid=$(zfs_get_objid $facet $tf)
26118
26119         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26120         blksz=$(zfs_object_blksz $facet $zfs_objid)
26121         (( blksz == PAGE_SIZE )) ||
26122                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26123
26124         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26125         blksz=$(zfs_object_blksz $facet $zfs_objid)
26126         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26127
26128         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26129         blksz=$(zfs_object_blksz $facet $zfs_objid)
26130         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26131 }
26132 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26133
26134 test_313() {
26135         remote_ost_nodsh && skip "remote OST with nodsh"
26136
26137         local file=$DIR/$tfile
26138
26139         rm -f $file
26140         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26141
26142         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26143         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26144         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26145                 error "write should failed"
26146         do_facet ost1 "$LCTL set_param fail_loc=0"
26147         rm -f $file
26148 }
26149 run_test 313 "io should fail after last_rcvd update fail"
26150
26151 test_314() {
26152         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26153
26154         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26155         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26156         rm -f $DIR/$tfile
26157         wait_delete_completed
26158         do_facet ost1 "$LCTL set_param fail_loc=0"
26159 }
26160 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26161
26162 test_315() { # LU-618
26163         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26164
26165         local file=$DIR/$tfile
26166         rm -f $file
26167
26168         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26169                 error "multiop file write failed"
26170         $MULTIOP $file oO_RDONLY:r4063232_c &
26171         PID=$!
26172
26173         sleep 2
26174
26175         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26176         kill -USR1 $PID
26177
26178         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26179         rm -f $file
26180 }
26181 run_test 315 "read should be accounted"
26182
26183 test_316() {
26184         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26185         large_xattr_enabled || skip "ea_inode feature disabled"
26186
26187         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26188         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26189         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26190         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26191
26192         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26193 }
26194 run_test 316 "lfs migrate of file with large_xattr enabled"
26195
26196 test_317() {
26197         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26198                 skip "Need MDS version at least 2.11.53"
26199         if [ "$ost1_FSTYPE" == "zfs" ]; then
26200                 skip "LU-10370: no implementation for ZFS"
26201         fi
26202
26203         local trunc_sz
26204         local grant_blk_size
26205
26206         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26207                         awk '/grant_block_size:/ { print $2; exit; }')
26208         #
26209         # Create File of size 5M. Truncate it to below size's and verify
26210         # blocks count.
26211         #
26212         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26213                 error "Create file $DIR/$tfile failed"
26214         stack_trap "rm -f $DIR/$tfile" EXIT
26215
26216         for trunc_sz in 2097152 4097 4000 509 0; do
26217                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26218                         error "truncate $tfile to $trunc_sz failed"
26219                 local sz=$(stat --format=%s $DIR/$tfile)
26220                 local blk=$(stat --format=%b $DIR/$tfile)
26221                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26222                                      grant_blk_size) * 8))
26223
26224                 if [[ $blk -ne $trunc_blk ]]; then
26225                         $(which stat) $DIR/$tfile
26226                         error "Expected Block $trunc_blk got $blk for $tfile"
26227                 fi
26228
26229                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26230                         error "Expected Size $trunc_sz got $sz for $tfile"
26231         done
26232
26233         #
26234         # sparse file test
26235         # Create file with a hole and write actual 65536 bytes which aligned
26236         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26237         #
26238         local bs=65536
26239         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26240                 error "Create file : $DIR/$tfile"
26241
26242         #
26243         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26244         # blocks. The block count must drop to 8.
26245         #
26246         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26247                 ((bs - grant_blk_size) + 1)))
26248         $TRUNCATE $DIR/$tfile $trunc_sz ||
26249                 error "truncate $tfile to $trunc_sz failed"
26250
26251         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26252         sz=$(stat --format=%s $DIR/$tfile)
26253         blk=$(stat --format=%b $DIR/$tfile)
26254
26255         if [[ $blk -ne $trunc_bsz ]]; then
26256                 $(which stat) $DIR/$tfile
26257                 error "Expected Block $trunc_bsz got $blk for $tfile"
26258         fi
26259
26260         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26261                 error "Expected Size $trunc_sz got $sz for $tfile"
26262 }
26263 run_test 317 "Verify blocks get correctly update after truncate"
26264
26265 test_318() {
26266         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26267         local old_max_active=$($LCTL get_param -n \
26268                             ${llite_name}.max_read_ahead_async_active \
26269                             2>/dev/null)
26270
26271         $LCTL set_param llite.*.max_read_ahead_async_active=256
26272         local max_active=$($LCTL get_param -n \
26273                            ${llite_name}.max_read_ahead_async_active \
26274                            2>/dev/null)
26275         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26276
26277         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26278                 error "set max_read_ahead_async_active should succeed"
26279
26280         $LCTL set_param llite.*.max_read_ahead_async_active=512
26281         max_active=$($LCTL get_param -n \
26282                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26283         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26284
26285         # restore @max_active
26286         [ $old_max_active -ne 0 ] && $LCTL set_param \
26287                 llite.*.max_read_ahead_async_active=$old_max_active
26288
26289         local old_threshold=$($LCTL get_param -n \
26290                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26291         local max_per_file_mb=$($LCTL get_param -n \
26292                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26293
26294         local invalid=$(($max_per_file_mb + 1))
26295         $LCTL set_param \
26296                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26297                         && error "set $invalid should fail"
26298
26299         local valid=$(($invalid - 1))
26300         $LCTL set_param \
26301                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26302                         error "set $valid should succeed"
26303         local threshold=$($LCTL get_param -n \
26304                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26305         [ $threshold -eq $valid ] || error \
26306                 "expect threshold $valid got $threshold"
26307         $LCTL set_param \
26308                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26309 }
26310 run_test 318 "Verify async readahead tunables"
26311
26312 test_319() {
26313         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26314
26315         local before=$(date +%s)
26316         local evict
26317         local mdir=$DIR/$tdir
26318         local file=$mdir/xxx
26319
26320         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26321         touch $file
26322
26323 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26324         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26325         $LFS migrate -m1 $mdir &
26326
26327         sleep 1
26328         dd if=$file of=/dev/null
26329         wait
26330         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26331           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26332
26333         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26334 }
26335 run_test 319 "lost lease lock on migrate error"
26336
26337 test_398a() { # LU-4198
26338         local ost1_imp=$(get_osc_import_name client ost1)
26339         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26340                          cut -d'.' -f2)
26341
26342         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26343         stack_trap "rm -f $DIR/$tfile"
26344         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26345
26346         # request a new lock on client
26347         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26348
26349         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26350         local lock_count=$($LCTL get_param -n \
26351                            ldlm.namespaces.$imp_name.lru_size)
26352         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26353
26354         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26355
26356         # no lock cached, should use lockless DIO and not enqueue new lock
26357         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26358         lock_count=$($LCTL get_param -n \
26359                      ldlm.namespaces.$imp_name.lru_size)
26360         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26361
26362         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26363
26364         # no lock cached, should use locked DIO append
26365         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26366                 conv=notrunc || error "DIO append failed"
26367         lock_count=$($LCTL get_param -n \
26368                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
26369         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26370 }
26371 run_test 398a "direct IO should cancel lock otherwise lockless"
26372
26373 test_398b() { # LU-4198
26374         local before=$(date +%s)
26375         local njobs=4
26376         local size=48
26377
26378         which fio || skip_env "no fio installed"
26379         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26380         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26381
26382         # Single page, multiple pages, stripe size, 4*stripe size
26383         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26384                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26385                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26386                         --numjobs=$njobs --fallocate=none \
26387                         --iodepth=16 --allow_file_create=0 \
26388                         --size=$((size/njobs))M \
26389                         --filename=$DIR/$tfile &
26390                 bg_pid=$!
26391
26392                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26393                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26394                         --numjobs=$njobs --fallocate=none \
26395                         --iodepth=16 --allow_file_create=0 \
26396                         --size=$((size/njobs))M \
26397                         --filename=$DIR/$tfile || true
26398                 wait $bg_pid
26399         done
26400
26401         evict=$(do_facet client $LCTL get_param \
26402                 osc.$FSNAME-OST*-osc-*/state |
26403             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26404
26405         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26406                 (do_facet client $LCTL get_param \
26407                         osc.$FSNAME-OST*-osc-*/state;
26408                     error "eviction happened: $evict before:$before")
26409
26410         rm -f $DIR/$tfile
26411 }
26412 run_test 398b "DIO and buffer IO race"
26413
26414 test_398c() { # LU-4198
26415         local ost1_imp=$(get_osc_import_name client ost1)
26416         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26417                          cut -d'.' -f2)
26418
26419         which fio || skip_env "no fio installed"
26420
26421         saved_debug=$($LCTL get_param -n debug)
26422         $LCTL set_param debug=0
26423
26424         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26425         ((size /= 1024)) # by megabytes
26426         ((size /= 2)) # write half of the OST at most
26427         [ $size -gt 40 ] && size=40 #reduce test time anyway
26428
26429         $LFS setstripe -c 1 $DIR/$tfile
26430
26431         # it seems like ldiskfs reserves more space than necessary if the
26432         # writing blocks are not mapped, so it extends the file firstly
26433         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26434         cancel_lru_locks osc
26435
26436         # clear and verify rpc_stats later
26437         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26438
26439         local njobs=4
26440         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26441         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26442                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26443                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26444                 --filename=$DIR/$tfile
26445         [ $? -eq 0 ] || error "fio write error"
26446
26447         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26448                 error "Locks were requested while doing AIO"
26449
26450         # get the percentage of 1-page I/O
26451         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26452                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26453                 awk '{print $7}')
26454         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26455
26456         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26457         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26458                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26459                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26460                 --filename=$DIR/$tfile
26461         [ $? -eq 0 ] || error "fio mixed read write error"
26462
26463         echo "AIO with large block size ${size}M"
26464         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26465                 --numjobs=1 --fallocate=none --ioengine=libaio \
26466                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26467                 --filename=$DIR/$tfile
26468         [ $? -eq 0 ] || error "fio large block size failed"
26469
26470         rm -f $DIR/$tfile
26471         $LCTL set_param debug="$saved_debug"
26472 }
26473 run_test 398c "run fio to test AIO"
26474
26475 test_398d() { #  LU-13846
26476         which aiocp || skip_env "no aiocp installed"
26477         local aio_file=$DIR/$tfile.aio
26478
26479         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26480
26481         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26482         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26483         stack_trap "rm -f $DIR/$tfile $aio_file"
26484
26485         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26486
26487         # make sure we don't crash and fail properly
26488         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26489                 error "aio not aligned with PAGE SIZE should fail"
26490
26491         rm -f $DIR/$tfile $aio_file
26492 }
26493 run_test 398d "run aiocp to verify block size > stripe size"
26494
26495 test_398e() {
26496         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26497         touch $DIR/$tfile.new
26498         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26499 }
26500 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26501
26502 test_398f() { #  LU-14687
26503         which aiocp || skip_env "no aiocp installed"
26504         local aio_file=$DIR/$tfile.aio
26505
26506         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26507
26508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26509         stack_trap "rm -f $DIR/$tfile $aio_file"
26510
26511         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26512         $LCTL set_param fail_loc=0x1418
26513         # make sure we don't crash and fail properly
26514         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26515                 error "aio with page allocation failure succeeded"
26516         $LCTL set_param fail_loc=0
26517         diff $DIR/$tfile $aio_file
26518         [[ $? != 0 ]] || error "no diff after failed aiocp"
26519 }
26520 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26521
26522 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26523 # stripe and i/o size must be > stripe size
26524 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26525 # single RPC in flight.  This test shows async DIO submission is working by
26526 # showing multiple RPCs in flight.
26527 test_398g() { #  LU-13798
26528         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26529
26530         # We need to do some i/o first to acquire enough grant to put our RPCs
26531         # in flight; otherwise a new connection may not have enough grant
26532         # available
26533         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26534                 error "parallel dio failed"
26535         stack_trap "rm -f $DIR/$tfile"
26536
26537         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26538         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26539         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26540         stack_trap "$LCTL set_param -n $pages_per_rpc"
26541
26542         # Recreate file so it's empty
26543         rm -f $DIR/$tfile
26544         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26545         #Pause rpc completion to guarantee we see multiple rpcs in flight
26546         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26547         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26548         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26549
26550         # Clear rpc stats
26551         $LCTL set_param osc.*.rpc_stats=c
26552
26553         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26554                 error "parallel dio failed"
26555         stack_trap "rm -f $DIR/$tfile"
26556
26557         $LCTL get_param osc.*-OST0000-*.rpc_stats
26558         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26559                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26560                 grep "8:" | awk '{print $8}')
26561         # We look at the "8 rpcs in flight" field, and verify A) it is present
26562         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26563         # as expected for an 8M DIO to a file with 1M stripes.
26564         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26565
26566         # Verify turning off parallel dio works as expected
26567         # Clear rpc stats
26568         $LCTL set_param osc.*.rpc_stats=c
26569         $LCTL set_param llite.*.parallel_dio=0
26570         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26571
26572         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26573                 error "dio with parallel dio disabled failed"
26574
26575         # Ideally, we would see only one RPC in flight here, but there is an
26576         # unavoidable race between i/o completion and RPC in flight counting,
26577         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26578         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26579         # So instead we just verify it's always < 8.
26580         $LCTL get_param osc.*-OST0000-*.rpc_stats
26581         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26582                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26583                 grep '^$' -B1 | grep . | awk '{print $1}')
26584         [ $ret != "8:" ] ||
26585                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26586 }
26587 run_test 398g "verify parallel dio async RPC submission"
26588
26589 test_398h() { #  LU-13798
26590         local dio_file=$DIR/$tfile.dio
26591
26592         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26593
26594         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26595         stack_trap "rm -f $DIR/$tfile $dio_file"
26596
26597         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26598                 error "parallel dio failed"
26599         diff $DIR/$tfile $dio_file
26600         [[ $? == 0 ]] || error "file diff after aiocp"
26601 }
26602 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26603
26604 test_398i() { #  LU-13798
26605         local dio_file=$DIR/$tfile.dio
26606
26607         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26608
26609         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26610         stack_trap "rm -f $DIR/$tfile $dio_file"
26611
26612         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26613         $LCTL set_param fail_loc=0x1418
26614         # make sure we don't crash and fail properly
26615         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26616                 error "parallel dio page allocation failure succeeded"
26617         diff $DIR/$tfile $dio_file
26618         [[ $? != 0 ]] || error "no diff after failed aiocp"
26619 }
26620 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26621
26622 test_398j() { #  LU-13798
26623         # Stripe size > RPC size but less than i/o size tests split across
26624         # stripes and RPCs for individual i/o op
26625         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26626
26627         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26628         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26629         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26630         stack_trap "$LCTL set_param -n $pages_per_rpc"
26631
26632         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26633                 error "parallel dio write failed"
26634         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26635
26636         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26637                 error "parallel dio read failed"
26638         diff $DIR/$tfile $DIR/$tfile.2
26639         [[ $? == 0 ]] || error "file diff after parallel dio read"
26640 }
26641 run_test 398j "test parallel dio where stripe size > rpc_size"
26642
26643 test_398k() { #  LU-13798
26644         wait_delete_completed
26645         wait_mds_ost_sync
26646
26647         # 4 stripe file; we will cause out of space on OST0
26648         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26649
26650         # Fill OST0 (if it's not too large)
26651         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26652                    head -n1)
26653         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26654                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26655         fi
26656         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26657         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26658                 error "dd should fill OST0"
26659         stack_trap "rm -f $DIR/$tfile.1"
26660
26661         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26662         err=$?
26663
26664         ls -la $DIR/$tfile
26665         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26666                 error "file is not 0 bytes in size"
26667
26668         # dd above should not succeed, but don't error until here so we can
26669         # get debug info above
26670         [[ $err != 0 ]] ||
26671                 error "parallel dio write with enospc succeeded"
26672         stack_trap "rm -f $DIR/$tfile"
26673 }
26674 run_test 398k "test enospc on first stripe"
26675
26676 test_398l() { #  LU-13798
26677         wait_delete_completed
26678         wait_mds_ost_sync
26679
26680         # 4 stripe file; we will cause out of space on OST0
26681         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26682         # happens on the second i/o chunk we issue
26683         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26684
26685         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26686         stack_trap "rm -f $DIR/$tfile"
26687
26688         # Fill OST0 (if it's not too large)
26689         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26690                    head -n1)
26691         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26692                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26693         fi
26694         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26695         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26696                 error "dd should fill OST0"
26697         stack_trap "rm -f $DIR/$tfile.1"
26698
26699         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26700         err=$?
26701         stack_trap "rm -f $DIR/$tfile.2"
26702
26703         # Check that short write completed as expected
26704         ls -la $DIR/$tfile.2
26705         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26706                 error "file is not 1M in size"
26707
26708         # dd above should not succeed, but don't error until here so we can
26709         # get debug info above
26710         [[ $err != 0 ]] ||
26711                 error "parallel dio write with enospc succeeded"
26712
26713         # Truncate source file to same length as output file and diff them
26714         $TRUNCATE $DIR/$tfile 1048576
26715         diff $DIR/$tfile $DIR/$tfile.2
26716         [[ $? == 0 ]] || error "data incorrect after short write"
26717 }
26718 run_test 398l "test enospc on intermediate stripe/RPC"
26719
26720 test_398m() { #  LU-13798
26721         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26722
26723         # Set up failure on OST0, the first stripe:
26724         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26725         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26726         # OST0 is on ost1, OST1 is on ost2.
26727         # So this fail_val specifies OST0
26728         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26729         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26730
26731         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26732                 error "parallel dio write with failure on first stripe succeeded"
26733         stack_trap "rm -f $DIR/$tfile"
26734         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26735
26736         # Place data in file for read
26737         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26738                 error "parallel dio write failed"
26739
26740         # Fail read on OST0, first stripe
26741         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26742         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26743         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26744                 error "parallel dio read with error on first stripe succeeded"
26745         rm -f $DIR/$tfile.2
26746         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26747
26748         # Switch to testing on OST1, second stripe
26749         # Clear file contents, maintain striping
26750         echo > $DIR/$tfile
26751         # Set up failure on OST1, second stripe:
26752         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26753         stack_trap "do_facet ost2 $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 second stripe succeeded"
26757         stack_trap "rm -f $DIR/$tfile"
26758         do_facet ost2 $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 OST1, second stripe
26765         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26766         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26767         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26768                 error "parallel dio read with error on second stripe succeeded"
26769         rm -f $DIR/$tfile.2
26770         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26771 }
26772 run_test 398m "test RPC failures with parallel dio"
26773
26774 # Parallel submission of DIO should not cause problems for append, but it's
26775 # important to verify.
26776 test_398n() { #  LU-13798
26777         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26778
26779         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26780                 error "dd to create source file failed"
26781         stack_trap "rm -f $DIR/$tfile"
26782
26783         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26784                 error "parallel dio write with failure on second stripe succeeded"
26785         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26786         diff $DIR/$tfile $DIR/$tfile.1
26787         [[ $? == 0 ]] || error "data incorrect after append"
26788
26789 }
26790 run_test 398n "test append with parallel DIO"
26791
26792 test_398o() {
26793         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26794 }
26795 run_test 398o "right kms with DIO"
26796
26797 test_398p()
26798 {
26799         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26800         which aiocp || skip_env "no aiocp installed"
26801
26802         local stripe_size=$((1024 * 1024)) #1 MiB
26803         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26804         local file_size=$((25 * stripe_size))
26805
26806         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26807         stack_trap "rm -f $DIR/$tfile*"
26808         # Just a bit bigger than the largest size in the test set below
26809         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26810                 error "buffered i/o to create file failed"
26811
26812         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26813                 $((stripe_size * 4)); do
26814
26815                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26816
26817                 echo "bs: $bs, file_size $file_size"
26818                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26819                         $DIR/$tfile.1 $DIR/$tfile.2 &
26820                 pid_dio1=$!
26821                 # Buffered I/O with similar but not the same block size
26822                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26823                         conv=notrunc &
26824                 pid_bio2=$!
26825                 wait $pid_dio1
26826                 rc1=$?
26827                 wait $pid_bio2
26828                 rc2=$?
26829                 if (( rc1 != 0 )); then
26830                         error "aio copy 1 w/bsize $bs failed: $rc1"
26831                 fi
26832                 if (( rc2 != 0 )); then
26833                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26834                 fi
26835
26836                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26837                         error "size incorrect"
26838                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26839                         error "files differ, bsize $bs"
26840                 rm -f $DIR/$tfile.2
26841         done
26842 }
26843 run_test 398p "race aio with buffered i/o"
26844
26845 test_398q()
26846 {
26847         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26848
26849         local stripe_size=$((1024 * 1024)) #1 MiB
26850         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26851         local file_size=$((25 * stripe_size))
26852
26853         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26854         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26855
26856         # Just a bit bigger than the largest size in the test set below
26857         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26858                 error "buffered i/o to create file failed"
26859
26860         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26861                 $((stripe_size * 4)); do
26862
26863                 echo "bs: $bs, file_size $file_size"
26864                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26865                         conv=notrunc oflag=direct iflag=direct &
26866                 pid_dio1=$!
26867                 # Buffered I/O with similar but not the same block size
26868                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26869                         conv=notrunc &
26870                 pid_bio2=$!
26871                 wait $pid_dio1
26872                 rc1=$?
26873                 wait $pid_bio2
26874                 rc2=$?
26875                 if (( rc1 != 0 )); then
26876                         error "dio copy 1 w/bsize $bs failed: $rc1"
26877                 fi
26878                 if (( rc2 != 0 )); then
26879                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26880                 fi
26881
26882                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26883                         error "size incorrect"
26884                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26885                         error "files differ, bsize $bs"
26886         done
26887
26888         rm -f $DIR/$tfile*
26889 }
26890 run_test 398q "race dio with buffered i/o"
26891
26892 test_fake_rw() {
26893         local read_write=$1
26894         if [ "$read_write" = "write" ]; then
26895                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26896         elif [ "$read_write" = "read" ]; then
26897                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26898         else
26899                 error "argument error"
26900         fi
26901
26902         # turn off debug for performance testing
26903         local saved_debug=$($LCTL get_param -n debug)
26904         $LCTL set_param debug=0
26905
26906         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26907
26908         # get ost1 size - $FSNAME-OST0000
26909         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26910         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26911         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26912
26913         if [ "$read_write" = "read" ]; then
26914                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26915         fi
26916
26917         local start_time=$(date +%s.%N)
26918         $dd_cmd bs=1M count=$blocks oflag=sync ||
26919                 error "real dd $read_write error"
26920         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26921
26922         if [ "$read_write" = "write" ]; then
26923                 rm -f $DIR/$tfile
26924         fi
26925
26926         # define OBD_FAIL_OST_FAKE_RW           0x238
26927         do_facet ost1 $LCTL set_param fail_loc=0x238
26928
26929         local start_time=$(date +%s.%N)
26930         $dd_cmd bs=1M count=$blocks oflag=sync ||
26931                 error "fake dd $read_write error"
26932         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26933
26934         if [ "$read_write" = "write" ]; then
26935                 # verify file size
26936                 cancel_lru_locks osc
26937                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26938                         error "$tfile size not $blocks MB"
26939         fi
26940         do_facet ost1 $LCTL set_param fail_loc=0
26941
26942         echo "fake $read_write $duration_fake vs. normal $read_write" \
26943                 "$duration in seconds"
26944         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26945                 error_not_in_vm "fake write is slower"
26946
26947         $LCTL set_param -n debug="$saved_debug"
26948         rm -f $DIR/$tfile
26949 }
26950 test_399a() { # LU-7655 for OST fake write
26951         remote_ost_nodsh && skip "remote OST with nodsh"
26952
26953         test_fake_rw write
26954 }
26955 run_test 399a "fake write should not be slower than normal write"
26956
26957 test_399b() { # LU-8726 for OST fake read
26958         remote_ost_nodsh && skip "remote OST with nodsh"
26959         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26960                 skip_env "ldiskfs only test"
26961         fi
26962
26963         test_fake_rw read
26964 }
26965 run_test 399b "fake read should not be slower than normal read"
26966
26967 test_400a() { # LU-1606, was conf-sanity test_74
26968         if ! which $CC > /dev/null 2>&1; then
26969                 skip_env "$CC is not installed"
26970         fi
26971
26972         local extra_flags=''
26973         local out=$TMP/$tfile
26974         local prefix=/usr/include/lustre
26975         local prog
26976
26977         # Oleg removes .c files in his test rig so test if any c files exist
26978         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26979                 skip_env "Needed .c test files are missing"
26980
26981         if ! [[ -d $prefix ]]; then
26982                 # Assume we're running in tree and fixup the include path.
26983                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26984                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26985                 extra_flags+=" -L$LUSTRE/utils/.libs"
26986         fi
26987
26988         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26989                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26990                         error "client api broken"
26991         done
26992         rm -f $out
26993 }
26994 run_test 400a "Lustre client api program can compile and link"
26995
26996 test_400b() { # LU-1606, LU-5011
26997         local header
26998         local out=$TMP/$tfile
26999         local prefix=/usr/include/linux/lustre
27000
27001         # We use a hard coded prefix so that this test will not fail
27002         # when run in tree. There are headers in lustre/include/lustre/
27003         # that are not packaged (like lustre_idl.h) and have more
27004         # complicated include dependencies (like config.h and lnet/types.h).
27005         # Since this test about correct packaging we just skip them when
27006         # they don't exist (see below) rather than try to fixup cppflags.
27007
27008         if ! which $CC > /dev/null 2>&1; then
27009                 skip_env "$CC is not installed"
27010         fi
27011
27012         for header in $prefix/*.h; do
27013                 if ! [[ -f "$header" ]]; then
27014                         continue
27015                 fi
27016
27017                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27018                         continue # lustre_ioctl.h is internal header
27019                 fi
27020
27021                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27022                         error "cannot compile '$header'"
27023         done
27024         rm -f $out
27025 }
27026 run_test 400b "packaged headers can be compiled"
27027
27028 test_401a() { #LU-7437
27029         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27030         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27031
27032         #count the number of parameters by "list_param -R"
27033         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27034         #count the number of parameters by listing proc files
27035         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27036         echo "proc_dirs='$proc_dirs'"
27037         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27038         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27039                       sort -u | wc -l)
27040
27041         [ $params -eq $procs ] ||
27042                 error "found $params parameters vs. $procs proc files"
27043
27044         # test the list_param -D option only returns directories
27045         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27046         #count the number of parameters by listing proc directories
27047         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27048                 sort -u | wc -l)
27049
27050         [ $params -eq $procs ] ||
27051                 error "found $params parameters vs. $procs proc files"
27052 }
27053 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27054
27055 test_401b() {
27056         # jobid_var may not allow arbitrary values, so use jobid_name
27057         # if available
27058         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27059                 local testname=jobid_name tmp='testing%p'
27060         else
27061                 local testname=jobid_var tmp=testing
27062         fi
27063
27064         local save=$($LCTL get_param -n $testname)
27065
27066         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27067                 error "no error returned when setting bad parameters"
27068
27069         local jobid_new=$($LCTL get_param -n foe $testname baz)
27070         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27071
27072         $LCTL set_param -n fog=bam $testname=$save bat=fog
27073         local jobid_old=$($LCTL get_param -n foe $testname bag)
27074         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27075 }
27076 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27077
27078 test_401c() {
27079         # jobid_var may not allow arbitrary values, so use jobid_name
27080         # if available
27081         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27082                 local testname=jobid_name
27083         else
27084                 local testname=jobid_var
27085         fi
27086
27087         local jobid_var_old=$($LCTL get_param -n $testname)
27088         local jobid_var_new
27089
27090         $LCTL set_param $testname= &&
27091                 error "no error returned for 'set_param a='"
27092
27093         jobid_var_new=$($LCTL get_param -n $testname)
27094         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27095                 error "$testname was changed by setting without value"
27096
27097         $LCTL set_param $testname &&
27098                 error "no error returned for 'set_param a'"
27099
27100         jobid_var_new=$($LCTL get_param -n $testname)
27101         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27102                 error "$testname was changed by setting without value"
27103 }
27104 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27105
27106 test_401d() {
27107         # jobid_var may not allow arbitrary values, so use jobid_name
27108         # if available
27109         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27110                 local testname=jobid_name new_value='foo=bar%p'
27111         else
27112                 local testname=jobid_var new_valuie=foo=bar
27113         fi
27114
27115         local jobid_var_old=$($LCTL get_param -n $testname)
27116         local jobid_var_new
27117
27118         $LCTL set_param $testname=$new_value ||
27119                 error "'set_param a=b' did not accept a value containing '='"
27120
27121         jobid_var_new=$($LCTL get_param -n $testname)
27122         [[ "$jobid_var_new" == "$new_value" ]] ||
27123                 error "'set_param a=b' failed on a value containing '='"
27124
27125         # Reset the $testname to test the other format
27126         $LCTL set_param $testname=$jobid_var_old
27127         jobid_var_new=$($LCTL get_param -n $testname)
27128         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27129                 error "failed to reset $testname"
27130
27131         $LCTL set_param $testname $new_value ||
27132                 error "'set_param a b' did not accept a value containing '='"
27133
27134         jobid_var_new=$($LCTL get_param -n $testname)
27135         [[ "$jobid_var_new" == "$new_value" ]] ||
27136                 error "'set_param a b' failed on a value containing '='"
27137
27138         $LCTL set_param $testname $jobid_var_old
27139         jobid_var_new=$($LCTL get_param -n $testname)
27140         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27141                 error "failed to reset $testname"
27142 }
27143 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27144
27145 test_401e() { # LU-14779
27146         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27147                 error "lctl list_param MGC* failed"
27148         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27149         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27150                 error "lctl get_param lru_size failed"
27151 }
27152 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27153
27154 test_402() {
27155         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27156         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27157                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27158         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27159                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27160                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27161         remote_mds_nodsh && skip "remote MDS with nodsh"
27162
27163         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27164 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27165         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27166         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27167                 echo "Touch failed - OK"
27168 }
27169 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27170
27171 test_403() {
27172         local file1=$DIR/$tfile.1
27173         local file2=$DIR/$tfile.2
27174         local tfile=$TMP/$tfile
27175
27176         rm -f $file1 $file2 $tfile
27177
27178         touch $file1
27179         ln $file1 $file2
27180
27181         # 30 sec OBD_TIMEOUT in ll_getattr()
27182         # right before populating st_nlink
27183         $LCTL set_param fail_loc=0x80001409
27184         stat -c %h $file1 > $tfile &
27185
27186         # create an alias, drop all locks and reclaim the dentry
27187         < $file2
27188         cancel_lru_locks mdc
27189         cancel_lru_locks osc
27190         sysctl -w vm.drop_caches=2
27191
27192         wait
27193
27194         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27195
27196         rm -f $tfile $file1 $file2
27197 }
27198 run_test 403 "i_nlink should not drop to zero due to aliasing"
27199
27200 test_404() { # LU-6601
27201         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27202                 skip "Need server version newer than 2.8.52"
27203         remote_mds_nodsh && skip "remote MDS with nodsh"
27204
27205         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27206                 awk '/osp .*-osc-MDT/ { print $4}')
27207
27208         local osp
27209         for osp in $mosps; do
27210                 echo "Deactivate: " $osp
27211                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27212                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27213                         awk -vp=$osp '$4 == p { print $2 }')
27214                 [ $stat = IN ] || {
27215                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27216                         error "deactivate error"
27217                 }
27218                 echo "Activate: " $osp
27219                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27220                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27221                         awk -vp=$osp '$4 == p { print $2 }')
27222                 [ $stat = UP ] || {
27223                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27224                         error "activate error"
27225                 }
27226         done
27227 }
27228 run_test 404 "validate manual {de}activated works properly for OSPs"
27229
27230 test_405() {
27231         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27232         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27233                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27234                         skip "Layout swap lock is not supported"
27235
27236         check_swap_layouts_support
27237         check_swap_layout_no_dom $DIR
27238
27239         test_mkdir $DIR/$tdir
27240         swap_lock_test -d $DIR/$tdir ||
27241                 error "One layout swap locked test failed"
27242 }
27243 run_test 405 "Various layout swap lock tests"
27244
27245 test_406() {
27246         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27247         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27248         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27250         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27251                 skip "Need MDS version at least 2.8.50"
27252
27253         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27254         local test_pool=$TESTNAME
27255
27256         pool_add $test_pool || error "pool_add failed"
27257         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27258                 error "pool_add_targets failed"
27259
27260         save_layout_restore_at_exit $MOUNT
27261
27262         # parent set default stripe count only, child will stripe from both
27263         # parent and fs default
27264         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27265                 error "setstripe $MOUNT failed"
27266         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27267         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27268         for i in $(seq 10); do
27269                 local f=$DIR/$tdir/$tfile.$i
27270                 touch $f || error "touch failed"
27271                 local count=$($LFS getstripe -c $f)
27272                 [ $count -eq $OSTCOUNT ] ||
27273                         error "$f stripe count $count != $OSTCOUNT"
27274                 local offset=$($LFS getstripe -i $f)
27275                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27276                 local size=$($LFS getstripe -S $f)
27277                 [ $size -eq $((def_stripe_size * 2)) ] ||
27278                         error "$f stripe size $size != $((def_stripe_size * 2))"
27279                 local pool=$($LFS getstripe -p $f)
27280                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27281         done
27282
27283         # change fs default striping, delete parent default striping, now child
27284         # will stripe from new fs default striping only
27285         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27286                 error "change $MOUNT default stripe failed"
27287         $LFS setstripe -c 0 $DIR/$tdir ||
27288                 error "delete $tdir default stripe failed"
27289         for i in $(seq 11 20); do
27290                 local f=$DIR/$tdir/$tfile.$i
27291                 touch $f || error "touch $f failed"
27292                 local count=$($LFS getstripe -c $f)
27293                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27294                 local offset=$($LFS getstripe -i $f)
27295                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27296                 local size=$($LFS getstripe -S $f)
27297                 [ $size -eq $def_stripe_size ] ||
27298                         error "$f stripe size $size != $def_stripe_size"
27299                 local pool=$($LFS getstripe -p $f)
27300                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27301         done
27302
27303         unlinkmany $DIR/$tdir/$tfile. 1 20
27304
27305         local f=$DIR/$tdir/$tfile
27306         pool_remove_all_targets $test_pool $f
27307         pool_remove $test_pool $f
27308 }
27309 run_test 406 "DNE support fs default striping"
27310
27311 test_407() {
27312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27313         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27314                 skip "Need MDS version at least 2.8.55"
27315         remote_mds_nodsh && skip "remote MDS with nodsh"
27316
27317         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27318                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27319         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27320                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27321         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27322
27323         #define OBD_FAIL_DT_TXN_STOP    0x2019
27324         for idx in $(seq $MDSCOUNT); do
27325                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27326         done
27327         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27328         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27329                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27330         true
27331 }
27332 run_test 407 "transaction fail should cause operation fail"
27333
27334 test_408() {
27335         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27336
27337         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27338         lctl set_param fail_loc=0x8000040a
27339         # let ll_prepare_partial_page() fail
27340         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27341
27342         rm -f $DIR/$tfile
27343
27344         # create at least 100 unused inodes so that
27345         # shrink_icache_memory(0) should not return 0
27346         touch $DIR/$tfile-{0..100}
27347         rm -f $DIR/$tfile-{0..100}
27348         sync
27349
27350         echo 2 > /proc/sys/vm/drop_caches
27351 }
27352 run_test 408 "drop_caches should not hang due to page leaks"
27353
27354 test_409()
27355 {
27356         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27357
27358         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27359         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27360         touch $DIR/$tdir/guard || error "(2) Fail to create"
27361
27362         local PREFIX=$(str_repeat 'A' 128)
27363         echo "Create 1K hard links start at $(date)"
27364         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27365                 error "(3) Fail to hard link"
27366
27367         echo "Links count should be right although linkEA overflow"
27368         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27369         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27370         [ $linkcount -eq 1001 ] ||
27371                 error "(5) Unexpected hard links count: $linkcount"
27372
27373         echo "List all links start at $(date)"
27374         ls -l $DIR/$tdir/foo > /dev/null ||
27375                 error "(6) Fail to list $DIR/$tdir/foo"
27376
27377         echo "Unlink hard links start at $(date)"
27378         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27379                 error "(7) Fail to unlink"
27380         echo "Unlink hard links finished at $(date)"
27381 }
27382 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27383
27384 test_410()
27385 {
27386         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27387                 skip "Need client version at least 2.9.59"
27388         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27389                 skip "Need MODULES build"
27390
27391         # Create a file, and stat it from the kernel
27392         local testfile=$DIR/$tfile
27393         touch $testfile
27394
27395         local run_id=$RANDOM
27396         local my_ino=$(stat --format "%i" $testfile)
27397
27398         # Try to insert the module. This will always fail as the
27399         # module is designed to not be inserted.
27400         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27401             &> /dev/null
27402
27403         # Anything but success is a test failure
27404         dmesg | grep -q \
27405             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27406             error "no inode match"
27407 }
27408 run_test 410 "Test inode number returned from kernel thread"
27409
27410 cleanup_test411_cgroup() {
27411         trap 0
27412         rmdir "$1"
27413 }
27414
27415 test_411() {
27416         local cg_basedir=/sys/fs/cgroup/memory
27417         # LU-9966
27418         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27419                 skip "no setup for cgroup"
27420
27421         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27422                 error "test file creation failed"
27423         cancel_lru_locks osc
27424
27425         # Create a very small memory cgroup to force a slab allocation error
27426         local cgdir=$cg_basedir/osc_slab_alloc
27427         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27428         trap "cleanup_test411_cgroup $cgdir" EXIT
27429         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27430         echo 1M > $cgdir/memory.limit_in_bytes
27431
27432         # Should not LBUG, just be killed by oom-killer
27433         # dd will return 0 even allocation failure in some environment.
27434         # So don't check return value
27435         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27436         cleanup_test411_cgroup $cgdir
27437
27438         return 0
27439 }
27440 run_test 411 "Slab allocation error with cgroup does not LBUG"
27441
27442 test_412() {
27443         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27444         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27445                 skip "Need server version at least 2.10.55"
27446
27447         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27448                 error "mkdir failed"
27449         $LFS getdirstripe $DIR/$tdir
27450         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27451         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27452                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27453         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27454         [ $stripe_count -eq 2 ] ||
27455                 error "expect 2 get $stripe_count"
27456
27457         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27458
27459         local index
27460         local index2
27461
27462         # subdirs should be on the same MDT as parent
27463         for i in $(seq 0 $((MDSCOUNT - 1))); do
27464                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27465                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27466                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27467                 (( index == i )) || error "mdt$i/sub on MDT$index"
27468         done
27469
27470         # stripe offset -1, ditto
27471         for i in {1..10}; do
27472                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27473                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27474                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27475                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27476                 (( index == index2 )) ||
27477                         error "qos$i on MDT$index, sub on MDT$index2"
27478         done
27479
27480         local testdir=$DIR/$tdir/inherit
27481
27482         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27483         # inherit 2 levels
27484         for i in 1 2; do
27485                 testdir=$testdir/s$i
27486                 mkdir $testdir || error "mkdir $testdir failed"
27487                 index=$($LFS getstripe -m $testdir)
27488                 (( index == 1 )) ||
27489                         error "$testdir on MDT$index"
27490         done
27491
27492         # not inherit any more
27493         testdir=$testdir/s3
27494         mkdir $testdir || error "mkdir $testdir failed"
27495         getfattr -d -m dmv $testdir | grep dmv &&
27496                 error "default LMV set on $testdir" || true
27497 }
27498 run_test 412 "mkdir on specific MDTs"
27499
27500 TEST413_COUNT=${TEST413_COUNT:-200}
27501
27502 #
27503 # set_maxage() is used by test_413 only.
27504 # This is a helper function to set maxage. Does not return any value.
27505 # Input: maxage to set
27506 #
27507 set_maxage() {
27508         local lmv_qos_maxage
27509         local lod_qos_maxage
27510         local new_maxage=$1
27511
27512         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27513         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27514         stack_trap "$LCTL set_param \
27515                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27516         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27517                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27518         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27519                 lod.*.mdt_qos_maxage=$new_maxage
27520         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27521                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27522 }
27523
27524 generate_uneven_mdts() {
27525         local threshold=$1
27526         local ffree
27527         local bavail
27528         local max
27529         local min
27530         local max_index
27531         local min_index
27532         local tmp
27533         local i
27534
27535         echo
27536         echo "Check for uneven MDTs: "
27537
27538         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27539         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27540         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27541
27542         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27543         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27544         max_index=0
27545         min_index=0
27546         for ((i = 1; i < ${#ffree[@]}; i++)); do
27547                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27548                 if [ $tmp -gt $max ]; then
27549                         max=$tmp
27550                         max_index=$i
27551                 fi
27552                 if [ $tmp -lt $min ]; then
27553                         min=$tmp
27554                         min_index=$i
27555                 fi
27556         done
27557
27558         (( min > 0 )) || skip "low space on MDT$min_index"
27559         (( ${ffree[min_index]} > 0 )) ||
27560                 skip "no free files on MDT$min_index"
27561         (( ${ffree[min_index]} < 10000000 )) ||
27562                 skip "too many free files on MDT$min_index"
27563
27564         # Check if we need to generate uneven MDTs
27565         local diff=$(((max - min) * 100 / min))
27566         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27567         local testdir # individual folder within $testdirp
27568         local start
27569         local cmd
27570
27571         # fallocate is faster to consume space on MDT, if available
27572         if check_fallocate_supported mds$((min_index + 1)); then
27573                 cmd="fallocate -l 128K "
27574         else
27575                 cmd="dd if=/dev/zero bs=128K count=1 of="
27576         fi
27577
27578         echo "using cmd $cmd"
27579         for (( i = 0; diff < threshold; i++ )); do
27580                 testdir=${testdirp}/$i
27581                 [ -d $testdir ] && continue
27582
27583                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27584
27585                 mkdir -p $testdirp
27586                 # generate uneven MDTs, create till $threshold% diff
27587                 echo -n "weight diff=$diff% must be > $threshold% ..."
27588                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27589                 $LFS mkdir -i $min_index $testdir ||
27590                         error "mkdir $testdir failed"
27591                 $LFS setstripe -E 1M -L mdt $testdir ||
27592                         error "setstripe $testdir failed"
27593                 start=$SECONDS
27594                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27595                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27596                 done
27597                 sync; sleep 1; sync
27598
27599                 # wait for QOS to update
27600                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27601
27602                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27603                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27604                 max=$(((${ffree[max_index]} >> 8) *
27605                         (${bavail[max_index]} * bsize >> 16)))
27606                 min=$(((${ffree[min_index]} >> 8) *
27607                         (${bavail[min_index]} * bsize >> 16)))
27608                 (( min > 0 )) || skip "low space on MDT$min_index"
27609                 diff=$(((max - min) * 100 / min))
27610         done
27611
27612         echo "MDT filesfree available: ${ffree[*]}"
27613         echo "MDT blocks available: ${bavail[*]}"
27614         echo "weight diff=$diff%"
27615 }
27616
27617 test_qos_mkdir() {
27618         local mkdir_cmd=$1
27619         local stripe_count=$2
27620         local mdts=$(comma_list $(mdts_nodes))
27621
27622         local testdir
27623         local lmv_qos_prio_free
27624         local lmv_qos_threshold_rr
27625         local lod_qos_prio_free
27626         local lod_qos_threshold_rr
27627         local total
27628         local count
27629         local i
27630
27631         # @total is total directories created if it's testing plain
27632         # directories, otherwise it's total stripe object count for
27633         # striped directories test.
27634         # remote/striped directory unlinking is slow on zfs and may
27635         # timeout, test with fewer directories
27636         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27637
27638         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27639         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27640         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27641                 head -n1)
27642         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27643         stack_trap "$LCTL set_param \
27644                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27645         stack_trap "$LCTL set_param \
27646                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27647
27648         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27649                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27650         lod_qos_prio_free=${lod_qos_prio_free%%%}
27651         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27652                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27653         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27654         stack_trap "do_nodes $mdts $LCTL set_param \
27655                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27656         stack_trap "do_nodes $mdts $LCTL set_param \
27657                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27658
27659         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27660         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27661
27662         testdir=$DIR/$tdir-s$stripe_count/rr
27663
27664         local stripe_index=$($LFS getstripe -m $testdir)
27665         local test_mkdir_rr=true
27666
27667         getfattr -d -m dmv -e hex $testdir | grep dmv
27668         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27669                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27670                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27671                         test_mkdir_rr=false
27672         fi
27673
27674         echo
27675         $test_mkdir_rr &&
27676                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27677                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27678
27679         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27680         for (( i = 0; i < total / stripe_count; i++ )); do
27681                 eval $mkdir_cmd $testdir/subdir$i ||
27682                         error "$mkdir_cmd subdir$i failed"
27683         done
27684
27685         for (( i = 0; i < $MDSCOUNT; i++ )); do
27686                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27687                 echo "$count directories created on MDT$i"
27688                 if $test_mkdir_rr; then
27689                         (( count == total / stripe_count / MDSCOUNT )) ||
27690                                 error "subdirs are not evenly distributed"
27691                 elif (( i == stripe_index )); then
27692                         (( count == total / stripe_count )) ||
27693                                 error "$count subdirs created on MDT$i"
27694                 else
27695                         (( count == 0 )) ||
27696                                 error "$count subdirs created on MDT$i"
27697                 fi
27698
27699                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27700                         count=$($LFS getdirstripe $testdir/* |
27701                                 grep -c -P "^\s+$i\t")
27702                         echo "$count stripes created on MDT$i"
27703                         # deviation should < 5% of average
27704                         delta=$((count - total / MDSCOUNT))
27705                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27706                                 error "stripes are not evenly distributed"
27707                 fi
27708         done
27709
27710         echo
27711         echo "Check for uneven MDTs: "
27712
27713         local ffree
27714         local bavail
27715         local max
27716         local min
27717         local max_index
27718         local min_index
27719         local tmp
27720
27721         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27722         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27723         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27724
27725         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27726         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27727         max_index=0
27728         min_index=0
27729         for ((i = 1; i < ${#ffree[@]}; i++)); do
27730                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27731                 if [ $tmp -gt $max ]; then
27732                         max=$tmp
27733                         max_index=$i
27734                 fi
27735                 if [ $tmp -lt $min ]; then
27736                         min=$tmp
27737                         min_index=$i
27738                 fi
27739         done
27740         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27741
27742         (( min > 0 )) || skip "low space on MDT$min_index"
27743         (( ${ffree[min_index]} < 10000000 )) ||
27744                 skip "too many free files on MDT$min_index"
27745
27746         generate_uneven_mdts 120
27747
27748         echo "MDT filesfree available: ${ffree[*]}"
27749         echo "MDT blocks available: ${bavail[*]}"
27750         echo "weight diff=$(((max - min) * 100 / min))%"
27751         echo
27752         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27753
27754         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27755         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27756         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27757         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27758         # decrease statfs age, so that it can be updated in time
27759         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27760         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27761
27762         sleep 1
27763
27764         testdir=$DIR/$tdir-s$stripe_count/qos
27765
27766         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27767         for (( i = 0; i < total / stripe_count; i++ )); do
27768                 eval $mkdir_cmd $testdir/subdir$i ||
27769                         error "$mkdir_cmd subdir$i failed"
27770         done
27771
27772         max=0
27773         for (( i = 0; i < $MDSCOUNT; i++ )); do
27774                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27775                 (( count > max )) && max=$count
27776                 echo "$count directories created on MDT$i : curmax=$max"
27777         done
27778
27779         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27780
27781         # D-value should > 10% of average
27782         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27783                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27784
27785         # ditto for stripes
27786         if (( stripe_count > 1 )); then
27787                 max=0
27788                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27789                         count=$($LFS getdirstripe $testdir/* |
27790                                 grep -c -P "^\s+$i\t")
27791                         (( count > max )) && max=$count
27792                         echo "$count stripes created on MDT$i"
27793                 done
27794
27795                 min=$($LFS getdirstripe $testdir/* |
27796                         grep -c -P "^\s+$min_index\t")
27797                 (( max - min > total / MDSCOUNT / 10 )) ||
27798                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27799         fi
27800 }
27801
27802 most_full_mdt() {
27803         local ffree
27804         local bavail
27805         local bsize
27806         local min
27807         local min_index
27808         local tmp
27809
27810         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27811         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27812         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27813
27814         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27815         min_index=0
27816         for ((i = 1; i < ${#ffree[@]}; i++)); do
27817                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27818                 (( tmp < min )) && min=$tmp && min_index=$i
27819         done
27820
27821         echo -n $min_index
27822 }
27823
27824 test_413a() {
27825         [ $MDSCOUNT -lt 2 ] &&
27826                 skip "We need at least 2 MDTs for this test"
27827
27828         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27829                 skip "Need server version at least 2.12.52"
27830
27831         local stripe_max=$((MDSCOUNT - 1))
27832         local stripe_count
27833
27834         # let caller set maxage for latest result
27835         set_maxage 1
27836
27837         # fill MDT unevenly
27838         generate_uneven_mdts 120
27839
27840         # test 4-stripe directory at most, otherwise it's too slow
27841         # We are being very defensive. Although Autotest uses 4 MDTs.
27842         # We make sure stripe_max does not go over 4.
27843         (( stripe_max > 4 )) && stripe_max=4
27844         # unlinking striped directory is slow on zfs, and may timeout, only test
27845         # plain directory
27846         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27847         for stripe_count in $(seq 1 $stripe_max); do
27848                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27849                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27850                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27851                         error "mkdir failed"
27852                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27853         done
27854 }
27855 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27856
27857 test_413b() {
27858         [ $MDSCOUNT -lt 2 ] &&
27859                 skip "We need at least 2 MDTs for this test"
27860
27861         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27862                 skip "Need server version at least 2.12.52"
27863
27864         local stripe_max=$((MDSCOUNT - 1))
27865         local testdir
27866         local stripe_count
27867
27868         # let caller set maxage for latest result
27869         set_maxage 1
27870
27871         # fill MDT unevenly
27872         generate_uneven_mdts 120
27873
27874         # test 4-stripe directory at most, otherwise it's too slow
27875         # We are being very defensive. Although Autotest uses 4 MDTs.
27876         # We make sure stripe_max does not go over 4.
27877         (( stripe_max > 4 )) && stripe_max=4
27878         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27879         for stripe_count in $(seq 1 $stripe_max); do
27880                 testdir=$DIR/$tdir-s$stripe_count
27881                 mkdir $testdir || error "mkdir $testdir failed"
27882                 mkdir $testdir/rr || error "mkdir rr failed"
27883                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27884                         error "mkdir qos failed"
27885                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27886                         $testdir/rr || error "setdirstripe rr failed"
27887                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27888                         error "setdirstripe failed"
27889                 test_qos_mkdir "mkdir" $stripe_count
27890         done
27891 }
27892 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27893
27894 test_413c() {
27895         (( $MDSCOUNT >= 2 )) ||
27896                 skip "We need at least 2 MDTs for this test"
27897
27898         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27899                 skip "Need server version at least 2.14.51"
27900
27901         local testdir
27902         local inherit
27903         local inherit_rr
27904         local lmv_qos_maxage
27905         local lod_qos_maxage
27906
27907         # let caller set maxage for latest result
27908         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27909         $LCTL set_param lmv.*.qos_maxage=1
27910         stack_trap "$LCTL set_param \
27911                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27912         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27913                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27914         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27915                 lod.*.mdt_qos_maxage=1
27916         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27917                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27918
27919         # fill MDT unevenly
27920         generate_uneven_mdts 120
27921
27922         testdir=$DIR/${tdir}-s1
27923         mkdir $testdir || error "mkdir $testdir failed"
27924         mkdir $testdir/rr || error "mkdir rr failed"
27925         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27926         # default max_inherit is -1, default max_inherit_rr is 0
27927         $LFS setdirstripe -D -c 1 $testdir/rr ||
27928                 error "setdirstripe rr failed"
27929         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27930                 error "setdirstripe qos failed"
27931         test_qos_mkdir "mkdir" 1
27932
27933         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27934         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27935         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27936         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27937         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27938
27939         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27940         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27941         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27942         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27943         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27944         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27945         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27946                 error "level2 shouldn't have default LMV" || true
27947 }
27948 run_test 413c "mkdir with default LMV max inherit rr"
27949
27950 test_413d() {
27951         (( MDSCOUNT >= 2 )) ||
27952                 skip "We need at least 2 MDTs for this test"
27953
27954         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27955                 skip "Need server version at least 2.14.51"
27956
27957         local lmv_qos_threshold_rr
27958
27959         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27960                 head -n1)
27961         stack_trap "$LCTL set_param \
27962                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27963
27964         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27965         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27966         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27967                 error "$tdir shouldn't have default LMV"
27968         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27969                 error "mkdir sub failed"
27970
27971         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27972
27973         (( count == 100 )) || error "$count subdirs on MDT0"
27974 }
27975 run_test 413d "inherit ROOT default LMV"
27976
27977 test_413e() {
27978         (( MDSCOUNT >= 2 )) ||
27979                 skip "We need at least 2 MDTs for this test"
27980         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27981                 skip "Need server version at least 2.14.55"
27982
27983         local testdir=$DIR/$tdir
27984         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27985         local max_inherit
27986         local sub_max_inherit
27987
27988         mkdir -p $testdir || error "failed to create $testdir"
27989
27990         # set default max-inherit to -1 if stripe count is 0 or 1
27991         $LFS setdirstripe -D -c 1 $testdir ||
27992                 error "failed to set default LMV"
27993         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27994         (( max_inherit == -1 )) ||
27995                 error "wrong max_inherit value $max_inherit"
27996
27997         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27998         $LFS setdirstripe -D -c -1 $testdir ||
27999                 error "failed to set default LMV"
28000         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28001         (( max_inherit > 0 )) ||
28002                 error "wrong max_inherit value $max_inherit"
28003
28004         # and the subdir will decrease the max_inherit by 1
28005         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28006         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28007         (( sub_max_inherit == max_inherit - 1)) ||
28008                 error "wrong max-inherit of subdir $sub_max_inherit"
28009
28010         # check specified --max-inherit and warning message
28011         stack_trap "rm -f $tmpfile"
28012         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28013                 error "failed to set default LMV"
28014         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28015         (( max_inherit == -1 )) ||
28016                 error "wrong max_inherit value $max_inherit"
28017
28018         # check the warning messages
28019         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28020                 error "failed to detect warning string"
28021         fi
28022 }
28023 run_test 413e "check default max-inherit value"
28024
28025 test_fs_dmv_inherit()
28026 {
28027         local testdir=$DIR/$tdir
28028
28029         local count
28030         local inherit
28031         local inherit_rr
28032
28033         for i in 1 2; do
28034                 mkdir $testdir || error "mkdir $testdir failed"
28035                 count=$($LFS getdirstripe -D -c $testdir)
28036                 (( count == 1 )) ||
28037                         error "$testdir default LMV count mismatch $count != 1"
28038                 inherit=$($LFS getdirstripe -D -X $testdir)
28039                 (( inherit == 3 - i )) ||
28040                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28041                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28042                 (( inherit_rr == 3 - i )) ||
28043                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28044                 testdir=$testdir/sub
28045         done
28046
28047         mkdir $testdir || error "mkdir $testdir failed"
28048         count=$($LFS getdirstripe -D -c $testdir)
28049         (( count == 0 )) ||
28050                 error "$testdir default LMV count not zero: $count"
28051 }
28052
28053 test_413f() {
28054         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28055
28056         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28057                 skip "Need server version at least 2.14.55"
28058
28059         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28060                 error "dump $DIR default LMV failed"
28061         stack_trap "setfattr --restore=$TMP/dmv.ea"
28062
28063         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28064                 error "set $DIR default LMV failed"
28065
28066         test_fs_dmv_inherit
28067 }
28068 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28069
28070 test_413g() {
28071         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28072
28073         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28074         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28075                 error "dump $DIR default LMV failed"
28076         stack_trap "setfattr --restore=$TMP/dmv.ea"
28077
28078         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28079                 error "set $DIR default LMV failed"
28080
28081         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28082                 error "mount $MOUNT2 failed"
28083         stack_trap "umount_client $MOUNT2"
28084
28085         local saved_DIR=$DIR
28086
28087         export DIR=$MOUNT2
28088
28089         stack_trap "export DIR=$saved_DIR"
28090
28091         # first check filesystem-wide default LMV inheritance
28092         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28093
28094         # then check subdirs are spread to all MDTs
28095         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28096
28097         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28098
28099         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28100 }
28101 run_test 413g "enforce ROOT default LMV on subdir mount"
28102
28103 test_413h() {
28104         (( MDSCOUNT >= 2 )) ||
28105                 skip "We need at least 2 MDTs for this test"
28106
28107         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28108                 skip "Need server version at least 2.15.50.6"
28109
28110         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28111
28112         stack_trap "$LCTL set_param \
28113                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28114         $LCTL set_param lmv.*.qos_maxage=1
28115
28116         local depth=5
28117         local rr_depth=4
28118         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28119         local count=$((MDSCOUNT * 20))
28120
28121         generate_uneven_mdts 50
28122
28123         mkdir -p $dir || error "mkdir $dir failed"
28124         stack_trap "rm -rf $dir"
28125         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28126                 --max-inherit-rr=$rr_depth $dir
28127
28128         for ((d=0; d < depth + 2; d++)); do
28129                 log "dir=$dir:"
28130                 for ((sub=0; sub < count; sub++)); do
28131                         mkdir $dir/d$sub
28132                 done
28133                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28134                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28135                 # subdirs within $rr_depth should be created round-robin
28136                 if (( d < rr_depth )); then
28137                         (( ${num[0]} != count )) ||
28138                                 error "all objects created on MDT ${num[1]}"
28139                 fi
28140
28141                 dir=$dir/d0
28142         done
28143 }
28144 run_test 413h "don't stick to parent for round-robin dirs"
28145
28146 test_413i() {
28147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28148
28149         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28150                 skip "Need server version at least 2.14.55"
28151
28152         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28153                 error "dump $DIR default LMV failed"
28154         stack_trap "setfattr --restore=$TMP/dmv.ea"
28155
28156         local testdir=$DIR/$tdir
28157         local def_max_rr=1
28158         local def_max=3
28159         local count
28160
28161         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28162                 --max-inherit-rr=$def_max_rr $DIR ||
28163                 error "set $DIR default LMV failed"
28164
28165         for i in $(seq 2 3); do
28166                 def_max=$((def_max - 1))
28167                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28168
28169                 mkdir $testdir
28170                 # RR is decremented and keeps zeroed once exhausted
28171                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28172                 (( count == def_max_rr )) ||
28173                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28174
28175                 # max-inherit is decremented
28176                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28177                 (( count == def_max )) ||
28178                         error_noexit "$testdir: max-inherit $count != $def_max"
28179
28180                 testdir=$testdir/d$i
28181         done
28182
28183         # d3 is the last inherited from ROOT, no inheritance anymore
28184         # i.e. no the default layout anymore
28185         mkdir -p $testdir/d4/d5
28186         count=$($LFS getdirstripe -D --max-inherit $testdir)
28187         (( count == -1 )) ||
28188                 error_noexit "$testdir: max-inherit $count != -1"
28189
28190         local p_count=$($LFS getdirstripe -i $testdir)
28191
28192         for i in $(seq 4 5); do
28193                 testdir=$testdir/d$i
28194
28195                 # the root default layout is not applied once exhausted
28196                 count=$($LFS getdirstripe -i $testdir)
28197                 (( count == p_count )) ||
28198                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28199         done
28200
28201         $LFS setdirstripe -i 0 $DIR/d2
28202         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28203         (( count == -1 )) ||
28204                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28205 }
28206 run_test 413i "check default layout inheritance"
28207
28208 test_413z() {
28209         local pids=""
28210         local subdir
28211         local pid
28212
28213         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28214                 unlinkmany $subdir/f. $TEST413_COUNT &
28215                 pids="$pids $!"
28216         done
28217
28218         for pid in $pids; do
28219                 wait $pid
28220         done
28221
28222         true
28223 }
28224 run_test 413z "413 test cleanup"
28225
28226 test_414() {
28227 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28228         $LCTL set_param fail_loc=0x80000521
28229         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28230         rm -f $DIR/$tfile
28231 }
28232 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28233
28234 test_415() {
28235         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28236         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28237                 skip "Need server version at least 2.11.52"
28238
28239         # LU-11102
28240         local total=500
28241         local max=120
28242
28243         # this test may be slow on ZFS
28244         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28245
28246         # though this test is designed for striped directory, let's test normal
28247         # directory too since lock is always saved as CoS lock.
28248         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28249         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28250         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28251         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28252         wait_delete_completed_mds
28253
28254         # run a loop without concurrent touch to measure rename duration.
28255         # only for test debug/robustness, NOT part of COS functional test.
28256         local start_time=$SECONDS
28257         for ((i = 0; i < total; i++)); do
28258                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28259                         > /dev/null
28260         done
28261         local baseline=$((SECONDS - start_time))
28262         echo "rename $total files without 'touch' took $baseline sec"
28263
28264         (
28265                 while true; do
28266                         touch $DIR/$tdir
28267                 done
28268         ) &
28269         local setattr_pid=$!
28270
28271         # rename files back to original name so unlinkmany works
28272         start_time=$SECONDS
28273         for ((i = 0; i < total; i++)); do
28274                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28275                         > /dev/null
28276         done
28277         local duration=$((SECONDS - start_time))
28278
28279         kill -9 $setattr_pid
28280
28281         echo "rename $total files with 'touch' took $duration sec"
28282         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28283         (( duration <= max )) ||
28284                 error_not_in_vm "rename took $duration > $max sec"
28285 }
28286 run_test 415 "lock revoke is not missing"
28287
28288 test_416() {
28289         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28290                 skip "Need server version at least 2.11.55"
28291
28292         # define OBD_FAIL_OSD_TXN_START    0x19a
28293         do_facet mds1 lctl set_param fail_loc=0x19a
28294
28295         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28296
28297         true
28298 }
28299 run_test 416 "transaction start failure won't cause system hung"
28300
28301 cleanup_417() {
28302         trap 0
28303         do_nodes $(comma_list $(mdts_nodes)) \
28304                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28305         do_nodes $(comma_list $(mdts_nodes)) \
28306                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28307         do_nodes $(comma_list $(mdts_nodes)) \
28308                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28309 }
28310
28311 test_417() {
28312         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28313         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28314                 skip "Need MDS version at least 2.11.56"
28315
28316         trap cleanup_417 RETURN EXIT
28317
28318         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28319         do_nodes $(comma_list $(mdts_nodes)) \
28320                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28321         $LFS migrate -m 0 $DIR/$tdir.1 &&
28322                 error "migrate dir $tdir.1 should fail"
28323
28324         do_nodes $(comma_list $(mdts_nodes)) \
28325                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28326         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28327                 error "create remote dir $tdir.2 should fail"
28328
28329         do_nodes $(comma_list $(mdts_nodes)) \
28330                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28331         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28332                 error "create striped dir $tdir.3 should fail"
28333         true
28334 }
28335 run_test 417 "disable remote dir, striped dir and dir migration"
28336
28337 # Checks that the outputs of df [-i] and lfs df [-i] match
28338 #
28339 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28340 check_lfs_df() {
28341         local dir=$2
28342         local inodes
28343         local df_out
28344         local lfs_df_out
28345         local count
28346         local passed=false
28347
28348         # blocks or inodes
28349         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28350
28351         for count in {1..100}; do
28352                 do_nodes "$CLIENTS" \
28353                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28354                 sync; sleep 0.2
28355
28356                 # read the lines of interest
28357                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28358                         error "df $inodes $dir | tail -n +2 failed"
28359                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28360                         error "lfs df $inodes $dir | grep summary: failed"
28361
28362                 # skip first substrings of each output as they are different
28363                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28364                 # compare the two outputs
28365                 passed=true
28366                 #  skip "available" on MDT until LU-13997 is fixed.
28367                 #for i in {1..5}; do
28368                 for i in 1 2 4 5; do
28369                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28370                 done
28371                 $passed && break
28372         done
28373
28374         if ! $passed; then
28375                 df -P $inodes $dir
28376                 echo
28377                 lfs df $inodes $dir
28378                 error "df and lfs df $1 output mismatch: "      \
28379                       "df ${inodes}: ${df_out[*]}, "            \
28380                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28381         fi
28382 }
28383
28384 test_418() {
28385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28386
28387         local dir=$DIR/$tdir
28388         local numfiles=$((RANDOM % 4096 + 2))
28389         local numblocks=$((RANDOM % 256 + 1))
28390
28391         wait_delete_completed
28392         test_mkdir $dir
28393
28394         # check block output
28395         check_lfs_df blocks $dir
28396         # check inode output
28397         check_lfs_df inodes $dir
28398
28399         # create a single file and retest
28400         echo "Creating a single file and testing"
28401         createmany -o $dir/$tfile- 1 &>/dev/null ||
28402                 error "creating 1 file in $dir failed"
28403         check_lfs_df blocks $dir
28404         check_lfs_df inodes $dir
28405
28406         # create a random number of files
28407         echo "Creating $((numfiles - 1)) files and testing"
28408         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28409                 error "creating $((numfiles - 1)) files in $dir failed"
28410
28411         # write a random number of blocks to the first test file
28412         echo "Writing $numblocks 4K blocks and testing"
28413         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28414                 count=$numblocks &>/dev/null ||
28415                 error "dd to $dir/${tfile}-0 failed"
28416
28417         # retest
28418         check_lfs_df blocks $dir
28419         check_lfs_df inodes $dir
28420
28421         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28422                 error "unlinking $numfiles files in $dir failed"
28423 }
28424 run_test 418 "df and lfs df outputs match"
28425
28426 test_419()
28427 {
28428         local dir=$DIR/$tdir
28429
28430         mkdir -p $dir
28431         touch $dir/file
28432
28433         cancel_lru_locks mdc
28434
28435         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28436         $LCTL set_param fail_loc=0x1410
28437         cat $dir/file
28438         $LCTL set_param fail_loc=0
28439         rm -rf $dir
28440 }
28441 run_test 419 "Verify open file by name doesn't crash kernel"
28442
28443 test_420()
28444 {
28445         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28446                 skip "Need MDS version at least 2.12.53"
28447
28448         local SAVE_UMASK=$(umask)
28449         local dir=$DIR/$tdir
28450         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28451
28452         mkdir -p $dir
28453         umask 0000
28454         mkdir -m03777 $dir/testdir
28455         ls -dn $dir/testdir
28456         # Need to remove trailing '.' when SELinux is enabled
28457         local dirperms=$(ls -dn $dir/testdir |
28458                          awk '{ sub(/\.$/, "", $1); print $1}')
28459         [ $dirperms == "drwxrwsrwt" ] ||
28460                 error "incorrect perms on $dir/testdir"
28461
28462         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28463                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28464         ls -n $dir/testdir/testfile
28465         local fileperms=$(ls -n $dir/testdir/testfile |
28466                           awk '{ sub(/\.$/, "", $1); print $1}')
28467         [ $fileperms == "-rwxr-xr-x" ] ||
28468                 error "incorrect perms on $dir/testdir/testfile"
28469
28470         umask $SAVE_UMASK
28471 }
28472 run_test 420 "clear SGID bit on non-directories for non-members"
28473
28474 test_421a() {
28475         local cnt
28476         local fid1
28477         local fid2
28478
28479         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28480                 skip "Need MDS version at least 2.12.54"
28481
28482         test_mkdir $DIR/$tdir
28483         createmany -o $DIR/$tdir/f 3
28484         cnt=$(ls -1 $DIR/$tdir | wc -l)
28485         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28486
28487         fid1=$(lfs path2fid $DIR/$tdir/f1)
28488         fid2=$(lfs path2fid $DIR/$tdir/f2)
28489         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28490
28491         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28492         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28493
28494         cnt=$(ls -1 $DIR/$tdir | wc -l)
28495         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28496
28497         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28498         createmany -o $DIR/$tdir/f 3
28499         cnt=$(ls -1 $DIR/$tdir | wc -l)
28500         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28501
28502         fid1=$(lfs path2fid $DIR/$tdir/f1)
28503         fid2=$(lfs path2fid $DIR/$tdir/f2)
28504         echo "remove using fsname $FSNAME"
28505         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28506
28507         cnt=$(ls -1 $DIR/$tdir | wc -l)
28508         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28509 }
28510 run_test 421a "simple rm by fid"
28511
28512 test_421b() {
28513         local cnt
28514         local FID1
28515         local FID2
28516
28517         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28518                 skip "Need MDS version at least 2.12.54"
28519
28520         test_mkdir $DIR/$tdir
28521         createmany -o $DIR/$tdir/f 3
28522         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28523         MULTIPID=$!
28524
28525         FID1=$(lfs path2fid $DIR/$tdir/f1)
28526         FID2=$(lfs path2fid $DIR/$tdir/f2)
28527         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28528
28529         kill -USR1 $MULTIPID
28530         wait
28531
28532         cnt=$(ls $DIR/$tdir | wc -l)
28533         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28534 }
28535 run_test 421b "rm by fid on open file"
28536
28537 test_421c() {
28538         local cnt
28539         local FIDS
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         touch $DIR/$tdir/$tfile
28547         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28548         cnt=$(ls -1 $DIR/$tdir | wc -l)
28549         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28550
28551         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28552         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28553
28554         cnt=$(ls $DIR/$tdir | wc -l)
28555         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28556 }
28557 run_test 421c "rm by fid against hardlinked files"
28558
28559 test_421d() {
28560         local cnt
28561         local FIDS
28562
28563         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28564                 skip "Need MDS version at least 2.12.54"
28565
28566         test_mkdir $DIR/$tdir
28567         createmany -o $DIR/$tdir/f 4097
28568         cnt=$(ls -1 $DIR/$tdir | wc -l)
28569         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28570
28571         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28572         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28573
28574         cnt=$(ls $DIR/$tdir | wc -l)
28575         rm -rf $DIR/$tdir
28576         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28577 }
28578 run_test 421d "rmfid en masse"
28579
28580 test_421e() {
28581         local cnt
28582         local FID
28583
28584         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28585         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28586                 skip "Need MDS version at least 2.12.54"
28587
28588         mkdir -p $DIR/$tdir
28589         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28590         createmany -o $DIR/$tdir/striped_dir/f 512
28591         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28592         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28593
28594         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28595                 sed "s/[/][^:]*://g")
28596         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28597
28598         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28599         rm -rf $DIR/$tdir
28600         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28601 }
28602 run_test 421e "rmfid in DNE"
28603
28604 test_421f() {
28605         local cnt
28606         local FID
28607
28608         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28609                 skip "Need MDS version at least 2.12.54"
28610
28611         test_mkdir $DIR/$tdir
28612         touch $DIR/$tdir/f
28613         cnt=$(ls -1 $DIR/$tdir | wc -l)
28614         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28615
28616         FID=$(lfs path2fid $DIR/$tdir/f)
28617         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28618         # rmfid should fail
28619         cnt=$(ls -1 $DIR/$tdir | wc -l)
28620         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28621
28622         chmod a+rw $DIR/$tdir
28623         ls -la $DIR/$tdir
28624         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28625         # rmfid should fail
28626         cnt=$(ls -1 $DIR/$tdir | wc -l)
28627         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28628
28629         rm -f $DIR/$tdir/f
28630         $RUNAS touch $DIR/$tdir/f
28631         FID=$(lfs path2fid $DIR/$tdir/f)
28632         echo "rmfid as root"
28633         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28634         cnt=$(ls -1 $DIR/$tdir | wc -l)
28635         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28636
28637         rm -f $DIR/$tdir/f
28638         $RUNAS touch $DIR/$tdir/f
28639         cnt=$(ls -1 $DIR/$tdir | wc -l)
28640         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28641         FID=$(lfs path2fid $DIR/$tdir/f)
28642         # rmfid w/o user_fid2path mount option should fail
28643         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28644         cnt=$(ls -1 $DIR/$tdir | wc -l)
28645         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28646
28647         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28648         stack_trap "rmdir $tmpdir"
28649         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28650                 error "failed to mount client'"
28651         stack_trap "umount_client $tmpdir"
28652
28653         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28654         # rmfid should succeed
28655         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28656         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28657
28658         # rmfid shouldn't allow to remove files due to dir's permission
28659         chmod a+rwx $tmpdir/$tdir
28660         touch $tmpdir/$tdir/f
28661         ls -la $tmpdir/$tdir
28662         FID=$(lfs path2fid $tmpdir/$tdir/f)
28663         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28664         return 0
28665 }
28666 run_test 421f "rmfid checks permissions"
28667
28668 test_421g() {
28669         local cnt
28670         local FIDS
28671
28672         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28673         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28674                 skip "Need MDS version at least 2.12.54"
28675
28676         mkdir -p $DIR/$tdir
28677         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28678         createmany -o $DIR/$tdir/striped_dir/f 512
28679         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28680         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28681
28682         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28683                 sed "s/[/][^:]*://g")
28684
28685         rm -f $DIR/$tdir/striped_dir/f1*
28686         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28687         removed=$((512 - cnt))
28688
28689         # few files have been just removed, so we expect
28690         # rmfid to fail on their fids
28691         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28692         [ $removed != $errors ] && error "$errors != $removed"
28693
28694         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28695         rm -rf $DIR/$tdir
28696         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28697 }
28698 run_test 421g "rmfid to return errors properly"
28699
28700 test_421h() {
28701         local mount_other
28702         local mount_ret
28703         local rmfid_ret
28704         local old_fid
28705         local fidA
28706         local fidB
28707         local fidC
28708         local fidD
28709
28710         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28711                 skip "Need MDS version at least 2.15.53"
28712
28713         test_mkdir $DIR/$tdir
28714         test_mkdir $DIR/$tdir/subdir
28715         touch $DIR/$tdir/subdir/file0
28716         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28717         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28718         rm -f $DIR/$tdir/subdir/file0
28719         touch $DIR/$tdir/subdir/fileA
28720         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28721         echo File $DIR/$tdir/subdir/fileA FID $fidA
28722         touch $DIR/$tdir/subdir/fileB
28723         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28724         echo File $DIR/$tdir/subdir/fileB FID $fidB
28725         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28726         touch $DIR/$tdir/subdir/fileC
28727         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28728         echo File $DIR/$tdir/subdir/fileC FID $fidC
28729         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28730         touch $DIR/$tdir/fileD
28731         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28732         echo File $DIR/$tdir/fileD FID $fidD
28733
28734         # mount another client mount point with subdirectory mount
28735         export FILESET=/$tdir/subdir
28736         mount_other=${MOUNT}_other
28737         mount_client $mount_other ${MOUNT_OPTS}
28738         mount_ret=$?
28739         export FILESET=""
28740         (( mount_ret == 0 )) || error "mount $mount_other failed"
28741
28742         echo Removing FIDs:
28743         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28744         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28745         rmfid_ret=$?
28746
28747         umount_client $mount_other || error "umount $mount_other failed"
28748
28749         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28750
28751         # fileA should have been deleted
28752         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28753
28754         # fileB should have been deleted
28755         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28756
28757         # fileC should not have been deleted, fid also exists outside of fileset
28758         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28759
28760         # fileD should not have been deleted, it exists outside of fileset
28761         stat $DIR/$tdir/fileD || error "fileD deleted"
28762 }
28763 run_test 421h "rmfid with fileset mount"
28764
28765 test_422() {
28766         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28767         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28768         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28769         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28770         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28771
28772         local amc=$(at_max_get client)
28773         local amo=$(at_max_get mds1)
28774         local timeout=`lctl get_param -n timeout`
28775
28776         at_max_set 0 client
28777         at_max_set 0 mds1
28778
28779 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28780         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28781                         fail_val=$(((2*timeout + 10)*1000))
28782         touch $DIR/$tdir/d3/file &
28783         sleep 2
28784 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28785         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28786                         fail_val=$((2*timeout + 5))
28787         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28788         local pid=$!
28789         sleep 1
28790         kill -9 $pid
28791         sleep $((2 * timeout))
28792         echo kill $pid
28793         kill -9 $pid
28794         lctl mark touch
28795         touch $DIR/$tdir/d2/file3
28796         touch $DIR/$tdir/d2/file4
28797         touch $DIR/$tdir/d2/file5
28798
28799         wait
28800         at_max_set $amc client
28801         at_max_set $amo mds1
28802
28803         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28804         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28805                 error "Watchdog is always throttled"
28806 }
28807 run_test 422 "kill a process with RPC in progress"
28808
28809 stat_test() {
28810     df -h $MOUNT &
28811     df -h $MOUNT &
28812     df -h $MOUNT &
28813     df -h $MOUNT &
28814     df -h $MOUNT &
28815     df -h $MOUNT &
28816 }
28817
28818 test_423() {
28819     local _stats
28820     # ensure statfs cache is expired
28821     sleep 2;
28822
28823     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28824     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28825
28826     return 0
28827 }
28828 run_test 423 "statfs should return a right data"
28829
28830 test_424() {
28831 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28832         $LCTL set_param fail_loc=0x80000522
28833         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28834         rm -f $DIR/$tfile
28835 }
28836 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28837
28838 test_425() {
28839         test_mkdir -c -1 $DIR/$tdir
28840         $LFS setstripe -c -1 $DIR/$tdir
28841
28842         lru_resize_disable "" 100
28843         stack_trap "lru_resize_enable" EXIT
28844
28845         sleep 5
28846
28847         for i in $(seq $((MDSCOUNT * 125))); do
28848                 local t=$DIR/$tdir/$tfile_$i
28849
28850                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28851                         error_noexit "Create file $t"
28852         done
28853         stack_trap "rm -rf $DIR/$tdir" EXIT
28854
28855         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28856                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28857                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28858
28859                 [ $lock_count -le $lru_size ] ||
28860                         error "osc lock count $lock_count > lru size $lru_size"
28861         done
28862
28863         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28864                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28865                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28866
28867                 [ $lock_count -le $lru_size ] ||
28868                         error "mdc lock count $lock_count > lru size $lru_size"
28869         done
28870 }
28871 run_test 425 "lock count should not exceed lru size"
28872
28873 test_426() {
28874         splice-test -r $DIR/$tfile
28875         splice-test -rd $DIR/$tfile
28876         splice-test $DIR/$tfile
28877         splice-test -d $DIR/$tfile
28878 }
28879 run_test 426 "splice test on Lustre"
28880
28881 test_427() {
28882         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28883         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28884                 skip "Need MDS version at least 2.12.4"
28885         local log
28886
28887         mkdir $DIR/$tdir
28888         mkdir $DIR/$tdir/1
28889         mkdir $DIR/$tdir/2
28890         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28891         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28892
28893         $LFS getdirstripe $DIR/$tdir/1/dir
28894
28895         #first setfattr for creating updatelog
28896         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28897
28898 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28899         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28900         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28901         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28902
28903         sleep 2
28904         fail mds2
28905         wait_recovery_complete mds2 $((2*TIMEOUT))
28906
28907         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28908         echo $log | grep "get update log failed" &&
28909                 error "update log corruption is detected" || true
28910 }
28911 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28912
28913 test_428() {
28914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28915         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
28916                               awk '/^max_cached_mb/ { print $2 }')
28917         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
28918
28919         $LCTL set_param -n llite.*.max_cached_mb=64
28920
28921         mkdir $DIR/$tdir
28922         $LFS setstripe -c 1 $DIR/$tdir
28923         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28924         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28925         #test write
28926         for f in $(seq 4); do
28927                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28928         done
28929         wait
28930
28931         cancel_lru_locks osc
28932         # Test read
28933         for f in $(seq 4); do
28934                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28935         done
28936         wait
28937 }
28938 run_test 428 "large block size IO should not hang"
28939
28940 test_429() { # LU-7915 / LU-10948
28941         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28942         local testfile=$DIR/$tfile
28943         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28944         local new_flag=1
28945         local first_rpc
28946         local second_rpc
28947         local third_rpc
28948
28949         $LCTL get_param $ll_opencache_threshold_count ||
28950                 skip "client does not have opencache parameter"
28951
28952         set_opencache $new_flag
28953         stack_trap "restore_opencache"
28954         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28955                 error "enable opencache failed"
28956         touch $testfile
28957         # drop MDC DLM locks
28958         cancel_lru_locks mdc
28959         # clear MDC RPC stats counters
28960         $LCTL set_param $mdc_rpcstats=clear
28961
28962         # According to the current implementation, we need to run 3 times
28963         # open & close file to verify if opencache is enabled correctly.
28964         # 1st, RPCs are sent for lookup/open and open handle is released on
28965         #      close finally.
28966         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28967         #      so open handle won't be released thereafter.
28968         # 3rd, No RPC is sent out.
28969         $MULTIOP $testfile oc || error "multiop failed"
28970         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28971         echo "1st: $first_rpc RPCs in flight"
28972
28973         $MULTIOP $testfile oc || error "multiop failed"
28974         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28975         echo "2nd: $second_rpc RPCs in flight"
28976
28977         $MULTIOP $testfile oc || error "multiop failed"
28978         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28979         echo "3rd: $third_rpc RPCs in flight"
28980
28981         #verify no MDC RPC is sent
28982         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28983 }
28984 run_test 429 "verify if opencache flag on client side does work"
28985
28986 lseek_test_430() {
28987         local offset
28988         local file=$1
28989
28990         # data at [200K, 400K)
28991         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28992                 error "256K->512K dd fails"
28993         # data at [2M, 3M)
28994         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28995                 error "2M->3M dd fails"
28996         # data at [4M, 5M)
28997         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28998                 error "4M->5M dd fails"
28999         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29000         # start at first component hole #1
29001         printf "Seeking hole from 1000 ... "
29002         offset=$(lseek_test -l 1000 $file)
29003         echo $offset
29004         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29005         printf "Seeking data from 1000 ... "
29006         offset=$(lseek_test -d 1000 $file)
29007         echo $offset
29008         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29009
29010         # start at first component data block
29011         printf "Seeking hole from 300000 ... "
29012         offset=$(lseek_test -l 300000 $file)
29013         echo $offset
29014         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29015         printf "Seeking data from 300000 ... "
29016         offset=$(lseek_test -d 300000 $file)
29017         echo $offset
29018         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29019
29020         # start at the first component but beyond end of object size
29021         printf "Seeking hole from 1000000 ... "
29022         offset=$(lseek_test -l 1000000 $file)
29023         echo $offset
29024         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29025         printf "Seeking data from 1000000 ... "
29026         offset=$(lseek_test -d 1000000 $file)
29027         echo $offset
29028         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29029
29030         # start at second component stripe 2 (empty file)
29031         printf "Seeking hole from 1500000 ... "
29032         offset=$(lseek_test -l 1500000 $file)
29033         echo $offset
29034         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29035         printf "Seeking data from 1500000 ... "
29036         offset=$(lseek_test -d 1500000 $file)
29037         echo $offset
29038         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29039
29040         # start at second component stripe 1 (all data)
29041         printf "Seeking hole from 3000000 ... "
29042         offset=$(lseek_test -l 3000000 $file)
29043         echo $offset
29044         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29045         printf "Seeking data from 3000000 ... "
29046         offset=$(lseek_test -d 3000000 $file)
29047         echo $offset
29048         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29049
29050         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29051                 error "2nd dd fails"
29052         echo "Add data block at 640K...1280K"
29053
29054         # start at before new data block, in hole
29055         printf "Seeking hole from 600000 ... "
29056         offset=$(lseek_test -l 600000 $file)
29057         echo $offset
29058         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29059         printf "Seeking data from 600000 ... "
29060         offset=$(lseek_test -d 600000 $file)
29061         echo $offset
29062         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29063
29064         # start at the first component new data block
29065         printf "Seeking hole from 1000000 ... "
29066         offset=$(lseek_test -l 1000000 $file)
29067         echo $offset
29068         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29069         printf "Seeking data from 1000000 ... "
29070         offset=$(lseek_test -d 1000000 $file)
29071         echo $offset
29072         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29073
29074         # start at second component stripe 2, new data
29075         printf "Seeking hole from 1200000 ... "
29076         offset=$(lseek_test -l 1200000 $file)
29077         echo $offset
29078         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29079         printf "Seeking data from 1200000 ... "
29080         offset=$(lseek_test -d 1200000 $file)
29081         echo $offset
29082         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29083
29084         # start beyond file end
29085         printf "Using offset > filesize ... "
29086         lseek_test -l 4000000 $file && error "lseek should fail"
29087         printf "Using offset > filesize ... "
29088         lseek_test -d 4000000 $file && error "lseek should fail"
29089
29090         printf "Done\n\n"
29091 }
29092
29093 test_430a() {
29094         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29095                 skip "MDT does not support SEEK_HOLE"
29096
29097         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29098                 skip "OST does not support SEEK_HOLE"
29099
29100         local file=$DIR/$tdir/$tfile
29101
29102         mkdir -p $DIR/$tdir
29103
29104         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29105         # OST stripe #1 will have continuous data at [1M, 3M)
29106         # OST stripe #2 is empty
29107         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29108         lseek_test_430 $file
29109         rm $file
29110         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29111         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29112         lseek_test_430 $file
29113         rm $file
29114         $LFS setstripe -c2 -S 512K $file
29115         echo "Two stripes, stripe size 512K"
29116         lseek_test_430 $file
29117         rm $file
29118         # FLR with stale mirror
29119         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29120                        -N -c2 -S 1M $file
29121         echo "Mirrored file:"
29122         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29123         echo "Plain 2 stripes 1M"
29124         lseek_test_430 $file
29125         rm $file
29126 }
29127 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29128
29129 test_430b() {
29130         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29131                 skip "OST does not support SEEK_HOLE"
29132
29133         local offset
29134         local file=$DIR/$tdir/$tfile
29135
29136         mkdir -p $DIR/$tdir
29137         # Empty layout lseek should fail
29138         $MCREATE $file
29139         # seek from 0
29140         printf "Seeking hole from 0 ... "
29141         lseek_test -l 0 $file && error "lseek should fail"
29142         printf "Seeking data from 0 ... "
29143         lseek_test -d 0 $file && error "lseek should fail"
29144         rm $file
29145
29146         # 1M-hole file
29147         $LFS setstripe -E 1M -c2 -E eof $file
29148         $TRUNCATE $file 1048576
29149         printf "Seeking hole from 1000000 ... "
29150         offset=$(lseek_test -l 1000000 $file)
29151         echo $offset
29152         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29153         printf "Seeking data from 1000000 ... "
29154         lseek_test -d 1000000 $file && error "lseek should fail"
29155         rm $file
29156
29157         # full component followed by non-inited one
29158         $LFS setstripe -E 1M -c2 -E eof $file
29159         dd if=/dev/urandom of=$file bs=1M count=1
29160         printf "Seeking hole from 1000000 ... "
29161         offset=$(lseek_test -l 1000000 $file)
29162         echo $offset
29163         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29164         printf "Seeking hole from 1048576 ... "
29165         lseek_test -l 1048576 $file && error "lseek should fail"
29166         # init second component and truncate back
29167         echo "123" >> $file
29168         $TRUNCATE $file 1048576
29169         printf "Seeking hole from 1000000 ... "
29170         offset=$(lseek_test -l 1000000 $file)
29171         echo $offset
29172         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29173         printf "Seeking hole from 1048576 ... "
29174         lseek_test -l 1048576 $file && error "lseek should fail"
29175         # boundary checks for big values
29176         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29177         offset=$(lseek_test -d 0 $file.10g)
29178         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29179         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29180         offset=$(lseek_test -d 0 $file.100g)
29181         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29182         return 0
29183 }
29184 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29185
29186 test_430c() {
29187         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29188                 skip "OST does not support SEEK_HOLE"
29189
29190         local file=$DIR/$tdir/$tfile
29191         local start
29192
29193         mkdir -p $DIR/$tdir
29194         stack_trap "rm -f $file $file.tmp"
29195         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29196
29197         # cp version 8.33+ prefers lseek over fiemap
29198         local ver=$(cp --version | awk '{ print $4; exit; }')
29199
29200         echo "cp $ver installed"
29201         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29202                 start=$SECONDS
29203                 time cp -v $file $file.tmp || error "cp $file failed"
29204                 (( SECONDS - start < 5 )) || {
29205                         strace cp $file $file.tmp |&
29206                                 grep -E "open|read|seek|FIEMAP" |
29207                                 grep -A 100 $file
29208                         error "cp: too long runtime $((SECONDS - start))"
29209                 }
29210         else
29211                 echo "cp test skipped due to $ver < 8.33"
29212         fi
29213
29214         # tar version 1.29+ supports SEEK_HOLE/DATA
29215         ver=$(tar --version | awk '{ print $4; exit; }')
29216         echo "tar $ver installed"
29217         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29218                 start=$SECONDS
29219                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29220                 (( SECONDS - start < 5 )) || {
29221                         strace tar cf $file.tmp --sparse $file |&
29222                                 grep -E "open|read|seek|FIEMAP" |
29223                                 grep -A 100 $file
29224                         error "tar: too long runtime $((SECONDS - start))"
29225                 }
29226         else
29227                 echo "tar test skipped due to $ver < 1.29"
29228         fi
29229 }
29230 run_test 430c "lseek: external tools check"
29231
29232 test_431() { # LU-14187
29233         local file=$DIR/$tdir/$tfile
29234
29235         mkdir -p $DIR/$tdir
29236         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29237         dd if=/dev/urandom of=$file bs=4k count=1
29238         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29239         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29240         #define OBD_FAIL_OST_RESTART_IO 0x251
29241         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29242         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29243         cp $file $file.0
29244         cancel_lru_locks
29245         sync_all_data
29246         echo 3 > /proc/sys/vm/drop_caches
29247         diff  $file $file.0 || error "data diff"
29248 }
29249 run_test 431 "Restart transaction for IO"
29250
29251 cleanup_test_432() {
29252         do_facet mgs $LCTL nodemap_activate 0
29253         wait_nm_sync active
29254 }
29255
29256 test_432() {
29257         local tmpdir=$TMP/dir432
29258
29259         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29260                 skip "Need MDS version at least 2.14.52"
29261
29262         stack_trap cleanup_test_432 EXIT
29263         mkdir $DIR/$tdir
29264         mkdir $tmpdir
29265
29266         do_facet mgs $LCTL nodemap_activate 1
29267         wait_nm_sync active
29268         do_facet mgs $LCTL nodemap_modify --name default \
29269                 --property admin --value 1
29270         do_facet mgs $LCTL nodemap_modify --name default \
29271                 --property trusted --value 1
29272         cancel_lru_locks mdc
29273         wait_nm_sync default admin_nodemap
29274         wait_nm_sync default trusted_nodemap
29275
29276         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29277                grep -ci "Operation not permitted") -ne 0 ]; then
29278                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29279         fi
29280 }
29281 run_test 432 "mv dir from outside Lustre"
29282
29283 test_433() {
29284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29285
29286         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29287                 skip "inode cache not supported"
29288
29289         $LCTL set_param llite.*.inode_cache=0
29290         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29291
29292         local count=256
29293         local before
29294         local after
29295
29296         cancel_lru_locks mdc
29297         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29298         createmany -m $DIR/$tdir/f $count
29299         createmany -d $DIR/$tdir/d $count
29300         ls -l $DIR/$tdir > /dev/null
29301         stack_trap "rm -rf $DIR/$tdir"
29302
29303         before=$(num_objects)
29304         cancel_lru_locks mdc
29305         after=$(num_objects)
29306
29307         # sometimes even @before is less than 2 * count
29308         while (( before - after < count )); do
29309                 sleep 1
29310                 after=$(num_objects)
29311                 wait=$((wait + 1))
29312                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29313                 if (( wait > 60 )); then
29314                         error "inode slab grew from $before to $after"
29315                 fi
29316         done
29317
29318         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29319 }
29320 run_test 433 "ldlm lock cancel releases dentries and inodes"
29321
29322 test_434() {
29323         local file
29324         local getxattr_count
29325         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29326         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29327
29328         [[ $(getenforce) == "Disabled" ]] ||
29329                 skip "lsm selinux module have to be disabled for this test"
29330
29331         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29332                 error "fail to create $DIR/$tdir/ on MDT0000"
29333
29334         touch $DIR/$tdir/$tfile-{001..100}
29335
29336         # disable the xattr cache
29337         save_lustre_params client "llite.*.xattr_cache" > $p
29338         lctl set_param llite.*.xattr_cache=0
29339         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29340
29341         # clear clients mdc stats
29342         clear_stats $mdc_stat_param ||
29343                 error "fail to clear stats on mdc MDT0000"
29344
29345         for file in $DIR/$tdir/$tfile-{001..100}; do
29346                 getfattr -n security.selinux $file |&
29347                         grep -q "Operation not supported" ||
29348                         error "getxattr on security.selinux should return EOPNOTSUPP"
29349         done
29350
29351         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29352         (( getxattr_count < 100 )) ||
29353                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29354 }
29355 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29356
29357 test_440() {
29358         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29359                 source $LUSTRE/scripts/bash-completion/lustre
29360         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29361                 source /usr/share/bash-completion/completions/lustre
29362         else
29363                 skip "bash completion scripts not found"
29364         fi
29365
29366         local lctl_completions
29367         local lfs_completions
29368
29369         lctl_completions=$(_lustre_cmds lctl)
29370         if [[ ! $lctl_completions =~ "get_param" ]]; then
29371                 error "lctl bash completion failed"
29372         fi
29373
29374         lfs_completions=$(_lustre_cmds lfs)
29375         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29376                 error "lfs bash completion failed"
29377         fi
29378 }
29379 run_test 440 "bash completion for lfs, lctl"
29380
29381 prep_801() {
29382         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29383         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29384                 skip "Need server version at least 2.9.55"
29385
29386         start_full_debug_logging
29387 }
29388
29389 post_801() {
29390         stop_full_debug_logging
29391 }
29392
29393 barrier_stat() {
29394         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29395                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29396                            awk '/The barrier for/ { print $7 }')
29397                 echo $st
29398         else
29399                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29400                 echo \'$st\'
29401         fi
29402 }
29403
29404 barrier_expired() {
29405         local expired
29406
29407         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29408                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29409                           awk '/will be expired/ { print $7 }')
29410         else
29411                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29412         fi
29413
29414         echo $expired
29415 }
29416
29417 test_801a() {
29418         prep_801
29419
29420         echo "Start barrier_freeze at: $(date)"
29421         #define OBD_FAIL_BARRIER_DELAY          0x2202
29422         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29423         # Do not reduce barrier time - See LU-11873
29424         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29425
29426         sleep 2
29427         local b_status=$(barrier_stat)
29428         echo "Got barrier status at: $(date)"
29429         [ "$b_status" = "'freezing_p1'" ] ||
29430                 error "(1) unexpected barrier status $b_status"
29431
29432         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29433         wait
29434         b_status=$(barrier_stat)
29435         [ "$b_status" = "'frozen'" ] ||
29436                 error "(2) unexpected barrier status $b_status"
29437
29438         local expired=$(barrier_expired)
29439         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29440         sleep $((expired + 3))
29441
29442         b_status=$(barrier_stat)
29443         [ "$b_status" = "'expired'" ] ||
29444                 error "(3) unexpected barrier status $b_status"
29445
29446         # Do not reduce barrier time - See LU-11873
29447         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29448                 error "(4) fail to freeze barrier"
29449
29450         b_status=$(barrier_stat)
29451         [ "$b_status" = "'frozen'" ] ||
29452                 error "(5) unexpected barrier status $b_status"
29453
29454         echo "Start barrier_thaw at: $(date)"
29455         #define OBD_FAIL_BARRIER_DELAY          0x2202
29456         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29457         do_facet mgs $LCTL barrier_thaw $FSNAME &
29458
29459         sleep 2
29460         b_status=$(barrier_stat)
29461         echo "Got barrier status at: $(date)"
29462         [ "$b_status" = "'thawing'" ] ||
29463                 error "(6) unexpected barrier status $b_status"
29464
29465         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29466         wait
29467         b_status=$(barrier_stat)
29468         [ "$b_status" = "'thawed'" ] ||
29469                 error "(7) unexpected barrier status $b_status"
29470
29471         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29472         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29473         do_facet mgs $LCTL barrier_freeze $FSNAME
29474
29475         b_status=$(barrier_stat)
29476         [ "$b_status" = "'failed'" ] ||
29477                 error "(8) unexpected barrier status $b_status"
29478
29479         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29480         do_facet mgs $LCTL barrier_thaw $FSNAME
29481
29482         post_801
29483 }
29484 run_test 801a "write barrier user interfaces and stat machine"
29485
29486 test_801b() {
29487         prep_801
29488
29489         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29490         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29491         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29492         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29493         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29494
29495         cancel_lru_locks mdc
29496
29497         # 180 seconds should be long enough
29498         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29499
29500         local b_status=$(barrier_stat)
29501         [ "$b_status" = "'frozen'" ] ||
29502                 error "(6) unexpected barrier status $b_status"
29503
29504         mkdir $DIR/$tdir/d0/d10 &
29505         mkdir_pid=$!
29506
29507         touch $DIR/$tdir/d1/f13 &
29508         touch_pid=$!
29509
29510         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29511         ln_pid=$!
29512
29513         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29514         mv_pid=$!
29515
29516         rm -f $DIR/$tdir/d4/f12 &
29517         rm_pid=$!
29518
29519         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29520
29521         # To guarantee taht the 'stat' is not blocked
29522         b_status=$(barrier_stat)
29523         [ "$b_status" = "'frozen'" ] ||
29524                 error "(8) unexpected barrier status $b_status"
29525
29526         # let above commands to run at background
29527         sleep 5
29528
29529         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29530         ps -p $touch_pid || error "(10) touch should be blocked"
29531         ps -p $ln_pid || error "(11) link should be blocked"
29532         ps -p $mv_pid || error "(12) rename should be blocked"
29533         ps -p $rm_pid || error "(13) unlink should be blocked"
29534
29535         b_status=$(barrier_stat)
29536         [ "$b_status" = "'frozen'" ] ||
29537                 error "(14) unexpected barrier status $b_status"
29538
29539         do_facet mgs $LCTL barrier_thaw $FSNAME
29540         b_status=$(barrier_stat)
29541         [ "$b_status" = "'thawed'" ] ||
29542                 error "(15) unexpected barrier status $b_status"
29543
29544         wait $mkdir_pid || error "(16) mkdir should succeed"
29545         wait $touch_pid || error "(17) touch should succeed"
29546         wait $ln_pid || error "(18) link should succeed"
29547         wait $mv_pid || error "(19) rename should succeed"
29548         wait $rm_pid || error "(20) unlink should succeed"
29549
29550         post_801
29551 }
29552 run_test 801b "modification will be blocked by write barrier"
29553
29554 test_801c() {
29555         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29556
29557         prep_801
29558
29559         stop mds2 || error "(1) Fail to stop mds2"
29560
29561         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29562
29563         local b_status=$(barrier_stat)
29564         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29565                 do_facet mgs $LCTL barrier_thaw $FSNAME
29566                 error "(2) unexpected barrier status $b_status"
29567         }
29568
29569         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29570                 error "(3) Fail to rescan barrier bitmap"
29571
29572         # Do not reduce barrier time - See LU-11873
29573         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29574
29575         b_status=$(barrier_stat)
29576         [ "$b_status" = "'frozen'" ] ||
29577                 error "(4) unexpected barrier status $b_status"
29578
29579         do_facet mgs $LCTL barrier_thaw $FSNAME
29580         b_status=$(barrier_stat)
29581         [ "$b_status" = "'thawed'" ] ||
29582                 error "(5) unexpected barrier status $b_status"
29583
29584         local devname=$(mdsdevname 2)
29585
29586         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29587
29588         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29589                 error "(7) Fail to rescan barrier bitmap"
29590
29591         post_801
29592 }
29593 run_test 801c "rescan barrier bitmap"
29594
29595 test_802b() {
29596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29597         remote_mds_nodsh && skip "remote MDS with nodsh"
29598
29599         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29600                 skip "readonly option not available"
29601
29602         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29603
29604         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29605                 error "(2) Fail to copy"
29606
29607         # write back all cached data before setting MDT to readonly
29608         cancel_lru_locks
29609         sync_all_data
29610
29611         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29612         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29613
29614         echo "Modify should be refused"
29615         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29616
29617         echo "Read should be allowed"
29618         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29619                 error "(7) Read should succeed under ro mode"
29620
29621         # disable readonly
29622         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29623 }
29624 run_test 802b "be able to set MDTs to readonly"
29625
29626 test_803a() {
29627         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29628         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29629                 skip "MDS needs to be newer than 2.10.54"
29630
29631         mkdir_on_mdt0 $DIR/$tdir
29632         # Create some objects on all MDTs to trigger related logs objects
29633         for idx in $(seq $MDSCOUNT); do
29634                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29635                         $DIR/$tdir/dir${idx} ||
29636                         error "Fail to create $DIR/$tdir/dir${idx}"
29637         done
29638
29639         wait_delete_completed # ensure old test cleanups are finished
29640         sleep 3
29641         echo "before create:"
29642         $LFS df -i $MOUNT
29643         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29644
29645         for i in {1..10}; do
29646                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29647                         error "Fail to create $DIR/$tdir/foo$i"
29648         done
29649
29650         # sync ZFS-on-MDS to refresh statfs data
29651         wait_zfs_commit mds1
29652         sleep 3
29653         echo "after create:"
29654         $LFS df -i $MOUNT
29655         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29656
29657         # allow for an llog to be cleaned up during the test
29658         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29659                 error "before ($before_used) + 10 > after ($after_used)"
29660
29661         for i in {1..10}; do
29662                 rm -rf $DIR/$tdir/foo$i ||
29663                         error "Fail to remove $DIR/$tdir/foo$i"
29664         done
29665
29666         # sync ZFS-on-MDS to refresh statfs data
29667         wait_zfs_commit mds1
29668         wait_delete_completed
29669         sleep 3 # avoid MDT return cached statfs
29670         echo "after unlink:"
29671         $LFS df -i $MOUNT
29672         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29673
29674         # allow for an llog to be created during the test
29675         [ $after_used -le $((before_used + 1)) ] ||
29676                 error "after ($after_used) > before ($before_used) + 1"
29677 }
29678 run_test 803a "verify agent object for remote object"
29679
29680 test_803b() {
29681         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29682         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29683                 skip "MDS needs to be newer than 2.13.56"
29684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29685
29686         for i in $(seq 0 $((MDSCOUNT - 1))); do
29687                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29688         done
29689
29690         local before=0
29691         local after=0
29692
29693         local tmp
29694
29695         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29696         for i in $(seq 0 $((MDSCOUNT - 1))); do
29697                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29698                         awk '/getattr/ { print $2 }')
29699                 before=$((before + tmp))
29700         done
29701         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29702         for i in $(seq 0 $((MDSCOUNT - 1))); do
29703                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29704                         awk '/getattr/ { print $2 }')
29705                 after=$((after + tmp))
29706         done
29707
29708         [ $before -eq $after ] || error "getattr count $before != $after"
29709 }
29710 run_test 803b "remote object can getattr from cache"
29711
29712 test_804() {
29713         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29714         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29715                 skip "MDS needs to be newer than 2.10.54"
29716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29717
29718         mkdir -p $DIR/$tdir
29719         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29720                 error "Fail to create $DIR/$tdir/dir0"
29721
29722         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29723         local dev=$(mdsdevname 2)
29724
29725         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29726                 grep ${fid} || error "NOT found agent entry for dir0"
29727
29728         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29729                 error "Fail to create $DIR/$tdir/dir1"
29730
29731         touch $DIR/$tdir/dir1/foo0 ||
29732                 error "Fail to create $DIR/$tdir/dir1/foo0"
29733         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29734         local rc=0
29735
29736         for idx in $(seq $MDSCOUNT); do
29737                 dev=$(mdsdevname $idx)
29738                 do_facet mds${idx} \
29739                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29740                         grep ${fid} && rc=$idx
29741         done
29742
29743         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29744                 error "Fail to rename foo0 to foo1"
29745         if [ $rc -eq 0 ]; then
29746                 for idx in $(seq $MDSCOUNT); do
29747                         dev=$(mdsdevname $idx)
29748                         do_facet mds${idx} \
29749                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29750                         grep ${fid} && rc=$idx
29751                 done
29752         fi
29753
29754         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29755                 error "Fail to rename foo1 to foo2"
29756         if [ $rc -eq 0 ]; then
29757                 for idx in $(seq $MDSCOUNT); do
29758                         dev=$(mdsdevname $idx)
29759                         do_facet mds${idx} \
29760                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29761                         grep ${fid} && rc=$idx
29762                 done
29763         fi
29764
29765         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29766
29767         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29768                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29769         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29770                 error "Fail to rename foo2 to foo0"
29771         unlink $DIR/$tdir/dir1/foo0 ||
29772                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29773         rm -rf $DIR/$tdir/dir0 ||
29774                 error "Fail to rm $DIR/$tdir/dir0"
29775
29776         for idx in $(seq $MDSCOUNT); do
29777                 rc=0
29778
29779                 stop mds${idx}
29780                 dev=$(mdsdevname $idx)
29781                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29782                         rc=$?
29783                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29784                         error "mount mds$idx failed"
29785                 df $MOUNT > /dev/null 2>&1
29786
29787                 # e2fsck should not return error
29788                 [ $rc -eq 0 ] ||
29789                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29790         done
29791 }
29792 run_test 804 "verify agent entry for remote entry"
29793
29794 cleanup_805() {
29795         do_facet $SINGLEMDS zfs set quota=$old $fsset
29796         unlinkmany $DIR/$tdir/f- 1000000
29797         trap 0
29798 }
29799
29800 test_805() {
29801         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29802         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29803         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29804                 skip "netfree not implemented before 0.7"
29805         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29806                 skip "Need MDS version at least 2.10.57"
29807
29808         local fsset
29809         local freekb
29810         local usedkb
29811         local old
29812         local quota
29813         local pref="osd-zfs.$FSNAME-MDT0000."
29814
29815         # limit available space on MDS dataset to meet nospace issue
29816         # quickly. then ZFS 0.7.2 can use reserved space if asked
29817         # properly (using netfree flag in osd_declare_destroy()
29818         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29819         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29820                 gawk '{print $3}')
29821         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29822         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29823         let "usedkb=usedkb-freekb"
29824         let "freekb=freekb/2"
29825         if let "freekb > 5000"; then
29826                 let "freekb=5000"
29827         fi
29828         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29829         trap cleanup_805 EXIT
29830         mkdir_on_mdt0 $DIR/$tdir
29831         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29832                 error "Can't set PFL layout"
29833         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29834         rm -rf $DIR/$tdir || error "not able to remove"
29835         do_facet $SINGLEMDS zfs set quota=$old $fsset
29836         trap 0
29837 }
29838 run_test 805 "ZFS can remove from full fs"
29839
29840 # Size-on-MDS test
29841 check_lsom_data()
29842 {
29843         local file=$1
29844         local expect=$(stat -c %s $file)
29845
29846         check_lsom_size $1 $expect
29847
29848         local blocks=$($LFS getsom -b $file)
29849         expect=$(stat -c %b $file)
29850         [[ $blocks == $expect ]] ||
29851                 error "$file expected blocks: $expect, got: $blocks"
29852 }
29853
29854 check_lsom_size()
29855 {
29856         local size
29857         local expect=$2
29858
29859         cancel_lru_locks mdc
29860
29861         size=$($LFS getsom -s $1)
29862         [[ $size == $expect ]] ||
29863                 error "$file expected size: $expect, got: $size"
29864 }
29865
29866 test_806() {
29867         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29868                 skip "Need MDS version at least 2.11.52"
29869
29870         local bs=1048576
29871
29872         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29873
29874         disable_opencache
29875         stack_trap "restore_opencache"
29876
29877         # single-threaded write
29878         echo "Test SOM for single-threaded write"
29879         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29880                 error "write $tfile failed"
29881         check_lsom_size $DIR/$tfile $bs
29882
29883         local num=32
29884         local size=$(($num * $bs))
29885         local offset=0
29886         local i
29887
29888         echo "Test SOM for single client multi-threaded($num) write"
29889         $TRUNCATE $DIR/$tfile 0
29890         for ((i = 0; i < $num; i++)); do
29891                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29892                 local pids[$i]=$!
29893                 offset=$((offset + $bs))
29894         done
29895         for (( i=0; i < $num; i++ )); do
29896                 wait ${pids[$i]}
29897         done
29898         check_lsom_size $DIR/$tfile $size
29899
29900         $TRUNCATE $DIR/$tfile 0
29901         for ((i = 0; i < $num; i++)); do
29902                 offset=$((offset - $bs))
29903                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29904                 local pids[$i]=$!
29905         done
29906         for (( i=0; i < $num; i++ )); do
29907                 wait ${pids[$i]}
29908         done
29909         check_lsom_size $DIR/$tfile $size
29910
29911         # multi-client writes
29912         num=$(get_node_count ${CLIENTS//,/ })
29913         size=$(($num * $bs))
29914         offset=0
29915         i=0
29916
29917         echo "Test SOM for multi-client ($num) writes"
29918         $TRUNCATE $DIR/$tfile 0
29919         for client in ${CLIENTS//,/ }; do
29920                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29921                 local pids[$i]=$!
29922                 i=$((i + 1))
29923                 offset=$((offset + $bs))
29924         done
29925         for (( i=0; i < $num; i++ )); do
29926                 wait ${pids[$i]}
29927         done
29928         check_lsom_size $DIR/$tfile $offset
29929
29930         i=0
29931         $TRUNCATE $DIR/$tfile 0
29932         for client in ${CLIENTS//,/ }; do
29933                 offset=$((offset - $bs))
29934                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29935                 local pids[$i]=$!
29936                 i=$((i + 1))
29937         done
29938         for (( i=0; i < $num; i++ )); do
29939                 wait ${pids[$i]}
29940         done
29941         check_lsom_size $DIR/$tfile $size
29942
29943         # verify SOM blocks count
29944         echo "Verify SOM block count"
29945         $TRUNCATE $DIR/$tfile 0
29946         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29947                 error "failed to write file $tfile with fdatasync and fstat"
29948         check_lsom_data $DIR/$tfile
29949
29950         $TRUNCATE $DIR/$tfile 0
29951         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29952                 error "failed to write file $tfile with fdatasync"
29953         check_lsom_data $DIR/$tfile
29954
29955         $TRUNCATE $DIR/$tfile 0
29956         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29957                 error "failed to write file $tfile with sync IO"
29958         check_lsom_data $DIR/$tfile
29959
29960         # verify truncate
29961         echo "Test SOM for truncate"
29962         # use ftruncate to sync blocks on close request
29963         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29964         check_lsom_size $DIR/$tfile 16384
29965         check_lsom_data $DIR/$tfile
29966
29967         $TRUNCATE $DIR/$tfile 1234
29968         check_lsom_size $DIR/$tfile 1234
29969         # sync blocks on the MDT
29970         $MULTIOP $DIR/$tfile oc
29971         check_lsom_data $DIR/$tfile
29972 }
29973 run_test 806 "Verify Lazy Size on MDS"
29974
29975 test_807() {
29976         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29977         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29978                 skip "Need MDS version at least 2.11.52"
29979
29980         # Registration step
29981         changelog_register || error "changelog_register failed"
29982         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29983         changelog_users $SINGLEMDS | grep -q $cl_user ||
29984                 error "User $cl_user not found in changelog_users"
29985
29986         rm -rf $DIR/$tdir || error "rm $tdir failed"
29987         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29988         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29989         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29990         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29991                 error "truncate $tdir/trunc failed"
29992
29993         local bs=1048576
29994         echo "Test SOM for single-threaded write with fsync"
29995         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29996                 error "write $tfile failed"
29997         sync;sync;sync
29998
29999         # multi-client wirtes
30000         local num=$(get_node_count ${CLIENTS//,/ })
30001         local offset=0
30002         local i=0
30003
30004         echo "Test SOM for multi-client ($num) writes"
30005         touch $DIR/$tfile || error "touch $tfile failed"
30006         $TRUNCATE $DIR/$tfile 0
30007         for client in ${CLIENTS//,/ }; do
30008                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30009                 local pids[$i]=$!
30010                 i=$((i + 1))
30011                 offset=$((offset + $bs))
30012         done
30013         for (( i=0; i < $num; i++ )); do
30014                 wait ${pids[$i]}
30015         done
30016
30017         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30018         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30019         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30020         check_lsom_data $DIR/$tdir/trunc
30021         check_lsom_data $DIR/$tdir/single_dd
30022         check_lsom_data $DIR/$tfile
30023
30024         rm -rf $DIR/$tdir
30025         # Deregistration step
30026         changelog_deregister || error "changelog_deregister failed"
30027 }
30028 run_test 807 "verify LSOM syncing tool"
30029
30030 check_som_nologged()
30031 {
30032         local lines=$($LFS changelog $FSNAME-MDT0000 |
30033                 grep 'x=trusted.som' | wc -l)
30034         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30035 }
30036
30037 test_808() {
30038         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30039                 skip "Need MDS version at least 2.11.55"
30040
30041         # Registration step
30042         changelog_register || error "changelog_register failed"
30043
30044         touch $DIR/$tfile || error "touch $tfile failed"
30045         check_som_nologged
30046
30047         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30048                 error "write $tfile failed"
30049         check_som_nologged
30050
30051         $TRUNCATE $DIR/$tfile 1234
30052         check_som_nologged
30053
30054         $TRUNCATE $DIR/$tfile 1048576
30055         check_som_nologged
30056
30057         # Deregistration step
30058         changelog_deregister || error "changelog_deregister failed"
30059 }
30060 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30061
30062 check_som_nodata()
30063 {
30064         $LFS getsom $1
30065         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30066 }
30067
30068 test_809() {
30069         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30070                 skip "Need MDS version at least 2.11.56"
30071
30072         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30073                 error "failed to create DoM-only file $DIR/$tfile"
30074         touch $DIR/$tfile || error "touch $tfile failed"
30075         check_som_nodata $DIR/$tfile
30076
30077         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30078                 error "write $tfile failed"
30079         check_som_nodata $DIR/$tfile
30080
30081         $TRUNCATE $DIR/$tfile 1234
30082         check_som_nodata $DIR/$tfile
30083
30084         $TRUNCATE $DIR/$tfile 4097
30085         check_som_nodata $DIR/$file
30086 }
30087 run_test 809 "Verify no SOM xattr store for DoM-only files"
30088
30089 test_810() {
30090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30091         $GSS && skip_env "could not run with gss"
30092         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30093                 skip "OST < 2.12.58 doesn't align checksum"
30094
30095         set_checksums 1
30096         stack_trap "set_checksums $ORIG_CSUM" EXIT
30097         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30098
30099         local csum
30100         local before
30101         local after
30102         for csum in $CKSUM_TYPES; do
30103                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30104                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30105                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30106                         eval set -- $i
30107                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30108                         before=$(md5sum $DIR/$tfile)
30109                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30110                         after=$(md5sum $DIR/$tfile)
30111                         [ "$before" == "$after" ] ||
30112                                 error "$csum: $before != $after bs=$1 seek=$2"
30113                 done
30114         done
30115 }
30116 run_test 810 "partial page writes on ZFS (LU-11663)"
30117
30118 test_812a() {
30119         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30120                 skip "OST < 2.12.51 doesn't support this fail_loc"
30121
30122         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30123         # ensure ost1 is connected
30124         stat $DIR/$tfile >/dev/null || error "can't stat"
30125         wait_osc_import_state client ost1 FULL
30126         # no locks, no reqs to let the connection idle
30127         cancel_lru_locks osc
30128
30129         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30130 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30131         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30132         wait_osc_import_state client ost1 CONNECTING
30133         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30134
30135         stat $DIR/$tfile >/dev/null || error "can't stat file"
30136 }
30137 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30138
30139 test_812b() { # LU-12378
30140         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30141                 skip "OST < 2.12.51 doesn't support this fail_loc"
30142
30143         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30144         # ensure ost1 is connected
30145         stat $DIR/$tfile >/dev/null || error "can't stat"
30146         wait_osc_import_state client ost1 FULL
30147         # no locks, no reqs to let the connection idle
30148         cancel_lru_locks osc
30149
30150         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30151 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30152         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30153         wait_osc_import_state client ost1 CONNECTING
30154         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30155
30156         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30157         wait_osc_import_state client ost1 IDLE
30158 }
30159 run_test 812b "do not drop no resend request for idle connect"
30160
30161 test_812c() {
30162         local old
30163
30164         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30165
30166         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30167         $LFS getstripe $DIR/$tfile
30168         $LCTL set_param osc.*.idle_timeout=10
30169         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30170         # ensure ost1 is connected
30171         stat $DIR/$tfile >/dev/null || error "can't stat"
30172         wait_osc_import_state client ost1 FULL
30173         # no locks, no reqs to let the connection idle
30174         cancel_lru_locks osc
30175
30176 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30177         $LCTL set_param fail_loc=0x80000533
30178         sleep 15
30179         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30180 }
30181 run_test 812c "idle import vs lock enqueue race"
30182
30183 test_813() {
30184         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30185         [ -z "$file_heat_sav" ] && skip "no file heat support"
30186
30187         local readsample
30188         local writesample
30189         local readbyte
30190         local writebyte
30191         local readsample1
30192         local writesample1
30193         local readbyte1
30194         local writebyte1
30195
30196         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30197         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30198
30199         $LCTL set_param -n llite.*.file_heat=1
30200         echo "Turn on file heat"
30201         echo "Period second: $period_second, Decay percentage: $decay_pct"
30202
30203         echo "QQQQ" > $DIR/$tfile
30204         echo "QQQQ" > $DIR/$tfile
30205         echo "QQQQ" > $DIR/$tfile
30206         cat $DIR/$tfile > /dev/null
30207         cat $DIR/$tfile > /dev/null
30208         cat $DIR/$tfile > /dev/null
30209         cat $DIR/$tfile > /dev/null
30210
30211         local out=$($LFS heat_get $DIR/$tfile)
30212
30213         $LFS heat_get $DIR/$tfile
30214         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30215         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30216         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30217         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30218
30219         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30220         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30221         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30222         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30223
30224         sleep $((period_second + 3))
30225         echo "Sleep $((period_second + 3)) seconds..."
30226         # The recursion formula to calculate the heat of the file f is as
30227         # follow:
30228         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30229         # Where Hi is the heat value in the period between time points i*I and
30230         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30231         # to the weight of Ci.
30232         out=$($LFS heat_get $DIR/$tfile)
30233         $LFS heat_get $DIR/$tfile
30234         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30235         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30236         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30237         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30238
30239         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30240                 error "read sample ($readsample) is wrong"
30241         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30242                 error "write sample ($writesample) is wrong"
30243         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30244                 error "read bytes ($readbyte) is wrong"
30245         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30246                 error "write bytes ($writebyte) is wrong"
30247
30248         echo "QQQQ" > $DIR/$tfile
30249         echo "QQQQ" > $DIR/$tfile
30250         echo "QQQQ" > $DIR/$tfile
30251         cat $DIR/$tfile > /dev/null
30252         cat $DIR/$tfile > /dev/null
30253         cat $DIR/$tfile > /dev/null
30254         cat $DIR/$tfile > /dev/null
30255
30256         sleep $((period_second + 3))
30257         echo "Sleep $((period_second + 3)) seconds..."
30258
30259         out=$($LFS heat_get $DIR/$tfile)
30260         $LFS heat_get $DIR/$tfile
30261         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30262         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30263         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30264         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30265
30266         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30267                 4 * $decay_pct) / 100") -eq 1 ] ||
30268                 error "read sample ($readsample1) is wrong"
30269         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30270                 3 * $decay_pct) / 100") -eq 1 ] ||
30271                 error "write sample ($writesample1) is wrong"
30272         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30273                 20 * $decay_pct) / 100") -eq 1 ] ||
30274                 error "read bytes ($readbyte1) is wrong"
30275         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30276                 15 * $decay_pct) / 100") -eq 1 ] ||
30277                 error "write bytes ($writebyte1) is wrong"
30278
30279         echo "Turn off file heat for the file $DIR/$tfile"
30280         $LFS heat_set -o $DIR/$tfile
30281
30282         echo "QQQQ" > $DIR/$tfile
30283         echo "QQQQ" > $DIR/$tfile
30284         echo "QQQQ" > $DIR/$tfile
30285         cat $DIR/$tfile > /dev/null
30286         cat $DIR/$tfile > /dev/null
30287         cat $DIR/$tfile > /dev/null
30288         cat $DIR/$tfile > /dev/null
30289
30290         out=$($LFS heat_get $DIR/$tfile)
30291         $LFS heat_get $DIR/$tfile
30292         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30293         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30294         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30295         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30296
30297         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30298         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30299         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30300         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30301
30302         echo "Trun on file heat for the file $DIR/$tfile"
30303         $LFS heat_set -O $DIR/$tfile
30304
30305         echo "QQQQ" > $DIR/$tfile
30306         echo "QQQQ" > $DIR/$tfile
30307         echo "QQQQ" > $DIR/$tfile
30308         cat $DIR/$tfile > /dev/null
30309         cat $DIR/$tfile > /dev/null
30310         cat $DIR/$tfile > /dev/null
30311         cat $DIR/$tfile > /dev/null
30312
30313         out=$($LFS heat_get $DIR/$tfile)
30314         $LFS heat_get $DIR/$tfile
30315         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30316         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30317         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30318         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30319
30320         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30321         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30322         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30323         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30324
30325         $LFS heat_set -c $DIR/$tfile
30326         $LCTL set_param -n llite.*.file_heat=0
30327         echo "Turn off file heat support for the Lustre filesystem"
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 -eq 0 ] || error "read sample ($readsample) is wrong"
30345         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30346         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30347         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30348
30349         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30350         rm -f $DIR/$tfile
30351 }
30352 run_test 813 "File heat verfication"
30353
30354 test_814()
30355 {
30356         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30357         echo -n y >> $DIR/$tfile
30358         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30359         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30360 }
30361 run_test 814 "sparse cp works as expected (LU-12361)"
30362
30363 test_815()
30364 {
30365         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30366         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30367 }
30368 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30369
30370 test_816() {
30371         local ost1_imp=$(get_osc_import_name client ost1)
30372         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30373                          cut -d'.' -f2)
30374
30375         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30376         # ensure ost1 is connected
30377
30378         stat $DIR/$tfile >/dev/null || error "can't stat"
30379         wait_osc_import_state client ost1 FULL
30380         # no locks, no reqs to let the connection idle
30381         cancel_lru_locks osc
30382         lru_resize_disable osc
30383         local before
30384         local now
30385         before=$($LCTL get_param -n \
30386                  ldlm.namespaces.$imp_name.lru_size)
30387
30388         wait_osc_import_state client ost1 IDLE
30389         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30390         now=$($LCTL get_param -n \
30391               ldlm.namespaces.$imp_name.lru_size)
30392         [ $before == $now ] || error "lru_size changed $before != $now"
30393 }
30394 run_test 816 "do not reset lru_resize on idle reconnect"
30395
30396 cleanup_817() {
30397         umount $tmpdir
30398         exportfs -u localhost:$DIR/nfsexp
30399         rm -rf $DIR/nfsexp
30400 }
30401
30402 test_817() {
30403         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30404
30405         mkdir -p $DIR/nfsexp
30406         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30407                 error "failed to export nfs"
30408
30409         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30410         stack_trap cleanup_817 EXIT
30411
30412         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30413                 error "failed to mount nfs to $tmpdir"
30414
30415         cp /bin/true $tmpdir
30416         $DIR/nfsexp/true || error "failed to execute 'true' command"
30417 }
30418 run_test 817 "nfsd won't cache write lock for exec file"
30419
30420 test_818() {
30421         test_mkdir -i0 -c1 $DIR/$tdir
30422         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30423         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30424         stop $SINGLEMDS
30425
30426         # restore osp-syn threads
30427         stack_trap "fail $SINGLEMDS"
30428
30429         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30430         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30431         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30432                 error "start $SINGLEMDS failed"
30433         rm -rf $DIR/$tdir
30434
30435         local testid=$(echo $TESTNAME | tr '_' ' ')
30436
30437         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30438                 grep "run LFSCK" || error "run LFSCK is not suggested"
30439 }
30440 run_test 818 "unlink with failed llog"
30441
30442 test_819a() {
30443         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30444         cancel_lru_locks osc
30445         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30446         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30447         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30448         rm -f $TDIR/$tfile
30449 }
30450 run_test 819a "too big niobuf in read"
30451
30452 test_819b() {
30453         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30454         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30456         cancel_lru_locks osc
30457         sleep 1
30458         rm -f $TDIR/$tfile
30459 }
30460 run_test 819b "too big niobuf in write"
30461
30462
30463 function test_820_start_ost() {
30464         sleep 5
30465
30466         for num in $(seq $OSTCOUNT); do
30467                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30468         done
30469 }
30470
30471 test_820() {
30472         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30473
30474         mkdir $DIR/$tdir
30475         umount_client $MOUNT || error "umount failed"
30476         for num in $(seq $OSTCOUNT); do
30477                 stop ost$num
30478         done
30479
30480         # mount client with no active OSTs
30481         # so that the client can't initialize max LOV EA size
30482         # from OSC notifications
30483         mount_client $MOUNT || error "mount failed"
30484         # delay OST starting to keep this 0 max EA size for a while
30485         test_820_start_ost &
30486
30487         # create a directory on MDS2
30488         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30489                 error "Failed to create directory"
30490         # open intent should update default EA size
30491         # see mdc_update_max_ea_from_body()
30492         # notice this is the very first RPC to MDS2
30493         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30494         ret=$?
30495         echo $out
30496         # With SSK, this situation can lead to -EPERM being returned.
30497         # In that case, simply retry.
30498         if [ $ret -ne 0 ] && $SHARED_KEY; then
30499                 if echo "$out" | grep -q "not permitted"; then
30500                         cp /etc/services $DIR/$tdir/mds2
30501                         ret=$?
30502                 fi
30503         fi
30504         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30505 }
30506 run_test 820 "update max EA from open intent"
30507
30508 test_823() {
30509         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30510         local OST_MAX_PRECREATE=20000
30511
30512         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30513                 skip "Need MDS version at least 2.14.56"
30514
30515         save_lustre_params mds1 \
30516                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30517         do_facet $SINGLEMDS "$LCTL set_param -n \
30518                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30519         do_facet $SINGLEMDS "$LCTL set_param -n \
30520                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30521
30522         stack_trap "restore_lustre_params < $p; rm $p"
30523
30524         do_facet $SINGLEMDS "$LCTL set_param -n \
30525                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30526
30527         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30528                       osp.$FSNAME-OST0000*MDT0000.create_count")
30529         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30530                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30531         local expect_count=$(((($max/2)/256) * 256))
30532
30533         log "setting create_count to 100200:"
30534         log " -result- count: $count with max: $max, expecting: $expect_count"
30535
30536         [[ $count -eq expect_count ]] ||
30537                 error "Create count not set to max precreate."
30538 }
30539 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30540
30541 test_831() {
30542         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30543                 skip "Need MDS version 2.14.56"
30544
30545         local sync_changes=$(do_facet $SINGLEMDS \
30546                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30547
30548         [ "$sync_changes" -gt 100 ] &&
30549                 skip "Sync changes $sync_changes > 100 already"
30550
30551         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30552
30553         $LFS mkdir -i 0 $DIR/$tdir
30554         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30555
30556         save_lustre_params mds1 \
30557                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30558         save_lustre_params mds1 \
30559                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30560
30561         do_facet mds1 "$LCTL set_param -n \
30562                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30563                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30564         stack_trap "restore_lustre_params < $p" EXIT
30565
30566         createmany -o $DIR/$tdir/f- 1000
30567         unlinkmany $DIR/$tdir/f- 1000 &
30568         local UNLINK_PID=$!
30569
30570         while sleep 1; do
30571                 sync_changes=$(do_facet mds1 \
30572                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30573                 # the check in the code is racy, fail the test
30574                 # if the value above the limit by 10.
30575                 [ $sync_changes -gt 110 ] && {
30576                         kill -2 $UNLINK_PID
30577                         wait
30578                         error "osp changes throttling failed, $sync_changes>110"
30579                 }
30580                 kill -0 $UNLINK_PID 2> /dev/null || break
30581         done
30582         wait
30583 }
30584 run_test 831 "throttling unlink/setattr queuing on OSP"
30585
30586 test_832() {
30587         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30588         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30589                 skip "Need MDS version 2.15.52+"
30590         is_rmentry_supported || skip "rm_entry not supported"
30591
30592         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30593         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30594         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30595                 error "mkdir remote_dir failed"
30596         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30597                 error "mkdir striped_dir failed"
30598         touch $DIR/$tdir/file || error "touch file failed"
30599         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30600         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30601 }
30602 run_test 832 "lfs rm_entry"
30603
30604 test_833() {
30605         local file=$DIR/$tfile
30606
30607         stack_trap "rm -f $file" EXIT
30608         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30609
30610         local wpid
30611         local rpid
30612         local rpid2
30613
30614         # Buffered I/O write
30615         (
30616                 while [ ! -e $DIR/sanity.833.lck ]; do
30617                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30618                                 error "failed to write $file"
30619                         sleep 0.$((RANDOM % 4 + 1))
30620                 done
30621         )&
30622         wpid=$!
30623
30624         # Buffered I/O read
30625         (
30626                 while [ ! -e $DIR/sanity.833.lck ]; do
30627                         dd if=$file of=/dev/null bs=1M count=50 ||
30628                                 error "failed to read $file"
30629                         sleep 0.$((RANDOM % 4 + 1))
30630                 done
30631         )&
30632         rpid=$!
30633
30634         # Direct I/O read
30635         (
30636                 while [ ! -e $DIR/sanity.833.lck ]; do
30637                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30638                                 error "failed to read $file in direct I/O mode"
30639                         sleep 0.$((RANDOM % 4 + 1))
30640                 done
30641         )&
30642         rpid2=$!
30643
30644         sleep 30
30645         touch $DIR/sanity.833.lck
30646         wait $wpid || error "$?: buffered write failed"
30647         wait $rpid || error "$?: buffered read failed"
30648         wait $rpid2 || error "$?: direct read failed"
30649 }
30650 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30651
30652 #
30653 # tests that do cleanup/setup should be run at the end
30654 #
30655
30656 test_900() {
30657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30658         local ls
30659
30660         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30661         $LCTL set_param fail_loc=0x903
30662
30663         cancel_lru_locks MGC
30664
30665         FAIL_ON_ERROR=true cleanup
30666         FAIL_ON_ERROR=true setup
30667 }
30668 run_test 900 "umount should not race with any mgc requeue thread"
30669
30670 # LUS-6253/LU-11185
30671 test_901() {
30672         local old
30673         local count
30674         local oldc
30675         local newc
30676         local olds
30677         local news
30678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30679
30680         # some get_param have a bug to handle dot in param name
30681         cancel_lru_locks MGC
30682         old=$(mount -t lustre | wc -l)
30683         # 1 config+sptlrpc
30684         # 2 params
30685         # 3 nodemap
30686         # 4 IR
30687         old=$((old * 4))
30688         oldc=0
30689         count=0
30690         while [ $old -ne $oldc ]; do
30691                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30692                 sleep 1
30693                 ((count++))
30694                 if [ $count -ge $TIMEOUT ]; then
30695                         error "too large timeout"
30696                 fi
30697         done
30698         umount_client $MOUNT || error "umount failed"
30699         mount_client $MOUNT || error "mount failed"
30700         cancel_lru_locks MGC
30701         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30702
30703         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30704
30705         return 0
30706 }
30707 run_test 901 "don't leak a mgc lock on client umount"
30708
30709 # LU-13377
30710 test_902() {
30711         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30712                 skip "client does not have LU-13377 fix"
30713         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30714         $LCTL set_param fail_loc=0x1415
30715         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30716         cancel_lru_locks osc
30717         rm -f $DIR/$tfile
30718 }
30719 run_test 902 "test short write doesn't hang lustre"
30720
30721 # LU-14711
30722 test_903() {
30723         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30724         echo "blah" > $DIR/${tfile}-2
30725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30726         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30727         $LCTL set_param fail_loc=0x417 fail_val=20
30728
30729         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30730         sleep 1 # To start the destroy
30731         wait_destroy_complete 150 || error "Destroy taking too long"
30732         cat $DIR/$tfile > /dev/null || error "Evicted"
30733 }
30734 run_test 903 "Test long page discard does not cause evictions"
30735
30736 test_904() {
30737         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30738         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30739                 grep -q project || skip "skip project quota not supported"
30740
30741         local testfile="$DIR/$tdir/$tfile"
30742         local xattr="trusted.projid"
30743         local projid
30744         local mdts=$(comma_list $(mdts_nodes))
30745         local saved=$(do_facet mds1 $LCTL get_param -n \
30746                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30747
30748         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30749         stack_trap "do_nodes $mdts $LCTL set_param \
30750                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30751
30752         mkdir -p $DIR/$tdir
30753         touch $testfile
30754         #hide projid xattr on server
30755         $LFS project -p 1 $testfile ||
30756                 error "set $testfile project id failed"
30757         getfattr -m - $testfile | grep $xattr &&
30758                 error "do not show trusted.projid when disabled on server"
30759         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30760         #should be hidden when projid is 0
30761         $LFS project -p 0 $testfile ||
30762                 error "set $testfile project id failed"
30763         getfattr -m - $testfile | grep $xattr &&
30764                 error "do not show trusted.projid with project ID 0"
30765
30766         #still can getxattr explicitly
30767         projid=$(getfattr -n $xattr $testfile |
30768                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30769         [ $projid == "0" ] ||
30770                 error "projid expected 0 not $projid"
30771
30772         #set the projid via setxattr
30773         setfattr -n $xattr -v "1000" $testfile ||
30774                 error "setattr failed with $?"
30775         projid=($($LFS project $testfile))
30776         [ ${projid[0]} == "1000" ] ||
30777                 error "projid expected 1000 not $projid"
30778
30779         #check the new projid via getxattr
30780         $LFS project -p 1001 $testfile ||
30781                 error "set $testfile project id failed"
30782         getfattr -m - $testfile | grep $xattr ||
30783                 error "should show trusted.projid when project ID != 0"
30784         projid=$(getfattr -n $xattr $testfile |
30785                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30786         [ $projid == "1001" ] ||
30787                 error "projid expected 1001 not $projid"
30788
30789         #try to set invalid projid
30790         setfattr -n $xattr -v "4294967295" $testfile &&
30791                 error "set invalid projid should fail"
30792
30793         #remove the xattr means setting projid to 0
30794         setfattr -x $xattr $testfile ||
30795                 error "setfattr failed with $?"
30796         projid=($($LFS project $testfile))
30797         [ ${projid[0]} == "0" ] ||
30798                 error "projid expected 0 not $projid"
30799
30800         #should be hidden when parent has inherit flag and same projid
30801         $LFS project -srp 1002 $DIR/$tdir ||
30802                 error "set $tdir project id failed"
30803         getfattr -m - $testfile | grep $xattr &&
30804                 error "do not show trusted.projid with inherit flag"
30805
30806         #still can getxattr explicitly
30807         projid=$(getfattr -n $xattr $testfile |
30808                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30809         [ $projid == "1002" ] ||
30810                 error "projid expected 1002 not $projid"
30811 }
30812 run_test 904 "virtual project ID xattr"
30813
30814 # LU-8582
30815 test_905() {
30816         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30817                 skip "need OST version >= 2.15.50.220 for fail_loc"
30818
30819         remote_ost_nodsh && skip "remote OST with nodsh"
30820         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30821
30822         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30823
30824         #define OBD_FAIL_OST_OPCODE 0x253
30825         # OST_LADVISE = 21
30826         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30827         $LFS ladvise -a willread $DIR/$tfile &&
30828                 error "unexpected success of ladvise with fault injection"
30829         $LFS ladvise -a willread $DIR/$tfile |&
30830                 grep -q "Operation not supported"
30831         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30832 }
30833 run_test 905 "bad or new opcode should not stuck client"
30834
30835 test_906() {
30836         grep -q io_uring_setup /proc/kallsyms ||
30837                 skip "Client OS does not support io_uring I/O engine"
30838         io_uring_probe || skip "kernel does not support io_uring fully"
30839         which fio || skip_env "no fio installed"
30840         fio --enghelp | grep -q io_uring ||
30841                 skip_env "fio does not support io_uring I/O engine"
30842
30843         local file=$DIR/$tfile
30844         local ioengine="io_uring"
30845         local numjobs=2
30846         local size=50M
30847
30848         fio --name=seqwrite --ioengine=$ioengine        \
30849                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30850                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30851                 error "fio seqwrite $file failed"
30852
30853         fio --name=seqread --ioengine=$ioengine \
30854                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30855                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30856                 error "fio seqread $file failed"
30857
30858         rm -f $file || error "rm -f $file failed"
30859 }
30860 run_test 906 "Simple test for io_uring I/O engine via fio"
30861
30862 test_907() {
30863         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
30864
30865         # set stripe size to max rpc size
30866         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
30867         $LFS getstripe $DIR/$tfile
30868 #define OBD_FAIL_OST_EROFS               0x216
30869         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
30870
30871         local bs=$((max_pages * PAGE_SIZE / 16))
30872
30873         # write full one stripe and one block
30874         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
30875
30876         rm $DIR/$tfile || error "rm failed"
30877 }
30878 run_test 907 "write rpc error during unlink"
30879
30880 complete_test $SECONDS
30881 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30882 check_and_cleanup_lustre
30883 if [ "$I_MOUNTED" != "yes" ]; then
30884         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30885 fi
30886 exit_status