Whamcloud - gitweb
LU-17151 tests: increase sanity/411b memory limit
[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 411a
62 fi
63
64 # skip cgroup tests for kernels < v4.18.0
65 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
66         always_except LU-13063 411b
67 fi
68
69 #                                  5              12     8   12  15   (min)"
70 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
71
72 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
73         #                                               13    (min)"
74         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
75 fi
76
77 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
78         always_except LU-1941 130b 130c 130d 130e 130f 130g
79         always_except LU-9054 312
80 fi
81
82 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
83
84 # Get the SLES distro version
85 #
86 # Returns a version string that should only be used in comparing
87 # strings returned by version_code()
88 sles_version_code()
89 {
90         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
91
92         # All SuSE Linux versions have one decimal. version_code expects two
93         local sles_version=$version.0
94         version_code $sles_version
95 }
96
97 # Check if we are running on Ubuntu or SLES so we can make decisions on
98 # what tests to run
99 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
100         sles_version=$(sles_version_code)
101         [ $sles_version -lt $(version_code 11.4.0) ] &&
102                 always_except LU-4341 170
103
104         [ $sles_version -lt $(version_code 12.0.0) ] &&
105                 always_except LU-3703 234
106 elif [ -r /etc/os-release ]; then
107         if grep -qi ubuntu /etc/os-release; then
108                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
109                                                 -e 's/^VERSION=//p' \
110                                                 /etc/os-release |
111                                                 awk '{ print $1 }'))
112
113                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
114                         always_except LU-10366 410
115                 fi
116         fi
117 fi
118
119 build_test_filter
120 FAIL_ON_ERROR=false
121
122 cleanup() {
123         echo -n "cln.."
124         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
125         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
126 }
127 setup() {
128         echo -n "mnt.."
129         load_modules
130         setupall || exit 10
131         echo "done"
132 }
133
134 check_swap_layouts_support()
135 {
136         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
137                 skip "Does not support layout lock."
138 }
139
140 check_swap_layout_no_dom()
141 {
142         local FOLDER=$1
143         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
144         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
145 }
146
147 check_and_setup_lustre
148 DIR=${DIR:-$MOUNT}
149 assert_DIR
150
151 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
152
153 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
154 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
155 rm -rf $DIR/[Rdfs][0-9]*
156
157 # $RUNAS_ID may get set incorrectly somewhere else
158 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
159         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
160
161 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
162
163 if [ "${ONLY}" = "MOUNT" ] ; then
164         echo "Lustre is up, please go on"
165         exit
166 fi
167
168 echo "preparing for tests involving mounts"
169 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
170 touch $EXT2_DEV
171 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
172 echo # add a newline after mke2fs.
173
174 umask 077
175
176 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
177
178 # ensure all internal functions know we want full debug
179 export PTLDEBUG=all
180 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
181
182 test_0a() {
183         touch $DIR/$tfile
184         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
185         rm $DIR/$tfile
186         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
187 }
188 run_test 0a "touch; rm ====================="
189
190 test_0b() {
191         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
192         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
193 }
194 run_test 0b "chmod 0755 $DIR ============================="
195
196 test_0c() {
197         $LCTL get_param mdc.*.import | grep "state: FULL" ||
198                 error "import not FULL"
199         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
200                 error "bad target"
201 }
202 run_test 0c "check import proc"
203
204 test_0d() { # LU-3397
205         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
206                 skip "proc exports not supported before 2.10.57"
207
208         local mgs_exp="mgs.MGS.exports"
209         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
210         local exp_client_nid
211         local exp_client_version
212         local exp_val
213         local imp_val
214         local temp_imp=$DIR/$tfile.import
215         local temp_exp=$DIR/$tfile.export
216
217         # save mgc import file to $temp_imp
218         $LCTL get_param mgc.*.import | tee $temp_imp
219         # Check if client uuid is found in MGS export
220         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
221                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
222                         $client_uuid ] &&
223                         break;
224         done
225         # save mgs export file to $temp_exp
226         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
227
228         # Compare the value of field "connect_flags"
229         imp_val=$(grep "connect_flags" $temp_imp)
230         exp_val=$(grep "connect_flags" $temp_exp)
231         [ "$exp_val" == "$imp_val" ] ||
232                 error "export flags '$exp_val' != import flags '$imp_val'"
233
234         # Compare client versions.  Only compare top-3 fields for compatibility
235         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
236         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
237         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
238         [ "$exp_val" == "$imp_val" ] ||
239                 error "exp version '$exp_client_version'($exp_val) != " \
240                         "'$(lustre_build_version client)'($imp_val)"
241 }
242 run_test 0d "check export proc ============================="
243
244 test_0e() { # LU-13417
245         (( $MDSCOUNT > 1 )) ||
246                 skip "We need at least 2 MDTs for this test"
247
248         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
249                 skip "Need server version at least 2.14.51"
250
251         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
252         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
253
254         [ $default_lmv_count -eq 1 ] ||
255                 error "$MOUNT default stripe count $default_lmv_count"
256
257         [ $default_lmv_index -eq -1 ] ||
258                 error "$MOUNT default stripe index $default_lmv_index"
259
260         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
261         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
262
263         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
264         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
265
266         [ $mdt_index1 -eq $mdt_index2 ] &&
267                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
268
269         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
270 }
271 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
272
273 test_1() {
274         test_mkdir $DIR/$tdir
275         test_mkdir $DIR/$tdir/d2
276         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
277         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
278         rmdir $DIR/$tdir/d2
279         rmdir $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
281 }
282 run_test 1 "mkdir; remkdir; rmdir"
283
284 test_2() {
285         test_mkdir $DIR/$tdir
286         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
287         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
288         rm -r $DIR/$tdir
289         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
290 }
291 run_test 2 "mkdir; touch; rmdir; check file"
292
293 test_3() {
294         test_mkdir $DIR/$tdir
295         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
296         touch $DIR/$tdir/$tfile
297         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
298         rm -r $DIR/$tdir
299         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
300 }
301 run_test 3 "mkdir; touch; rmdir; check dir"
302
303 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
304 test_4() {
305         test_mkdir -i 1 $DIR/$tdir
306
307         touch $DIR/$tdir/$tfile ||
308                 error "Create file under remote directory failed"
309
310         rmdir $DIR/$tdir &&
311                 error "Expect error removing in-use dir $DIR/$tdir"
312
313         test -d $DIR/$tdir || error "Remote directory disappeared"
314
315         rm -rf $DIR/$tdir || error "remove remote dir error"
316 }
317 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
318
319 test_5() {
320         test_mkdir $DIR/$tdir
321         test_mkdir $DIR/$tdir/d2
322         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
323         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
324         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
325 }
326 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
327
328 test_6a() {
329         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
330         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
331         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
332                 error "$tfile does not have perm 0666 or UID $UID"
333         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
334         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
335                 error "$tfile should be 0666 and owned by UID $UID"
336 }
337 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
338
339 test_6c() {
340         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
341
342         touch $DIR/$tfile
343         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
344         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
345                 error "$tfile should be owned by UID $RUNAS_ID"
346         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
347         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
348                 error "$tfile should be owned by UID $RUNAS_ID"
349 }
350 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
351
352 test_6e() {
353         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
354
355         touch $DIR/$tfile
356         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
357         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
358                 error "$tfile should be owned by GID $UID"
359         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
360         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
362 }
363 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
364
365 test_6g() {
366         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
367
368         test_mkdir $DIR/$tdir
369         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
370         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
371         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
372         test_mkdir $DIR/$tdir/d/subdir
373         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
374                 error "$tdir/d/subdir should be GID $RUNAS_GID"
375         if [[ $MDSCOUNT -gt 1 ]]; then
376                 # check remote dir sgid inherite
377                 $LFS mkdir -i 0 $DIR/$tdir.local ||
378                         error "mkdir $tdir.local failed"
379                 chmod g+s $DIR/$tdir.local ||
380                         error "chmod $tdir.local failed"
381                 chgrp $RUNAS_GID $DIR/$tdir.local ||
382                         error "chgrp $tdir.local failed"
383                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
384                         error "mkdir $tdir.remote failed"
385                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
387                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
388                         error "$tdir.remote should be mode 02755"
389         fi
390 }
391 run_test 6g "verify new dir in sgid dir inherits group"
392
393 test_6h() { # bug 7331
394         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
395
396         touch $DIR/$tfile || error "touch failed"
397         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
398         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
399                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
400         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
401                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
402 }
403 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
404
405 test_7a() {
406         test_mkdir $DIR/$tdir
407         $MCREATE $DIR/$tdir/$tfile
408         chmod 0666 $DIR/$tdir/$tfile
409         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
410                 error "$tdir/$tfile should be mode 0666"
411 }
412 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
413
414 test_7b() {
415         if [ ! -d $DIR/$tdir ]; then
416                 test_mkdir $DIR/$tdir
417         fi
418         $MCREATE $DIR/$tdir/$tfile
419         echo -n foo > $DIR/$tdir/$tfile
420         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
421         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
422 }
423 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
424
425 test_8() {
426         test_mkdir $DIR/$tdir
427         touch $DIR/$tdir/$tfile
428         chmod 0666 $DIR/$tdir/$tfile
429         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
430                 error "$tfile mode not 0666"
431 }
432 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
433
434 test_9() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         test_mkdir $DIR/$tdir/d2/d3
438         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
439 }
440 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
441
442 test_10() {
443         test_mkdir $DIR/$tdir
444         test_mkdir $DIR/$tdir/d2
445         touch $DIR/$tdir/d2/$tfile
446         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
447                 error "$tdir/d2/$tfile not a file"
448 }
449 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
450
451 test_11() {
452         test_mkdir $DIR/$tdir
453         test_mkdir $DIR/$tdir/d2
454         chmod 0666 $DIR/$tdir/d2
455         chmod 0705 $DIR/$tdir/d2
456         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
457                 error "$tdir/d2 mode not 0705"
458 }
459 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
460
461 test_12() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         chmod 0666 $DIR/$tdir/$tfile
465         chmod 0654 $DIR/$tdir/$tfile
466         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
467                 error "$tdir/d2 mode not 0654"
468 }
469 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
470
471 test_13() {
472         test_mkdir $DIR/$tdir
473         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
474         >  $DIR/$tdir/$tfile
475         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
476                 error "$tdir/$tfile size not 0 after truncate"
477 }
478 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
479
480 test_14() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         rm $DIR/$tdir/$tfile
484         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
485 }
486 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
487
488 test_15() {
489         test_mkdir $DIR/$tdir
490         touch $DIR/$tdir/$tfile
491         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
492         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
493                 error "$tdir/${tfile_2} not a file after rename"
494         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
495 }
496 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
497
498 test_16() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         rm -rf $DIR/$tdir/$tfile
502         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
503 }
504 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
505
506 test_17a() {
507         test_mkdir $DIR/$tdir
508         touch $DIR/$tdir/$tfile
509         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
510         ls -l $DIR/$tdir
511         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not a symlink"
513         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
514                 error "$tdir/l-exist not referencing a file"
515         rm -f $DIR/$tdir/l-exist
516         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
517 }
518 run_test 17a "symlinks: create, remove (real)"
519
520 test_17b() {
521         test_mkdir $DIR/$tdir
522         ln -s no-such-file $DIR/$tdir/l-dangle
523         ls -l $DIR/$tdir
524         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing no-such-file"
526         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
527                 error "$tdir/l-dangle not referencing non-existent file"
528         rm -f $DIR/$tdir/l-dangle
529         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
530 }
531 run_test 17b "symlinks: create, remove (dangling)"
532
533 test_17c() { # bug 3440 - don't save failed open RPC for replay
534         test_mkdir $DIR/$tdir
535         ln -s foo $DIR/$tdir/$tfile
536         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
537 }
538 run_test 17c "symlinks: open dangling (should return error)"
539
540 test_17d() {
541         test_mkdir $DIR/$tdir
542         ln -s foo $DIR/$tdir/$tfile
543         touch $DIR/$tdir/$tfile || error "creating to new symlink"
544 }
545 run_test 17d "symlinks: create dangling"
546
547 test_17e() {
548         test_mkdir $DIR/$tdir
549         local foo=$DIR/$tdir/$tfile
550         ln -s $foo $foo || error "create symlink failed"
551         ls -l $foo || error "ls -l failed"
552         ls $foo && error "ls not failed" || true
553 }
554 run_test 17e "symlinks: create recursive symlink (should return error)"
555
556 test_17f() {
557         test_mkdir $DIR/$tdir
558         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
562         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
563         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
564         ls -l  $DIR/$tdir
565 }
566 run_test 17f "symlinks: long and very long symlink name"
567
568 # str_repeat(S, N) generate a string that is string S repeated N times
569 str_repeat() {
570         local s=$1
571         local n=$2
572         local ret=''
573         while [ $((n -= 1)) -ge 0 ]; do
574                 ret=$ret$s
575         done
576         echo $ret
577 }
578
579 # Long symlinks and LU-2241
580 test_17g() {
581         test_mkdir $DIR/$tdir
582         local TESTS="59 60 61 4094 4095"
583
584         # Fix for inode size boundary in 2.1.4
585         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
586                 TESTS="4094 4095"
587
588         # Patch not applied to 2.2 or 2.3 branches
589         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
590         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
591                 TESTS="4094 4095"
592
593         for i in $TESTS; do
594                 local SYMNAME=$(str_repeat 'x' $i)
595                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
596                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
597         done
598 }
599 run_test 17g "symlinks: really long symlink name and inode boundaries"
600
601 test_17h() { #bug 17378
602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
603         remote_mds_nodsh && skip "remote MDS with nodsh"
604
605         local mdt_idx
606
607         test_mkdir $DIR/$tdir
608         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
609         $LFS setstripe -c -1 $DIR/$tdir
610         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
611         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
612         touch $DIR/$tdir/$tfile || true
613 }
614 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
615
616 test_17i() { #bug 20018
617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
618         remote_mds_nodsh && skip "remote MDS with nodsh"
619
620         local foo=$DIR/$tdir/$tfile
621         local mdt_idx
622
623         test_mkdir -c1 $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         ln -s $foo $foo || error "create symlink failed"
626 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
628         ls -l $foo && error "error not detected"
629         return 0
630 }
631 run_test 17i "don't panic on short symlink (should return error)"
632
633 test_17k() { #bug 22301
634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
635         [[ -z "$(which rsync 2>/dev/null)" ]] &&
636                 skip "no rsync command"
637         rsync --help | grep -q xattr ||
638                 skip_env "$(rsync --version | head -n1) does not support xattrs"
639         test_mkdir $DIR/$tdir
640         test_mkdir $DIR/$tdir.new
641         touch $DIR/$tdir/$tfile
642         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
643         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
644                 error "rsync failed with xattrs enabled"
645 }
646 run_test 17k "symlinks: rsync with xattrs enabled"
647
648 test_17l() { # LU-279
649         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
650                 skip "no getfattr command"
651
652         test_mkdir $DIR/$tdir
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
656                 # -h to not follow symlinks. -m '' to list all the xattrs.
657                 # grep to remove first line: '# file: $path'.
658                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
659                 do
660                         lgetxattr_size_check $path $xattr ||
661                                 error "lgetxattr_size_check $path $xattr failed"
662                 done
663         done
664 }
665 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
666
667 # LU-1540
668 test_17m() {
669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
670         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
671         remote_mds_nodsh && skip "remote MDS with nodsh"
672         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
673         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
674                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
675
676         local short_sym="0123456789"
677         local wdir=$DIR/$tdir
678         local i
679
680         test_mkdir $wdir
681         long_sym=$short_sym
682         # create a long symlink file
683         for ((i = 0; i < 4; ++i)); do
684                 long_sym=${long_sym}${long_sym}
685         done
686
687         echo "create 512 short and long symlink files under $wdir"
688         for ((i = 0; i < 256; ++i)); do
689                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
690                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
691         done
692
693         echo "erase them"
694         rm -f $wdir/*
695         sync
696         wait_delete_completed
697
698         echo "recreate the 512 symlink files with a shorter string"
699         for ((i = 0; i < 512; ++i)); do
700                 # rewrite the symlink file with a shorter string
701                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
702                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
703         done
704
705         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
706
707         echo "stop and checking mds${mds_index}:"
708         # e2fsck should not return error
709         stop mds${mds_index}
710         local devname=$(mdsdevname $mds_index)
711         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
712         rc=$?
713
714         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
715                 error "start mds${mds_index} failed"
716         df $MOUNT > /dev/null 2>&1
717         [ $rc -eq 0 ] ||
718                 error "e2fsck detected error for short/long symlink: rc=$rc"
719         rm -f $wdir/*
720 }
721 run_test 17m "run e2fsck against MDT which contains short/long symlink"
722
723 check_fs_consistency_17n() {
724         local mdt_index
725         local rc=0
726
727         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
728         # so it only check MDT1/MDT2 instead of all of MDTs.
729         for mdt_index in 1 2; do
730                 # e2fsck should not return error
731                 stop mds${mdt_index}
732                 local devname=$(mdsdevname $mdt_index)
733                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
734                         rc=$((rc + $?))
735
736                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
737                         error "mount mds$mdt_index failed"
738                 df $MOUNT > /dev/null 2>&1
739         done
740         return $rc
741 }
742
743 test_17n() {
744         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
746         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
747         remote_mds_nodsh && skip "remote MDS with nodsh"
748         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
749         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
750                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
751
752         local i
753
754         test_mkdir $DIR/$tdir
755         for ((i=0; i<10; i++)); do
756                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
757                         error "create remote dir error $i"
758                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
759                         error "create files under remote dir failed $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after create files under remote dir"
764
765         for ((i = 0; i < 10; i++)); do
766                 rm -rf $DIR/$tdir/remote_dir_${i} ||
767                         error "destroy remote dir error $i"
768         done
769
770         check_fs_consistency_17n ||
771                 error "e2fsck report error after unlink files under remote dir"
772
773         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
774                 skip "lustre < 2.4.50 does not support migrate mv"
775
776         for ((i = 0; i < 10; i++)); do
777                 mkdir -p $DIR/$tdir/remote_dir_${i}
778                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
779                         error "create files under remote dir failed $i"
780                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
781                         error "migrate remote dir error $i"
782         done
783         check_fs_consistency_17n || error "e2fsck report error after migration"
784
785         for ((i = 0; i < 10; i++)); do
786                 rm -rf $DIR/$tdir/remote_dir_${i} ||
787                         error "destroy remote dir error $i"
788         done
789
790         check_fs_consistency_17n || error "e2fsck report error after unlink"
791 }
792 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
793
794 test_17o() {
795         remote_mds_nodsh && skip "remote MDS with nodsh"
796         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
797                 skip "Need MDS version at least 2.3.64"
798
799         local wdir=$DIR/${tdir}o
800         local mdt_index
801         local rc=0
802
803         test_mkdir $wdir
804         touch $wdir/$tfile
805         mdt_index=$($LFS getstripe -m $wdir/$tfile)
806         mdt_index=$((mdt_index + 1))
807
808         cancel_lru_locks mdc
809         #fail mds will wait the failover finish then set
810         #following fail_loc to avoid interfer the recovery process.
811         fail mds${mdt_index}
812
813         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
814         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
815         ls -l $wdir/$tfile && rc=1
816         do_facet mds${mdt_index} lctl set_param fail_loc=0
817         [[ $rc -eq 0 ]] || error "stat file should fail"
818 }
819 run_test 17o "stat file with incompat LMA feature"
820
821 test_18() {
822         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
823         ls $DIR || error "Failed to ls $DIR: $?"
824 }
825 run_test 18 "touch .../f ; ls ... =============================="
826
827 test_19a() {
828         touch $DIR/$tfile
829         ls -l $DIR
830         rm $DIR/$tfile
831         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
832 }
833 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
834
835 test_19b() {
836         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
837 }
838 run_test 19b "ls -l .../f19 (should return error) =============="
839
840 test_19c() {
841         [ $RUNAS_ID -eq $UID ] &&
842                 skip_env "RUNAS_ID = UID = $UID -- skipping"
843
844         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
845 }
846 run_test 19c "$RUNAS touch .../f19 (should return error) =="
847
848 test_19d() {
849         cat $DIR/f19 && error || true
850 }
851 run_test 19d "cat .../f19 (should return error) =============="
852
853 test_20() {
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         touch $DIR/$tfile
859         rm $DIR/$tfile
860         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
861 }
862 run_test 20 "touch .../f ; ls -l ..."
863
864 test_21() {
865         test_mkdir $DIR/$tdir
866         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
867         ln -s dangle $DIR/$tdir/link
868         echo foo >> $DIR/$tdir/link
869         cat $DIR/$tdir/dangle
870         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
871         $CHECKSTAT -f -t file $DIR/$tdir/link ||
872                 error "$tdir/link not linked to a file"
873 }
874 run_test 21 "write to dangling link"
875
876 test_22() {
877         local wdir=$DIR/$tdir
878         test_mkdir $wdir
879         chown $RUNAS_ID:$RUNAS_GID $wdir
880         (cd $wdir || error "cd $wdir failed";
881                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
882                 $RUNAS tar xf -)
883         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
884         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
885         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
886                 error "checkstat -u failed"
887 }
888 run_test 22 "unpack tar archive as non-root user"
889
890 # was test_23
891 test_23a() {
892         test_mkdir $DIR/$tdir
893         local file=$DIR/$tdir/$tfile
894
895         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
896         openfile -f O_CREAT:O_EXCL $file &&
897                 error "$file recreate succeeded" || true
898 }
899 run_test 23a "O_CREAT|O_EXCL in subdir"
900
901 test_23b() { # bug 18988
902         test_mkdir $DIR/$tdir
903         local file=$DIR/$tdir/$tfile
904
905         rm -f $file
906         echo foo > $file || error "write filed"
907         echo bar >> $file || error "append filed"
908         $CHECKSTAT -s 8 $file || error "wrong size"
909         rm $file
910 }
911 run_test 23b "O_APPEND check"
912
913 # LU-9409, size with O_APPEND and tiny writes
914 test_23c() {
915         local file=$DIR/$tfile
916
917         # single dd
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
919         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
920         rm -f $file
921
922         # racing tiny writes
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
924         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
925         wait
926         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
927         rm -f $file
928
929         #racing tiny & normal writes
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
931         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
932         wait
933         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
934         rm -f $file
935
936         #racing tiny & normal writes 2, ugly numbers
937         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
938         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
939         wait
940         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
941         rm -f $file
942 }
943 run_test 23c "O_APPEND size checks for tiny writes"
944
945 # LU-11069 file offset is correct after appending writes
946 test_23d() {
947         local file=$DIR/$tfile
948         local offset
949
950         echo CentaurHauls > $file
951         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
952         if ((offset != 26)); then
953                 error "wrong offset, expected 26, got '$offset'"
954         fi
955 }
956 run_test 23d "file offset is correct after appending writes"
957
958 # rename sanity
959 test_24a() {
960         echo '-- same directory rename'
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.1
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
965 }
966 run_test 24a "rename file to non-existent target"
967
968 test_24b() {
969         test_mkdir $DIR/$tdir
970         touch $DIR/$tdir/$tfile.{1,2}
971         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
972         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
973         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
974 }
975 run_test 24b "rename file to existing target"
976
977 test_24c() {
978         test_mkdir $DIR/$tdir
979         test_mkdir $DIR/$tdir/d$testnum.1
980         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
981         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
982         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
983 }
984 run_test 24c "rename directory to non-existent target"
985
986 test_24d() {
987         test_mkdir -c1 $DIR/$tdir
988         test_mkdir -c1 $DIR/$tdir/d$testnum.1
989         test_mkdir -c1 $DIR/$tdir/d$testnum.2
990         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
991         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
992         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
993 }
994 run_test 24d "rename directory to existing target"
995
996 test_24e() {
997         echo '-- cross directory renames --'
998         test_mkdir $DIR/R5a
999         test_mkdir $DIR/R5b
1000         touch $DIR/R5a/f
1001         mv $DIR/R5a/f $DIR/R5b/g
1002         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1003         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1004 }
1005 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1006
1007 test_24f() {
1008         test_mkdir $DIR/R6a
1009         test_mkdir $DIR/R6b
1010         touch $DIR/R6a/f $DIR/R6b/g
1011         mv $DIR/R6a/f $DIR/R6b/g
1012         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1013         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1014 }
1015 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1016
1017 test_24g() {
1018         test_mkdir $DIR/R7a
1019         test_mkdir $DIR/R7b
1020         test_mkdir $DIR/R7a/d
1021         mv $DIR/R7a/d $DIR/R7b/e
1022         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1023         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1024 }
1025 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1026
1027 test_24h() {
1028         test_mkdir -c1 $DIR/R8a
1029         test_mkdir -c1 $DIR/R8b
1030         test_mkdir -c1 $DIR/R8a/d
1031         test_mkdir -c1 $DIR/R8b/e
1032         mrename $DIR/R8a/d $DIR/R8b/e
1033         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1034         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1035 }
1036 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1037
1038 test_24i() {
1039         echo "-- rename error cases"
1040         test_mkdir $DIR/R9
1041         test_mkdir $DIR/R9/a
1042         touch $DIR/R9/f
1043         mrename $DIR/R9/f $DIR/R9/a
1044         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1045         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1046         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1047 }
1048 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1049
1050 test_24j() {
1051         test_mkdir $DIR/R10
1052         mrename $DIR/R10/f $DIR/R10/g
1053         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1054         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1055         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1056 }
1057 run_test 24j "source does not exist ============================"
1058
1059 test_24k() {
1060         test_mkdir $DIR/R11a
1061         test_mkdir $DIR/R11a/d
1062         touch $DIR/R11a/f
1063         mv $DIR/R11a/f $DIR/R11a/d
1064         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1065         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1066 }
1067 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1068
1069 # bug 2429 - rename foo foo foo creates invalid file
1070 test_24l() {
1071         f="$DIR/f24l"
1072         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1073 }
1074 run_test 24l "Renaming a file to itself ========================"
1075
1076 test_24m() {
1077         f="$DIR/f24m"
1078         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1079         # on ext3 this does not remove either the source or target files
1080         # though the "expected" operation would be to remove the source
1081         $CHECKSTAT -t file ${f} || error "${f} missing"
1082         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1083 }
1084 run_test 24m "Renaming a file to a hard link to itself ========="
1085
1086 test_24n() {
1087     f="$DIR/f24n"
1088     # this stats the old file after it was renamed, so it should fail
1089     touch ${f}
1090     $CHECKSTAT ${f} || error "${f} missing"
1091     mv ${f} ${f}.rename
1092     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1093     $CHECKSTAT -a ${f} || error "${f} exists"
1094 }
1095 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1096
1097 test_24o() {
1098         test_mkdir $DIR/$tdir
1099         rename_many -s random -v -n 10 $DIR/$tdir
1100 }
1101 run_test 24o "rename of files during htree split"
1102
1103 test_24p() {
1104         test_mkdir $DIR/R12a
1105         test_mkdir $DIR/R12b
1106         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1107         mrename $DIR/R12a $DIR/R12b
1108         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1109         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1110         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1111         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1112 }
1113 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1114
1115 cleanup_multiop_pause() {
1116         trap 0
1117         kill -USR1 $MULTIPID
1118 }
1119
1120 test_24q() {
1121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1122
1123         test_mkdir $DIR/R13a
1124         test_mkdir $DIR/R13b
1125         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1126         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1127         MULTIPID=$!
1128
1129         trap cleanup_multiop_pause EXIT
1130         mrename $DIR/R13a $DIR/R13b
1131         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1132         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1133         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1134         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1135         cleanup_multiop_pause
1136         wait $MULTIPID || error "multiop close failed"
1137 }
1138 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1139
1140 test_24r() { #bug 3789
1141         test_mkdir $DIR/R14a
1142         test_mkdir $DIR/R14a/b
1143         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1145         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1146 }
1147 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1148
1149 test_24s() {
1150         test_mkdir $DIR/R15a
1151         test_mkdir $DIR/R15a/b
1152         test_mkdir $DIR/R15a/b/c
1153         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1154         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1155         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1156 }
1157 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1158
1159 test_24t() {
1160         test_mkdir $DIR/R16a
1161         test_mkdir $DIR/R16a/b
1162         test_mkdir $DIR/R16a/b/c
1163         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1164         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1165         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1166 }
1167 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1168
1169 test_24u() { # bug12192
1170         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1171         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1172 }
1173 run_test 24u "create stripe file"
1174
1175 simple_cleanup_common() {
1176         local createmany=$1
1177         local rc=0
1178
1179         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1180
1181         local start=$SECONDS
1182
1183         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1184         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1185         rc=$?
1186         wait_delete_completed
1187         echo "cleanup time $((SECONDS - start))"
1188         return $rc
1189 }
1190
1191 max_pages_per_rpc() {
1192         local mdtname="$(printf "MDT%04x" ${1:-0})"
1193         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1194 }
1195
1196 test_24v() {
1197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1198
1199         local nrfiles=${COUNT:-100000}
1200         local fname="$DIR/$tdir/$tfile"
1201
1202         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1203         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1204
1205         test_mkdir "$(dirname $fname)"
1206         # assume MDT0000 has the fewest inodes
1207         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1208         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1209         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1210
1211         stack_trap "simple_cleanup_common $nrfiles"
1212
1213         createmany -m "$fname" $nrfiles
1214
1215         cancel_lru_locks mdc
1216         lctl set_param mdc.*.stats clear
1217
1218         # was previously test_24D: LU-6101
1219         # readdir() returns correct number of entries after cursor reload
1220         local num_ls=$(ls $DIR/$tdir | wc -l)
1221         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1222         local num_all=$(ls -a $DIR/$tdir | wc -l)
1223         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1224                 [ $num_all -ne $((nrfiles + 2)) ]; then
1225                         error "Expected $nrfiles files, got $num_ls " \
1226                                 "($num_uniq unique $num_all .&..)"
1227         fi
1228         # LU-5 large readdir
1229         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1230         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1231         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1232         # take into account of overhead in lu_dirpage header and end mark in
1233         # each page, plus one in rpc_num calculation.
1234         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1235         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1236         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1237         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1238         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1239         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1240         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1241         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1242                 error "large readdir doesn't take effect: " \
1243                       "$mds_readpage should be about $rpc_max"
1244 }
1245 run_test 24v "list large directory (test hash collision, b=17560)"
1246
1247 test_24w() { # bug21506
1248         SZ1=234852
1249         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1250         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1251         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1252         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1253         [[ "$SZ1" -eq "$SZ2" ]] ||
1254                 error "Error reading at the end of the file $tfile"
1255 }
1256 run_test 24w "Reading a file larger than 4Gb"
1257
1258 test_24x() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1262                 skip "Need MDS version at least 2.7.56"
1263
1264         local MDTIDX=1
1265         local remote_dir=$DIR/$tdir/remote_dir
1266
1267         test_mkdir $DIR/$tdir
1268         $LFS mkdir -i $MDTIDX $remote_dir ||
1269                 error "create remote directory failed"
1270
1271         test_mkdir $DIR/$tdir/src_dir
1272         touch $DIR/$tdir/src_file
1273         test_mkdir $remote_dir/tgt_dir
1274         touch $remote_dir/tgt_file
1275
1276         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1277                 error "rename dir cross MDT failed!"
1278
1279         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1280                 error "rename file cross MDT failed!"
1281
1282         touch $DIR/$tdir/ln_file
1283         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1284                 error "ln file cross MDT failed"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24x "cross MDT rename/link"
1289
1290 test_24y() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1293
1294         local remote_dir=$DIR/$tdir/remote_dir
1295         local mdtidx=1
1296
1297         test_mkdir $DIR/$tdir
1298         $LFS mkdir -i $mdtidx $remote_dir ||
1299                 error "create remote directory failed"
1300
1301         test_mkdir $remote_dir/src_dir
1302         touch $remote_dir/src_file
1303         test_mkdir $remote_dir/tgt_dir
1304         touch $remote_dir/tgt_file
1305
1306         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1307                 error "rename subdir in the same remote dir failed!"
1308
1309         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1310                 error "rename files in the same remote dir failed!"
1311
1312         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1313                 error "link files in the same remote dir failed!"
1314
1315         rm -rf $DIR/$tdir || error "Can not delete directories"
1316 }
1317 run_test 24y "rename/link on the same dir should succeed"
1318
1319 test_24z() {
1320         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1321         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1322                 skip "Need MDS version at least 2.12.51"
1323
1324         local index
1325
1326         for index in 0 1; do
1327                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1328                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1329         done
1330
1331         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1332
1333         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1334         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1335
1336         local mdts=$(comma_list $(mdts_nodes))
1337
1338         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1339         stack_trap "do_nodes $mdts $LCTL \
1340                 set_param mdt.*.enable_remote_rename=1" EXIT
1341
1342         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1343
1344         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1345         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1346 }
1347 run_test 24z "cross-MDT rename is done as cp"
1348
1349 test_24A() { # LU-3182
1350         local NFILES=5000
1351
1352         test_mkdir $DIR/$tdir
1353         stack_trap "simple_cleanup_common $NFILES"
1354         createmany -m $DIR/$tdir/$tfile $NFILES
1355         local t=$(ls $DIR/$tdir | wc -l)
1356         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1357         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1358
1359         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1360                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1361 }
1362 run_test 24A "readdir() returns correct number of entries."
1363
1364 test_24B() { # LU-4805
1365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1366
1367         local count
1368
1369         test_mkdir $DIR/$tdir
1370         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1371                 error "create striped dir failed"
1372
1373         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1374         [ $count -eq 2 ] || error "Expected 2, got $count"
1375
1376         touch $DIR/$tdir/striped_dir/a
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 3 ] || error "Expected 3, got $count"
1380
1381         touch $DIR/$tdir/striped_dir/.f
1382
1383         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1384         [ $count -eq 4 ] || error "Expected 4, got $count"
1385
1386         rm -rf $DIR/$tdir || error "Can not delete directories"
1387 }
1388 run_test 24B "readdir for striped dir return correct number of entries"
1389
1390 test_24C() {
1391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1392
1393         mkdir $DIR/$tdir
1394         mkdir $DIR/$tdir/d0
1395         mkdir $DIR/$tdir/d1
1396
1397         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1398                 error "create striped dir failed"
1399
1400         cd $DIR/$tdir/d0/striped_dir
1401
1402         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1403         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1404         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d0_ino" = "$parent_ino" ] ||
1407                 error ".. wrong, expect $d0_ino, get $parent_ino"
1408
1409         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1410                 error "mv striped dir failed"
1411
1412         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1413
1414         [ "$d1_ino" = "$parent_ino" ] ||
1415                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1416 }
1417 run_test 24C "check .. in striped dir"
1418
1419 test_24E() {
1420         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1422
1423         mkdir -p $DIR/$tdir
1424         mkdir $DIR/$tdir/src_dir
1425         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1426                 error "create remote source failed"
1427
1428         touch $DIR/$tdir/src_dir/src_child/a
1429
1430         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1431                 error "create remote target dir failed"
1432
1433         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "create remote target child failed"
1435
1436         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1437                 error "rename dir cross MDT failed!"
1438
1439         find $DIR/$tdir
1440
1441         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1442                 error "src_child still exists after rename"
1443
1444         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1445                 error "missing file(a) after rename"
1446
1447         rm -rf $DIR/$tdir || error "Can not delete directories"
1448 }
1449 run_test 24E "cross MDT rename/link"
1450
1451 test_24F () {
1452         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1453
1454         local repeats=1000
1455         [ "$SLOW" = "no" ] && repeats=100
1456
1457         mkdir -p $DIR/$tdir
1458
1459         echo "$repeats repeats"
1460         for ((i = 0; i < repeats; i++)); do
1461                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1462                 touch $DIR/$tdir/test/a || error "touch fails"
1463                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1464                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1465         done
1466
1467         true
1468 }
1469 run_test 24F "hash order vs readdir (LU-11330)"
1470
1471 test_24G () {
1472         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1473
1474         local ino1
1475         local ino2
1476
1477         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1478         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1479         touch $DIR/$tdir-0/f1 || error "touch f1"
1480         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1481         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1482         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1483         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1484         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1485 }
1486 run_test 24G "migrate symlink in rename"
1487
1488 test_24H() {
1489         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1490         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1491                 skip "MDT1 should be on another node"
1492
1493         test_mkdir -i 1 -c 1 $DIR/$tdir
1494 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1495         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1496         touch $DIR/$tdir/$tfile || error "touch failed"
1497 }
1498 run_test 24H "repeat FLD_QUERY rpc"
1499
1500 test_25a() {
1501         echo '== symlink sanity ============================================='
1502
1503         test_mkdir $DIR/d25
1504         ln -s d25 $DIR/s25
1505         touch $DIR/s25/foo ||
1506                 error "File creation in symlinked directory failed"
1507 }
1508 run_test 25a "create file in symlinked directory ==============="
1509
1510 test_25b() {
1511         [ ! -d $DIR/d25 ] && test_25a
1512         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1513 }
1514 run_test 25b "lookup file in symlinked directory ==============="
1515
1516 test_26a() {
1517         test_mkdir $DIR/d26
1518         test_mkdir $DIR/d26/d26-2
1519         ln -s d26/d26-2 $DIR/s26
1520         touch $DIR/s26/foo || error "File creation failed"
1521 }
1522 run_test 26a "multiple component symlink ======================="
1523
1524 test_26b() {
1525         test_mkdir -p $DIR/$tdir/d26-2
1526         ln -s $tdir/d26-2/foo $DIR/s26-2
1527         touch $DIR/s26-2 || error "File creation failed"
1528 }
1529 run_test 26b "multiple component symlink at end of lookup ======"
1530
1531 test_26c() {
1532         test_mkdir $DIR/d26.2
1533         touch $DIR/d26.2/foo
1534         ln -s d26.2 $DIR/s26.2-1
1535         ln -s s26.2-1 $DIR/s26.2-2
1536         ln -s s26.2-2 $DIR/s26.2-3
1537         chmod 0666 $DIR/s26.2-3/foo
1538 }
1539 run_test 26c "chain of symlinks"
1540
1541 # recursive symlinks (bug 439)
1542 test_26d() {
1543         ln -s d26-3/foo $DIR/d26-3
1544 }
1545 run_test 26d "create multiple component recursive symlink"
1546
1547 test_26e() {
1548         [ ! -h $DIR/d26-3 ] && test_26d
1549         rm $DIR/d26-3
1550 }
1551 run_test 26e "unlink multiple component recursive symlink"
1552
1553 # recursive symlinks (bug 7022)
1554 test_26f() {
1555         test_mkdir $DIR/$tdir
1556         test_mkdir $DIR/$tdir/$tfile
1557         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1558         test_mkdir -p lndir/bar1
1559         test_mkdir $DIR/$tdir/$tfile/$tfile
1560         cd $tfile                || error "cd $tfile failed"
1561         ln -s .. dotdot          || error "ln dotdot failed"
1562         ln -s dotdot/lndir lndir || error "ln lndir failed"
1563         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1564         output=`ls $tfile/$tfile/lndir/bar1`
1565         [ "$output" = bar1 ] && error "unexpected output"
1566         rm -r $tfile             || error "rm $tfile failed"
1567         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1568 }
1569 run_test 26f "rm -r of a directory which has recursive symlink"
1570
1571 test_27a() {
1572         test_mkdir $DIR/$tdir
1573         $LFS getstripe $DIR/$tdir
1574         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1575         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1576         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1577 }
1578 run_test 27a "one stripe file"
1579
1580 test_27b() {
1581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1582
1583         test_mkdir $DIR/$tdir
1584         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1585         $LFS getstripe -c $DIR/$tdir/$tfile
1586         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1587                 error "two-stripe file doesn't have two stripes"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1590 }
1591 run_test 27b "create and write to two stripe file"
1592
1593 # 27c family tests specific striping, setstripe -o
1594 test_27ca() {
1595         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1596         test_mkdir -p $DIR/$tdir
1597         local osts="1"
1598
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1600         $LFS getstripe -i $DIR/$tdir/$tfile
1601         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1602                 error "stripe not on specified OST"
1603
1604         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1605 }
1606 run_test 27ca "one stripe on specified OST"
1607
1608 test_27cb() {
1609         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1610         test_mkdir -p $DIR/$tdir
1611         local osts="1,0"
1612         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1613         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1614         echo "$getstripe"
1615
1616         # Strip getstripe output to a space separated list of OSTs
1617         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1618                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1619         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1620                 error "stripes not on specified OSTs"
1621
1622         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1623 }
1624 run_test 27cb "two stripes on specified OSTs"
1625
1626 test_27cc() {
1627         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1628         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1629                 skip "server does not support overstriping"
1630
1631         test_mkdir -p $DIR/$tdir
1632         local osts="0,0"
1633         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1634         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1635         echo "$getstripe"
1636
1637         # Strip getstripe output to a space separated list of OSTs
1638         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1639                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1640         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1641                 error "stripes not on specified OSTs"
1642
1643         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1644 }
1645 run_test 27cc "two stripes on the same OST"
1646
1647 test_27cd() {
1648         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1649         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1650                 skip "server does not support overstriping"
1651         test_mkdir -p $DIR/$tdir
1652         local osts="0,1,1,0"
1653         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1654         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1655         echo "$getstripe"
1656
1657         # Strip getstripe output to a space separated list of OSTs
1658         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1659                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1660         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1661                 error "stripes not on specified OSTs"
1662
1663         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1664 }
1665 run_test 27cd "four stripes on two OSTs"
1666
1667 test_27ce() {
1668         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1669                 skip_env "too many osts, skipping"
1670         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1671                 skip "server does not support overstriping"
1672         # We do one more stripe than we have OSTs
1673         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1674                 skip_env "ea_inode feature disabled"
1675
1676         test_mkdir -p $DIR/$tdir
1677         local osts=""
1678         for i in $(seq 0 $OSTCOUNT);
1679         do
1680                 osts=$osts"0"
1681                 if [ $i -ne $OSTCOUNT ]; then
1682                         osts=$osts","
1683                 fi
1684         done
1685         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1686         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1687         echo "$getstripe"
1688
1689         # Strip getstripe output to a space separated list of OSTs
1690         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1691                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1692         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1693                 error "stripes not on specified OSTs"
1694
1695         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1696 }
1697 run_test 27ce "more stripes than OSTs with -o"
1698
1699 test_27cf() {
1700         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1701         local pid=0
1702
1703         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1705         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1706         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1707                 error "failed to set $osp_proc=0"
1708
1709         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1710         pid=$!
1711         sleep 1
1712         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1713         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1714                 error "failed to set $osp_proc=1"
1715         wait $pid
1716         [[ $pid -ne 0 ]] ||
1717                 error "should return error due to $osp_proc=0"
1718 }
1719 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1720
1721 test_27cg() {
1722         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1723                 skip "server does not support overstriping"
1724         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1725         large_xattr_enabled || skip_env "ea_inode feature disabled"
1726
1727         local osts="0"
1728
1729         for ((i=1;i<1000;i++)); do
1730                 osts+=",$((i % OSTCOUNT))"
1731         done
1732
1733         local mdts=$(comma_list $(mdts_nodes))
1734         local before=$(do_nodes $mdts \
1735                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1736                 awk '/many credits/{print $3}' |
1737                 calc_sum)
1738
1739         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1740         $LFS getstripe $DIR/$tfile | grep stripe
1741
1742         rm -f $DIR/$tfile || error "can't unlink"
1743
1744         after=$(do_nodes $mdts \
1745                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1746                 awk '/many credits/{print $3}' |
1747                 calc_sum)
1748
1749         (( before == after )) ||
1750                 error "too many credits happened: $after > $before"
1751 }
1752 run_test 27cg "1000 shouldn't cause too many credits"
1753
1754 test_27d() {
1755         test_mkdir $DIR/$tdir
1756         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1757                 error "setstripe failed"
1758         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1759         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1760 }
1761 run_test 27d "create file with default settings"
1762
1763 test_27e() {
1764         # LU-5839 adds check for existed layout before setting it
1765         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1766                 skip "Need MDS version at least 2.7.56"
1767
1768         test_mkdir $DIR/$tdir
1769         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1770         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1771         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1772 }
1773 run_test 27e "setstripe existing file (should return error)"
1774
1775 test_27f() {
1776         test_mkdir $DIR/$tdir
1777         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1778                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1779         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1780                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1781         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1782         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1783 }
1784 run_test 27f "setstripe with bad stripe size (should return error)"
1785
1786 test_27g() {
1787         test_mkdir $DIR/$tdir
1788         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1789         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1790                 error "$DIR/$tdir/$tfile has object"
1791 }
1792 run_test 27g "$LFS getstripe with no objects"
1793
1794 test_27ga() {
1795         test_mkdir $DIR/$tdir
1796         touch $DIR/$tdir/$tfile || error "touch failed"
1797         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1798         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1799         local rc=$?
1800         (( rc == 2 )) || error "getstripe did not return ENOENT"
1801 }
1802 run_test 27ga "$LFS getstripe with missing file (should return error)"
1803
1804 test_27i() {
1805         test_mkdir $DIR/$tdir
1806         touch $DIR/$tdir/$tfile || error "touch failed"
1807         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1808                 error "missing objects"
1809 }
1810 run_test 27i "$LFS getstripe with some objects"
1811
1812 test_27j() {
1813         test_mkdir $DIR/$tdir
1814         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1815                 error "setstripe failed" || true
1816 }
1817 run_test 27j "setstripe with bad stripe offset (should return error)"
1818
1819 test_27k() { # bug 2844
1820         test_mkdir $DIR/$tdir
1821         local file=$DIR/$tdir/$tfile
1822         local ll_max_blksize=$((4 * 1024 * 1024))
1823         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1824         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1825         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1826         dd if=/dev/zero of=$file bs=4k count=1
1827         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1828         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1829 }
1830 run_test 27k "limit i_blksize for broken user apps"
1831
1832 test_27l() {
1833         mcreate $DIR/$tfile || error "creating file"
1834         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1835                 error "setstripe should have failed" || true
1836 }
1837 run_test 27l "check setstripe permissions (should return error)"
1838
1839 test_27m() {
1840         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1841
1842         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1843                 skip_env "multiple clients -- skipping"
1844
1845         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1846                    head -n1)
1847         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1848                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1849         fi
1850         stack_trap simple_cleanup_common
1851         test_mkdir $DIR/$tdir
1852         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1853         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1854                 error "dd should fill OST0"
1855         i=2
1856         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1857                 i=$((i + 1))
1858                 [ $i -gt 256 ] && break
1859         done
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"
1865         i=$((i + 1))
1866         touch $DIR/$tdir/$tfile.$i
1867         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1868             awk '{print $1}'| grep -w "0") ] &&
1869                 error "OST0 was full but new created file still use it" || true
1870 }
1871 run_test 27m "create file while OST0 was full"
1872
1873 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1874 # if the OST isn't full anymore.
1875 reset_enospc() {
1876         local ostidx=${1:-""}
1877         local delay
1878         local ready
1879         local get_prealloc
1880
1881         local list=$(comma_list $(osts_nodes))
1882         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1883
1884         do_nodes $list lctl set_param fail_loc=0
1885         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1886         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1887                 awk '{print $1 * 2;exit;}')
1888         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1889                         grep -v \"^0$\""
1890         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1891 }
1892
1893 test_27n() {
1894         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1896         remote_mds_nodsh && skip "remote MDS with nodsh"
1897         remote_ost_nodsh && skip "remote OST with nodsh"
1898
1899         reset_enospc
1900         rm -f $DIR/$tdir/$tfile
1901         exhaust_precreations 0 0x80000215
1902         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1903         touch $DIR/$tdir/$tfile || error "touch failed"
1904         $LFS getstripe $DIR/$tdir/$tfile
1905         reset_enospc
1906 }
1907 run_test 27n "create file with some full OSTs"
1908
1909 test_27o() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917         exhaust_all_precreations 0x215
1918
1919         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1920
1921         reset_enospc
1922         rm -rf $DIR/$tdir/*
1923 }
1924 run_test 27o "create file with all full OSTs (should error)"
1925
1926 function create_and_checktime() {
1927         local fname=$1
1928         local loops=$2
1929         local i
1930
1931         for ((i=0; i < $loops; i++)); do
1932                 local start=$SECONDS
1933                 multiop $fname-$i Oc
1934                 ((SECONDS-start < TIMEOUT)) ||
1935                         error "creation took " $((SECONDS-$start)) && return 1
1936         done
1937 }
1938
1939 test_27oo() {
1940         local mdts=$(comma_list $(mdts_nodes))
1941
1942         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1943                 skip "Need MDS version at least 2.13.57"
1944
1945         local f0=$DIR/${tfile}-0
1946         local f1=$DIR/${tfile}-1
1947
1948         wait_delete_completed
1949
1950         # refill precreated objects
1951         $LFS setstripe -i0 -c1 $f0
1952
1953         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1954         # force QoS allocation policy
1955         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1956         stack_trap "do_nodes $mdts $LCTL set_param \
1957                 lov.*.qos_threshold_rr=$saved" EXIT
1958         sleep_maxage
1959
1960         # one OST is unavailable, but still have few objects preallocated
1961         stop ost1
1962         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1963                 rm -rf $f1 $DIR/$tdir*" EXIT
1964
1965         for ((i=0; i < 7; i++)); do
1966                 mkdir $DIR/$tdir$i || error "can't create dir"
1967                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1968                         error "can't set striping"
1969         done
1970         for ((i=0; i < 7; i++)); do
1971                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1972         done
1973         wait
1974 }
1975 run_test 27oo "don't let few threads to reserve too many objects"
1976
1977 test_27p() {
1978         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1980         remote_mds_nodsh && skip "remote MDS with nodsh"
1981         remote_ost_nodsh && skip "remote OST with nodsh"
1982
1983         reset_enospc
1984         rm -f $DIR/$tdir/$tfile
1985         test_mkdir $DIR/$tdir
1986
1987         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1988         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1989         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1990
1991         exhaust_precreations 0 0x80000215
1992         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1993         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1994         $LFS getstripe $DIR/$tdir/$tfile
1995
1996         reset_enospc
1997 }
1998 run_test 27p "append to a truncated file with some full OSTs"
1999
2000 test_27q() {
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003         remote_mds_nodsh && skip "remote MDS with nodsh"
2004         remote_ost_nodsh && skip "remote OST with nodsh"
2005
2006         reset_enospc
2007         rm -f $DIR/$tdir/$tfile
2008
2009         mkdir_on_mdt0 $DIR/$tdir
2010         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2011         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2012                 error "truncate $DIR/$tdir/$tfile failed"
2013         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2014
2015         exhaust_all_precreations 0x215
2016
2017         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2018         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2019
2020         reset_enospc
2021 }
2022 run_test 27q "append to truncated file with all OSTs full (should error)"
2023
2024 test_27r() {
2025         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028         remote_ost_nodsh && skip "remote OST with nodsh"
2029
2030         reset_enospc
2031         rm -f $DIR/$tdir/$tfile
2032         exhaust_precreations 0 0x80000215
2033
2034         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2035
2036         reset_enospc
2037 }
2038 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2039
2040 test_27s() { # bug 10725
2041         test_mkdir $DIR/$tdir
2042         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2043         local stripe_count=0
2044         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2045         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2046                 error "stripe width >= 2^32 succeeded" || true
2047
2048 }
2049 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2050
2051 test_27t() { # bug 10864
2052         WDIR=$(pwd)
2053         WLFS=$(which lfs)
2054         cd $DIR
2055         touch $tfile
2056         $WLFS getstripe $tfile
2057         cd $WDIR
2058 }
2059 run_test 27t "check that utils parse path correctly"
2060
2061 test_27u() { # bug 4900
2062         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2063         remote_mds_nodsh && skip "remote MDS with nodsh"
2064
2065         local index
2066         local list=$(comma_list $(mdts_nodes))
2067
2068 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2069         do_nodes $list $LCTL set_param fail_loc=0x139
2070         test_mkdir -p $DIR/$tdir
2071         stack_trap "simple_cleanup_common 1000"
2072         createmany -o $DIR/$tdir/$tfile 1000
2073         do_nodes $list $LCTL set_param fail_loc=0
2074
2075         TLOG=$TMP/$tfile.getstripe
2076         $LFS getstripe $DIR/$tdir > $TLOG
2077         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2078         [[ $OBJS -gt 0 ]] &&
2079                 error "$OBJS objects created on OST-0. See $TLOG" ||
2080                 rm -f $TLOG
2081 }
2082 run_test 27u "skip object creation on OSC w/o objects"
2083
2084 test_27v() { # bug 4900
2085         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2087         remote_mds_nodsh && skip "remote MDS with nodsh"
2088         remote_ost_nodsh && skip "remote OST with nodsh"
2089
2090         exhaust_all_precreations 0x215
2091         reset_enospc
2092
2093         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2094
2095         touch $DIR/$tdir/$tfile
2096         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2097         # all except ost1
2098         for (( i=1; i < OSTCOUNT; i++ )); do
2099                 do_facet ost$i lctl set_param fail_loc=0x705
2100         done
2101         local START=`date +%s`
2102         createmany -o $DIR/$tdir/$tfile 32
2103
2104         local FINISH=`date +%s`
2105         local TIMEOUT=`lctl get_param -n timeout`
2106         local PROCESS=$((FINISH - START))
2107         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2108                error "$FINISH - $START >= $TIMEOUT / 2"
2109         sleep $((TIMEOUT / 2 - PROCESS))
2110         reset_enospc
2111 }
2112 run_test 27v "skip object creation on slow OST"
2113
2114 test_27w() { # bug 10997
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2117         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2118                 error "stripe size $size != 65536" || true
2119         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2120                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2121 }
2122 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2123
2124 test_27wa() {
2125         [[ $OSTCOUNT -lt 2 ]] &&
2126                 skip_env "skipping multiple stripe count/offset test"
2127
2128         test_mkdir $DIR/$tdir
2129         for i in $(seq 1 $OSTCOUNT); do
2130                 offset=$((i - 1))
2131                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2132                         error "setstripe -c $i -i $offset failed"
2133                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2134                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2135                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2136                 [ $index -ne $offset ] &&
2137                         error "stripe offset $index != $offset" || true
2138         done
2139 }
2140 run_test 27wa "check $LFS setstripe -c -i options"
2141
2142 test_27x() {
2143         remote_ost_nodsh && skip "remote OST with nodsh"
2144         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2146
2147         OFFSET=$(($OSTCOUNT - 1))
2148         OSTIDX=0
2149         local OST=$(ostname_from_index $OSTIDX)
2150
2151         test_mkdir $DIR/$tdir
2152         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2153         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2154         sleep_maxage
2155         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2156         for i in $(seq 0 $OFFSET); do
2157                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2158                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2159                 error "OST0 was degraded but new created file still use it"
2160         done
2161         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2162 }
2163 run_test 27x "create files while OST0 is degraded"
2164
2165 test_27y() {
2166         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2167         remote_mds_nodsh && skip "remote MDS with nodsh"
2168         remote_ost_nodsh && skip "remote OST with nodsh"
2169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2170
2171         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2172         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2173                 osp.$mdtosc.prealloc_last_id)
2174         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2175                 osp.$mdtosc.prealloc_next_id)
2176         local fcount=$((last_id - next_id))
2177         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2178         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2179
2180         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2181                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2182         local OST_DEACTIVE_IDX=-1
2183         local OSC
2184         local OSTIDX
2185         local OST
2186
2187         for OSC in $MDS_OSCS; do
2188                 OST=$(osc_to_ost $OSC)
2189                 OSTIDX=$(index_from_ostuuid $OST)
2190                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2191                         OST_DEACTIVE_IDX=$OSTIDX
2192                 fi
2193                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2194                         echo $OSC "is Deactivated:"
2195                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2196                 fi
2197         done
2198
2199         OSTIDX=$(index_from_ostuuid $OST)
2200         test_mkdir $DIR/$tdir
2201         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=1
2210                 fi
2211         done
2212
2213         sleep_maxage
2214         createmany -o $DIR/$tdir/$tfile $fcount
2215
2216         for OSC in $MDS_OSCS; do
2217                 OST=$(osc_to_ost $OSC)
2218                 OSTIDX=$(index_from_ostuuid $OST)
2219                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2220                         echo $OST "is recovered from degraded:"
2221                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2222                                                 obdfilter.$OST.degraded=0
2223                 else
2224                         do_facet $SINGLEMDS lctl --device %$OSC activate
2225                 fi
2226         done
2227
2228         # all osp devices get activated, hence -1 stripe count restored
2229         local stripe_count=0
2230
2231         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2232         # devices get activated.
2233         sleep_maxage
2234         $LFS setstripe -c -1 $DIR/$tfile
2235         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2236         rm -f $DIR/$tfile
2237         [ $stripe_count -ne $OSTCOUNT ] &&
2238                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2239         return 0
2240 }
2241 run_test 27y "create files while OST0 is degraded and the rest inactive"
2242
2243 check_seq_oid()
2244 {
2245         log "check file $1"
2246
2247         lmm_count=$($LFS getstripe -c $1)
2248         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2249         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2250
2251         local old_ifs="$IFS"
2252         IFS=$'[:]'
2253         fid=($($LFS path2fid $1))
2254         IFS="$old_ifs"
2255
2256         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2257         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2258
2259         # compare lmm_seq and lu_fid->f_seq
2260         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2261         # compare lmm_object_id and lu_fid->oid
2262         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2263
2264         # check the trusted.fid attribute of the OST objects of the file
2265         local have_obdidx=false
2266         local stripe_nr=0
2267         $LFS getstripe $1 | while read obdidx oid hex seq; do
2268                 # skip lines up to and including "obdidx"
2269                 [ -z "$obdidx" ] && break
2270                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2271                 $have_obdidx || continue
2272
2273                 local ost=$((obdidx + 1))
2274                 local dev=$(ostdevname $ost)
2275                 local oid_hex
2276
2277                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2278
2279                 seq=$(echo $seq | sed -e "s/^0x//g")
2280                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2281                         oid_hex=$(echo $oid)
2282                 else
2283                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2284                 fi
2285                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2286
2287                 local ff=""
2288                 #
2289                 # Don't unmount/remount the OSTs if we don't need to do that.
2290                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2291                 # update too, until that use mount/ll_decode_filter_fid/mount.
2292                 # Re-enable when debugfs will understand new filter_fid.
2293                 #
2294                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2295                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2296                                 $dev 2>/dev/null" | grep "parent=")
2297                 fi
2298                 if [ -z "$ff" ]; then
2299                         stop ost$ost
2300                         mount_fstype ost$ost
2301                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2302                                 $(facet_mntpt ost$ost)/$obj_file)
2303                         unmount_fstype ost$ost
2304                         start ost$ost $dev $OST_MOUNT_OPTS
2305                         clients_up
2306                 fi
2307
2308                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2309
2310                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2311
2312                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2313                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2314                 #
2315                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2316                 #       stripe_size=1048576 component_id=1 component_start=0 \
2317                 #       component_end=33554432
2318                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2319                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2320                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2321                 local ff_pstripe
2322                 if grep -q 'stripe=' <<<$ff; then
2323                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2324                 else
2325                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2326                         # into f_ver in this case.  See comment on ff_parent.
2327                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2328                 fi
2329
2330                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2331                 [ $ff_pseq = $lmm_seq ] ||
2332                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2333                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2334                 [ $ff_poid = $lmm_oid ] ||
2335                         error "FF parent OID $ff_poid != $lmm_oid"
2336                 (($ff_pstripe == $stripe_nr)) ||
2337                         error "FF stripe $ff_pstripe != $stripe_nr"
2338
2339                 stripe_nr=$((stripe_nr + 1))
2340                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2341                         continue
2342                 if grep -q 'stripe_count=' <<<$ff; then
2343                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2344                                             -e 's/ .*//' <<<$ff)
2345                         [ $lmm_count = $ff_scnt ] ||
2346                                 error "FF stripe count $lmm_count != $ff_scnt"
2347                 fi
2348         done
2349 }
2350
2351 test_27z() {
2352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2353         remote_ost_nodsh && skip "remote OST with nodsh"
2354
2355         test_mkdir $DIR/$tdir
2356         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2357                 { error "setstripe -c -1 failed"; return 1; }
2358         # We need to send a write to every object to get parent FID info set.
2359         # This _should_ also work for setattr, but does not currently.
2360         # touch $DIR/$tdir/$tfile-1 ||
2361         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2362                 { error "dd $tfile-1 failed"; return 2; }
2363         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2364                 { error "setstripe -c -1 failed"; return 3; }
2365         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2366                 { error "dd $tfile-2 failed"; return 4; }
2367
2368         # make sure write RPCs have been sent to OSTs
2369         sync; sleep 5; sync
2370
2371         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2372         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2373 }
2374 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2375
2376 test_27A() { # b=19102
2377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2378
2379         save_layout_restore_at_exit $MOUNT
2380         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2381         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2382                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2383         local default_size=$($LFS getstripe -S $MOUNT)
2384         local default_offset=$($LFS getstripe -i $MOUNT)
2385         local dsize=$(do_facet $SINGLEMDS \
2386                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2387         [ $default_size -eq $dsize ] ||
2388                 error "stripe size $default_size != $dsize"
2389         [ $default_offset -eq -1 ] ||
2390                 error "stripe offset $default_offset != -1"
2391 }
2392 run_test 27A "check filesystem-wide default LOV EA values"
2393
2394 test_27B() { # LU-2523
2395         test_mkdir $DIR/$tdir
2396         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2397         touch $DIR/$tdir/f0
2398         # open f1 with O_LOV_DELAY_CREATE
2399         # rename f0 onto f1
2400         # call setstripe ioctl on open file descriptor for f1
2401         # close
2402         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2403                 $DIR/$tdir/f0
2404
2405         rm -f $DIR/$tdir/f1
2406         # open f1 with O_LOV_DELAY_CREATE
2407         # unlink f1
2408         # call setstripe ioctl on open file descriptor for f1
2409         # close
2410         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2411
2412         # Allow multiop to fail in imitation of NFS's busted semantics.
2413         true
2414 }
2415 run_test 27B "call setstripe on open unlinked file/rename victim"
2416
2417 # 27C family tests full striping and overstriping
2418 test_27Ca() { #LU-2871
2419         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2420
2421         declare -a ost_idx
2422         local index
2423         local found
2424         local i
2425         local j
2426
2427         test_mkdir $DIR/$tdir
2428         cd $DIR/$tdir
2429         for i in $(seq 0 $((OSTCOUNT - 1))); do
2430                 # set stripe across all OSTs starting from OST$i
2431                 $LFS setstripe -i $i -c -1 $tfile$i
2432                 # get striping information
2433                 ost_idx=($($LFS getstripe $tfile$i |
2434                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2435                 echo "OST Index: ${ost_idx[*]}"
2436
2437                 # check the layout
2438                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2439                         error "${#ost_idx[@]} != $OSTCOUNT"
2440
2441                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2442                         found=0
2443                         for j in "${ost_idx[@]}"; do
2444                                 if [ $index -eq $j ]; then
2445                                         found=1
2446                                         break
2447                                 fi
2448                         done
2449                         [ $found = 1 ] ||
2450                                 error "Can not find $index in ${ost_idx[*]}"
2451                 done
2452         done
2453 }
2454 run_test 27Ca "check full striping across all OSTs"
2455
2456 test_27Cb() {
2457         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2458                 skip "server does not support overstriping"
2459         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2460                 skip_env "too many osts, skipping"
2461
2462         test_mkdir -p $DIR/$tdir
2463         local setcount=$(($OSTCOUNT * 2))
2464         [ $setcount -lt 160 ] || large_xattr_enabled ||
2465                 skip_env "ea_inode feature disabled"
2466
2467         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2468                 error "setstripe failed"
2469
2470         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2471         [ $count -eq $setcount ] ||
2472                 error "stripe count $count, should be $setcount"
2473
2474         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2475                 error "overstriped should be set in pattern"
2476
2477         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2478                 error "dd failed"
2479 }
2480 run_test 27Cb "more stripes than OSTs with -C"
2481
2482 test_27Cc() {
2483         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2484                 skip "server does not support overstriping"
2485         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2486
2487         test_mkdir -p $DIR/$tdir
2488         local setcount=$(($OSTCOUNT - 1))
2489
2490         [ $setcount -lt 160 ] || large_xattr_enabled ||
2491                 skip_env "ea_inode feature disabled"
2492
2493         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2494                 error "setstripe failed"
2495
2496         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2497         [ $count -eq $setcount ] ||
2498                 error "stripe count $count, should be $setcount"
2499
2500         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2501                 error "overstriped should not be set in pattern"
2502
2503         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2504                 error "dd failed"
2505 }
2506 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2507
2508 test_27Cd() {
2509         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2510                 skip "server does not support overstriping"
2511         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2512         large_xattr_enabled || skip_env "ea_inode feature disabled"
2513
2514         force_new_seq_all
2515
2516         test_mkdir -p $DIR/$tdir
2517         local setcount=$LOV_MAX_STRIPE_COUNT
2518
2519         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2520                 error "setstripe failed"
2521
2522         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2523         [ $count -eq $setcount ] ||
2524                 error "stripe count $count, should be $setcount"
2525
2526         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2527                 error "overstriped should be set in pattern"
2528
2529         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2530                 error "dd failed"
2531
2532         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2533 }
2534 run_test 27Cd "test maximum stripe count"
2535
2536 test_27Ce() {
2537         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2538                 skip "server does not support overstriping"
2539         test_mkdir -p $DIR/$tdir
2540
2541         pool_add $TESTNAME || error "Pool creation failed"
2542         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2543
2544         local setcount=8
2545
2546         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2547                 error "setstripe failed"
2548
2549         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2550         [ $count -eq $setcount ] ||
2551                 error "stripe count $count, should be $setcount"
2552
2553         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2554                 error "overstriped should be set in pattern"
2555
2556         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2557                 error "dd failed"
2558
2559         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2560 }
2561 run_test 27Ce "test pool with overstriping"
2562
2563 test_27Cf() {
2564         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2565                 skip "server does not support overstriping"
2566         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2567                 skip_env "too many osts, skipping"
2568
2569         test_mkdir -p $DIR/$tdir
2570
2571         local setcount=$(($OSTCOUNT * 2))
2572         [ $setcount -lt 160 ] || large_xattr_enabled ||
2573                 skip_env "ea_inode feature disabled"
2574
2575         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2576                 error "setstripe failed"
2577
2578         echo 1 > $DIR/$tdir/$tfile
2579
2580         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2581         [ $count -eq $setcount ] ||
2582                 error "stripe count $count, should be $setcount"
2583
2584         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2585                 error "overstriped should be set in pattern"
2586
2587         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2588                 error "dd failed"
2589
2590         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2591 }
2592 run_test 27Cf "test default inheritance with overstriping"
2593
2594 test_27Cg() {
2595         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2596                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2597
2598         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2599         (( $? != 0 )) || error "must be an error for not existent OST#"
2600 }
2601 run_test 27Cg "test setstripe with wrong OST idx"
2602
2603 test_27D() {
2604         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2605         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2606         remote_mds_nodsh && skip "remote MDS with nodsh"
2607
2608         local POOL=${POOL:-testpool}
2609         local first_ost=0
2610         local last_ost=$(($OSTCOUNT - 1))
2611         local ost_step=1
2612         local ost_list=$(seq $first_ost $ost_step $last_ost)
2613         local ost_range="$first_ost $last_ost $ost_step"
2614
2615         test_mkdir $DIR/$tdir
2616         pool_add $POOL || error "pool_add failed"
2617         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2618
2619         local skip27D
2620         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2621                 skip27D+="-s 29"
2622         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2623                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2624                         skip27D+=" -s 30,31"
2625         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2626           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2627                 skip27D+=" -s 32,33"
2628         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2629                 skip27D+=" -s 34"
2630         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2631                 error "llapi_layout_test failed"
2632
2633         destroy_test_pools || error "destroy test pools failed"
2634 }
2635 run_test 27D "validate llapi_layout API"
2636
2637 # Verify that default_easize is increased from its initial value after
2638 # accessing a widely striped file.
2639 test_27E() {
2640         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2641         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2642                 skip "client does not have LU-3338 fix"
2643
2644         # 72 bytes is the minimum space required to store striping
2645         # information for a file striped across one OST:
2646         # (sizeof(struct lov_user_md_v3) +
2647         #  sizeof(struct lov_user_ost_data_v1))
2648         local min_easize=72
2649         $LCTL set_param -n llite.*.default_easize $min_easize ||
2650                 error "lctl set_param failed"
2651         local easize=$($LCTL get_param -n llite.*.default_easize)
2652
2653         [ $easize -eq $min_easize ] ||
2654                 error "failed to set default_easize"
2655
2656         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2657                 error "setstripe failed"
2658         # In order to ensure stat() call actually talks to MDS we need to
2659         # do something drastic to this file to shake off all lock, e.g.
2660         # rename it (kills lookup lock forcing cache cleaning)
2661         mv $DIR/$tfile $DIR/${tfile}-1
2662         ls -l $DIR/${tfile}-1
2663         rm $DIR/${tfile}-1
2664
2665         easize=$($LCTL get_param -n llite.*.default_easize)
2666
2667         [ $easize -gt $min_easize ] ||
2668                 error "default_easize not updated"
2669 }
2670 run_test 27E "check that default extended attribute size properly increases"
2671
2672 test_27F() { # LU-5346/LU-7975
2673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2674         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2675         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2676                 skip "Need MDS version at least 2.8.51"
2677         remote_ost_nodsh && skip "remote OST with nodsh"
2678
2679         test_mkdir $DIR/$tdir
2680         rm -f $DIR/$tdir/f0
2681         $LFS setstripe -c 2 $DIR/$tdir
2682
2683         # stop all OSTs to reproduce situation for LU-7975 ticket
2684         for num in $(seq $OSTCOUNT); do
2685                 stop ost$num
2686         done
2687
2688         # open/create f0 with O_LOV_DELAY_CREATE
2689         # truncate f0 to a non-0 size
2690         # close
2691         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2692
2693         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2694         # open/write it again to force delayed layout creation
2695         cat /etc/hosts > $DIR/$tdir/f0 &
2696         catpid=$!
2697
2698         # restart OSTs
2699         for num in $(seq $OSTCOUNT); do
2700                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2701                         error "ost$num failed to start"
2702         done
2703
2704         wait $catpid || error "cat failed"
2705
2706         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2707         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2708                 error "wrong stripecount"
2709
2710 }
2711 run_test 27F "Client resend delayed layout creation with non-zero size"
2712
2713 test_27G() { #LU-10629
2714         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2715                 skip "Need MDS version at least 2.11.51"
2716         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2717         remote_mds_nodsh && skip "remote MDS with nodsh"
2718         local POOL=${POOL:-testpool}
2719         local ostrange="0 0 1"
2720
2721         test_mkdir $DIR/$tdir
2722         touch $DIR/$tdir/$tfile.nopool
2723         pool_add $POOL || error "pool_add failed"
2724         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2725         $LFS setstripe -p $POOL $DIR/$tdir
2726
2727         local pool=$($LFS getstripe -p $DIR/$tdir)
2728
2729         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2730         touch $DIR/$tdir/$tfile.default
2731         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2732         $LFS find $DIR/$tdir -type f --pool $POOL
2733         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2734         [[ "$found" == "2" ]] ||
2735                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2736
2737         $LFS setstripe -d $DIR/$tdir
2738
2739         pool=$($LFS getstripe -p -d $DIR/$tdir)
2740
2741         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2742 }
2743 run_test 27G "Clear OST pool from stripe"
2744
2745 test_27H() {
2746         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2747                 skip "Need MDS version newer than 2.11.54"
2748         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2749         test_mkdir $DIR/$tdir
2750         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2751         touch $DIR/$tdir/$tfile
2752         $LFS getstripe -c $DIR/$tdir/$tfile
2753         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2754                 error "two-stripe file doesn't have two stripes"
2755
2756         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2757         $LFS getstripe -y $DIR/$tdir/$tfile
2758         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2759              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2760                 error "expected l_ost_idx: [02]$ not matched"
2761
2762         # make sure ost list has been cleared
2763         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2764         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2765                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2766         touch $DIR/$tdir/f3
2767         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2768 }
2769 run_test 27H "Set specific OSTs stripe"
2770
2771 test_27I() {
2772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2774         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2775                 skip "Need MDS version newer than 2.12.52"
2776         local pool=$TESTNAME
2777         local ostrange="1 1 1"
2778
2779         save_layout_restore_at_exit $MOUNT
2780         $LFS setstripe -c 2 -i 0 $MOUNT
2781         pool_add $pool || error "pool_add failed"
2782         pool_add_targets $pool $ostrange ||
2783                 error "pool_add_targets failed"
2784         test_mkdir $DIR/$tdir
2785         $LFS setstripe -p $pool $DIR/$tdir
2786         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2787         $LFS getstripe $DIR/$tdir/$tfile
2788 }
2789 run_test 27I "check that root dir striping does not break parent dir one"
2790
2791 test_27J() {
2792         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2793                 skip "Need MDS version newer than 2.12.51"
2794
2795         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2796         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2797         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2798            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2799                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2800
2801         test_mkdir $DIR/$tdir
2802         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2803         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2804
2805         # create foreign file (raw way)
2806         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2807                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2808
2809         ! $LFS setstripe --foreign --flags foo \
2810                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2811                         error "creating $tfile with '--flags foo' should fail"
2812
2813         ! $LFS setstripe --foreign --flags 0xffffffff \
2814                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2815                         error "creating $tfile w/ 0xffffffff flags should fail"
2816
2817         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2818                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2819
2820         # verify foreign file (raw way)
2821         parse_foreign_file -f $DIR/$tdir/$tfile |
2822                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2823                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2824         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2825                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2826         parse_foreign_file -f $DIR/$tdir/$tfile |
2827                 grep "lov_foreign_size: 73" ||
2828                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2829         parse_foreign_file -f $DIR/$tdir/$tfile |
2830                 grep "lov_foreign_type: 1" ||
2831                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2832         parse_foreign_file -f $DIR/$tdir/$tfile |
2833                 grep "lov_foreign_flags: 0x0000DA08" ||
2834                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2835         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2836                 grep "lov_foreign_value: 0x" |
2837                 sed -e 's/lov_foreign_value: 0x//')
2838         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2839         [[ $lov = ${lov2// /} ]] ||
2840                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2841
2842         # create foreign file (lfs + API)
2843         $LFS setstripe --foreign=none --flags 0xda08 \
2844                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2845                 error "$DIR/$tdir/${tfile}2: create failed"
2846
2847         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2848                 grep "lfm_magic:.*0x0BD70BD0" ||
2849                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2850         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2851         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2852                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2853         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2854                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2855         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2856                 grep "lfm_flags:.*0x0000DA08" ||
2857                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2858         $LFS getstripe $DIR/$tdir/${tfile}2 |
2859                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2860                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2861
2862         # modify striping should fail
2863         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2864                 error "$DIR/$tdir/$tfile: setstripe should fail"
2865         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2866                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2867
2868         # R/W should fail
2869         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2870         cat $DIR/$tdir/${tfile}2 &&
2871                 error "$DIR/$tdir/${tfile}2: read should fail"
2872         cat /etc/passwd > $DIR/$tdir/$tfile &&
2873                 error "$DIR/$tdir/$tfile: write should fail"
2874         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2875                 error "$DIR/$tdir/${tfile}2: write should fail"
2876
2877         # chmod should work
2878         chmod 222 $DIR/$tdir/$tfile ||
2879                 error "$DIR/$tdir/$tfile: chmod failed"
2880         chmod 222 $DIR/$tdir/${tfile}2 ||
2881                 error "$DIR/$tdir/${tfile}2: chmod failed"
2882
2883         # chown should work
2884         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2885                 error "$DIR/$tdir/$tfile: chown failed"
2886         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2887                 error "$DIR/$tdir/${tfile}2: chown failed"
2888
2889         # rename should work
2890         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2891                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2892         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2893                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2894
2895         #remove foreign file
2896         rm $DIR/$tdir/${tfile}.new ||
2897                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2898         rm $DIR/$tdir/${tfile}2.new ||
2899                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2900 }
2901 run_test 27J "basic ops on file with foreign LOV"
2902
2903 test_27K() {
2904         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2905                 skip "Need MDS version newer than 2.12.49"
2906
2907         test_mkdir $DIR/$tdir
2908         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2909         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2910
2911         # create foreign dir (raw way)
2912         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2913                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2914
2915         ! $LFS setdirstripe --foreign --flags foo \
2916                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2917                         error "creating $tdir with '--flags foo' should fail"
2918
2919         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2920                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2921                         error "creating $tdir w/ 0xffffffff flags should fail"
2922
2923         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2924                 error "create_foreign_dir FAILED"
2925
2926         # verify foreign dir (raw way)
2927         parse_foreign_dir -d $DIR/$tdir/$tdir |
2928                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2929                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2930         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2931                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2932         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2933                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2934         parse_foreign_dir -d $DIR/$tdir/$tdir |
2935                 grep "lmv_foreign_flags: 55813$" ||
2936                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2937         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2938                 grep "lmv_foreign_value: 0x" |
2939                 sed 's/lmv_foreign_value: 0x//')
2940         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2941                 sed 's/ //g')
2942         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2943
2944         # create foreign dir (lfs + API)
2945         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2946                 $DIR/$tdir/${tdir}2 ||
2947                 error "$DIR/$tdir/${tdir}2: create failed"
2948
2949         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2950
2951         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2952                 grep "lfm_magic:.*0x0CD50CD0" ||
2953                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2954         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2955         # - sizeof(lfm_type) - sizeof(lfm_flags)
2956         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2957                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2958         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2959                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2960         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2961                 grep "lfm_flags:.*0x0000DA05" ||
2962                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2963         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2964                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2965                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2966
2967         # file create in dir should fail
2968         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2969         touch $DIR/$tdir/${tdir}2/$tfile &&
2970                 error "$DIR/${tdir}2: file create should fail"
2971
2972         # chmod should work
2973         chmod 777 $DIR/$tdir/$tdir ||
2974                 error "$DIR/$tdir: chmod failed"
2975         chmod 777 $DIR/$tdir/${tdir}2 ||
2976                 error "$DIR/${tdir}2: chmod failed"
2977
2978         # chown should work
2979         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2980                 error "$DIR/$tdir: chown failed"
2981         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2982                 error "$DIR/${tdir}2: chown failed"
2983
2984         # rename should work
2985         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2986                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2987         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2988                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2989
2990         #remove foreign dir
2991         rmdir $DIR/$tdir/${tdir}.new ||
2992                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2993         rmdir $DIR/$tdir/${tdir}2.new ||
2994                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2995 }
2996 run_test 27K "basic ops on dir with foreign LMV"
2997
2998 test_27L() {
2999         remote_mds_nodsh && skip "remote MDS with nodsh"
3000
3001         local POOL=${POOL:-$TESTNAME}
3002
3003         pool_add $POOL || error "pool_add failed"
3004
3005         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3006                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3007                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3008 }
3009 run_test 27L "lfs pool_list gives correct pool name"
3010
3011 test_27M() {
3012         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3013                 skip "Need MDS version >= than 2.12.57"
3014         remote_mds_nodsh && skip "remote MDS with nodsh"
3015         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3016
3017         # Set default striping on directory
3018         local setcount=4
3019         local stripe_opt
3020         local mdts=$(comma_list $(mdts_nodes))
3021
3022         # if we run against a 2.12 server which lacks overstring support
3023         # then the connect_flag will not report overstriping, even if client
3024         # is 2.14+
3025         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3026                 stripe_opt="-C $setcount"
3027         elif (( $OSTCOUNT >= $setcount )); then
3028                 stripe_opt="-c $setcount"
3029         else
3030                 skip "server does not support overstriping"
3031         fi
3032
3033         test_mkdir $DIR/$tdir
3034
3035         # Validate existing append_* params and ensure restore
3036         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3037         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3038         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3039
3040         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3041         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3042         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3043
3044         $LFS setstripe $stripe_opt $DIR/$tdir
3045
3046         echo 1 > $DIR/$tdir/${tfile}.1
3047         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3048         (( $count == $setcount )) ||
3049                 error "(1) stripe count $count, should be $setcount"
3050
3051         local appendcount=$orig_count
3052         echo 1 >> $DIR/$tdir/${tfile}.2_append
3053         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3054         (( $count == $appendcount )) ||
3055                 error "(2)stripe count $count, should be $appendcount for append"
3056
3057         # Disable O_APPEND striping, verify it works
3058         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3059
3060         # Should now get the default striping, which is 4
3061         setcount=4
3062         echo 1 >> $DIR/$tdir/${tfile}.3_append
3063         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3064         (( $count == $setcount )) ||
3065                 error "(3) stripe count $count, should be $setcount"
3066
3067         # Try changing the stripe count for append files
3068         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3069
3070         # Append striping is now 2 (directory default is still 4)
3071         appendcount=2
3072         echo 1 >> $DIR/$tdir/${tfile}.4_append
3073         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3074         (( $count == $appendcount )) ||
3075                 error "(4) stripe count $count, should be $appendcount for append"
3076
3077         # Test append stripe count of -1
3078         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3079         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3080                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3081                 touch $DIR/$tdir/$tfile.specific.{1..128}
3082         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3083
3084         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3085         appendcount=$OSTCOUNT
3086         echo 1 >> $DIR/$tdir/${tfile}.5
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3088         (( $count == $appendcount )) ||
3089                 error "(5) stripe count $count, should be $appendcount for append"
3090
3091         # Set append striping back to default of 1
3092         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3093
3094         # Try a new default striping, PFL + DOM
3095         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3096
3097         # Create normal DOM file, DOM returns stripe count == 0
3098         setcount=0
3099         touch $DIR/$tdir/${tfile}.6
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3101         (( $count == $setcount )) ||
3102                 error "(6) stripe count $count, should be $setcount"
3103
3104         # Show
3105         appendcount=1
3106         echo 1 >> $DIR/$tdir/${tfile}.7_append
3107         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3108         (( $count == $appendcount )) ||
3109                 error "(7) stripe count $count, should be $appendcount for append"
3110
3111         # Clean up DOM layout
3112         $LFS setstripe -d $DIR/$tdir
3113
3114         save_layout_restore_at_exit $MOUNT
3115         # Now test that append striping works when layout is from root
3116         $LFS setstripe -c 2 $MOUNT
3117         # Make a special directory for this
3118         mkdir $DIR/${tdir}/${tdir}.2
3119
3120         # Verify for normal file
3121         setcount=2
3122         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3123         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3124         (( $count == $setcount )) ||
3125                 error "(8) stripe count $count, should be $setcount"
3126
3127         appendcount=1
3128         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3129         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3130         (( $count == $appendcount )) ||
3131                 error "(9) stripe count $count, should be $appendcount for append"
3132
3133         # Now test O_APPEND striping with pools
3134         pool_add $TESTNAME || error "pool creation failed"
3135         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3136         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3137
3138         echo 1 >> $DIR/$tdir/${tfile}.10_append
3139
3140         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3141         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3142
3143         # Check that count is still correct
3144         appendcount=1
3145         echo 1 >> $DIR/$tdir/${tfile}.11_append
3146         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3147         (( $count == $appendcount )) ||
3148                 error "(11) stripe count $count, should be $appendcount for append"
3149
3150         # Disable O_APPEND stripe count, verify pool works separately
3151         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3152
3153         echo 1 >> $DIR/$tdir/${tfile}.12_append
3154
3155         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3156         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3157
3158         # Remove pool setting, verify it's not applied
3159         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3160
3161         echo 1 >> $DIR/$tdir/${tfile}.13_append
3162
3163         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3164         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3165 }
3166 run_test 27M "test O_APPEND striping"
3167
3168 test_27N() {
3169         combined_mgs_mds && skip "needs separate MGS/MDT"
3170
3171         pool_add $TESTNAME || error "pool_add failed"
3172         do_facet mgs "$LCTL pool_list $FSNAME" |
3173                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3174                 error "lctl pool_list on MGS failed"
3175 }
3176 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3177
3178 clean_foreign_symlink() {
3179         trap 0
3180         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3181         for i in $DIR/$tdir/* ; do
3182                 $LFS unlink_foreign $i || true
3183         done
3184 }
3185
3186 test_27O() {
3187         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3188                 skip "Need MDS version newer than 2.12.51"
3189
3190         test_mkdir $DIR/$tdir
3191         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3192         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3193
3194         trap clean_foreign_symlink EXIT
3195
3196         # enable foreign_symlink behaviour
3197         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3198
3199         # foreign symlink LOV format is a partial path by default
3200
3201         # create foreign file (lfs + API)
3202         $LFS setstripe --foreign=symlink --flags 0xda05 \
3203                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}: create failed"
3205
3206         $LFS getstripe -v $DIR/$tdir/${tfile} |
3207                 grep "lfm_magic:.*0x0BD70BD0" ||
3208                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3209         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3210                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3211         $LFS getstripe -v $DIR/$tdir/${tfile} |
3212                 grep "lfm_flags:.*0x0000DA05" ||
3213                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3214         $LFS getstripe $DIR/$tdir/${tfile} |
3215                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3216                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3217
3218         # modify striping should fail
3219         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3220                 error "$DIR/$tdir/$tfile: setstripe should fail"
3221
3222         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3223         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3224         cat /etc/passwd > $DIR/$tdir/$tfile &&
3225                 error "$DIR/$tdir/$tfile: write should fail"
3226
3227         # rename should succeed
3228         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3229                 error "$DIR/$tdir/$tfile: rename has failed"
3230
3231         #remove foreign_symlink file should fail
3232         rm $DIR/$tdir/${tfile}.new &&
3233                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3234
3235         #test fake symlink
3236         mkdir /tmp/${uuid1} ||
3237                 error "/tmp/${uuid1}: mkdir has failed"
3238         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3239                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3240         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3241         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3242                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3243         #read should succeed now
3244         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3245                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3246         #write should succeed now
3247         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3248                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3249         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3250                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3251         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3252                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3253
3254         #check that getstripe still works
3255         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3256                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3257
3258         # chmod should still succeed
3259         chmod 644 $DIR/$tdir/${tfile}.new ||
3260                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3261
3262         # chown should still succeed
3263         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3264                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3265
3266         # rename should still succeed
3267         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3268                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3269
3270         #remove foreign_symlink file should still fail
3271         rm $DIR/$tdir/${tfile} &&
3272                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3273
3274         #use special ioctl() to unlink foreign_symlink file
3275         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3276                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3277
3278 }
3279 run_test 27O "basic ops on foreign file of symlink type"
3280
3281 test_27P() {
3282         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3283                 skip "Need MDS version newer than 2.12.49"
3284
3285         test_mkdir $DIR/$tdir
3286         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3287         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3288
3289         trap clean_foreign_symlink EXIT
3290
3291         # enable foreign_symlink behaviour
3292         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3293
3294         # foreign symlink LMV format is a partial path by default
3295
3296         # create foreign dir (lfs + API)
3297         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3298                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3299                 error "$DIR/$tdir/${tdir}: create failed"
3300
3301         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3302
3303         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3304                 grep "lfm_magic:.*0x0CD50CD0" ||
3305                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3306         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3307                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3308         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3309                 grep "lfm_flags:.*0x0000DA05" ||
3310                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3311         $LFS getdirstripe $DIR/$tdir/${tdir} |
3312                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3313                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3314
3315         # file create in dir should fail
3316         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3317         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3318
3319         # rename should succeed
3320         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3321                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3322
3323         #remove foreign_symlink dir should fail
3324         rmdir $DIR/$tdir/${tdir}.new &&
3325                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3326
3327         #test fake symlink
3328         mkdir -p /tmp/${uuid1}/${uuid2} ||
3329                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3330         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3331                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3332         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3333         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3334                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3335         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3336                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3337
3338         #check that getstripe fails now that foreign_symlink enabled
3339         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3340                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3341
3342         # file create in dir should work now
3343         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3344                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3345         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3346                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3347         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3348                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3349
3350         # chmod should still succeed
3351         chmod 755 $DIR/$tdir/${tdir}.new ||
3352                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3353
3354         # chown should still succeed
3355         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3356                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3357
3358         # rename should still succeed
3359         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3360                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3361
3362         #remove foreign_symlink dir should still fail
3363         rmdir $DIR/$tdir/${tdir} &&
3364                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3365
3366         #use special ioctl() to unlink foreign_symlink file
3367         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3368                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3369
3370         #created file should still exist
3371         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3372                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3373         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3374                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3375 }
3376 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3377
3378 test_27Q() {
3379         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3380         stack_trap "rm -f $TMP/$tfile*"
3381
3382         test_mkdir $DIR/$tdir-1
3383         test_mkdir $DIR/$tdir-2
3384
3385         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3386         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3387
3388         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3389         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3390
3391         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3392         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3393
3394         # Create some bad symlinks and ensure that we don't loop
3395         # forever or something. These should return ELOOP (40) and
3396         # ENOENT (2) but I don't want to test for that because there's
3397         # always some weirdo architecture that needs to ruin
3398         # everything by defining these error numbers differently.
3399
3400         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3401         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3402
3403         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3404         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3405
3406         return 0
3407 }
3408 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3409
3410 test_27R() {
3411         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3412                 skip "need MDS 2.14.55 or later"
3413         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3414
3415         local testdir="$DIR/$tdir"
3416         test_mkdir -p $testdir
3417         stack_trap "rm -rf $testdir"
3418         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3419
3420         local f1="$testdir/f1"
3421         touch $f1 || error "failed to touch $f1"
3422         local count=$($LFS getstripe -c $f1)
3423         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3424
3425         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3426         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3427
3428         local maxcount=$(($OSTCOUNT - 1))
3429         local mdts=$(comma_list $(mdts_nodes))
3430         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3431         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3432
3433         local f2="$testdir/f2"
3434         touch $f2 || error "failed to touch $f2"
3435         local count=$($LFS getstripe -c $f2)
3436         (( $count == $maxcount )) || error "wrong stripe count"
3437 }
3438 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3439
3440 test_27T() {
3441         [ $(facet_host client) == $(facet_host ost1) ] &&
3442                 skip "need ost1 and client on different nodes"
3443
3444 #define OBD_FAIL_OSC_NO_GRANT            0x411
3445         $LCTL set_param fail_loc=0x20000411 fail_val=1
3446 #define OBD_FAIL_OST_ENOSPC              0x215
3447         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3448         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3449         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3450                 error "multiop failed"
3451 }
3452 run_test 27T "no eio on close on partial write due to enosp"
3453
3454 test_27U() {
3455         local dir=$DIR/$tdir
3456         local file=$dir/$tfile
3457         local append_pool=${TESTNAME}-append
3458         local normal_pool=${TESTNAME}-normal
3459         local pool
3460         local stripe_count
3461         local stripe_count2
3462         local mdts=$(comma_list $(mdts_nodes))
3463
3464         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3465                 skip "Need MDS version at least 2.15.51 for append pool feature"
3466
3467         # Validate existing append_* params and ensure restore
3468         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3469         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3470         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3471
3472         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3473         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3474         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3475
3476         pool_add $append_pool || error "pool creation failed"
3477         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3478
3479         pool_add $normal_pool || error "pool creation failed"
3480         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3481
3482         test_mkdir $dir
3483         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3484
3485         echo XXX >> $file.1
3486         $LFS getstripe $file.1
3487
3488         pool=$($LFS getstripe -p $file.1)
3489         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3490
3491         stripe_count2=$($LFS getstripe -c $file.1)
3492         ((stripe_count2 == stripe_count)) ||
3493                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3494
3495         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3496
3497         echo XXX >> $file.2
3498         $LFS getstripe $file.2
3499
3500         pool=$($LFS getstripe -p $file.2)
3501         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3502
3503         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3504
3505         echo XXX >> $file.3
3506         $LFS getstripe $file.3
3507
3508         stripe_count2=$($LFS getstripe -c $file.3)
3509         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3510 }
3511 run_test 27U "append pool and stripe count work with composite default layout"
3512
3513 test_27V() {
3514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3515         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3516
3517         local dir=$DIR/$tdir
3518         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3519         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3520         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3521         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3522         local pid
3523
3524         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3525
3526         do_facet mds1 $LCTL set_param $lod_param=0
3527         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3528
3529         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3530         stack_trap "rm -rf $dir"
3531
3532         # exercise race in LU-16981 with deactivating OST while creating a file
3533         (
3534                 while true; do
3535                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3536                         sleep 0.1
3537                         do_facet mds1 \
3538                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3539                 done
3540         ) &
3541
3542         pid=$!
3543         stack_trap "kill -9 $pid"
3544
3545         # errors here are OK so ignore them (just don't want to crash)
3546         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3547
3548         return 0
3549 }
3550 run_test 27V "creating widely striped file races with deactivating OST"
3551
3552 # createtest also checks that device nodes are created and
3553 # then visible correctly (#2091)
3554 test_28() { # bug 2091
3555         test_mkdir $DIR/d28
3556         $CREATETEST $DIR/d28/ct || error "createtest failed"
3557 }
3558 run_test 28 "create/mknod/mkdir with bad file types ============"
3559
3560 test_29() {
3561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3562
3563         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3564                 disable_opencache
3565                 stack_trap "restore_opencache"
3566         }
3567
3568         sync; sleep 1; sync # flush out any dirty pages from previous tests
3569         cancel_lru_locks
3570         test_mkdir $DIR/d29
3571         touch $DIR/d29/foo
3572         log 'first d29'
3573         ls -l $DIR/d29
3574
3575         local locks_orig=$(total_used_locks mdc)
3576         (( $locks_orig != 0 )) || error "No mdc lock count"
3577
3578         local locks_unused_orig=$(total_unused_locks mdc)
3579
3580         log 'second d29'
3581         ls -l $DIR/d29
3582         log 'done'
3583
3584         local locks_current=$(total_used_locks mdc)
3585
3586         local locks_unused_current=$(total_unused_locks mdc)
3587
3588         if (( $locks_current > $locks_orig )); then
3589                 $LCTL set_param -n ldlm.dump_namespaces ""
3590                 error "CURRENT: $locks_current > $locks_orig"
3591         fi
3592         if (( $locks_unused_current > $locks_unused_orig )); then
3593                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3594         fi
3595 }
3596 run_test 29 "IT_GETATTR regression  ============================"
3597
3598 test_30a() { # was test_30
3599         cp $(which ls) $DIR || cp /bin/ls $DIR
3600         $DIR/ls / || error "Can't execute binary from lustre"
3601         rm $DIR/ls
3602 }
3603 run_test 30a "execute binary from Lustre (execve) =============="
3604
3605 test_30b() {
3606         cp `which ls` $DIR || cp /bin/ls $DIR
3607         chmod go+rx $DIR/ls
3608         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3609         rm $DIR/ls
3610 }
3611 run_test 30b "execute binary from Lustre as non-root ==========="
3612
3613 test_30c() { # b=22376
3614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3615
3616         cp $(which ls) $DIR || cp /bin/ls $DIR
3617         chmod a-rw $DIR/ls
3618         cancel_lru_locks mdc
3619         cancel_lru_locks osc
3620         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3621         rm -f $DIR/ls
3622 }
3623 run_test 30c "execute binary from Lustre without read perms ===="
3624
3625 test_30d() {
3626         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3627
3628         for i in {1..10}; do
3629                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3630                 local PID=$!
3631                 sleep 1
3632                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3633                 wait $PID || error "executing dd from Lustre failed"
3634                 rm -f $DIR/$tfile
3635         done
3636
3637         rm -f $DIR/dd
3638 }
3639 run_test 30d "execute binary from Lustre while clear locks"
3640
3641 test_31a() {
3642         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3643         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3644 }
3645 run_test 31a "open-unlink file =================================="
3646
3647 test_31b() {
3648         touch $DIR/f31 || error "touch $DIR/f31 failed"
3649         ln $DIR/f31 $DIR/f31b || error "ln failed"
3650         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3651         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3652 }
3653 run_test 31b "unlink file with multiple links while open ======="
3654
3655 test_31c() {
3656         touch $DIR/f31 || error "touch $DIR/f31 failed"
3657         ln $DIR/f31 $DIR/f31c || error "ln failed"
3658         multiop_bg_pause $DIR/f31 O_uc ||
3659                 error "multiop_bg_pause for $DIR/f31 failed"
3660         MULTIPID=$!
3661         $MULTIOP $DIR/f31c Ouc
3662         kill -USR1 $MULTIPID
3663         wait $MULTIPID
3664 }
3665 run_test 31c "open-unlink file with multiple links ============="
3666
3667 test_31d() {
3668         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3669         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3670 }
3671 run_test 31d "remove of open directory ========================="
3672
3673 test_31e() { # bug 2904
3674         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3675 }
3676 run_test 31e "remove of open non-empty directory ==============="
3677
3678 test_31f() { # bug 4554
3679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3680
3681         set -vx
3682         test_mkdir $DIR/d31f
3683         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3684         cp /etc/hosts $DIR/d31f
3685         ls -l $DIR/d31f
3686         $LFS getstripe $DIR/d31f/hosts
3687         multiop_bg_pause $DIR/d31f D_c || return 1
3688         MULTIPID=$!
3689
3690         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3691         test_mkdir $DIR/d31f
3692         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3693         cp /etc/hosts $DIR/d31f
3694         ls -l $DIR/d31f
3695         $LFS getstripe $DIR/d31f/hosts
3696         multiop_bg_pause $DIR/d31f D_c || return 1
3697         MULTIPID2=$!
3698
3699         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3700         wait $MULTIPID || error "first opendir $MULTIPID failed"
3701
3702         sleep 6
3703
3704         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3705         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3706         set +vx
3707 }
3708 run_test 31f "remove of open directory with open-unlink file ==="
3709
3710 test_31g() {
3711         echo "-- cross directory link --"
3712         test_mkdir -c1 $DIR/${tdir}ga
3713         test_mkdir -c1 $DIR/${tdir}gb
3714         touch $DIR/${tdir}ga/f
3715         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3716         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3717         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3718         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3719         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3720 }
3721 run_test 31g "cross directory link==============="
3722
3723 test_31h() {
3724         echo "-- cross directory link --"
3725         test_mkdir -c1 $DIR/${tdir}
3726         test_mkdir -c1 $DIR/${tdir}/dir
3727         touch $DIR/${tdir}/f
3728         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3729         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3730         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3731         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3732         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3733 }
3734 run_test 31h "cross directory link under child==============="
3735
3736 test_31i() {
3737         echo "-- cross directory link --"
3738         test_mkdir -c1 $DIR/$tdir
3739         test_mkdir -c1 $DIR/$tdir/dir
3740         touch $DIR/$tdir/dir/f
3741         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3742         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3743         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3744         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3745         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3746 }
3747 run_test 31i "cross directory link under parent==============="
3748
3749 test_31j() {
3750         test_mkdir -c1 -p $DIR/$tdir
3751         test_mkdir -c1 -p $DIR/$tdir/dir1
3752         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3753         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3754         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3755         return 0
3756 }
3757 run_test 31j "link for directory"
3758
3759 test_31k() {
3760         test_mkdir -c1 -p $DIR/$tdir
3761         touch $DIR/$tdir/s
3762         touch $DIR/$tdir/exist
3763         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3764         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3765         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3766         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3767         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3768         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3769         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3770         return 0
3771 }
3772 run_test 31k "link to file: the same, non-existing, dir"
3773
3774 test_31l() {
3775         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3776
3777         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3778         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3779                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3780
3781         touch $DIR/$tfile || error "create failed"
3782         mkdir $DIR/$tdir || error "mkdir failed"
3783         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3784 }
3785 run_test 31l "link to file: target dir has trailing slash"
3786
3787 test_31m() {
3788         mkdir $DIR/d31m
3789         touch $DIR/d31m/s
3790         mkdir $DIR/d31m2
3791         touch $DIR/d31m2/exist
3792         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3793         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3794         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3795         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3796         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3797         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3798         return 0
3799 }
3800 run_test 31m "link to file: the same, non-existing, dir"
3801
3802 test_31n() {
3803         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3804         nlink=$(stat --format=%h $DIR/$tfile)
3805         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3806         local fd=$(free_fd)
3807         local cmd="exec $fd<$DIR/$tfile"
3808         eval $cmd
3809         cmd="exec $fd<&-"
3810         trap "eval $cmd" EXIT
3811         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3812         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3813         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3814         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3815         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3816         eval $cmd
3817 }
3818 run_test 31n "check link count of unlinked file"
3819
3820 link_one() {
3821         local tempfile=$(mktemp $1_XXXXXX)
3822         link $tempfile $1 2> /dev/null &&
3823                 echo "$BASHPID: link $tempfile to $1 succeeded"
3824         unlink $tempfile
3825 }
3826
3827 test_31o() { # LU-2901
3828         test_mkdir $DIR/$tdir
3829         for LOOP in $(seq 100); do
3830                 rm -f $DIR/$tdir/$tfile*
3831                 for THREAD in $(seq 8); do
3832                         link_one $DIR/$tdir/$tfile.$LOOP &
3833                 done
3834                 wait
3835                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3836                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3837                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3838                         break || true
3839         done
3840 }
3841 run_test 31o "duplicate hard links with same filename"
3842
3843 test_31p() {
3844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3845
3846         test_mkdir $DIR/$tdir
3847         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3848         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3849
3850         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3851                 error "open unlink test1 failed"
3852         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3853                 error "open unlink test2 failed"
3854
3855         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3856                 error "test1 still exists"
3857         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3858                 error "test2 still exists"
3859 }
3860 run_test 31p "remove of open striped directory"
3861
3862 test_31q() {
3863         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3864
3865         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3866         index=$($LFS getdirstripe -i $DIR/$tdir)
3867         [ $index -eq 3 ] || error "first stripe index $index != 3"
3868         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3869         [ $index -eq 1 ] || error "second stripe index $index != 1"
3870
3871         # when "-c <stripe_count>" is set, the number of MDTs specified after
3872         # "-i" should equal to the stripe count
3873         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3874 }
3875 run_test 31q "create striped directory on specific MDTs"
3876
3877 #LU-14949
3878 test_31r() {
3879         touch $DIR/$tfile.target
3880         touch $DIR/$tfile.source
3881
3882         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3883         $LCTL set_param fail_loc=0x1419 fail_val=3
3884         cat $DIR/$tfile.target &
3885         CATPID=$!
3886
3887         # Guarantee open is waiting before we get here
3888         sleep 1
3889         mv $DIR/$tfile.source $DIR/$tfile.target
3890
3891         wait $CATPID
3892         RC=$?
3893         if [[ $RC -ne 0 ]]; then
3894                 error "open with cat failed, rc=$RC"
3895         fi
3896 }
3897 run_test 31r "open-rename(replace) race"
3898
3899 cleanup_test32_mount() {
3900         local rc=0
3901         trap 0
3902         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3903         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3904         losetup -d $loopdev || true
3905         rm -rf $DIR/$tdir
3906         return $rc
3907 }
3908
3909 test_32a() {
3910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3911
3912         echo "== more mountpoints and symlinks ================="
3913         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3914         trap cleanup_test32_mount EXIT
3915         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3916         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3917                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3918         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3919                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3920         cleanup_test32_mount
3921 }
3922 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3923
3924 test_32b() {
3925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3926
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3933                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3934         cleanup_test32_mount
3935 }
3936 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3937
3938 test_32c() {
3939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3940
3941         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3942         trap cleanup_test32_mount EXIT
3943         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3944         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3945                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3946         test_mkdir -p $DIR/$tdir/d2/test_dir
3947         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3948                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3949         cleanup_test32_mount
3950 }
3951 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3952
3953 test_32d() {
3954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3955
3956         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3957         trap cleanup_test32_mount EXIT
3958         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3959         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3960                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3961         test_mkdir -p $DIR/$tdir/d2/test_dir
3962         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3963                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3964         cleanup_test32_mount
3965 }
3966 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3967
3968 test_32e() {
3969         rm -fr $DIR/$tdir
3970         test_mkdir -p $DIR/$tdir/tmp
3971         local tmp_dir=$DIR/$tdir/tmp
3972         ln -s $DIR/$tdir $tmp_dir/symlink11
3973         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3974         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3975         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3976 }
3977 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3978
3979 test_32f() {
3980         rm -fr $DIR/$tdir
3981         test_mkdir -p $DIR/$tdir/tmp
3982         local tmp_dir=$DIR/$tdir/tmp
3983         ln -s $DIR/$tdir $tmp_dir/symlink11
3984         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3985         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3986         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3987 }
3988 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3989
3990 test_32g() {
3991         local tmp_dir=$DIR/$tdir/tmp
3992         test_mkdir -p $tmp_dir
3993         test_mkdir $DIR/${tdir}2
3994         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3995         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3996         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3997         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3998         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3999         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4000 }
4001 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4002
4003 test_32h() {
4004         rm -fr $DIR/$tdir $DIR/${tdir}2
4005         tmp_dir=$DIR/$tdir/tmp
4006         test_mkdir -p $tmp_dir
4007         test_mkdir $DIR/${tdir}2
4008         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4009         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4010         ls $tmp_dir/symlink12 || error "listing symlink12"
4011         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4012 }
4013 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4014
4015 test_32i() {
4016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4017
4018         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4019         trap cleanup_test32_mount EXIT
4020         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4021         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4022                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4023         touch $DIR/$tdir/test_file
4024         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4025                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4026         cleanup_test32_mount
4027 }
4028 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4029
4030 test_32j() {
4031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4032
4033         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4034         trap cleanup_test32_mount EXIT
4035         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4036         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4037                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4038         touch $DIR/$tdir/test_file
4039         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4040                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4041         cleanup_test32_mount
4042 }
4043 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4044
4045 test_32k() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4052                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4053         test_mkdir -p $DIR/$tdir/d2
4054         touch $DIR/$tdir/d2/test_file || error "touch failed"
4055         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4056                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4057         cleanup_test32_mount
4058 }
4059 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4060
4061 test_32l() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         rm -fr $DIR/$tdir
4065         trap cleanup_test32_mount EXIT
4066         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4067         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4068                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4069         test_mkdir -p $DIR/$tdir/d2
4070         touch $DIR/$tdir/d2/test_file || error "touch failed"
4071         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4072                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4073         cleanup_test32_mount
4074 }
4075 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4076
4077 test_32m() {
4078         rm -fr $DIR/d32m
4079         test_mkdir -p $DIR/d32m/tmp
4080         TMP_DIR=$DIR/d32m/tmp
4081         ln -s $DIR $TMP_DIR/symlink11
4082         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4083         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4084                 error "symlink11 not a link"
4085         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4086                 error "symlink01 not a link"
4087 }
4088 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4089
4090 test_32n() {
4091         rm -fr $DIR/d32n
4092         test_mkdir -p $DIR/d32n/tmp
4093         TMP_DIR=$DIR/d32n/tmp
4094         ln -s $DIR $TMP_DIR/symlink11
4095         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4096         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4097         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4098 }
4099 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4100
4101 test_32o() {
4102         touch $DIR/$tfile
4103         test_mkdir -p $DIR/d32o/tmp
4104         TMP_DIR=$DIR/d32o/tmp
4105         ln -s $DIR/$tfile $TMP_DIR/symlink12
4106         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4107         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4108                 error "symlink12 not a link"
4109         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4110         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4111                 error "$DIR/d32o/tmp/symlink12 not file type"
4112         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4113                 error "$DIR/d32o/symlink02 not file type"
4114 }
4115 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4116
4117 test_32p() {
4118         log 32p_1
4119         rm -fr $DIR/d32p
4120         log 32p_2
4121         rm -f $DIR/$tfile
4122         log 32p_3
4123         touch $DIR/$tfile
4124         log 32p_4
4125         test_mkdir -p $DIR/d32p/tmp
4126         log 32p_5
4127         TMP_DIR=$DIR/d32p/tmp
4128         log 32p_6
4129         ln -s $DIR/$tfile $TMP_DIR/symlink12
4130         log 32p_7
4131         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4132         log 32p_8
4133         cat $DIR/d32p/tmp/symlink12 ||
4134                 error "Can't open $DIR/d32p/tmp/symlink12"
4135         log 32p_9
4136         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4137         log 32p_10
4138 }
4139 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4140
4141 test_32q() {
4142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4143
4144         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4145         trap cleanup_test32_mount EXIT
4146         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4147         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4148         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4149                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4150         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4151         cleanup_test32_mount
4152 }
4153 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4154
4155 test_32r() {
4156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4157
4158         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4159         trap cleanup_test32_mount EXIT
4160         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4161         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4162         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4163                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4164         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4165         cleanup_test32_mount
4166 }
4167 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4168
4169 test_33aa() {
4170         rm -f $DIR/$tfile
4171         touch $DIR/$tfile
4172         chmod 444 $DIR/$tfile
4173         chown $RUNAS_ID $DIR/$tfile
4174         log 33_1
4175         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4176         log 33_2
4177 }
4178 run_test 33aa "write file with mode 444 (should return error)"
4179
4180 test_33a() {
4181         rm -fr $DIR/$tdir
4182         test_mkdir $DIR/$tdir
4183         chown $RUNAS_ID $DIR/$tdir
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4185                 error "$RUNAS create $tdir/$tfile failed"
4186         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4187                 error "open RDWR" || true
4188 }
4189 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4190
4191 test_33b() {
4192         rm -fr $DIR/$tdir
4193         test_mkdir $DIR/$tdir
4194         chown $RUNAS_ID $DIR/$tdir
4195         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4196 }
4197 run_test 33b "test open file with malformed flags (No panic)"
4198
4199 test_33c() {
4200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4201         remote_ost_nodsh && skip "remote OST with nodsh"
4202
4203         local ostnum
4204         local ostname
4205         local write_bytes
4206         local all_zeros
4207
4208         all_zeros=true
4209         test_mkdir $DIR/$tdir
4210         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4211
4212         sync
4213         for ostnum in $(seq $OSTCOUNT); do
4214                 # test-framework's OST numbering is one-based, while Lustre's
4215                 # is zero-based
4216                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4217                 # check if at least some write_bytes stats are counted
4218                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4219                               obdfilter.$ostname.stats |
4220                               awk '/^write_bytes/ {print $7}' )
4221                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4222                 if (( ${write_bytes:-0} > 0 )); then
4223                         all_zeros=false
4224                         break
4225                 fi
4226         done
4227
4228         $all_zeros || return 0
4229
4230         # Write four bytes
4231         echo foo > $DIR/$tdir/bar
4232         # Really write them
4233         sync
4234
4235         # Total up write_bytes after writing.  We'd better find non-zeros.
4236         for ostnum in $(seq $OSTCOUNT); do
4237                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4238                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4239                               obdfilter/$ostname/stats |
4240                               awk '/^write_bytes/ {print $7}' )
4241                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4242                 if (( ${write_bytes:-0} > 0 )); then
4243                         all_zeros=false
4244                         break
4245                 fi
4246         done
4247
4248         if $all_zeros; then
4249                 for ostnum in $(seq $OSTCOUNT); do
4250                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4251                         echo "Check write_bytes is in obdfilter.*.stats:"
4252                         do_facet ost$ostnum lctl get_param -n \
4253                                 obdfilter.$ostname.stats
4254                 done
4255                 error "OST not keeping write_bytes stats (b=22312)"
4256         fi
4257 }
4258 run_test 33c "test write_bytes stats"
4259
4260 test_33d() {
4261         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4263
4264         local MDTIDX=1
4265         local remote_dir=$DIR/$tdir/remote_dir
4266
4267         test_mkdir $DIR/$tdir
4268         $LFS mkdir -i $MDTIDX $remote_dir ||
4269                 error "create remote directory failed"
4270
4271         touch $remote_dir/$tfile
4272         chmod 444 $remote_dir/$tfile
4273         chown $RUNAS_ID $remote_dir/$tfile
4274
4275         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4276
4277         chown $RUNAS_ID $remote_dir
4278         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4279                                         error "create" || true
4280         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4281                                     error "open RDWR" || true
4282         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4283 }
4284 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4285
4286 test_33e() {
4287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4288
4289         mkdir $DIR/$tdir
4290
4291         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4292         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4293         mkdir $DIR/$tdir/local_dir
4294
4295         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4296         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4297         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4298
4299         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4300                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4301
4302         rmdir $DIR/$tdir/* || error "rmdir failed"
4303
4304         umask 777
4305         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4306         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4307         mkdir $DIR/$tdir/local_dir
4308
4309         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4310         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4311         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4312
4313         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4314                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4315
4316         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4317
4318         umask 000
4319         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4320         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4321         mkdir $DIR/$tdir/local_dir
4322
4323         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4324         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4325         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4326
4327         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4328                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4329 }
4330 run_test 33e "mkdir and striped directory should have same mode"
4331
4332 cleanup_33f() {
4333         trap 0
4334         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4335 }
4336
4337 test_33f() {
4338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4339         remote_mds_nodsh && skip "remote MDS with nodsh"
4340
4341         mkdir $DIR/$tdir
4342         chmod go+rwx $DIR/$tdir
4343         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4344         trap cleanup_33f EXIT
4345
4346         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4347                 error "cannot create striped directory"
4348
4349         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4350                 error "cannot create files in striped directory"
4351
4352         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4353                 error "cannot remove files in striped directory"
4354
4355         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4356                 error "cannot remove striped directory"
4357
4358         cleanup_33f
4359 }
4360 run_test 33f "nonroot user can create, access, and remove a striped directory"
4361
4362 test_33g() {
4363         mkdir -p $DIR/$tdir/dir2
4364
4365         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4366         echo $err
4367         [[ $err =~ "exists" ]] || error "Not exists error"
4368 }
4369 run_test 33g "nonroot user create already existing root created file"
4370
4371 sub_33h() {
4372         local hash_type=$1
4373         local count=250
4374
4375         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4376                 error "lfs mkdir -H $hash_type $tdir failed"
4377         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4378
4379         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4380         local index2
4381         local fname
4382
4383         for fname in $DIR/$tdir/$tfile.bak \
4384                      $DIR/$tdir/$tfile.SAV \
4385                      $DIR/$tdir/$tfile.orig \
4386                      $DIR/$tdir/$tfile~; do
4387                 touch $fname || error "touch $fname failed"
4388                 index2=$($LFS getstripe -m $fname)
4389                 (( $index == $index2 )) ||
4390                         error "$fname MDT index mismatch $index != $index2"
4391         done
4392
4393         local failed=0
4394         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4395         local pattern
4396
4397         for pattern in ${patterns[*]}; do
4398                 echo "pattern $pattern"
4399                 fname=$DIR/$tdir/$pattern
4400                 for (( i = 0; i < $count; i++ )); do
4401                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4402                                 error "mktemp $DIR/$tdir/$pattern failed"
4403                         index2=$($LFS getstripe -m $fname)
4404                         (( $index == $index2 )) && continue
4405
4406                         failed=$((failed + 1))
4407                         echo "$fname MDT index mismatch $index != $index2"
4408                 done
4409         done
4410
4411         echo "$failed/$count MDT index mismatches, expect ~2-4"
4412         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4413
4414         local same=0
4415         local expect
4416
4417         # verify that "crush" is still broken with all files on same MDT,
4418         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4419         [[ "$hash_type" == "crush" ]] && expect=$count ||
4420                 expect=$((count / MDSCOUNT))
4421
4422         # crush2 doesn't put all-numeric suffixes on the same MDT,
4423         # filename like $tfile.12345678 should *not* be considered temp
4424         for pattern in ${patterns[*]}; do
4425                 local base=${pattern%%X*}
4426                 local suff=${pattern#$base}
4427
4428                 echo "pattern $pattern"
4429                 for (( i = 0; i < $count; i++ )); do
4430                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4431                         touch $fname || 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         same=0
4446
4447         # crush2 doesn't put suffixes with special characters on the same MDT
4448         # filename like $tfile.txt.1234 should *not* be considered temp
4449         for pattern in ${patterns[*]}; do
4450                 local base=${pattern%%X*}
4451                 local suff=${pattern#$base}
4452
4453                 pattern=$base...${suff/XXX}
4454                 echo "pattern=$pattern"
4455                 for (( i = 0; i < $count; i++ )); do
4456                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4457                                 error "touch $fname failed"
4458                         index2=$($LFS getstripe -m $fname)
4459                         (( $index != $index2 )) && continue
4460
4461                         same=$((same + 1))
4462                 done
4463         done
4464
4465         # the number of "bad" hashes is random, as it depends on the random
4466         # filenames generated by "mktemp".  Allow some margin in the results.
4467         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4468         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4469            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4470                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4471 }
4472
4473 test_33h() {
4474         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4475         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4476                 skip "Need MDS version at least 2.13.50"
4477
4478         sub_33h crush
4479 }
4480 run_test 33h "temp file is located on the same MDT as target (crush)"
4481
4482 test_33hh() {
4483         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4484         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4485         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4486                 skip "Need MDS version at least 2.15.0 for crush2"
4487
4488         sub_33h crush2
4489 }
4490 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4491
4492 test_33i()
4493 {
4494         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4495
4496         local FNAME=$(str_repeat 'f' 250)
4497
4498         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4499         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4500
4501         local count
4502         local total
4503
4504         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4505
4506         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4507
4508         lctl --device %$MDC deactivate
4509         stack_trap "lctl --device %$MDC activate"
4510         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4511         total=$(\ls -l $DIR/$tdir | wc -l)
4512         # "ls -l" will list total in the first line
4513         total=$((total - 1))
4514         (( total + count == 1000 )) ||
4515                 error "ls list $total files, $count files on MDT1"
4516 }
4517 run_test 33i "striped directory can be accessed when one MDT is down"
4518
4519 test_33j() {
4520         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4521
4522         mkdir -p $DIR/$tdir/
4523
4524         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4525                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4526
4527         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4528                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4529
4530         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4531                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4532
4533         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4534                 error "-D was not specified, but still failed"
4535 }
4536 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4537
4538 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4539 test_34a() {
4540         rm -f $DIR/f34
4541         $MCREATE $DIR/f34 || error "mcreate failed"
4542         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4543                 error "getstripe failed"
4544         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4545         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4546                 error "getstripe failed"
4547         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4548                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4549 }
4550 run_test 34a "truncate file that has not been opened ==========="
4551
4552 test_34b() {
4553         [ ! -f $DIR/f34 ] && test_34a
4554         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4555                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4556         $OPENFILE -f O_RDONLY $DIR/f34
4557         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4558                 error "getstripe failed"
4559         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4560                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4561 }
4562 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4563
4564 test_34c() {
4565         [ ! -f $DIR/f34 ] && test_34a
4566         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4567                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4568         $OPENFILE -f O_RDWR $DIR/f34
4569         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4570                 error "$LFS getstripe failed"
4571         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4572                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4573 }
4574 run_test 34c "O_RDWR opening file-with-size works =============="
4575
4576 test_34d() {
4577         [ ! -f $DIR/f34 ] && test_34a
4578         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4579                 error "dd failed"
4580         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4581                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4582         rm $DIR/f34
4583 }
4584 run_test 34d "write to sparse file ============================="
4585
4586 test_34e() {
4587         rm -f $DIR/f34e
4588         $MCREATE $DIR/f34e || error "mcreate failed"
4589         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4590         $CHECKSTAT -s 1000 $DIR/f34e ||
4591                 error "Size of $DIR/f34e not equal to 1000 bytes"
4592         $OPENFILE -f O_RDWR $DIR/f34e
4593         $CHECKSTAT -s 1000 $DIR/f34e ||
4594                 error "Size of $DIR/f34e not equal to 1000 bytes"
4595 }
4596 run_test 34e "create objects, some with size and some without =="
4597
4598 test_34f() { # bug 6242, 6243
4599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4600
4601         SIZE34F=48000
4602         rm -f $DIR/f34f
4603         $MCREATE $DIR/f34f || error "mcreate failed"
4604         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4605         dd if=$DIR/f34f of=$TMP/f34f
4606         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4607         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4608         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4609         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4610         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4611 }
4612 run_test 34f "read from a file with no objects until EOF ======="
4613
4614 test_34g() {
4615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4616
4617         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4618                 error "dd failed"
4619         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4620         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4621                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4622         cancel_lru_locks osc
4623         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4624                 error "wrong size after lock cancel"
4625
4626         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4627         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4628                 error "expanding truncate failed"
4629         cancel_lru_locks osc
4630         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4631                 error "wrong expanded size after lock cancel"
4632 }
4633 run_test 34g "truncate long file ==============================="
4634
4635 test_34h() {
4636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4637
4638         local gid=10
4639         local sz=1000
4640
4641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4642         sync # Flush the cache so that multiop below does not block on cache
4643              # flush when getting the group lock
4644         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4645         MULTIPID=$!
4646
4647         # Since just timed wait is not good enough, let's do a sync write
4648         # that way we are sure enough time for a roundtrip + processing
4649         # passed + 2 seconds of extra margin.
4650         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4651         rm $DIR/${tfile}-1
4652         sleep 2
4653
4654         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4655                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4656                 kill -9 $MULTIPID
4657         fi
4658         wait $MULTIPID
4659         local nsz=`stat -c %s $DIR/$tfile`
4660         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4661 }
4662 run_test 34h "ftruncate file under grouplock should not block"
4663
4664 test_35a() {
4665         cp /bin/sh $DIR/f35a
4666         chmod 444 $DIR/f35a
4667         chown $RUNAS_ID $DIR/f35a
4668         $RUNAS $DIR/f35a && error || true
4669         rm $DIR/f35a
4670 }
4671 run_test 35a "exec file with mode 444 (should return and not leak)"
4672
4673 test_36a() {
4674         rm -f $DIR/f36
4675         utime $DIR/f36 || error "utime failed for MDS"
4676 }
4677 run_test 36a "MDS utime check (mknod, utime)"
4678
4679 test_36b() {
4680         echo "" > $DIR/f36
4681         utime $DIR/f36 || error "utime failed for OST"
4682 }
4683 run_test 36b "OST utime check (open, utime)"
4684
4685 test_36c() {
4686         rm -f $DIR/d36/f36
4687         test_mkdir $DIR/d36
4688         chown $RUNAS_ID $DIR/d36
4689         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4690 }
4691 run_test 36c "non-root MDS utime check (mknod, utime)"
4692
4693 test_36d() {
4694         [ ! -d $DIR/d36 ] && test_36c
4695         echo "" > $DIR/d36/f36
4696         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4697 }
4698 run_test 36d "non-root OST utime check (open, utime)"
4699
4700 test_36e() {
4701         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4702
4703         test_mkdir $DIR/$tdir
4704         touch $DIR/$tdir/$tfile
4705         $RUNAS utime $DIR/$tdir/$tfile &&
4706                 error "utime worked, expected failure" || true
4707 }
4708 run_test 36e "utime on non-owned file (should return error)"
4709
4710 subr_36fh() {
4711         local fl="$1"
4712         local LANG_SAVE=$LANG
4713         local LC_LANG_SAVE=$LC_LANG
4714         export LANG=C LC_LANG=C # for date language
4715
4716         DATESTR="Dec 20  2000"
4717         test_mkdir $DIR/$tdir
4718         lctl set_param fail_loc=$fl
4719         date; date +%s
4720         cp /etc/hosts $DIR/$tdir/$tfile
4721         sync & # write RPC generated with "current" inode timestamp, but delayed
4722         sleep 1
4723         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4724         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4725         cancel_lru_locks $OSC
4726         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4727         date; date +%s
4728         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4729                 echo "BEFORE: $LS_BEFORE" && \
4730                 echo "AFTER : $LS_AFTER" && \
4731                 echo "WANT  : $DATESTR" && \
4732                 error "$DIR/$tdir/$tfile timestamps changed" || true
4733
4734         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4735 }
4736
4737 test_36f() {
4738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4739
4740         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4741         subr_36fh "0x80000214"
4742 }
4743 run_test 36f "utime on file racing with OST BRW write =========="
4744
4745 test_36g() {
4746         remote_ost_nodsh && skip "remote OST with nodsh"
4747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4748         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4749                 skip "Need MDS version at least 2.12.51"
4750
4751         local fmd_max_age
4752         local fmd
4753         local facet="ost1"
4754         local tgt="obdfilter"
4755
4756         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4757
4758         test_mkdir $DIR/$tdir
4759         fmd_max_age=$(do_facet $facet \
4760                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4761                 head -n 1")
4762
4763         echo "FMD max age: ${fmd_max_age}s"
4764         touch $DIR/$tdir/$tfile
4765         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4766                 gawk '{cnt=cnt+$1}  END{print cnt}')
4767         echo "FMD before: $fmd"
4768         [[ $fmd == 0 ]] &&
4769                 error "FMD wasn't create by touch"
4770         sleep $((fmd_max_age + 12))
4771         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4772                 gawk '{cnt=cnt+$1}  END{print cnt}')
4773         echo "FMD after: $fmd"
4774         [[ $fmd == 0 ]] ||
4775                 error "FMD wasn't expired by ping"
4776 }
4777 run_test 36g "FMD cache expiry ====================="
4778
4779 test_36h() {
4780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4781
4782         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4783         subr_36fh "0x80000227"
4784 }
4785 run_test 36h "utime on file racing with OST BRW write =========="
4786
4787 test_36i() {
4788         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4789
4790         test_mkdir $DIR/$tdir
4791         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4792
4793         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4794         local new_mtime=$((mtime + 200))
4795
4796         #change Modify time of striped dir
4797         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4798                         error "change mtime failed"
4799
4800         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4801
4802         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4803 }
4804 run_test 36i "change mtime on striped directory"
4805
4806 # test_37 - duplicate with tests 32q 32r
4807
4808 test_38() {
4809         local file=$DIR/$tfile
4810         touch $file
4811         openfile -f O_DIRECTORY $file
4812         local RC=$?
4813         local ENOTDIR=20
4814         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4815         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4816 }
4817 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4818
4819 test_39a() { # was test_39
4820         touch $DIR/$tfile
4821         touch $DIR/${tfile}2
4822 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4823 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4824 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4825         sleep 2
4826         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4827         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4828                 echo "mtime"
4829                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4830                 echo "atime"
4831                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4832                 echo "ctime"
4833                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4834                 error "O_TRUNC didn't change timestamps"
4835         fi
4836 }
4837 run_test 39a "mtime changed on create"
4838
4839 test_39b() {
4840         test_mkdir -c1 $DIR/$tdir
4841         cp -p /etc/passwd $DIR/$tdir/fopen
4842         cp -p /etc/passwd $DIR/$tdir/flink
4843         cp -p /etc/passwd $DIR/$tdir/funlink
4844         cp -p /etc/passwd $DIR/$tdir/frename
4845         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4846
4847         sleep 1
4848         echo "aaaaaa" >> $DIR/$tdir/fopen
4849         echo "aaaaaa" >> $DIR/$tdir/flink
4850         echo "aaaaaa" >> $DIR/$tdir/funlink
4851         echo "aaaaaa" >> $DIR/$tdir/frename
4852
4853         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4854         local link_new=`stat -c %Y $DIR/$tdir/flink`
4855         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4856         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4857
4858         cat $DIR/$tdir/fopen > /dev/null
4859         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4860         rm -f $DIR/$tdir/funlink2
4861         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4862
4863         for (( i=0; i < 2; i++ )) ; do
4864                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4865                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4866                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4867                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4868
4869                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4870                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4871                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4872                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4873
4874                 cancel_lru_locks $OSC
4875                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4876         done
4877 }
4878 run_test 39b "mtime change on open, link, unlink, rename  ======"
4879
4880 # this should be set to past
4881 TEST_39_MTIME=`date -d "1 year ago" +%s`
4882
4883 # bug 11063
4884 test_39c() {
4885         touch $DIR1/$tfile
4886         sleep 2
4887         local mtime0=`stat -c %Y $DIR1/$tfile`
4888
4889         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4890         local mtime1=`stat -c %Y $DIR1/$tfile`
4891         [ "$mtime1" = $TEST_39_MTIME ] || \
4892                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4893
4894         local d1=`date +%s`
4895         echo hello >> $DIR1/$tfile
4896         local d2=`date +%s`
4897         local mtime2=`stat -c %Y $DIR1/$tfile`
4898         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4899                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4900
4901         mv $DIR1/$tfile $DIR1/$tfile-1
4902
4903         for (( i=0; i < 2; i++ )) ; do
4904                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4905                 [ "$mtime2" = "$mtime3" ] || \
4906                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4907
4908                 cancel_lru_locks $OSC
4909                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4910         done
4911 }
4912 run_test 39c "mtime change on rename ==========================="
4913
4914 # bug 21114
4915 test_39d() {
4916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4917
4918         touch $DIR1/$tfile
4919         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4920
4921         for (( i=0; i < 2; i++ )) ; do
4922                 local mtime=`stat -c %Y $DIR1/$tfile`
4923                 [ $mtime = $TEST_39_MTIME ] || \
4924                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4925
4926                 cancel_lru_locks $OSC
4927                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4928         done
4929 }
4930 run_test 39d "create, utime, stat =============================="
4931
4932 # bug 21114
4933 test_39e() {
4934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4935
4936         touch $DIR1/$tfile
4937         local mtime1=`stat -c %Y $DIR1/$tfile`
4938
4939         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4940
4941         for (( i=0; i < 2; i++ )) ; do
4942                 local mtime2=`stat -c %Y $DIR1/$tfile`
4943                 [ $mtime2 = $TEST_39_MTIME ] || \
4944                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4945
4946                 cancel_lru_locks $OSC
4947                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4948         done
4949 }
4950 run_test 39e "create, stat, utime, stat ========================"
4951
4952 # bug 21114
4953 test_39f() {
4954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4955
4956         touch $DIR1/$tfile
4957         mtime1=`stat -c %Y $DIR1/$tfile`
4958
4959         sleep 2
4960         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4961
4962         for (( i=0; i < 2; i++ )) ; do
4963                 local mtime2=`stat -c %Y $DIR1/$tfile`
4964                 [ $mtime2 = $TEST_39_MTIME ] || \
4965                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4966
4967                 cancel_lru_locks $OSC
4968                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4969         done
4970 }
4971 run_test 39f "create, stat, sleep, utime, stat ================="
4972
4973 # bug 11063
4974 test_39g() {
4975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4976
4977         echo hello >> $DIR1/$tfile
4978         local mtime1=`stat -c %Y $DIR1/$tfile`
4979
4980         sleep 2
4981         chmod o+r $DIR1/$tfile
4982
4983         for (( i=0; i < 2; i++ )) ; do
4984                 local mtime2=`stat -c %Y $DIR1/$tfile`
4985                 [ "$mtime1" = "$mtime2" ] || \
4986                         error "lost mtime: $mtime2, should be $mtime1"
4987
4988                 cancel_lru_locks $OSC
4989                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4990         done
4991 }
4992 run_test 39g "write, chmod, stat ==============================="
4993
4994 # bug 11063
4995 test_39h() {
4996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4997
4998         touch $DIR1/$tfile
4999         sleep 1
5000
5001         local d1=`date`
5002         echo hello >> $DIR1/$tfile
5003         local mtime1=`stat -c %Y $DIR1/$tfile`
5004
5005         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5006         local d2=`date`
5007         if [ "$d1" != "$d2" ]; then
5008                 echo "write and touch not within one second"
5009         else
5010                 for (( i=0; i < 2; i++ )) ; do
5011                         local mtime2=`stat -c %Y $DIR1/$tfile`
5012                         [ "$mtime2" = $TEST_39_MTIME ] || \
5013                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5014
5015                         cancel_lru_locks $OSC
5016                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5017                 done
5018         fi
5019 }
5020 run_test 39h "write, utime within one second, stat ============="
5021
5022 test_39i() {
5023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5024
5025         touch $DIR1/$tfile
5026         sleep 1
5027
5028         echo hello >> $DIR1/$tfile
5029         local mtime1=`stat -c %Y $DIR1/$tfile`
5030
5031         mv $DIR1/$tfile $DIR1/$tfile-1
5032
5033         for (( i=0; i < 2; i++ )) ; do
5034                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5035
5036                 [ "$mtime1" = "$mtime2" ] || \
5037                         error "lost mtime: $mtime2, should be $mtime1"
5038
5039                 cancel_lru_locks $OSC
5040                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5041         done
5042 }
5043 run_test 39i "write, rename, stat =============================="
5044
5045 test_39j() {
5046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5047
5048         start_full_debug_logging
5049         touch $DIR1/$tfile
5050         sleep 1
5051
5052         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5053         lctl set_param fail_loc=0x80000412
5054         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5055                 error "multiop failed"
5056         local multipid=$!
5057         local mtime1=`stat -c %Y $DIR1/$tfile`
5058
5059         mv $DIR1/$tfile $DIR1/$tfile-1
5060
5061         kill -USR1 $multipid
5062         wait $multipid || error "multiop close failed"
5063
5064         for (( i=0; i < 2; i++ )) ; do
5065                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5066                 [ "$mtime1" = "$mtime2" ] ||
5067                         error "mtime is lost on close: $mtime2, " \
5068                               "should be $mtime1"
5069
5070                 cancel_lru_locks
5071                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5072         done
5073         lctl set_param fail_loc=0
5074         stop_full_debug_logging
5075 }
5076 run_test 39j "write, rename, close, stat ======================="
5077
5078 test_39k() {
5079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5080
5081         touch $DIR1/$tfile
5082         sleep 1
5083
5084         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5085         local multipid=$!
5086         local mtime1=`stat -c %Y $DIR1/$tfile`
5087
5088         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5089
5090         kill -USR1 $multipid
5091         wait $multipid || error "multiop close failed"
5092
5093         for (( i=0; i < 2; i++ )) ; do
5094                 local mtime2=`stat -c %Y $DIR1/$tfile`
5095
5096                 [ "$mtime2" = $TEST_39_MTIME ] || \
5097                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5098
5099                 cancel_lru_locks
5100                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5101         done
5102 }
5103 run_test 39k "write, utime, close, stat ========================"
5104
5105 # this should be set to future
5106 TEST_39_ATIME=`date -d "1 year" +%s`
5107
5108 test_39l() {
5109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5110         remote_mds_nodsh && skip "remote MDS with nodsh"
5111
5112         local atime_diff=$(do_facet $SINGLEMDS \
5113                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5114         rm -rf $DIR/$tdir
5115         mkdir_on_mdt0 $DIR/$tdir
5116
5117         # test setting directory atime to future
5118         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5119         local atime=$(stat -c %X $DIR/$tdir)
5120         [ "$atime" = $TEST_39_ATIME ] ||
5121                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5122
5123         # test setting directory atime from future to now
5124         local now=$(date +%s)
5125         touch -a -d @$now $DIR/$tdir
5126
5127         atime=$(stat -c %X $DIR/$tdir)
5128         [ "$atime" -eq "$now"  ] ||
5129                 error "atime is not updated from future: $atime, $now"
5130
5131         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5132         sleep 3
5133
5134         # test setting directory atime when now > dir atime + atime_diff
5135         local d1=$(date +%s)
5136         ls $DIR/$tdir
5137         local d2=$(date +%s)
5138         cancel_lru_locks mdc
5139         atime=$(stat -c %X $DIR/$tdir)
5140         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5141                 error "atime is not updated  : $atime, should be $d2"
5142
5143         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5144         sleep 3
5145
5146         # test not setting directory atime when now < dir atime + atime_diff
5147         ls $DIR/$tdir
5148         cancel_lru_locks mdc
5149         atime=$(stat -c %X $DIR/$tdir)
5150         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5151                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5152
5153         do_facet $SINGLEMDS \
5154                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5155 }
5156 run_test 39l "directory atime update ==========================="
5157
5158 test_39m() {
5159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5160
5161         touch $DIR1/$tfile
5162         sleep 2
5163         local far_past_mtime=$(date -d "May 29 1953" +%s)
5164         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5165
5166         touch -m -d @$far_past_mtime $DIR1/$tfile
5167         touch -a -d @$far_past_atime $DIR1/$tfile
5168
5169         for (( i=0; i < 2; i++ )) ; do
5170                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5171                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5172                         error "atime or mtime set incorrectly"
5173
5174                 cancel_lru_locks $OSC
5175                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5176         done
5177 }
5178 run_test 39m "test atime and mtime before 1970"
5179
5180 test_39n() { # LU-3832
5181         remote_mds_nodsh && skip "remote MDS with nodsh"
5182
5183         local atime_diff=$(do_facet $SINGLEMDS \
5184                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5185         local atime0
5186         local atime1
5187         local atime2
5188
5189         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5190
5191         rm -rf $DIR/$tfile
5192         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5193         atime0=$(stat -c %X $DIR/$tfile)
5194
5195         sleep 5
5196         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5197         atime1=$(stat -c %X $DIR/$tfile)
5198
5199         sleep 5
5200         cancel_lru_locks mdc
5201         cancel_lru_locks osc
5202         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5203         atime2=$(stat -c %X $DIR/$tfile)
5204
5205         do_facet $SINGLEMDS \
5206                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5207
5208         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5209         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5210 }
5211 run_test 39n "check that O_NOATIME is honored"
5212
5213 test_39o() {
5214         TESTDIR=$DIR/$tdir/$tfile
5215         [ -e $TESTDIR ] && rm -rf $TESTDIR
5216         mkdir -p $TESTDIR
5217         cd $TESTDIR
5218         links1=2
5219         ls
5220         mkdir a b
5221         ls
5222         links2=$(stat -c %h .)
5223         [ $(($links1 + 2)) != $links2 ] &&
5224                 error "wrong links count $(($links1 + 2)) != $links2"
5225         rmdir b
5226         links3=$(stat -c %h .)
5227         [ $(($links1 + 1)) != $links3 ] &&
5228                 error "wrong links count $links1 != $links3"
5229         return 0
5230 }
5231 run_test 39o "directory cached attributes updated after create"
5232
5233 test_39p() {
5234         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5235
5236         local MDTIDX=1
5237         TESTDIR=$DIR/$tdir/$tdir
5238         [ -e $TESTDIR ] && rm -rf $TESTDIR
5239         test_mkdir -p $TESTDIR
5240         cd $TESTDIR
5241         links1=2
5242         ls
5243         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5244         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5245         ls
5246         links2=$(stat -c %h .)
5247         [ $(($links1 + 2)) != $links2 ] &&
5248                 error "wrong links count $(($links1 + 2)) != $links2"
5249         rmdir remote_dir2
5250         links3=$(stat -c %h .)
5251         [ $(($links1 + 1)) != $links3 ] &&
5252                 error "wrong links count $links1 != $links3"
5253         return 0
5254 }
5255 run_test 39p "remote directory cached attributes updated after create ========"
5256
5257 test_39r() {
5258         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5259                 skip "no atime update on old OST"
5260         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5261                 skip_env "ldiskfs only test"
5262         fi
5263
5264         local saved_adiff
5265         saved_adiff=$(do_facet ost1 \
5266                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5267         stack_trap "do_facet ost1 \
5268                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5269
5270         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5271
5272         $LFS setstripe -i 0 $DIR/$tfile
5273         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5274                 error "can't write initial file"
5275         cancel_lru_locks osc
5276
5277         # exceed atime_diff and access file
5278         sleep 10
5279         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5280                 error "can't udpate atime"
5281
5282         local atime_cli=$(stat -c %X $DIR/$tfile)
5283         echo "client atime: $atime_cli"
5284         # allow atime update to be written to device
5285         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5286         sleep 5
5287
5288         local ostdev=$(ostdevname 1)
5289         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5290         local seq=${fid[3]#0x}
5291         local oid=${fid[1]}
5292         local oid_hex
5293
5294         if [ $seq == 0 ]; then
5295                 oid_hex=${fid[1]}
5296         else
5297                 oid_hex=${fid[2]#0x}
5298         fi
5299         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5300         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5301
5302         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5303         local atime_ost=$(do_facet ost1 "$cmd" |&
5304                           awk -F'[: ]' '/atime:/ { print $4 }')
5305         (( atime_cli == atime_ost )) ||
5306                 error "atime on client $atime_cli != ost $atime_ost"
5307 }
5308 run_test 39r "lazy atime update on OST"
5309
5310 test_39q() { # LU-8041
5311         local testdir=$DIR/$tdir
5312         mkdir -p $testdir
5313         multiop_bg_pause $testdir D_c || error "multiop failed"
5314         local multipid=$!
5315         cancel_lru_locks mdc
5316         kill -USR1 $multipid
5317         local atime=$(stat -c %X $testdir)
5318         [ "$atime" -ne 0 ] || error "atime is zero"
5319 }
5320 run_test 39q "close won't zero out atime"
5321
5322 test_39s() {
5323         local atime0
5324         local atime1
5325         local atime2
5326         local atime3
5327         local atime4
5328
5329         umount_client $MOUNT
5330         mount_client $MOUNT relatime
5331
5332         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5333         atime0=$(stat -c %X $DIR/$tfile)
5334
5335         # First read updates atime
5336         sleep 1
5337         cat $DIR/$tfile >/dev/null
5338         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5339
5340         # Next reads do not update atime
5341         sleep 1
5342         cat $DIR/$tfile >/dev/null
5343         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5344
5345         # If mtime is greater than atime, atime is updated
5346         sleep 1
5347         touch -m $DIR/$tfile # (mtime = now)
5348         sleep 1
5349         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5350         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5351
5352         # Next reads do not update atime
5353         sleep 1
5354         cat $DIR/$tfile >/dev/null
5355         atime4=$(stat -c %X $DIR/$tfile)
5356
5357         # Remount the client to clear 'relatime' option
5358         remount_client $MOUNT
5359
5360         (( atime0 < atime1 )) ||
5361                 error "atime $atime0 should be smaller than $atime1"
5362         (( atime1 == atime2 )) ||
5363                 error "atime $atime1 was updated to $atime2"
5364         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5365         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5366 }
5367 run_test 39s "relatime is supported"
5368
5369 test_40() {
5370         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5371         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5372                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5373         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5374                 error "$tfile is not 4096 bytes in size"
5375 }
5376 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5377
5378 test_41() {
5379         # bug 1553
5380         small_write $DIR/f41 18
5381 }
5382 run_test 41 "test small file write + fstat ====================="
5383
5384 count_ost_writes() {
5385         lctl get_param -n ${OSC}.*.stats |
5386                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5387                         END { printf("%0.0f", writes) }'
5388 }
5389
5390 # decent default
5391 WRITEBACK_SAVE=500
5392 DIRTY_RATIO_SAVE=40
5393 MAX_DIRTY_RATIO=50
5394 BG_DIRTY_RATIO_SAVE=10
5395 MAX_BG_DIRTY_RATIO=25
5396
5397 start_writeback() {
5398         trap 0
5399         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5400         # dirty_ratio, dirty_background_ratio
5401         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5402                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5403                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5404                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5405         else
5406                 # if file not here, we are a 2.4 kernel
5407                 kill -CONT `pidof kupdated`
5408         fi
5409 }
5410
5411 stop_writeback() {
5412         # setup the trap first, so someone cannot exit the test at the
5413         # exact wrong time and mess up a machine
5414         trap start_writeback EXIT
5415         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5416         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5417                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5418                 sysctl -w vm.dirty_writeback_centisecs=0
5419                 sysctl -w vm.dirty_writeback_centisecs=0
5420                 # save and increase /proc/sys/vm/dirty_ratio
5421                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5422                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5423                 # save and increase /proc/sys/vm/dirty_background_ratio
5424                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5425                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5426         else
5427                 # if file not here, we are a 2.4 kernel
5428                 kill -STOP `pidof kupdated`
5429         fi
5430 }
5431
5432 # ensure that all stripes have some grant before we test client-side cache
5433 setup_test42() {
5434         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5435                 dd if=/dev/zero of=$i bs=4k count=1
5436                 rm $i
5437         done
5438 }
5439
5440 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5441 # file truncation, and file removal.
5442 test_42a() {
5443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5444
5445         setup_test42
5446         cancel_lru_locks $OSC
5447         stop_writeback
5448         sync; sleep 1; sync # just to be safe
5449         BEFOREWRITES=`count_ost_writes`
5450         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5451         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5452         AFTERWRITES=`count_ost_writes`
5453         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5454                 error "$BEFOREWRITES < $AFTERWRITES"
5455         start_writeback
5456 }
5457 run_test 42a "ensure that we don't flush on close"
5458
5459 test_42b() {
5460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5461
5462         setup_test42
5463         cancel_lru_locks $OSC
5464         stop_writeback
5465         sync
5466         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5467         BEFOREWRITES=$(count_ost_writes)
5468         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5469         AFTERWRITES=$(count_ost_writes)
5470         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5471                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5472         fi
5473         BEFOREWRITES=$(count_ost_writes)
5474         sync || error "sync: $?"
5475         AFTERWRITES=$(count_ost_writes)
5476         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5477                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5478         fi
5479         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5480         start_writeback
5481         return 0
5482 }
5483 run_test 42b "test destroy of file with cached dirty data ======"
5484
5485 # if these tests just want to test the effect of truncation,
5486 # they have to be very careful.  consider:
5487 # - the first open gets a {0,EOF}PR lock
5488 # - the first write conflicts and gets a {0, count-1}PW
5489 # - the rest of the writes are under {count,EOF}PW
5490 # - the open for truncate tries to match a {0,EOF}PR
5491 #   for the filesize and cancels the PWs.
5492 # any number of fixes (don't get {0,EOF} on open, match
5493 # composite locks, do smarter file size management) fix
5494 # this, but for now we want these tests to verify that
5495 # the cancellation with truncate intent works, so we
5496 # start the file with a full-file pw lock to match against
5497 # until the truncate.
5498 trunc_test() {
5499         test=$1
5500         file=$DIR/$test
5501         offset=$2
5502         cancel_lru_locks $OSC
5503         stop_writeback
5504         # prime the file with 0,EOF PW to match
5505         touch $file
5506         $TRUNCATE $file 0
5507         sync; sync
5508         # now the real test..
5509         dd if=/dev/zero of=$file bs=1024 count=100
5510         BEFOREWRITES=`count_ost_writes`
5511         $TRUNCATE $file $offset
5512         cancel_lru_locks $OSC
5513         AFTERWRITES=`count_ost_writes`
5514         start_writeback
5515 }
5516
5517 test_42c() {
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         trunc_test 42c 1024
5521         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5522                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5523         rm $file
5524 }
5525 run_test 42c "test partial truncate of file with cached dirty data"
5526
5527 test_42d() {
5528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5529
5530         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5531         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5532         $LCTL set_param debug=+cache
5533
5534         trunc_test 42d 0
5535         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5536                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5537         rm $file
5538 }
5539 run_test 42d "test complete truncate of file with cached dirty data"
5540
5541 test_42e() { # bug22074
5542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5543
5544         local TDIR=$DIR/${tdir}e
5545         local pages=16 # hardcoded 16 pages, don't change it.
5546         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5547         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5548         local max_dirty_mb
5549         local warmup_files
5550
5551         test_mkdir $DIR/${tdir}e
5552         $LFS setstripe -c 1 $TDIR
5553         createmany -o $TDIR/f $files
5554
5555         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5556
5557         # we assume that with $OSTCOUNT files, at least one of them will
5558         # be allocated on OST0.
5559         warmup_files=$((OSTCOUNT * max_dirty_mb))
5560         createmany -o $TDIR/w $warmup_files
5561
5562         # write a large amount of data into one file and sync, to get good
5563         # avail_grant number from OST.
5564         for ((i=0; i<$warmup_files; i++)); do
5565                 idx=$($LFS getstripe -i $TDIR/w$i)
5566                 [ $idx -ne 0 ] && continue
5567                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5568                 break
5569         done
5570         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5571         sync
5572         $LCTL get_param $proc_osc0/cur_dirty_bytes
5573         $LCTL get_param $proc_osc0/cur_grant_bytes
5574
5575         # create as much dirty pages as we can while not to trigger the actual
5576         # RPCs directly. but depends on the env, VFS may trigger flush during this
5577         # period, hopefully we are good.
5578         for ((i=0; i<$warmup_files; i++)); do
5579                 idx=$($LFS getstripe -i $TDIR/w$i)
5580                 [ $idx -ne 0 ] && continue
5581                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5582         done
5583         $LCTL get_param $proc_osc0/cur_dirty_bytes
5584         $LCTL get_param $proc_osc0/cur_grant_bytes
5585
5586         # perform the real test
5587         $LCTL set_param $proc_osc0/rpc_stats 0
5588         for ((;i<$files; i++)); do
5589                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5590                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5591         done
5592         sync
5593         $LCTL get_param $proc_osc0/rpc_stats
5594
5595         local percent=0
5596         local have_ppr=false
5597         $LCTL get_param $proc_osc0/rpc_stats |
5598                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5599                         # skip lines until we are at the RPC histogram data
5600                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5601                         $have_ppr || continue
5602
5603                         # we only want the percent stat for < 16 pages
5604                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5605
5606                         percent=$((percent + WPCT))
5607                         if [[ $percent -gt 15 ]]; then
5608                                 error "less than 16-pages write RPCs" \
5609                                       "$percent% > 15%"
5610                                 break
5611                         fi
5612                 done
5613         rm -rf $TDIR
5614 }
5615 run_test 42e "verify sub-RPC writes are not done synchronously"
5616
5617 test_43A() { # was test_43
5618         test_mkdir $DIR/$tdir
5619         cp -p /bin/ls $DIR/$tdir/$tfile
5620         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5621         pid=$!
5622         # give multiop a chance to open
5623         sleep 1
5624
5625         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5626         kill -USR1 $pid
5627         # Wait for multiop to exit
5628         wait $pid
5629 }
5630 run_test 43A "execution of file opened for write should return -ETXTBSY"
5631
5632 test_43a() {
5633         test_mkdir $DIR/$tdir
5634         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5635         $DIR/$tdir/sleep 60 &
5636         SLEEP_PID=$!
5637         # Make sure exec of $tdir/sleep wins race with truncate
5638         sleep 1
5639         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5640         kill $SLEEP_PID
5641 }
5642 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5643
5644 test_43b() {
5645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5646
5647         test_mkdir $DIR/$tdir
5648         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5649         $DIR/$tdir/sleep 60 &
5650         SLEEP_PID=$!
5651         # Make sure exec of $tdir/sleep wins race with truncate
5652         sleep 1
5653         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5654         kill $SLEEP_PID
5655 }
5656 run_test 43b "truncate of file being executed should return -ETXTBSY"
5657
5658 test_43c() {
5659         local testdir="$DIR/$tdir"
5660         test_mkdir $testdir
5661         cp $SHELL $testdir/
5662         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5663                 ( cd $testdir && md5sum -c )
5664 }
5665 run_test 43c "md5sum of copy into lustre"
5666
5667 test_44A() { # was test_44
5668         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5669
5670         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5671         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5672 }
5673 run_test 44A "zero length read from a sparse stripe"
5674
5675 test_44a() {
5676         local nstripe=$($LFS getstripe -c -d $DIR)
5677         [ -z "$nstripe" ] && skip "can't get stripe info"
5678         [[ $nstripe -gt $OSTCOUNT ]] &&
5679                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5680
5681         local stride=$($LFS getstripe -S -d $DIR)
5682         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5683                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5684         fi
5685
5686         OFFSETS="0 $((stride/2)) $((stride-1))"
5687         for offset in $OFFSETS; do
5688                 for i in $(seq 0 $((nstripe-1))); do
5689                         local GLOBALOFFSETS=""
5690                         # size in Bytes
5691                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5692                         local myfn=$DIR/d44a-$size
5693                         echo "--------writing $myfn at $size"
5694                         ll_sparseness_write $myfn $size ||
5695                                 error "ll_sparseness_write"
5696                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5697                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5698                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5699
5700                         for j in $(seq 0 $((nstripe-1))); do
5701                                 # size in Bytes
5702                                 size=$((((j + $nstripe )*$stride + $offset)))
5703                                 ll_sparseness_write $myfn $size ||
5704                                         error "ll_sparseness_write"
5705                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5706                         done
5707                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5708                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5709                         rm -f $myfn
5710                 done
5711         done
5712 }
5713 run_test 44a "test sparse pwrite ==============================="
5714
5715 dirty_osc_total() {
5716         tot=0
5717         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5718                 tot=$(($tot + $d))
5719         done
5720         echo $tot
5721 }
5722 do_dirty_record() {
5723         before=`dirty_osc_total`
5724         echo executing "\"$*\""
5725         eval $*
5726         after=`dirty_osc_total`
5727         echo before $before, after $after
5728 }
5729 test_45() {
5730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5731
5732         f="$DIR/f45"
5733         # Obtain grants from OST if it supports it
5734         echo blah > ${f}_grant
5735         stop_writeback
5736         sync
5737         do_dirty_record "echo blah > $f"
5738         [[ $before -eq $after ]] && error "write wasn't cached"
5739         do_dirty_record "> $f"
5740         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5741         do_dirty_record "echo blah > $f"
5742         [[ $before -eq $after ]] && error "write wasn't cached"
5743         do_dirty_record "sync"
5744         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5745         do_dirty_record "echo blah > $f"
5746         [[ $before -eq $after ]] && error "write wasn't cached"
5747         do_dirty_record "cancel_lru_locks osc"
5748         [[ $before -gt $after ]] ||
5749                 error "lock cancellation didn't lower dirty count"
5750         start_writeback
5751 }
5752 run_test 45 "osc io page accounting ============================"
5753
5754 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5755 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5756 # objects offset and an assert hit when an rpc was built with 1023's mapped
5757 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5758 test_46() {
5759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5760
5761         f="$DIR/f46"
5762         stop_writeback
5763         sync
5764         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5765         sync
5766         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5767         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5768         sync
5769         start_writeback
5770 }
5771 run_test 46 "dirtying a previously written page ================"
5772
5773 # test_47 is removed "Device nodes check" is moved to test_28
5774
5775 test_48a() { # bug 2399
5776         [ "$mds1_FSTYPE" = "zfs" ] &&
5777         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5778                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5779
5780         test_mkdir $DIR/$tdir
5781         cd $DIR/$tdir
5782         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5783         test_mkdir $DIR/$tdir
5784         touch foo || error "'touch foo' failed after recreating cwd"
5785         test_mkdir bar
5786         touch .foo || error "'touch .foo' failed after recreating cwd"
5787         test_mkdir .bar
5788         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5789         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5790         cd . || error "'cd .' failed after recreating cwd"
5791         mkdir . && error "'mkdir .' worked after recreating cwd"
5792         rmdir . && error "'rmdir .' worked after recreating cwd"
5793         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5794         cd .. || error "'cd ..' failed after recreating cwd"
5795 }
5796 run_test 48a "Access renamed working dir (should return errors)="
5797
5798 test_48b() { # bug 2399
5799         rm -rf $DIR/$tdir
5800         test_mkdir $DIR/$tdir
5801         cd $DIR/$tdir
5802         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5803         touch foo && error "'touch foo' worked after removing cwd"
5804         mkdir foo && error "'mkdir foo' worked after removing cwd"
5805         touch .foo && error "'touch .foo' worked after removing cwd"
5806         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5807         ls . > /dev/null && error "'ls .' worked after removing cwd"
5808         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5809         mkdir . && error "'mkdir .' worked after removing cwd"
5810         rmdir . && error "'rmdir .' worked after removing cwd"
5811         ln -s . foo && error "'ln -s .' worked after removing cwd"
5812         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5813 }
5814 run_test 48b "Access removed working dir (should return errors)="
5815
5816 test_48c() { # bug 2350
5817         #lctl set_param debug=-1
5818         #set -vx
5819         rm -rf $DIR/$tdir
5820         test_mkdir -p $DIR/$tdir/dir
5821         cd $DIR/$tdir/dir
5822         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5823         $TRACE touch foo && error "touch foo worked after removing cwd"
5824         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5825         touch .foo && error "touch .foo worked after removing cwd"
5826         mkdir .foo && error "mkdir .foo worked after removing cwd"
5827         $TRACE ls . && error "'ls .' worked after removing cwd"
5828         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5829         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5830         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5831         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5832         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5833 }
5834 run_test 48c "Access removed working subdir (should return errors)"
5835
5836 test_48d() { # bug 2350
5837         #lctl set_param debug=-1
5838         #set -vx
5839         rm -rf $DIR/$tdir
5840         test_mkdir -p $DIR/$tdir/dir
5841         cd $DIR/$tdir/dir
5842         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5843         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5844         $TRACE touch foo && error "'touch foo' worked after removing parent"
5845         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5846         touch .foo && error "'touch .foo' worked after removing parent"
5847         mkdir .foo && error "mkdir .foo worked after removing parent"
5848         $TRACE ls . && error "'ls .' worked after removing parent"
5849         $TRACE ls .. && error "'ls ..' worked after removing parent"
5850         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5851         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5852         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5853         true
5854 }
5855 run_test 48d "Access removed parent subdir (should return errors)"
5856
5857 test_48e() { # bug 4134
5858         #lctl set_param debug=-1
5859         #set -vx
5860         rm -rf $DIR/$tdir
5861         test_mkdir -p $DIR/$tdir/dir
5862         cd $DIR/$tdir/dir
5863         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5864         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5865         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5866         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5867         # On a buggy kernel addition of "touch foo" after cd .. will
5868         # produce kernel oops in lookup_hash_it
5869         touch ../foo && error "'cd ..' worked after recreate parent"
5870         cd $DIR
5871         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5872 }
5873 run_test 48e "Access to recreated parent subdir (should return errors)"
5874
5875 test_48f() {
5876         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5877                 skip "need MDS >= 2.13.55"
5878         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5879         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5880                 skip "needs different host for mdt1 mdt2"
5881         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5882
5883         $LFS mkdir -i0 $DIR/$tdir
5884         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5885
5886         for d in sub1 sub2 sub3; do
5887                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5888                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5889                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5890         done
5891
5892         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5893 }
5894 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5895
5896 test_49() { # LU-1030
5897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5898         remote_ost_nodsh && skip "remote OST with nodsh"
5899
5900         # get ost1 size - $FSNAME-OST0000
5901         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5902                 awk '{ print $4 }')
5903         # write 800M at maximum
5904         [[ $ost1_size -lt 2 ]] && ost1_size=2
5905         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5906
5907         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5908         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5909         local dd_pid=$!
5910
5911         # change max_pages_per_rpc while writing the file
5912         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5913         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5914         # loop until dd process exits
5915         while ps ax -opid | grep -wq $dd_pid; do
5916                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5917                 sleep $((RANDOM % 5 + 1))
5918         done
5919         # restore original max_pages_per_rpc
5920         $LCTL set_param $osc1_mppc=$orig_mppc
5921         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5922 }
5923 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5924
5925 test_50() {
5926         # bug 1485
5927         test_mkdir $DIR/$tdir
5928         cd $DIR/$tdir
5929         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5930 }
5931 run_test 50 "special situations: /proc symlinks  ==============="
5932
5933 test_51a() {    # was test_51
5934         # bug 1516 - create an empty entry right after ".." then split dir
5935         test_mkdir -c1 $DIR/$tdir
5936         touch $DIR/$tdir/foo
5937         $MCREATE $DIR/$tdir/bar
5938         rm $DIR/$tdir/foo
5939         createmany -m $DIR/$tdir/longfile 201
5940         FNUM=202
5941         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5942                 $MCREATE $DIR/$tdir/longfile$FNUM
5943                 FNUM=$(($FNUM + 1))
5944                 echo -n "+"
5945         done
5946         echo
5947         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5948 }
5949 run_test 51a "special situations: split htree with empty entry =="
5950
5951 cleanup_print_lfs_df () {
5952         trap 0
5953         $LFS df
5954         $LFS df -i
5955 }
5956
5957 test_51b() {
5958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5959
5960         local dir=$DIR/$tdir
5961         local nrdirs=$((65536 + 100))
5962
5963         # cleanup the directory
5964         rm -fr $dir
5965
5966         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5967
5968         $LFS df
5969         $LFS df -i
5970         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5971         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5972         [[ $numfree -lt $nrdirs ]] &&
5973                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5974
5975         # need to check free space for the directories as well
5976         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5977         numfree=$(( blkfree / $(fs_inode_ksize) ))
5978         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5979
5980         trap cleanup_print_lfs_df EXIT
5981
5982         # create files
5983         createmany -d $dir/d $nrdirs || {
5984                 unlinkmany $dir/d $nrdirs
5985                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5986         }
5987
5988         # really created :
5989         nrdirs=$(ls -U $dir | wc -l)
5990
5991         # unlink all but 100 subdirectories, then check it still works
5992         local left=100
5993         local delete=$((nrdirs - left))
5994
5995         $LFS df
5996         $LFS df -i
5997
5998         # for ldiskfs the nlink count should be 1, but this is OSD specific
5999         # and so this is listed for informational purposes only
6000         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6001         unlinkmany -d $dir/d $delete ||
6002                 error "unlink of first $delete subdirs failed"
6003
6004         echo "nlink between: $(stat -c %h $dir)"
6005         local found=$(ls -U $dir | wc -l)
6006         [ $found -ne $left ] &&
6007                 error "can't find subdirs: found only $found, expected $left"
6008
6009         unlinkmany -d $dir/d $delete $left ||
6010                 error "unlink of second $left subdirs failed"
6011         # regardless of whether the backing filesystem tracks nlink accurately
6012         # or not, the nlink count shouldn't be more than "." and ".." here
6013         local after=$(stat -c %h $dir)
6014         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6015                 echo "nlink after: $after"
6016
6017         cleanup_print_lfs_df
6018 }
6019 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6020
6021 test_51d_sub() {
6022         local stripecount=$1
6023         local nfiles=$2
6024
6025         log "create files with stripecount=$stripecount"
6026         $LFS setstripe -C $stripecount $DIR/$tdir
6027         createmany -o $DIR/$tdir/t- $nfiles
6028         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6029         for ((n = 0; n < $OSTCOUNT; n++)); do
6030                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6031                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6032                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6033                             '($1 == '$n') { objs += 1 } \
6034                             END { printf("%0.0f", objs) }')
6035                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6036         done
6037         unlinkmany $DIR/$tdir/t- $nfiles
6038         rm  -f $TMP/$tfile
6039
6040         local nlast
6041         local min=4
6042         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6043
6044         # For some combinations of stripecount and OSTCOUNT current code
6045         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6046         # than others. Rather than skipping this test entirely, check that
6047         # and keep testing to ensure imbalance does not get worse. LU-15282
6048         (( (OSTCOUNT == 6 && stripecount == 4) ||
6049            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6050            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6051         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6052                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6053                         { $LFS df && $LFS df -i &&
6054                         error "stripecount=$stripecount: " \
6055                               "OST $n has fewer objects vs. OST $nlast " \
6056                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6057                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6058                         { $LFS df && $LFS df -i &&
6059                         error "stripecount=$stripecount: " \
6060                               "OST $n has more objects vs. OST $nlast " \
6061                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6062
6063                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6064                         { $LFS df && $LFS df -i &&
6065                         error "stripecount=$stripecount: " \
6066                               "OST $n has fewer #0 objects vs. OST $nlast " \
6067                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6068                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6069                         { $LFS df && $LFS df -i &&
6070                         error "stripecount=$stripecount: " \
6071                               "OST $n has more #0 objects vs. OST $nlast " \
6072                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6073         done
6074 }
6075
6076 test_51d() {
6077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6078         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6079
6080         local stripecount
6081         local per_ost=100
6082         local nfiles=$((per_ost * OSTCOUNT))
6083         local mdts=$(comma_list $(mdts_nodes))
6084         local param="osp.*.create_count"
6085         local qos_old=$(do_facet mds1 \
6086                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6087
6088         do_nodes $mdts \
6089                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6090         stack_trap "do_nodes $mdts \
6091                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6092
6093         test_mkdir $DIR/$tdir
6094         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6095         (( dirstripes > 0 )) || dirstripes=1
6096
6097         # Ensure enough OST objects precreated for tests to pass without
6098         # running out of objects.  This is an LOV r-r OST algorithm test,
6099         # not an OST object precreation test.
6100         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6101         (( old >= nfiles )) ||
6102         {
6103                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6104
6105                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6106                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6107
6108                 # trigger precreation from all MDTs for all OSTs
6109                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6110                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6111                 done
6112         }
6113
6114         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6115                 sleep 8  # allow object precreation to catch up
6116                 test_51d_sub $stripecount $nfiles
6117         done
6118 }
6119 run_test 51d "check LOV round-robin OST object distribution"
6120
6121 test_51e() {
6122         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6123                 skip_env "ldiskfs only test"
6124         fi
6125
6126         test_mkdir -c1 $DIR/$tdir
6127         test_mkdir -c1 $DIR/$tdir/d0
6128
6129         touch $DIR/$tdir/d0/foo
6130         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6131                 error "file exceed 65000 nlink limit!"
6132         unlinkmany $DIR/$tdir/d0/f- 65001
6133         return 0
6134 }
6135 run_test 51e "check file nlink limit"
6136
6137 test_51f() {
6138         test_mkdir $DIR/$tdir
6139
6140         local max=100000
6141         local ulimit_old=$(ulimit -n)
6142         local spare=20 # number of spare fd's for scripts/libraries, etc.
6143         local mdt=$($LFS getstripe -m $DIR/$tdir)
6144         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6145
6146         echo "MDT$mdt numfree=$numfree, max=$max"
6147         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6148         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6149                 while ! ulimit -n $((numfree + spare)); do
6150                         numfree=$((numfree * 3 / 4))
6151                 done
6152                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6153         else
6154                 echo "left ulimit at $ulimit_old"
6155         fi
6156
6157         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6158                 unlinkmany $DIR/$tdir/f $numfree
6159                 error "create+open $numfree files in $DIR/$tdir failed"
6160         }
6161         ulimit -n $ulimit_old
6162
6163         # if createmany exits at 120s there will be fewer than $numfree files
6164         unlinkmany $DIR/$tdir/f $numfree || true
6165 }
6166 run_test 51f "check many open files limit"
6167
6168 test_52a() {
6169         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6170         test_mkdir $DIR/$tdir
6171         touch $DIR/$tdir/foo
6172         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6173         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6174         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6175         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6176         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6177                                         error "link worked"
6178         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6179         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6180         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6181                                                      error "lsattr"
6182         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6183         cp -r $DIR/$tdir $TMP/
6184         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6185 }
6186 run_test 52a "append-only flag test (should return errors)"
6187
6188 test_52b() {
6189         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6190         test_mkdir $DIR/$tdir
6191         touch $DIR/$tdir/foo
6192         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6193         cat test > $DIR/$tdir/foo && error "cat test worked"
6194         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6195         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6196         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6197                                         error "link worked"
6198         echo foo >> $DIR/$tdir/foo && error "echo worked"
6199         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6200         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6201         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6202         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6203                                                         error "lsattr"
6204         chattr -i $DIR/$tdir/foo || error "chattr failed"
6205
6206         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6207 }
6208 run_test 52b "immutable flag test (should return errors) ======="
6209
6210 test_53() {
6211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6212         remote_mds_nodsh && skip "remote MDS with nodsh"
6213         remote_ost_nodsh && skip "remote OST with nodsh"
6214
6215         local param
6216         local param_seq
6217         local ostname
6218         local mds_last
6219         local mds_last_seq
6220         local ost_last
6221         local ost_last_seq
6222         local ost_last_id
6223         local ostnum
6224         local node
6225         local found=false
6226         local support_last_seq=true
6227
6228         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6229                 support_last_seq=false
6230
6231         # only test MDT0000
6232         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6233         local value
6234         for value in $(do_facet $SINGLEMDS \
6235                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6236                 param=$(echo ${value[0]} | cut -d "=" -f1)
6237                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6238
6239                 if $support_last_seq; then
6240                         param_seq=$(echo $param |
6241                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6242                         mds_last_seq=$(do_facet $SINGLEMDS \
6243                                        $LCTL get_param -n $param_seq)
6244                 fi
6245                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6246
6247                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6248                 node=$(facet_active_host ost$((ostnum+1)))
6249                 param="obdfilter.$ostname.last_id"
6250                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6251                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6252                         ost_last_id=$ost_last
6253
6254                         if $support_last_seq; then
6255                                 ost_last_id=$(echo $ost_last |
6256                                               awk -F':' '{print $2}' |
6257                                               sed -e "s/^0x//g")
6258                                 ost_last_seq=$(echo $ost_last |
6259                                                awk -F':' '{print $1}')
6260                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6261                         fi
6262
6263                         if [[ $ost_last_id != $mds_last ]]; then
6264                                 error "$ost_last_id != $mds_last"
6265                         else
6266                                 found=true
6267                                 break
6268                         fi
6269                 done
6270         done
6271         $found || error "can not match last_seq/last_id for $mdtosc"
6272         return 0
6273 }
6274 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6275
6276 test_54a() {
6277         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6278
6279         LANG=C $SOCKETSERVER $DIR/socket ||
6280                 error "$SOCKETSERVER $DIR/socket failed: $?"
6281         LANG=C $SOCKETCLIENT $DIR/socket ||
6282                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6283         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6284 }
6285 run_test 54a "unix domain socket test =========================="
6286
6287 test_54b() {
6288         f="$DIR/f54b"
6289         mknod $f c 1 3
6290         chmod 0666 $f
6291         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6292 }
6293 run_test 54b "char device works in lustre ======================"
6294
6295 find_loop_dev() {
6296         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6297         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6298         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6299
6300         for i in $(seq 3 7); do
6301                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6302                 LOOPDEV=$LOOPBASE$i
6303                 LOOPNUM=$i
6304                 break
6305         done
6306 }
6307
6308 cleanup_54c() {
6309         local rc=0
6310         loopdev="$DIR/loop54c"
6311
6312         trap 0
6313         $UMOUNT $DIR/$tdir || rc=$?
6314         losetup -d $loopdev || true
6315         losetup -d $LOOPDEV || true
6316         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6317         return $rc
6318 }
6319
6320 test_54c() {
6321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6322
6323         loopdev="$DIR/loop54c"
6324
6325         find_loop_dev
6326         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6327         trap cleanup_54c EXIT
6328         mknod $loopdev b 7 $LOOPNUM
6329         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6330         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6331         losetup $loopdev $DIR/$tfile ||
6332                 error "can't set up $loopdev for $DIR/$tfile"
6333         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6334         test_mkdir $DIR/$tdir
6335         mount -t ext2 $loopdev $DIR/$tdir ||
6336                 error "error mounting $loopdev on $DIR/$tdir"
6337         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6338                 error "dd write"
6339         df $DIR/$tdir
6340         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6341                 error "dd read"
6342         cleanup_54c
6343 }
6344 run_test 54c "block device works in lustre ====================="
6345
6346 test_54d() {
6347         local pipe="$DIR/$tfile.pipe"
6348         local string="aaaaaa"
6349
6350         mknod $pipe p
6351         echo -n "$string" > $pipe &
6352         local result=$(cat $pipe)
6353         [[ "$result" == "$string" ]] || error "$result != $string"
6354 }
6355 run_test 54d "fifo device works in lustre ======================"
6356
6357 test_54e() {
6358         f="$DIR/f54e"
6359         string="aaaaaa"
6360         cp -aL /dev/console $f
6361         echo $string > $f || error "echo $string to $f failed"
6362 }
6363 run_test 54e "console/tty device works in lustre ======================"
6364
6365 test_55a() {
6366         local dev_path="/sys/kernel/debug/lustre/devices"
6367
6368         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6369
6370         # This must be run in iteractive mode, since attach and setup
6371         # are stateful
6372         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6373                 attach obd_test obd_name obd_uuid
6374                 setup obd_test
6375         EOF"
6376
6377         echo "Devices:"
6378         cat "$dev_path" | tail -n 10
6379
6380         $LCTL --device "obd_name" cleanup
6381         $LCTL --device "obd_name" detach
6382
6383         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6384                 error "OBD unit test failed"
6385
6386         rmmod -v obd_test ||
6387                 error "rmmod failed (may trigger a failure in a later test)"
6388 }
6389 run_test 55a "OBD device life cycle unit tests"
6390
6391 test_55b() {
6392         local dev_path="/sys/kernel/debug/lustre/devices"
6393         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6394
6395         # Set up a large number of devices, using the number
6396         # that can be set up in about a minute (based on prior
6397         # testing). We don't want to run this test forever.
6398         local num_dev_to_create="$(( 24000 - $dev_count))"
6399
6400         load_module obdclass/obd_test || error "load_module failed"
6401
6402         local start=$SECONDS
6403
6404         # This must be run in iteractive mode, since attach and setup
6405         # are stateful
6406         for ((i = 1; i <= num_dev_to_create; i++)); do
6407                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6408                 echo "setup obd_test_$i"
6409         done | $LCTL || error "OBD device creation failed"
6410
6411         echo "Load time: $((SECONDS - start))"
6412         echo "Devices:"
6413         cat "$dev_path" | tail -n 10
6414
6415         for ((i = 1; i <= num_dev_to_create; i++)); do
6416                 echo "--device obd_name_$i cleanup"
6417                 echo "--device obd_name_$i detach"
6418         done | $LCTL || error "OBD device cleanup failed"
6419
6420         echo "Unload time: $((SECONDS - start))"
6421
6422         rmmod -v obd_test ||
6423                 error "rmmod failed (may trigger a failure in a later test)"
6424 }
6425 run_test 55b "Load and unload max OBD devices"
6426
6427 test_56a() {
6428         local numfiles=3
6429         local numdirs=2
6430         local dir=$DIR/$tdir
6431
6432         rm -rf $dir
6433         test_mkdir -p $dir/dir
6434         for i in $(seq $numfiles); do
6435                 touch $dir/file$i
6436                 touch $dir/dir/file$i
6437         done
6438
6439         local numcomp=$($LFS getstripe --component-count $dir)
6440
6441         [[ $numcomp == 0 ]] && numcomp=1
6442
6443         # test lfs getstripe with --recursive
6444         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6445
6446         [[ $filenum -eq $((numfiles * 2)) ]] ||
6447                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6448         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6449         [[ $filenum -eq $numfiles ]] ||
6450                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6451         echo "$LFS getstripe showed obdidx or l_ost_idx"
6452
6453         # test lfs getstripe with file instead of dir
6454         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6455         [[ $filenum -eq 1 ]] ||
6456                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6457         echo "$LFS getstripe file1 passed"
6458
6459         #test lfs getstripe with --verbose
6460         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6461         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6462                 error "$LFS getstripe --verbose $dir: "\
6463                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6464         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6465                 error "$LFS getstripe $dir: showed lmm_magic"
6466
6467         #test lfs getstripe with -v prints lmm_fid
6468         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6469         local countfids=$((numdirs + numfiles * numcomp))
6470         [[ $filenum -eq $countfids ]] ||
6471                 error "$LFS getstripe -v $dir: "\
6472                       "got $filenum want $countfids lmm_fid"
6473         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6474                 error "$LFS getstripe $dir: showed lmm_fid by default"
6475         echo "$LFS getstripe --verbose passed"
6476
6477         #check for FID information
6478         local fid1=$($LFS getstripe --fid $dir/file1)
6479         local fid2=$($LFS getstripe --verbose $dir/file1 |
6480                      awk '/lmm_fid: / { print $2; exit; }')
6481         local fid3=$($LFS path2fid $dir/file1)
6482
6483         [ "$fid1" != "$fid2" ] &&
6484                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6485         [ "$fid1" != "$fid3" ] &&
6486                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6487         echo "$LFS getstripe --fid passed"
6488
6489         #test lfs getstripe with --obd
6490         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6491                 error "$LFS getstripe --obd wrong_uuid: should return error"
6492
6493         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6494
6495         local ostidx=1
6496         local obduuid=$(ostuuid_from_index $ostidx)
6497         local found=$($LFS getstripe -r --obd $obduuid $dir |
6498                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6499
6500         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6501         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6502                 ((filenum--))
6503         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6504                 ((filenum--))
6505
6506         [[ $found -eq $filenum ]] ||
6507                 error "$LFS getstripe --obd: found $found expect $filenum"
6508         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6509                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6510                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6511                 error "$LFS getstripe --obd: should not show file on other obd"
6512         echo "$LFS getstripe --obd passed"
6513 }
6514 run_test 56a "check $LFS getstripe"
6515
6516 test_56b() {
6517         local dir=$DIR/$tdir
6518         local numdirs=3
6519
6520         test_mkdir $dir
6521         for i in $(seq $numdirs); do
6522                 test_mkdir $dir/dir$i
6523         done
6524
6525         # test lfs getdirstripe default mode is non-recursion, which is
6526         # different from lfs getstripe
6527         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6528
6529         [[ $dircnt -eq 1 ]] ||
6530                 error "$LFS getdirstripe: found $dircnt, not 1"
6531         dircnt=$($LFS getdirstripe --recursive $dir |
6532                 grep -c lmv_stripe_count)
6533         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6534                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6535 }
6536 run_test 56b "check $LFS getdirstripe"
6537
6538 test_56bb() {
6539         verify_yaml_available || skip_env "YAML verification not installed"
6540         local output_file=$DIR/$tfile.out
6541
6542         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6543
6544         cat $output_file
6545         cat $output_file | verify_yaml || error "layout is not valid YAML"
6546 }
6547 run_test 56bb "check $LFS getdirstripe layout is YAML"
6548
6549 test_56c() {
6550         remote_ost_nodsh && skip "remote OST with nodsh"
6551
6552         local ost_idx=0
6553         local ost_name=$(ostname_from_index $ost_idx)
6554         local old_status=$(ost_dev_status $ost_idx)
6555         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6556
6557         [[ -z "$old_status" ]] ||
6558                 skip_env "OST $ost_name is in $old_status status"
6559
6560         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6561         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6562                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6563         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6564                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6565                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6566         fi
6567
6568         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6569                 error "$LFS df -v showing inactive devices"
6570         sleep_maxage
6571
6572         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6573
6574         [[ "$new_status" =~ "D" ]] ||
6575                 error "$ost_name status is '$new_status', missing 'D'"
6576         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6577                 [[ "$new_status" =~ "N" ]] ||
6578                         error "$ost_name status is '$new_status', missing 'N'"
6579         fi
6580         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6581                 [[ "$new_status" =~ "f" ]] ||
6582                         error "$ost_name status is '$new_status', missing 'f'"
6583         fi
6584
6585         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6586         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6587                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6588         [[ -z "$p" ]] && restore_lustre_params < $p || true
6589         sleep_maxage
6590
6591         new_status=$(ost_dev_status $ost_idx)
6592         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6593                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6594         # can't check 'f' as devices may actually be on flash
6595 }
6596 run_test 56c "check 'lfs df' showing device status"
6597
6598 test_56d() {
6599         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6600         local osts=$($LFS df -v $MOUNT | grep -c OST)
6601
6602         $LFS df $MOUNT
6603
6604         (( mdts == MDSCOUNT )) ||
6605                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6606         (( osts == OSTCOUNT )) ||
6607                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6608 }
6609 run_test 56d "'lfs df -v' prints only configured devices"
6610
6611 test_56e() {
6612         err_enoent=2 # No such file or directory
6613         err_eopnotsupp=95 # Operation not supported
6614
6615         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6616         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6617
6618         # Check for handling of path not exists
6619         output=$($LFS df $enoent_mnt 2>&1)
6620         ret=$?
6621
6622         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6623         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6624                 error "expect failure $err_enoent, not $ret"
6625
6626         # Check for handling of non-Lustre FS
6627         output=$($LFS df $notsup_mnt)
6628         ret=$?
6629
6630         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6631         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6632                 error "expect success $err_eopnotsupp, not $ret"
6633
6634         # Check for multiple LustreFS argument
6635         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6636         ret=$?
6637
6638         [[ $output -eq 3 && $ret -eq 0 ]] ||
6639                 error "expect success 3, not $output, rc = $ret"
6640
6641         # Check for correct non-Lustre FS handling among multiple
6642         # LustreFS argument
6643         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6644                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6645         ret=$?
6646
6647         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6648                 error "expect success 2, not $output, rc = $ret"
6649 }
6650 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6651
6652 NUMFILES=3
6653 NUMDIRS=3
6654 setup_56() {
6655         local local_tdir="$1"
6656         local local_numfiles="$2"
6657         local local_numdirs="$3"
6658         local dir_params="$4"
6659         local dir_stripe_params="$5"
6660
6661         if [ ! -d "$local_tdir" ] ; then
6662                 test_mkdir -p $dir_stripe_params $local_tdir
6663                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6664                 for i in $(seq $local_numfiles) ; do
6665                         touch $local_tdir/file$i
6666                 done
6667                 for i in $(seq $local_numdirs) ; do
6668                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6669                         for j in $(seq $local_numfiles) ; do
6670                                 touch $local_tdir/dir$i/file$j
6671                         done
6672                 done
6673         fi
6674 }
6675
6676 setup_56_special() {
6677         local local_tdir=$1
6678         local local_numfiles=$2
6679         local local_numdirs=$3
6680
6681         setup_56 $local_tdir $local_numfiles $local_numdirs
6682
6683         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6684                 for i in $(seq $local_numfiles) ; do
6685                         mknod $local_tdir/loop${i}b b 7 $i
6686                         mknod $local_tdir/null${i}c c 1 3
6687                         ln -s $local_tdir/file1 $local_tdir/link${i}
6688                 done
6689                 for i in $(seq $local_numdirs) ; do
6690                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6691                         mknod $local_tdir/dir$i/null${i}c c 1 3
6692                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6693                 done
6694         fi
6695 }
6696
6697 test_56g() {
6698         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6699         local expected=$(($NUMDIRS + 2))
6700
6701         setup_56 $dir $NUMFILES $NUMDIRS
6702
6703         # test lfs find with -name
6704         for i in $(seq $NUMFILES) ; do
6705                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6706
6707                 [ $nums -eq $expected ] ||
6708                         error "lfs find -name '*$i' $dir wrong: "\
6709                               "found $nums, expected $expected"
6710         done
6711 }
6712 run_test 56g "check lfs find -name"
6713
6714 test_56h() {
6715         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6716         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6717
6718         setup_56 $dir $NUMFILES $NUMDIRS
6719
6720         # test lfs find with ! -name
6721         for i in $(seq $NUMFILES) ; do
6722                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6723
6724                 [ $nums -eq $expected ] ||
6725                         error "lfs find ! -name '*$i' $dir wrong: "\
6726                               "found $nums, expected $expected"
6727         done
6728 }
6729 run_test 56h "check lfs find ! -name"
6730
6731 test_56i() {
6732         local dir=$DIR/$tdir
6733
6734         test_mkdir $dir
6735
6736         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6737         local out=$($cmd)
6738
6739         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6740 }
6741 run_test 56i "check 'lfs find -ost UUID' skips directories"
6742
6743 test_56j() {
6744         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6745
6746         setup_56_special $dir $NUMFILES $NUMDIRS
6747
6748         local expected=$((NUMDIRS + 1))
6749         local cmd="$LFS find -type d $dir"
6750         local nums=$($cmd | wc -l)
6751
6752         [ $nums -eq $expected ] ||
6753                 error "'$cmd' wrong: found $nums, expected $expected"
6754 }
6755 run_test 56j "check lfs find -type d"
6756
6757 test_56k() {
6758         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6759
6760         setup_56_special $dir $NUMFILES $NUMDIRS
6761
6762         local expected=$(((NUMDIRS + 1) * NUMFILES))
6763         local cmd="$LFS find -type f $dir"
6764         local nums=$($cmd | wc -l)
6765
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768 }
6769 run_test 56k "check lfs find -type f"
6770
6771 test_56l() {
6772         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6773
6774         setup_56_special $dir $NUMFILES $NUMDIRS
6775
6776         local expected=$((NUMDIRS + NUMFILES))
6777         local cmd="$LFS find -type b $dir"
6778         local nums=$($cmd | wc -l)
6779
6780         [ $nums -eq $expected ] ||
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782 }
6783 run_test 56l "check lfs find -type b"
6784
6785 test_56m() {
6786         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6787
6788         setup_56_special $dir $NUMFILES $NUMDIRS
6789
6790         local expected=$((NUMDIRS + NUMFILES))
6791         local cmd="$LFS find -type c $dir"
6792         local nums=$($cmd | wc -l)
6793         [ $nums -eq $expected ] ||
6794                 error "'$cmd' wrong: found $nums, expected $expected"
6795 }
6796 run_test 56m "check lfs find -type c"
6797
6798 test_56n() {
6799         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6800         setup_56_special $dir $NUMFILES $NUMDIRS
6801
6802         local expected=$((NUMDIRS + NUMFILES))
6803         local cmd="$LFS find -type l $dir"
6804         local nums=$($cmd | wc -l)
6805
6806         [ $nums -eq $expected ] ||
6807                 error "'$cmd' wrong: found $nums, expected $expected"
6808 }
6809 run_test 56n "check lfs find -type l"
6810
6811 test_56o() {
6812         local dir=$DIR/$tdir
6813
6814         setup_56 $dir $NUMFILES $NUMDIRS
6815         utime $dir/file1 > /dev/null || error "utime (1)"
6816         utime $dir/file2 > /dev/null || error "utime (2)"
6817         utime $dir/dir1 > /dev/null || error "utime (3)"
6818         utime $dir/dir2 > /dev/null || error "utime (4)"
6819         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6820         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6821
6822         local expected=4
6823         local nums=$($LFS find -mtime +0 $dir | wc -l)
6824
6825         [ $nums -eq $expected ] ||
6826                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6827
6828         expected=12
6829         cmd="$LFS find -mtime 0 $dir"
6830         nums=$($cmd | wc -l)
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833 }
6834 run_test 56o "check lfs find -mtime for old files"
6835
6836 test_56ob() {
6837         local dir=$DIR/$tdir
6838         local expected=1
6839         local count=0
6840
6841         # just to make sure there is something that won't be found
6842         test_mkdir $dir
6843         touch $dir/$tfile.now
6844
6845         for age in year week day hour min; do
6846                 count=$((count + 1))
6847
6848                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6849                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6850                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6851
6852                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6853                 local nums=$($cmd | wc -l)
6854                 [ $nums -eq $expected ] ||
6855                         error "'$cmd' wrong: found $nums, expected $expected"
6856
6857                 cmd="$LFS find $dir -atime $count${age:0:1}"
6858                 nums=$($cmd | wc -l)
6859                 [ $nums -eq $expected ] ||
6860                         error "'$cmd' wrong: found $nums, expected $expected"
6861         done
6862
6863         sleep 2
6864         cmd="$LFS find $dir -ctime +1s -type f"
6865         nums=$($cmd | wc -l)
6866         (( $nums == $count * 2 + 1)) ||
6867                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6868 }
6869 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6870
6871 test_newerXY_base() {
6872         local x=$1
6873         local y=$2
6874         local dir=$DIR/$tdir
6875         local ref
6876         local negref
6877
6878         if [ $y == "t" ]; then
6879                 if [ $x == "b" ]; then
6880                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6881                 else
6882                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6883                 fi
6884         else
6885                 ref=$DIR/$tfile.newer.$x$y
6886                 touch $ref || error "touch $ref failed"
6887         fi
6888
6889         echo "before = $ref"
6890         sleep 2
6891         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6892         sleep 2
6893         if [ $y == "t" ]; then
6894                 if [ $x == "b" ]; then
6895                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6896                 else
6897                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6898                 fi
6899         else
6900                 negref=$DIR/$tfile.negnewer.$x$y
6901                 touch $negref || error "touch $negref failed"
6902         fi
6903
6904         echo "after = $negref"
6905         local cmd="$LFS find $dir -newer$x$y $ref"
6906         local nums=$(eval $cmd | wc -l)
6907         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6908
6909         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6910                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6911
6912         cmd="$LFS find $dir ! -newer$x$y $negref"
6913         nums=$(eval $cmd | wc -l)
6914         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6915                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6916
6917         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6918         nums=$(eval $cmd | wc -l)
6919         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6920                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6921
6922         rm -rf $DIR/*
6923 }
6924
6925 test_56oc() {
6926         test_newerXY_base "a" "a"
6927         test_newerXY_base "a" "m"
6928         test_newerXY_base "a" "c"
6929         test_newerXY_base "m" "a"
6930         test_newerXY_base "m" "m"
6931         test_newerXY_base "m" "c"
6932         test_newerXY_base "c" "a"
6933         test_newerXY_base "c" "m"
6934         test_newerXY_base "c" "c"
6935
6936         test_newerXY_base "a" "t"
6937         test_newerXY_base "m" "t"
6938         test_newerXY_base "c" "t"
6939
6940         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6941            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6942                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6943
6944         test_newerXY_base "b" "b"
6945         test_newerXY_base "b" "t"
6946 }
6947 run_test 56oc "check lfs find -newerXY work"
6948
6949 test_56od() {
6950         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6951                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6952
6953         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6954                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6955
6956         local dir=$DIR/$tdir
6957         local ref=$DIR/$tfile.ref
6958         local negref=$DIR/$tfile.negref
6959
6960         mkdir $dir || error "mkdir $dir failed"
6961         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6962         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6963         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6964         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6965         touch $ref || error "touch $ref failed"
6966         # sleep 3 seconds at least
6967         sleep 3
6968
6969         local before=$(do_facet mds1 date +%s)
6970         local skew=$(($(date +%s) - before + 1))
6971
6972         if (( skew < 0 && skew > -5 )); then
6973                 sleep $((0 - skew + 1))
6974                 skew=0
6975         fi
6976
6977         # Set the dir stripe params to limit files all on MDT0,
6978         # otherwise we need to calc the max clock skew between
6979         # the client and MDTs.
6980         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6981         sleep 2
6982         touch $negref || error "touch $negref failed"
6983
6984         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6985         local nums=$($cmd | wc -l)
6986         local expected=$(((NUMFILES + 1) * NUMDIRS))
6987
6988         [ $nums -eq $expected ] ||
6989                 error "'$cmd' wrong: found $nums, expected $expected"
6990
6991         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6992         nums=$($cmd | wc -l)
6993         expected=$((NUMFILES + 1))
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996
6997         [ $skew -lt 0 ] && return
6998
6999         local after=$(do_facet mds1 date +%s)
7000         local age=$((after - before + 1 + skew))
7001
7002         cmd="$LFS find $dir -btime -${age}s -type f"
7003         nums=$($cmd | wc -l)
7004         expected=$(((NUMFILES + 1) * NUMDIRS))
7005
7006         echo "Clock skew between client and server: $skew, age:$age"
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         expected=$(($NUMDIRS + 1))
7011         cmd="$LFS find $dir -btime -${age}s -type d"
7012         nums=$($cmd | wc -l)
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015         rm -f $ref $negref || error "Failed to remove $ref $negref"
7016 }
7017 run_test 56od "check lfs find -btime with units"
7018
7019 test_56p() {
7020         [ $RUNAS_ID -eq $UID ] &&
7021                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7022
7023         local dir=$DIR/$tdir
7024
7025         setup_56 $dir $NUMFILES $NUMDIRS
7026         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7027
7028         local expected=$NUMFILES
7029         local cmd="$LFS find -uid $RUNAS_ID $dir"
7030         local nums=$($cmd | wc -l)
7031
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034
7035         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7036         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7037         nums=$($cmd | wc -l)
7038         [ $nums -eq $expected ] ||
7039                 error "'$cmd' wrong: found $nums, expected $expected"
7040 }
7041 run_test 56p "check lfs find -uid and ! -uid"
7042
7043 test_56q() {
7044         [ $RUNAS_ID -eq $UID ] &&
7045                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7046
7047         local dir=$DIR/$tdir
7048
7049         setup_56 $dir $NUMFILES $NUMDIRS
7050         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7051
7052         local expected=$NUMFILES
7053         local cmd="$LFS find -gid $RUNAS_GID $dir"
7054         local nums=$($cmd | wc -l)
7055
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058
7059         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7060         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7061         nums=$($cmd | wc -l)
7062         [ $nums -eq $expected ] ||
7063                 error "'$cmd' wrong: found $nums, expected $expected"
7064 }
7065 run_test 56q "check lfs find -gid and ! -gid"
7066
7067 test_56r() {
7068         local dir=$DIR/$tdir
7069
7070         setup_56 $dir $NUMFILES $NUMDIRS
7071
7072         local expected=12
7073         local cmd="$LFS find -size 0 -type f -lazy $dir"
7074         local nums=$($cmd | wc -l)
7075
7076         [ $nums -eq $expected ] ||
7077                 error "'$cmd' wrong: found $nums, expected $expected"
7078         cmd="$LFS find -size 0 -type f $dir"
7079         nums=$($cmd | wc -l)
7080         [ $nums -eq $expected ] ||
7081                 error "'$cmd' wrong: found $nums, expected $expected"
7082
7083         expected=0
7084         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] ||
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088         cmd="$LFS find ! -size 0 -type f $dir"
7089         nums=$($cmd | wc -l)
7090         [ $nums -eq $expected ] ||
7091                 error "'$cmd' wrong: found $nums, expected $expected"
7092
7093         echo "test" > $dir/$tfile
7094         echo "test2" > $dir/$tfile.2 && sync
7095         expected=1
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=1
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         expected=2
7116         cmd="$LFS find -size +0 -type f -lazy $dir"
7117         nums=$($cmd | wc -l)
7118         [ $nums -eq $expected ] ||
7119                 error "'$cmd' wrong: found $nums, expected $expected"
7120         cmd="$LFS find -size +0 -type f $dir"
7121         nums=$($cmd | wc -l)
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124
7125         expected=2
7126         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7127         nums=$($cmd | wc -l)
7128         [ $nums -eq $expected ] ||
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130         cmd="$LFS find ! -size -5 -type f $dir"
7131         nums=$($cmd | wc -l)
7132         [ $nums -eq $expected ] ||
7133                 error "'$cmd' wrong: found $nums, expected $expected"
7134
7135         expected=12
7136         cmd="$LFS find -size -5 -type f -lazy $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140         cmd="$LFS find -size -5 -type f $dir"
7141         nums=$($cmd | wc -l)
7142         [ $nums -eq $expected ] ||
7143                 error "'$cmd' wrong: found $nums, expected $expected"
7144 }
7145 run_test 56r "check lfs find -size works"
7146
7147 test_56ra_sub() {
7148         local expected=$1
7149         local glimpses=$2
7150         local cmd="$3"
7151
7152         cancel_lru_locks $OSC
7153
7154         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7155         local nums=$($cmd | wc -l)
7156
7157         [ $nums -eq $expected ] ||
7158                 error "'$cmd' wrong: found $nums, expected $expected"
7159
7160         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7161
7162         if (( rpcs_before + glimpses != rpcs_after )); then
7163                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7164                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7165
7166                 if [[ $glimpses == 0 ]]; then
7167                         error "'$cmd' should not send glimpse RPCs to OST"
7168                 else
7169                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7170                 fi
7171         fi
7172 }
7173
7174 test_56ra() {
7175         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7176                 skip "MDS < 2.12.58 doesn't return LSOM data"
7177         local dir=$DIR/$tdir
7178         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7179
7180         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7181
7182         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7183         $LCTL set_param -n llite.*.statahead_agl=0
7184         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7185
7186         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7187         # open and close all files to ensure LSOM is updated
7188         cancel_lru_locks $OSC
7189         find $dir -type f | xargs cat > /dev/null
7190
7191         #   expect_found  glimpse_rpcs  command_to_run
7192         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7193         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7194         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7195         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7196
7197         echo "test" > $dir/$tfile
7198         echo "test2" > $dir/$tfile.2 && sync
7199         cancel_lru_locks $OSC
7200         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7201
7202         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7203         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7204         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7205         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7206
7207         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7208         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7209         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7210         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7211         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7212         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7213 }
7214 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7215
7216 test_56rb() {
7217         local dir=$DIR/$tdir
7218         local tmp=$TMP/$tfile.log
7219         local mdt_idx;
7220
7221         test_mkdir -p $dir || error "failed to mkdir $dir"
7222         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7223                 error "failed to setstripe $dir/$tfile"
7224         mdt_idx=$($LFS getdirstripe -i $dir)
7225         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7226
7227         stack_trap "rm -f $tmp" EXIT
7228         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7229         ! grep -q obd_uuid $tmp ||
7230                 error "failed to find --size +100K --ost 0 $dir"
7231         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7232         ! grep -q obd_uuid $tmp ||
7233                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7234 }
7235 run_test 56rb "check lfs find --size --ost/--mdt works"
7236
7237 test_56rc() {
7238         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7239         local dir=$DIR/$tdir
7240         local found
7241
7242         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7243         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7244         (( $MDSCOUNT > 2 )) &&
7245                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7246         mkdir $dir/$tdir-{1..10}
7247         touch $dir/$tfile-{1..10}
7248
7249         found=$($LFS find $dir --mdt-count 2 | wc -l)
7250         expect=11
7251         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7252
7253         found=$($LFS find $dir -T +1 | wc -l)
7254         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7255         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7256
7257         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7258         expect=11
7259         (( $found == $expect )) || error "found $found all_char, expect $expect"
7260
7261         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7262         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7263         (( $found == $expect )) || error "found $found all_char, expect $expect"
7264 }
7265 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7266
7267 test_56rd() {
7268         local dir=$DIR/$tdir
7269
7270         test_mkdir $dir
7271         rm -f $dir/*
7272
7273         mkfifo $dir/fifo || error "failed to create fifo file"
7274         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7275                 error "should not fail even cannot get projid from pipe file"
7276         found=$($LFS find $dir -t p --printf "%y")
7277         [[ "p" == $found ]] || error "found $found, expect p"
7278
7279         mknod $dir/chardev c 1 5 ||
7280                 error "failed to create character device file"
7281         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7282                 error "should not fail even cannot get projid from chardev file"
7283         found=$($LFS find $dir -t c --printf "%y")
7284         [[ "c" == $found ]] || error "found $found, expect c"
7285
7286         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7287         (( found == 2 )) || error "unable to list all files"
7288 }
7289 run_test 56rd "check lfs find --printf special files"
7290
7291 test_56s() { # LU-611 #LU-9369
7292         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7293
7294         local dir=$DIR/$tdir
7295         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7296
7297         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7298         for i in $(seq $NUMDIRS); do
7299                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7300         done
7301
7302         local expected=$NUMDIRS
7303         local cmd="$LFS find -c $OSTCOUNT $dir"
7304         local nums=$($cmd | wc -l)
7305
7306         [ $nums -eq $expected ] || {
7307                 $LFS getstripe -R $dir
7308                 error "'$cmd' wrong: found $nums, expected $expected"
7309         }
7310
7311         expected=$((NUMDIRS + onestripe))
7312         cmd="$LFS find -stripe-count +0 -type f $dir"
7313         nums=$($cmd | wc -l)
7314         [ $nums -eq $expected ] || {
7315                 $LFS getstripe -R $dir
7316                 error "'$cmd' wrong: found $nums, expected $expected"
7317         }
7318
7319         expected=$onestripe
7320         cmd="$LFS find -stripe-count 1 -type f $dir"
7321         nums=$($cmd | wc -l)
7322         [ $nums -eq $expected ] || {
7323                 $LFS getstripe -R $dir
7324                 error "'$cmd' wrong: found $nums, expected $expected"
7325         }
7326
7327         cmd="$LFS find -stripe-count -2 -type f $dir"
7328         nums=$($cmd | wc -l)
7329         [ $nums -eq $expected ] || {
7330                 $LFS getstripe -R $dir
7331                 error "'$cmd' wrong: found $nums, expected $expected"
7332         }
7333
7334         expected=0
7335         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7336         nums=$($cmd | wc -l)
7337         [ $nums -eq $expected ] || {
7338                 $LFS getstripe -R $dir
7339                 error "'$cmd' wrong: found $nums, expected $expected"
7340         }
7341 }
7342 run_test 56s "check lfs find -stripe-count works"
7343
7344 test_56t() { # LU-611 #LU-9369
7345         local dir=$DIR/$tdir
7346
7347         setup_56 $dir 0 $NUMDIRS
7348         for i in $(seq $NUMDIRS); do
7349                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7350         done
7351
7352         local expected=$NUMDIRS
7353         local cmd="$LFS find -S 8M $dir"
7354         local nums=$($cmd | wc -l)
7355
7356         [ $nums -eq $expected ] || {
7357                 $LFS getstripe -R $dir
7358                 error "'$cmd' wrong: found $nums, expected $expected"
7359         }
7360         rm -rf $dir
7361
7362         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7363
7364         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7365
7366         expected=$(((NUMDIRS + 1) * NUMFILES))
7367         cmd="$LFS find -stripe-size 512k -type f $dir"
7368         nums=$($cmd | wc -l)
7369         [ $nums -eq $expected ] ||
7370                 error "'$cmd' wrong: found $nums, expected $expected"
7371
7372         cmd="$LFS find -stripe-size +320k -type f $dir"
7373         nums=$($cmd | wc -l)
7374         [ $nums -eq $expected ] ||
7375                 error "'$cmd' wrong: found $nums, expected $expected"
7376
7377         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7378         cmd="$LFS find -stripe-size +200k -type f $dir"
7379         nums=$($cmd | wc -l)
7380         [ $nums -eq $expected ] ||
7381                 error "'$cmd' wrong: found $nums, expected $expected"
7382
7383         cmd="$LFS find -stripe-size -640k -type f $dir"
7384         nums=$($cmd | wc -l)
7385         [ $nums -eq $expected ] ||
7386                 error "'$cmd' wrong: found $nums, expected $expected"
7387
7388         expected=4
7389         cmd="$LFS find -stripe-size 256k -type f $dir"
7390         nums=$($cmd | wc -l)
7391         [ $nums -eq $expected ] ||
7392                 error "'$cmd' wrong: found $nums, expected $expected"
7393
7394         cmd="$LFS find -stripe-size -320k -type f $dir"
7395         nums=$($cmd | wc -l)
7396         [ $nums -eq $expected ] ||
7397                 error "'$cmd' wrong: found $nums, expected $expected"
7398
7399         expected=0
7400         cmd="$LFS find -stripe-size 1024k -type f $dir"
7401         nums=$($cmd | wc -l)
7402         [ $nums -eq $expected ] ||
7403                 error "'$cmd' wrong: found $nums, expected $expected"
7404 }
7405 run_test 56t "check lfs find -stripe-size works"
7406
7407 test_56u() { # LU-611
7408         local dir=$DIR/$tdir
7409
7410         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7411
7412         if [[ $OSTCOUNT -gt 1 ]]; then
7413                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7414                 onestripe=4
7415         else
7416                 onestripe=0
7417         fi
7418
7419         local expected=$(((NUMDIRS + 1) * NUMFILES))
7420         local cmd="$LFS find -stripe-index 0 -type f $dir"
7421         local nums=$($cmd | wc -l)
7422
7423         [ $nums -eq $expected ] ||
7424                 error "'$cmd' wrong: found $nums, expected $expected"
7425
7426         expected=$onestripe
7427         cmd="$LFS find -stripe-index 1 -type f $dir"
7428         nums=$($cmd | wc -l)
7429         [ $nums -eq $expected ] ||
7430                 error "'$cmd' wrong: found $nums, expected $expected"
7431
7432         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7433         nums=$($cmd | wc -l)
7434         [ $nums -eq $expected ] ||
7435                 error "'$cmd' wrong: found $nums, expected $expected"
7436
7437         expected=0
7438         # This should produce an error and not return any files
7439         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7440         nums=$($cmd 2>/dev/null | wc -l)
7441         [ $nums -eq $expected ] ||
7442                 error "'$cmd' wrong: found $nums, expected $expected"
7443
7444         if [[ $OSTCOUNT -gt 1 ]]; then
7445                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7446                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7447                 nums=$($cmd | wc -l)
7448                 [ $nums -eq $expected ] ||
7449                         error "'$cmd' wrong: found $nums, expected $expected"
7450         fi
7451 }
7452 run_test 56u "check lfs find -stripe-index works"
7453
7454 test_56v() {
7455         local mdt_idx=0
7456         local dir=$DIR/$tdir
7457
7458         setup_56 $dir $NUMFILES $NUMDIRS
7459
7460         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7461         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7462
7463         for file in $($LFS find -m $UUID $dir); do
7464                 file_midx=$($LFS getstripe -m $file)
7465                 [ $file_midx -eq $mdt_idx ] ||
7466                         error "lfs find -m $UUID != getstripe -m $file_midx"
7467         done
7468 }
7469 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7470
7471 test_56wa() {
7472         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7474
7475         local dir=$DIR/$tdir
7476
7477         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7478         stack_trap "rm -rf $dir"
7479
7480         local stripe_size=$($LFS getstripe -S -d $dir) ||
7481                 error "$LFS getstripe -S -d $dir failed"
7482         stripe_size=${stripe_size%% *}
7483
7484         local file_size=$((stripe_size * OSTCOUNT))
7485         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7486         local required_space=$((file_num * file_size))
7487         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7488                            head -n1)
7489         (( free_space >= required_space / 1024 )) ||
7490                 skip_env "need $required_space, have $free_space kbytes"
7491
7492         local dd_bs=65536
7493         local dd_count=$((file_size / dd_bs))
7494
7495         # write data into the files
7496         local i
7497         local j
7498         local file
7499
7500         for ((i = 1; i <= NUMFILES; i++ )); do
7501                 file=$dir/file$i
7502                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7503                         error "write data into $file failed"
7504         done
7505         for ((i = 1; i <= NUMDIRS; i++ )); do
7506                 for ((j = 1; j <= NUMFILES; j++ )); do
7507                         file=$dir/dir$i/file$j
7508                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7509                                 error "write data into $file failed"
7510                 done
7511         done
7512
7513         # $LFS_MIGRATE will fail if hard link migration is unsupported
7514         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7515                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7516                         error "creating links to $dir/dir1/file1 failed"
7517         fi
7518
7519         local expected=-1
7520
7521         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7522
7523         # lfs_migrate file
7524         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7525
7526         echo "$cmd"
7527         eval $cmd || error "$cmd failed"
7528
7529         check_stripe_count $dir/file1 $expected
7530
7531         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7532                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7533                 # OST 1 if it is on OST 0. This file is small enough to
7534                 # be on only one stripe.
7535                 file=$dir/migr_1_ost
7536                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7537                         error "write data into $file failed"
7538                 local obdidx=$($LFS getstripe -i $file)
7539                 local oldmd5=$(md5sum $file)
7540                 local newobdidx=0
7541
7542                 (( obdidx != 0 )) || newobdidx=1
7543                 cmd="$LFS migrate -i $newobdidx $file"
7544                 echo $cmd
7545                 eval $cmd || error "$cmd failed"
7546
7547                 local realobdix=$($LFS getstripe -i $file)
7548                 local newmd5=$(md5sum $file)
7549
7550                 (( $newobdidx == $realobdix )) ||
7551                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7552                 [[ "$oldmd5" == "$newmd5" ]] ||
7553                         error "md5sum differ: $oldmd5, $newmd5"
7554         fi
7555
7556         # lfs_migrate dir
7557         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7558         echo "$cmd"
7559         eval $cmd || error "$cmd failed"
7560
7561         for (( j = 1; j <= NUMFILES; j++ )); do
7562                 check_stripe_count $dir/dir1/file$j $expected
7563         done
7564
7565         # lfs_migrate works with lfs find
7566         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7567              $LFS_MIGRATE -y -c $expected"
7568         echo "$cmd"
7569         eval $cmd || error "$cmd failed"
7570
7571         for (( i = 2; i <= NUMFILES; i++ )); do
7572                 check_stripe_count $dir/file$i $expected
7573         done
7574         for (( i = 2; i <= NUMDIRS; i++ )); do
7575                 for (( j = 1; j <= NUMFILES; j++ )); do
7576                         check_stripe_count $dir/dir$i/file$j $expected
7577                 done
7578         done
7579 }
7580 run_test 56wa "check lfs_migrate -c stripe_count works"
7581
7582 test_56wb() {
7583         local file1=$DIR/$tdir/file1
7584         local create_pool=false
7585         local initial_pool=$($LFS getstripe -p $DIR)
7586         local pool_list=()
7587         local pool=""
7588
7589         echo -n "Creating test dir..."
7590         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7591         echo "done."
7592
7593         echo -n "Creating test file..."
7594         touch $file1 || error "cannot create file"
7595         echo "done."
7596
7597         echo -n "Detecting existing pools..."
7598         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7599
7600         if [ ${#pool_list[@]} -gt 0 ]; then
7601                 echo "${pool_list[@]}"
7602                 for thispool in "${pool_list[@]}"; do
7603                         if [[ -z "$initial_pool" ||
7604                               "$initial_pool" != "$thispool" ]]; then
7605                                 pool="$thispool"
7606                                 echo "Using existing pool '$pool'"
7607                                 break
7608                         fi
7609                 done
7610         else
7611                 echo "none detected."
7612         fi
7613         if [ -z "$pool" ]; then
7614                 pool=${POOL:-testpool}
7615                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7616                 echo -n "Creating pool '$pool'..."
7617                 create_pool=true
7618                 pool_add $pool &> /dev/null ||
7619                         error "pool_add failed"
7620                 echo "done."
7621
7622                 echo -n "Adding target to pool..."
7623                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7624                         error "pool_add_targets failed"
7625                 echo "done."
7626         fi
7627
7628         echo -n "Setting pool using -p option..."
7629         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7630                 error "migrate failed rc = $?"
7631         echo "done."
7632
7633         echo -n "Verifying test file is in pool after migrating..."
7634         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7635                 error "file was not migrated to pool $pool"
7636         echo "done."
7637
7638         echo -n "Removing test file from pool '$pool'..."
7639         # "lfs migrate $file" won't remove the file from the pool
7640         # until some striping information is changed.
7641         $LFS migrate -c 1 $file1 &> /dev/null ||
7642                 error "cannot remove from pool"
7643         [ "$($LFS getstripe -p $file1)" ] &&
7644                 error "pool still set"
7645         echo "done."
7646
7647         echo -n "Setting pool using --pool option..."
7648         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7649                 error "migrate failed rc = $?"
7650         echo "done."
7651
7652         # Clean up
7653         rm -f $file1
7654         if $create_pool; then
7655                 destroy_test_pools 2> /dev/null ||
7656                         error "destroy test pools failed"
7657         fi
7658 }
7659 run_test 56wb "check lfs_migrate pool support"
7660
7661 test_56wc() {
7662         local file1="$DIR/$tdir/$tfile"
7663         local md5
7664         local parent_ssize
7665         local parent_scount
7666         local cur_ssize
7667         local cur_scount
7668         local orig_ssize
7669         local new_scount
7670         local cur_comp
7671
7672         echo -n "Creating test dir..."
7673         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7674         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7675                 error "cannot set stripe by '-S 1M -c 1'"
7676         echo "done"
7677
7678         echo -n "Setting initial stripe for test file..."
7679         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7680                 error "cannot set stripe"
7681         cur_ssize=$($LFS getstripe -S "$file1")
7682         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7683         echo "done."
7684
7685         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7686         stack_trap "rm -f $file1"
7687         md5="$(md5sum $file1)"
7688
7689         # File currently set to -S 512K -c 1
7690
7691         # Ensure -c and -S options are rejected when -R is set
7692         echo -n "Verifying incompatible options are detected..."
7693         $LFS_MIGRATE -R -c 1 "$file1" &&
7694                 error "incompatible -R and -c options not detected"
7695         $LFS_MIGRATE -R -S 1M "$file1" &&
7696                 error "incompatible -R and -S options not detected"
7697         $LFS_MIGRATE -R -p pool "$file1" &&
7698                 error "incompatible -R and -p options not detected"
7699         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7700                 error "incompatible -R and -E options not detected"
7701         $LFS_MIGRATE -R -A "$file1" &&
7702                 error "incompatible -R and -A options not detected"
7703         $LFS_MIGRATE -A -c 1 "$file1" &&
7704                 error "incompatible -A and -c options not detected"
7705         $LFS_MIGRATE -A -S 1M "$file1" &&
7706                 error "incompatible -A and -S options not detected"
7707         $LFS_MIGRATE -A -p pool "$file1" &&
7708                 error "incompatible -A and -p options not detected"
7709         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7710                 error "incompatible -A and -E options not detected"
7711         echo "done."
7712
7713         # Ensure unrecognized options are passed through to 'lfs migrate'
7714         echo -n "Verifying -S option is passed through to lfs migrate..."
7715         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7716         cur_ssize=$($LFS getstripe -S "$file1")
7717         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7718         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7719         echo "done."
7720
7721         # File currently set to -S 1M -c 1
7722
7723         # Ensure long options are supported
7724         echo -n "Verifying long options supported..."
7725         $LFS_MIGRATE --non-block "$file1" ||
7726                 error "long option without argument not supported"
7727         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7728                 error "long option with argument not supported"
7729         cur_ssize=$($LFS getstripe -S "$file1")
7730         (( cur_ssize == 524288 )) ||
7731                 error "migrate --stripe-size $cur_ssize != 524288"
7732         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7733         echo "done."
7734
7735         # File currently set to -S 512K -c 1
7736
7737         if (( OSTCOUNT > 1 )); then
7738                 echo -n "Verifying explicit stripe count can be set..."
7739                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7740                 cur_scount=$($LFS getstripe -c "$file1")
7741                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7742                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7743                         error "file data has changed (3)"
7744                 echo "done."
7745         fi
7746
7747         # File currently set to -S 512K -c 1 or -S 512K -c 2
7748
7749         # Ensure parent striping is used if -R is set, and no stripe
7750         # count or size is specified
7751         echo -n "Setting stripe for parent directory..."
7752         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7753                 error "cannot set stripe '-S 2M -c 1'"
7754         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7755         echo "done."
7756
7757         echo -n "Verifying restripe option uses parent stripe settings..."
7758         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7759         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7760         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7761         cur_ssize=$($LFS getstripe -S "$file1")
7762         (( cur_ssize == parent_ssize )) ||
7763                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7764         cur_scount=$($LFS getstripe -c "$file1")
7765         (( cur_scount == parent_scount )) ||
7766                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7767         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7768         echo "done."
7769
7770         # File currently set to -S 1M -c 1
7771
7772         # Ensure striping is preserved if -R is not set, and no stripe
7773         # count or size is specified
7774         echo -n "Verifying striping size preserved when not specified..."
7775         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7776         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7777                 error "cannot set stripe on parent directory"
7778         $LFS_MIGRATE "$file1" || error "migrate failed"
7779         cur_ssize=$($LFS getstripe -S "$file1")
7780         (( cur_ssize == orig_ssize )) ||
7781                 error "migrate by default $cur_ssize != $orig_ssize"
7782         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7783         echo "done."
7784
7785         # Ensure file name properly detected when final option has no argument
7786         echo -n "Verifying file name properly detected..."
7787         $LFS_MIGRATE "$file1" ||
7788                 error "file name interpreted as option argument"
7789         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7790         echo "done."
7791
7792         # Ensure PFL arguments are passed through properly
7793         echo -n "Verifying PFL options passed through..."
7794         new_scount=$(((OSTCOUNT + 1) / 2))
7795         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7796                 error "migrate PFL arguments failed"
7797         cur_comp=$($LFS getstripe --comp-count $file1)
7798         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7799         cur_scount=$($LFS getstripe --stripe-count $file1)
7800         (( cur_scount == new_scount)) ||
7801                 error "PFL stripe count $cur_scount != $new_scount"
7802         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7803         echo "done."
7804 }
7805 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7806
7807 test_56wd() {
7808         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7809
7810         local file1=$DIR/$tdir/$tfile
7811
7812         echo -n "Creating test dir..."
7813         test_mkdir $DIR/$tdir || error "cannot create dir"
7814         echo "done."
7815
7816         echo -n "Creating test file..."
7817         echo "$tfile" > $file1
7818         echo "done."
7819
7820         # Ensure 'lfs migrate' will fail by using a non-existent option,
7821         # and make sure rsync is not called to recover
7822         echo -n "Make sure --no-rsync option works..."
7823         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7824                 grep -q 'refusing to fall back to rsync' ||
7825                 error "rsync was called with --no-rsync set"
7826         echo "done."
7827
7828         # Ensure rsync is called without trying 'lfs migrate' first
7829         echo -n "Make sure --rsync option works..."
7830         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7831                 grep -q 'falling back to rsync' &&
7832                 error "lfs migrate was called with --rsync set"
7833         echo "done."
7834 }
7835 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7836
7837 test_56we() {
7838         local td=$DIR/$tdir
7839         local tf=$td/$tfile
7840
7841         test_mkdir $td || error "cannot create $td"
7842         touch $tf || error "cannot touch $tf"
7843
7844         echo -n "Make sure --non-direct|-D works..."
7845         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7846                 grep -q "lfs migrate --non-direct" ||
7847                 error "--non-direct option cannot work correctly"
7848         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7849                 grep -q "lfs migrate -D" ||
7850                 error "-D option cannot work correctly"
7851         echo "done."
7852 }
7853 run_test 56we "check lfs_migrate --non-direct|-D support"
7854
7855 test_56x() {
7856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7857         check_swap_layouts_support
7858
7859         local dir=$DIR/$tdir
7860         local ref1=/etc/passwd
7861         local file1=$dir/file1
7862
7863         test_mkdir $dir || error "creating dir $dir"
7864         $LFS setstripe -c 2 $file1
7865         cp $ref1 $file1
7866         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7867         stripe=$($LFS getstripe -c $file1)
7868         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7869         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7870
7871         # clean up
7872         rm -f $file1
7873 }
7874 run_test 56x "lfs migration support"
7875
7876 test_56xa() {
7877         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7878         check_swap_layouts_support
7879
7880         local dir=$DIR/$tdir/$testnum
7881
7882         test_mkdir -p $dir
7883
7884         local ref1=/etc/passwd
7885         local file1=$dir/file1
7886
7887         $LFS setstripe -c 2 $file1
7888         cp $ref1 $file1
7889         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7890
7891         local stripe=$($LFS getstripe -c $file1)
7892
7893         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7894         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7895
7896         # clean up
7897         rm -f $file1
7898 }
7899 run_test 56xa "lfs migration --block support"
7900
7901 check_migrate_links() {
7902         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7903         local dir="$1"
7904         local file1="$dir/file1"
7905         local begin="$2"
7906         local count="$3"
7907         local runas="$4"
7908         local total_count=$(($begin + $count - 1))
7909         local symlink_count=10
7910         local uniq_count=10
7911
7912         if [ ! -f "$file1" ]; then
7913                 echo -n "creating initial file..."
7914                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7915                         error "cannot setstripe initial file"
7916                 echo "done"
7917
7918                 echo -n "creating symlinks..."
7919                 for s in $(seq 1 $symlink_count); do
7920                         ln -s "$file1" "$dir/slink$s" ||
7921                                 error "cannot create symlinks"
7922                 done
7923                 echo "done"
7924
7925                 echo -n "creating nonlinked files..."
7926                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7927                         error "cannot create nonlinked files"
7928                 echo "done"
7929         fi
7930
7931         # create hard links
7932         if [ ! -f "$dir/file$total_count" ]; then
7933                 echo -n "creating hard links $begin:$total_count..."
7934                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7935                         /dev/null || error "cannot create hard links"
7936                 echo "done"
7937         fi
7938
7939         echo -n "checking number of hard links listed in xattrs..."
7940         local fid=$($LFS getstripe -F "$file1")
7941         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7942
7943         echo "${#paths[*]}"
7944         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7945                         skip "hard link list has unexpected size, skipping test"
7946         fi
7947         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7948                         error "link names should exceed xattrs size"
7949         fi
7950
7951         echo -n "migrating files..."
7952         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7953         local rc=$?
7954         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7955         echo "done"
7956
7957         # make sure all links have been properly migrated
7958         echo -n "verifying files..."
7959         fid=$($LFS getstripe -F "$file1") ||
7960                 error "cannot get fid for file $file1"
7961         for i in $(seq 2 $total_count); do
7962                 local fid2=$($LFS getstripe -F $dir/file$i)
7963
7964                 [ "$fid2" == "$fid" ] ||
7965                         error "migrated hard link has mismatched FID"
7966         done
7967
7968         # make sure hard links were properly detected, and migration was
7969         # performed only once for the entire link set; nonlinked files should
7970         # also be migrated
7971         local actual=$(grep -c 'done' <<< "$migrate_out")
7972         local expected=$(($uniq_count + 1))
7973
7974         [ "$actual" -eq  "$expected" ] ||
7975                 error "hard links individually migrated ($actual != $expected)"
7976
7977         # make sure the correct number of hard links are present
7978         local hardlinks=$(stat -c '%h' "$file1")
7979
7980         [ $hardlinks -eq $total_count ] ||
7981                 error "num hard links $hardlinks != $total_count"
7982         echo "done"
7983
7984         return 0
7985 }
7986
7987 test_56xb() {
7988         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7989                 skip "Need MDS version at least 2.10.55"
7990
7991         local dir="$DIR/$tdir"
7992
7993         test_mkdir "$dir" || error "cannot create dir $dir"
7994
7995         echo "testing lfs migrate mode when all links fit within xattrs"
7996         check_migrate_links "$dir" 2 99
7997
7998         echo "testing rsync mode when all links fit within xattrs"
7999         check_migrate_links --rsync "$dir" 2 99
8000
8001         echo "testing lfs migrate mode when all links do not fit within xattrs"
8002         check_migrate_links "$dir" 101 100
8003
8004         echo "testing rsync mode when all links do not fit within xattrs"
8005         check_migrate_links --rsync "$dir" 101 100
8006
8007         chown -R $RUNAS_ID $dir
8008         echo "testing non-root lfs migrate mode when not all links are in xattr"
8009         check_migrate_links "$dir" 101 100 "$RUNAS"
8010
8011         # clean up
8012         rm -rf $dir
8013 }
8014 run_test 56xb "lfs migration hard link support"
8015
8016 test_56xc() {
8017         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8018
8019         local dir="$DIR/$tdir"
8020
8021         test_mkdir "$dir" || error "cannot create dir $dir"
8022
8023         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8024         echo -n "Setting initial stripe for 20MB test file..."
8025         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8026                 error "cannot setstripe 20MB file"
8027         echo "done"
8028         echo -n "Sizing 20MB test file..."
8029         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8030         echo "done"
8031         echo -n "Verifying small file autostripe count is 1..."
8032         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8033                 error "cannot migrate 20MB file"
8034         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8035                 error "cannot get stripe for $dir/20mb"
8036         [ $stripe_count -eq 1 ] ||
8037                 error "unexpected stripe count $stripe_count for 20MB file"
8038         rm -f "$dir/20mb"
8039         echo "done"
8040
8041         # Test 2: File is small enough to fit within the available space on
8042         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8043         # have at least an additional 1KB for each desired stripe for test 3
8044         echo -n "Setting stripe for 1GB test file..."
8045         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8046         echo "done"
8047         echo -n "Sizing 1GB test file..."
8048         # File size is 1GB + 3KB
8049         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8050         echo "done"
8051
8052         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8053         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8054         if (( avail > 524288 * OSTCOUNT )); then
8055                 echo -n "Migrating 1GB file..."
8056                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8057                         error "cannot migrate 1GB file"
8058                 echo "done"
8059                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8060                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8061                         error "cannot getstripe for 1GB file"
8062                 [ $stripe_count -eq 2 ] ||
8063                         error "unexpected stripe count $stripe_count != 2"
8064                 echo "done"
8065         fi
8066
8067         # Test 3: File is too large to fit within the available space on
8068         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8069         if [ $OSTCOUNT -ge 3 ]; then
8070                 # The required available space is calculated as
8071                 # file size (1GB + 3KB) / OST count (3).
8072                 local kb_per_ost=349526
8073
8074                 echo -n "Migrating 1GB file with limit..."
8075                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8076                         error "cannot migrate 1GB file with limit"
8077                 echo "done"
8078
8079                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8080                 echo -n "Verifying 1GB autostripe count with limited space..."
8081                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8082                         error "unexpected stripe count $stripe_count (min 3)"
8083                 echo "done"
8084         fi
8085
8086         # clean up
8087         rm -rf $dir
8088 }
8089 run_test 56xc "lfs migration autostripe"
8090
8091 test_56xd() {
8092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8093
8094         local dir=$DIR/$tdir
8095         local f_mgrt=$dir/$tfile.mgrt
8096         local f_yaml=$dir/$tfile.yaml
8097         local f_copy=$dir/$tfile.copy
8098         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8099         local layout_copy="-c 2 -S 2M -i 1"
8100         local yamlfile=$dir/yamlfile
8101         local layout_before;
8102         local layout_after;
8103
8104         test_mkdir "$dir" || error "cannot create dir $dir"
8105         stack_trap "rm -rf $dir"
8106         $LFS setstripe $layout_yaml $f_yaml ||
8107                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8108         $LFS getstripe --yaml $f_yaml > $yamlfile
8109         $LFS setstripe $layout_copy $f_copy ||
8110                 error "cannot setstripe $f_copy with layout $layout_copy"
8111         touch $f_mgrt
8112         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8113
8114         # 1. test option --yaml
8115         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8116                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8117         layout_before=$(get_layout_param $f_yaml)
8118         layout_after=$(get_layout_param $f_mgrt)
8119         [ "$layout_after" == "$layout_before" ] ||
8120                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8121
8122         # 2. test option --copy
8123         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8124                 error "cannot migrate $f_mgrt with --copy $f_copy"
8125         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8126         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8127         [ "$layout_after" == "$layout_before" ] ||
8128                 error "lfs_migrate --copy: $layout_after != $layout_before"
8129 }
8130 run_test 56xd "check lfs_migrate --yaml and --copy support"
8131
8132 test_56xe() {
8133         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8134
8135         local dir=$DIR/$tdir
8136         local f_comp=$dir/$tfile
8137         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8138         local layout_before=""
8139         local layout_after=""
8140
8141         test_mkdir "$dir" || error "cannot create dir $dir"
8142         stack_trap "rm -rf $dir"
8143         $LFS setstripe $layout $f_comp ||
8144                 error "cannot setstripe $f_comp with layout $layout"
8145         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8146         dd if=/dev/zero of=$f_comp bs=1M count=4
8147
8148         # 1. migrate a comp layout file by lfs_migrate
8149         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8150         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8151         [ "$layout_before" == "$layout_after" ] ||
8152                 error "lfs_migrate: $layout_before != $layout_after"
8153
8154         # 2. migrate a comp layout file by lfs migrate
8155         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8156         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8157         [ "$layout_before" == "$layout_after" ] ||
8158                 error "lfs migrate: $layout_before != $layout_after"
8159 }
8160 run_test 56xe "migrate a composite layout file"
8161
8162 test_56xf() {
8163         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8164
8165         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8166                 skip "Need server version at least 2.13.53"
8167
8168         local dir=$DIR/$tdir
8169         local f_comp=$dir/$tfile
8170         local layout="-E 1M -c1 -E -1 -c2"
8171         local fid_before=""
8172         local fid_after=""
8173
8174         test_mkdir "$dir" || error "cannot create dir $dir"
8175         stack_trap "rm -rf $dir"
8176         $LFS setstripe $layout $f_comp ||
8177                 error "cannot setstripe $f_comp with layout $layout"
8178         fid_before=$($LFS getstripe --fid $f_comp)
8179         dd if=/dev/zero of=$f_comp bs=1M count=4
8180
8181         # 1. migrate a comp layout file to a comp layout
8182         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8183         fid_after=$($LFS getstripe --fid $f_comp)
8184         [ "$fid_before" == "$fid_after" ] ||
8185                 error "comp-to-comp migrate: $fid_before != $fid_after"
8186
8187         # 2. migrate a comp layout file to a plain layout
8188         $LFS migrate -c2 $f_comp ||
8189                 error "cannot migrate $f_comp by lfs migrate"
8190         fid_after=$($LFS getstripe --fid $f_comp)
8191         [ "$fid_before" == "$fid_after" ] ||
8192                 error "comp-to-plain migrate: $fid_before != $fid_after"
8193
8194         # 3. migrate a plain layout file to a comp layout
8195         $LFS migrate $layout $f_comp ||
8196                 error "cannot migrate $f_comp by lfs migrate"
8197         fid_after=$($LFS getstripe --fid $f_comp)
8198         [ "$fid_before" == "$fid_after" ] ||
8199                 error "plain-to-comp migrate: $fid_before != $fid_after"
8200 }
8201 run_test 56xf "FID is not lost during migration of a composite layout file"
8202
8203 check_file_ost_range() {
8204         local file="$1"
8205         shift
8206         local range="$*"
8207         local -a file_range
8208         local idx
8209
8210         file_range=($($LFS getstripe -y "$file" |
8211                 awk '/l_ost_idx:/ { print $NF }'))
8212
8213         if [[ "${#file_range[@]}" = 0 ]]; then
8214                 echo "No osts found for $file"
8215                 return 1
8216         fi
8217
8218         for idx in "${file_range[@]}"; do
8219                 [[ " $range " =~ " $idx " ]] ||
8220                         return 1
8221         done
8222
8223         return 0
8224 }
8225
8226 sub_test_56xg() {
8227         local stripe_opt="$1"
8228         local pool="$2"
8229         shift 2
8230         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8231
8232         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8233                 error "Fail to migrate $tfile on $pool"
8234         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8235                 error "$tfile is not in pool $pool"
8236         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8237                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8238 }
8239
8240 test_56xg() {
8241         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8242         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8243         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8244                 skip "Need MDS version newer than 2.14.52"
8245
8246         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8247         local -a pool_ranges=("0 0" "1 1" "0 1")
8248
8249         # init pools
8250         for i in "${!pool_names[@]}"; do
8251                 pool_add ${pool_names[$i]} ||
8252                         error "pool_add failed (pool: ${pool_names[$i]})"
8253                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8254                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8255         done
8256
8257         # init the file to migrate
8258         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8259                 error "Unable to create $tfile on OST1"
8260         stack_trap "rm -f $DIR/$tfile"
8261         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8262                 error "Unable to write on $tfile"
8263
8264         echo "1. migrate $tfile on pool ${pool_names[0]}"
8265         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8266
8267         echo "2. migrate $tfile on pool ${pool_names[2]}"
8268         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8269
8270         echo "3. migrate $tfile on pool ${pool_names[1]}"
8271         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8272
8273         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8274         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8275         echo
8276
8277         # Clean pools
8278         destroy_test_pools ||
8279                 error "pool_destroy failed"
8280 }
8281 run_test 56xg "lfs migrate pool support"
8282
8283 test_56xh() {
8284         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8285
8286         local size_mb=25
8287         local file1=$DIR/$tfile
8288         local tmp1=$TMP/$tfile.tmp
8289
8290         $LFS setstripe -c 2 $file1
8291
8292         stack_trap "rm -f $file1 $tmp1"
8293         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8294                         error "error creating $tmp1"
8295         ls -lsh $tmp1
8296         cp $tmp1 $file1
8297
8298         local start=$SECONDS
8299
8300         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8301                 error "migrate failed rc = $?"
8302
8303         local elapsed=$((SECONDS - start))
8304
8305         # with 1MB/s, elapsed should equal size_mb
8306         (( elapsed >= size_mb * 95 / 100 )) ||
8307                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8308
8309         (( elapsed <= size_mb * 120 / 100 )) ||
8310                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8311
8312         (( elapsed <= size_mb * 350 / 100 )) ||
8313                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8314
8315         stripe=$($LFS getstripe -c $file1)
8316         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8317         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8318
8319         # Clean up file (since it is multiple MB)
8320         rm -f $file1 $tmp1
8321 }
8322 run_test 56xh "lfs migrate bandwidth limitation support"
8323
8324 test_56xi() {
8325         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8326         verify_yaml_available || skip_env "YAML verification not installed"
8327
8328         local size_mb=5
8329         local file1=$DIR/$tfile.1
8330         local file2=$DIR/$tfile.2
8331         local file3=$DIR/$tfile.3
8332         local output_file=$DIR/$tfile.out
8333         local tmp1=$TMP/$tfile.tmp
8334
8335         $LFS setstripe -c 2 $file1
8336         $LFS setstripe -c 2 $file2
8337         $LFS setstripe -c 2 $file3
8338
8339         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8340         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8341                         error "error creating $tmp1"
8342         ls -lsh $tmp1
8343         cp $tmp1 $file1
8344         cp $tmp1 $file2
8345         cp $tmp1 $file3
8346
8347         $LFS migrate --stats --stats-interval=1 \
8348                 -c 1 $file1 $file2 $file3 1> $output_file ||
8349                 error "migrate failed rc = $?"
8350
8351         cat $output_file
8352         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8353
8354         # Clean up file (since it is multiple MB)
8355         rm -f $file1 $file2 $file3 $tmp1 $output_file
8356 }
8357 run_test 56xi "lfs migrate stats support"
8358
8359 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8360         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8361
8362         local file=$DIR/$tfile
8363         local linkdir=$DIR/$tdir
8364
8365         test_mkdir $linkdir || error "fail to create $linkdir"
8366         $LFS setstripe -i 0 -c 1 -S1M $file
8367         stack_trap "rm -rf $file $linkdir"
8368         dd if=/dev/urandom of=$file bs=1M count=10 ||
8369                 error "fail to create $file"
8370
8371         # Create file links
8372         local cpts
8373         local threads_max
8374         local nlinks
8375
8376         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8377         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8378         (( nlinks = thread_max * 3 / 2 / cpts))
8379
8380         echo "create $nlinks hard links of $file"
8381         createmany -l $file $linkdir/link $nlinks
8382
8383         # Parallel migrates (should not block)
8384         local i
8385         for ((i = 0; i < nlinks; i++)); do
8386                 echo $linkdir/link$i
8387         done | xargs -n1 -P $nlinks $LFS migrate -c2
8388
8389         local stripe_count
8390         stripe_count=$($LFS getstripe -c $file) ||
8391                 error "fail to get stripe count on $file"
8392
8393         ((stripe_count == 2)) ||
8394                 error "fail to migrate $file (stripe_count = $stripe_count)"
8395 }
8396 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8397
8398 test_56xk() {
8399         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8400
8401         local size_mb=5
8402         local file1=$DIR/$tfile
8403
8404         stack_trap "rm -f $file1"
8405         $LFS setstripe -c 1 $file1
8406         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8407                 error "error creating $file1"
8408         $LFS mirror extend -N $file1 || error "can't mirror"
8409         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8410                 error "can't dd"
8411         $LFS getstripe $file1 | grep stale ||
8412                 error "one component must be stale"
8413
8414         local start=$SECONDS
8415         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8416                 error "migrate failed rc = $?"
8417         local elapsed=$((SECONDS - start))
8418         $LFS getstripe $file1 | grep stale &&
8419                 error "all components must be sync"
8420
8421         # with 1MB/s, elapsed should equal size_mb
8422         (( elapsed >= size_mb * 95 / 100 )) ||
8423                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8424
8425         (( elapsed <= size_mb * 120 / 100 )) ||
8426                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8427
8428         (( elapsed <= size_mb * 350 / 100 )) ||
8429                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8430 }
8431 run_test 56xk "lfs mirror resync bandwidth limitation support"
8432
8433 test_56xl() {
8434         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8435         verify_yaml_available || skip_env "YAML verification not installed"
8436
8437         local size_mb=5
8438         local file1=$DIR/$tfile.1
8439         local output_file=$DIR/$tfile.out
8440
8441         stack_trap "rm -f $file1"
8442         $LFS setstripe -c 1 $file1
8443         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8444                 error "error creating $file1"
8445         $LFS mirror extend -N $file1 || error "can't mirror"
8446         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8447                 error "can't dd"
8448         $LFS getstripe $file1 | grep stale ||
8449                 error "one component must be stale"
8450         $LFS getstripe $file1
8451
8452         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8453                 error "resync failed rc = $?"
8454         $LFS getstripe $file1 | grep stale &&
8455                 error "all components must be sync"
8456
8457         cat $output_file
8458         cat $output_file | verify_yaml || error "stats is not valid YAML"
8459 }
8460 run_test 56xl "lfs mirror resync stats support"
8461
8462 test_56y() {
8463         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8464                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8465
8466         local res=""
8467         local dir=$DIR/$tdir
8468         local f1=$dir/file1
8469         local f2=$dir/file2
8470
8471         test_mkdir -p $dir || error "creating dir $dir"
8472         touch $f1 || error "creating std file $f1"
8473         $MULTIOP $f2 H2c || error "creating released file $f2"
8474
8475         # a directory can be raid0, so ask only for files
8476         res=$($LFS find $dir -L raid0 -type f | wc -l)
8477         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8478
8479         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8480         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8481
8482         # only files can be released, so no need to force file search
8483         res=$($LFS find $dir -L released)
8484         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8485
8486         res=$($LFS find $dir -type f \! -L released)
8487         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8488 }
8489 run_test 56y "lfs find -L raid0|released"
8490
8491 test_56z() { # LU-4824
8492         # This checks to make sure 'lfs find' continues after errors
8493         # There are two classes of errors that should be caught:
8494         # - If multiple paths are provided, all should be searched even if one
8495         #   errors out
8496         # - If errors are encountered during the search, it should not terminate
8497         #   early
8498         local dir=$DIR/$tdir
8499         local i
8500
8501         test_mkdir $dir
8502         for i in d{0..9}; do
8503                 test_mkdir $dir/$i
8504                 touch $dir/$i/$tfile
8505         done
8506         $LFS find $DIR/non_existent_dir $dir &&
8507                 error "$LFS find did not return an error"
8508         # Make a directory unsearchable. This should NOT be the last entry in
8509         # directory order.  Arbitrarily pick the 6th entry
8510         chmod 700 $($LFS find $dir -type d | sed '6!d')
8511
8512         $RUNAS $LFS find $DIR/non_existent $dir
8513         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8514
8515         # The user should be able to see 10 directories and 9 files
8516         (( count == 19 )) ||
8517                 error "$LFS find found $count != 19 entries after error"
8518 }
8519 run_test 56z "lfs find should continue after an error"
8520
8521 test_56aa() { # LU-5937
8522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8523
8524         local dir=$DIR/$tdir
8525
8526         mkdir $dir
8527         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8528
8529         createmany -o $dir/striped_dir/${tfile}- 1024
8530         local dirs=$($LFS find --size +8k $dir/)
8531
8532         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8533 }
8534 run_test 56aa "lfs find --size under striped dir"
8535
8536 test_56ab() { # LU-10705
8537         test_mkdir $DIR/$tdir
8538         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8539         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8540         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8541         # Flush writes to ensure valid blocks.  Need to be more thorough for
8542         # ZFS, since blocks are not allocated/returned to client immediately.
8543         sync_all_data
8544         wait_zfs_commit ost1 2
8545         cancel_lru_locks osc
8546         ls -ls $DIR/$tdir
8547
8548         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8549
8550         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8551
8552         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8553         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8554
8555         rm -f $DIR/$tdir/$tfile.[123]
8556 }
8557 run_test 56ab "lfs find --blocks"
8558
8559 # LU-11188
8560 test_56aca() {
8561         local dir="$DIR/$tdir"
8562         local perms=(001 002 003 004 005 006 007
8563                      010 020 030 040 050 060 070
8564                      100 200 300 400 500 600 700
8565                      111 222 333 444 555 666 777)
8566         local perm_minus=(8 8 4 8 4 4 2
8567                           8 8 4 8 4 4 2
8568                           8 8 4 8 4 4 2
8569                           4 4 2 4 2 2 1)
8570         local perm_slash=(8  8 12  8 12 12 14
8571                           8  8 12  8 12 12 14
8572                           8  8 12  8 12 12 14
8573                          16 16 24 16 24 24 28)
8574
8575         test_mkdir "$dir"
8576         for perm in ${perms[*]}; do
8577                 touch "$dir/$tfile.$perm"
8578                 chmod $perm "$dir/$tfile.$perm"
8579         done
8580
8581         for ((i = 0; i < ${#perms[*]}; i++)); do
8582                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8583                 (( $num == 1 )) ||
8584                         error "lfs find -perm ${perms[i]}:"\
8585                               "$num != 1"
8586
8587                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8588                 (( $num == ${perm_minus[i]} )) ||
8589                         error "lfs find -perm -${perms[i]}:"\
8590                               "$num != ${perm_minus[i]}"
8591
8592                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8593                 (( $num == ${perm_slash[i]} )) ||
8594                         error "lfs find -perm /${perms[i]}:"\
8595                               "$num != ${perm_slash[i]}"
8596         done
8597 }
8598 run_test 56aca "check lfs find -perm with octal representation"
8599
8600 test_56acb() {
8601         local dir=$DIR/$tdir
8602         # p is the permission of write and execute for user, group and other
8603         # without the umask. It is used to test +wx.
8604         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8605         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8606         local symbolic=(+t  a+t u+t g+t o+t
8607                         g+s u+s o+s +s o+sr
8608                         o=r,ug+o,u+w
8609                         u+ g+ o+ a+ ugo+
8610                         u- g- o- a- ugo-
8611                         u= g= o= a= ugo=
8612                         o=r,ug+o,u+w u=r,a+u,u+w
8613                         g=r,ugo=g,u+w u+x,+X +X
8614                         u+x,u+X u+X u+x,g+X o+r,+X
8615                         u+x,go+X +wx +rwx)
8616
8617         test_mkdir $dir
8618         for perm in ${perms[*]}; do
8619                 touch "$dir/$tfile.$perm"
8620                 chmod $perm "$dir/$tfile.$perm"
8621         done
8622
8623         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8624                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8625
8626                 (( $num == 1 )) ||
8627                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8628         done
8629 }
8630 run_test 56acb "check lfs find -perm with symbolic representation"
8631
8632 test_56acc() {
8633         local dir=$DIR/$tdir
8634         local tests="17777 787 789 abcd
8635                 ug=uu ug=a ug=gu uo=ou urw
8636                 u+xg+x a=r,u+x,"
8637
8638         test_mkdir $dir
8639         for err in $tests; do
8640                 if $LFS find $dir -perm $err 2>/dev/null; then
8641                         error "lfs find -perm $err: parsing should have failed"
8642                 fi
8643         done
8644 }
8645 run_test 56acc "check parsing error for lfs find -perm"
8646
8647 test_56ba() {
8648         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8649                 skip "Need MDS version at least 2.10.50"
8650
8651         # Create composite files with one component
8652         local dir=$DIR/$tdir
8653
8654         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8655         # Create composite files with three components
8656         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8657         # LU-16904 Create plain layout files
8658         lfs setstripe -c 1 $dir/$tfile-{1..10}
8659
8660         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8661
8662         [[ $nfiles == 10 ]] ||
8663                 error "lfs find -E 1M found $nfiles != 10 files"
8664
8665         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8666         [[ $nfiles == 25 ]] ||
8667                 error "lfs find ! -E 1M found $nfiles != 25 files"
8668
8669         # All files have a component that starts at 0
8670         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8671         [[ $nfiles == 35 ]] ||
8672                 error "lfs find --component-start 0 - $nfiles != 35 files"
8673
8674         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8675         [[ $nfiles == 15 ]] ||
8676                 error "lfs find --component-start 2M - $nfiles != 15 files"
8677
8678         # All files created here have a componenet that does not starts at 2M
8679         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8680         [[ $nfiles == 35 ]] ||
8681                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8682
8683         # Find files with a specified number of components
8684         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8685         [[ $nfiles == 15 ]] ||
8686                 error "lfs find --component-count 3 - $nfiles != 15 files"
8687
8688         # Remember non-composite files have a component count of zero
8689         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8690         [[ $nfiles == 10 ]] ||
8691                 error "lfs find --component-count 0 - $nfiles != 10 files"
8692
8693         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8694         [[ $nfiles == 20 ]] ||
8695                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8696
8697         # All files have a flag called "init"
8698         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8699         [[ $nfiles == 35 ]] ||
8700                 error "lfs find --component-flags init - $nfiles != 35 files"
8701
8702         # Multi-component files will have a component not initialized
8703         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8704         [[ $nfiles == 15 ]] ||
8705                 error "lfs find !--component-flags init - $nfiles != 15 files"
8706
8707         rm -rf $dir
8708
8709 }
8710 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8711
8712 test_56ca() {
8713         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8714                 skip "Need MDS version at least 2.10.57"
8715
8716         local td=$DIR/$tdir
8717         local tf=$td/$tfile
8718         local dir
8719         local nfiles
8720         local cmd
8721         local i
8722         local j
8723
8724         # create mirrored directories and mirrored files
8725         mkdir $td || error "mkdir $td failed"
8726         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8727         createmany -o $tf- 10 || error "create $tf- failed"
8728
8729         for i in $(seq 2); do
8730                 dir=$td/dir$i
8731                 mkdir $dir || error "mkdir $dir failed"
8732                 $LFS mirror create -N$((3 + i)) $dir ||
8733                         error "create mirrored dir $dir failed"
8734                 createmany -o $dir/$tfile- 10 ||
8735                         error "create $dir/$tfile- failed"
8736         done
8737
8738         # change the states of some mirrored files
8739         echo foo > $tf-6
8740         for i in $(seq 2); do
8741                 dir=$td/dir$i
8742                 for j in $(seq 4 9); do
8743                         echo foo > $dir/$tfile-$j
8744                 done
8745         done
8746
8747         # find mirrored files with specific mirror count
8748         cmd="$LFS find --mirror-count 3 --type f $td"
8749         nfiles=$($cmd | wc -l)
8750         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8751
8752         cmd="$LFS find ! --mirror-count 3 --type f $td"
8753         nfiles=$($cmd | wc -l)
8754         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8755
8756         cmd="$LFS find --mirror-count +2 --type f $td"
8757         nfiles=$($cmd | wc -l)
8758         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8759
8760         cmd="$LFS find --mirror-count -6 --type f $td"
8761         nfiles=$($cmd | wc -l)
8762         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8763
8764         # find mirrored files with specific file state
8765         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8766         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8767
8768         cmd="$LFS find --mirror-state=ro --type f $td"
8769         nfiles=$($cmd | wc -l)
8770         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8771
8772         cmd="$LFS find ! --mirror-state=ro --type f $td"
8773         nfiles=$($cmd | wc -l)
8774         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8775
8776         cmd="$LFS find --mirror-state=wp --type f $td"
8777         nfiles=$($cmd | wc -l)
8778         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8779
8780         cmd="$LFS find ! --mirror-state=sp --type f $td"
8781         nfiles=$($cmd | wc -l)
8782         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8783 }
8784 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8785
8786 test_56da() { # LU-14179
8787         local path=$DIR/$tdir
8788
8789         test_mkdir $path
8790         cd $path
8791
8792         local longdir=$(str_repeat 'a' 255)
8793
8794         for i in {1..15}; do
8795                 path=$path/$longdir
8796                 test_mkdir $longdir
8797                 cd $longdir
8798         done
8799
8800         local len=${#path}
8801         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8802
8803         test_mkdir $lastdir
8804         cd $lastdir
8805         # PATH_MAX-1
8806         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8807
8808         # NAME_MAX
8809         touch $(str_repeat 'f' 255)
8810
8811         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8812                 error "lfs find reported an error"
8813
8814         rm -rf $DIR/$tdir
8815 }
8816 run_test 56da "test lfs find with long paths"
8817
8818 test_56ea() { #LU-10378
8819         local path=$DIR/$tdir
8820         local pool=$TESTNAME
8821
8822         # Create ost pool
8823         pool_add $pool || error "pool_add $pool failed"
8824         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8825                 error "adding targets to $pool failed"
8826
8827         # Set default pool on directory before creating file
8828         mkdir $path || error "mkdir $path failed"
8829         $LFS setstripe -p $pool $path ||
8830                 error "set OST pool on $pool failed"
8831         touch $path/$tfile || error "touch $path/$tfile failed"
8832
8833         # Compare basic file attributes from -printf and stat
8834         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8835         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8836
8837         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8838                 error "Attrs from lfs find and stat don't match"
8839
8840         # Compare Lustre attributes from lfs find and lfs getstripe
8841         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8842         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8843         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8844         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8845         local fpool=$($LFS getstripe --pool $path/$tfile)
8846         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8847
8848         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8849                 error "Attrs from lfs find and lfs getstripe don't match"
8850
8851         # Verify behavior for unknown escape/format sequences
8852         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8853
8854         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8855                 error "Escape/format codes don't match"
8856 }
8857 run_test 56ea "test lfs find -printf option"
8858
8859 test_56eb() {
8860         local dir=$DIR/$tdir
8861         local subdir_1=$dir/subdir_1
8862
8863         test_mkdir -p $subdir_1
8864         ln -s subdir_1 $dir/link_1
8865
8866         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8867                 error "symlink is not followed"
8868
8869         $LFS getstripe --no-follow $dir |
8870                 grep "^$dir/link_1 has no stripe info$" ||
8871                 error "symlink should not have stripe info"
8872
8873         touch $dir/testfile
8874         ln -s testfile $dir/file_link_2
8875
8876         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8877                 error "symlink is not followed"
8878
8879         $LFS getstripe --no-follow $dir |
8880                 grep "^$dir/file_link_2 has no stripe info$" ||
8881                 error "symlink should not have stripe info"
8882 }
8883 run_test 56eb "check lfs getstripe on symlink"
8884
8885 test_56ec() {
8886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8887         local dir=$DIR/$tdir
8888         local srcfile=$dir/srcfile
8889         local srcyaml=$dir/srcyaml
8890         local destfile=$dir/destfile
8891
8892         test_mkdir -p $dir
8893
8894         $LFS setstripe -i 1 $srcfile
8895         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8896         # if the setstripe yaml parsing fails for any reason, the command can
8897         # randomly assign the correct OST index, leading to an erroneous
8898         # success. but the chance of false success is low enough that a
8899         # regression should still be quickly caught.
8900         $LFS setstripe --yaml=$srcyaml $destfile
8901
8902         local srcindex=$($LFS getstripe -i $srcfile)
8903         local destindex=$($LFS getstripe -i $destfile)
8904
8905         if [[ ! $srcindex -eq $destindex ]]; then
8906                 error "setstripe did not set OST index correctly"
8907         fi
8908 }
8909 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8910
8911 test_56eda() {
8912         local dir=$DIR/$tdir
8913         local subdir=$dir/subdir
8914         local file1=$dir/$tfile
8915         local file2=$dir/$tfile\2
8916         local link=$dir/$tfile-link
8917         local nfiles
8918
8919         test_mkdir -p $dir
8920         $LFS setdirstripe -c1 $subdir
8921         touch $file1
8922         touch $file2
8923         ln $file2 $link
8924
8925         nfiles=$($LFS find --links 1 $dir | wc -l)
8926         (( $nfiles == 1 )) ||
8927                 error "lfs find --links expected 1 file, got $nfiles"
8928
8929         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8930         (( $nfiles == 2 )) ||
8931                 error "lfs find --links expected 2 files, got $nfiles"
8932
8933         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8934         (( $nfiles == 1 )) ||
8935                 error "lfs find --links expected 1 directory, got $nfiles"
8936 }
8937 run_test 56eda "check lfs find --links"
8938
8939 test_56edb() {
8940         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8941
8942         local dir=$DIR/$tdir
8943         local stripedir=$dir/stripedir
8944         local nfiles
8945
8946         test_mkdir -p $dir
8947
8948         $LFS setdirstripe -c2 $stripedir
8949
8950         $LFS getdirstripe $stripedir
8951
8952         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8953         (( $nfiles == 1 )) ||
8954                 error "lfs find --links expected 1 directory, got $nfiles"
8955 }
8956 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8957
8958 test_56ef() {
8959         local dir=$DIR/$tdir
8960         local dir1=$dir/d1
8961         local dir2=$dir/d2
8962         local nfiles
8963
8964         test_mkdir -p $dir
8965
8966         mkdir $dir1
8967         mkdir $dir2
8968
8969         touch $dir1/f
8970         touch $dir2/f
8971
8972         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8973         (( $nfiles == 2 )) ||
8974                 error "(1) lfs find expected 2 files, got $nfiles"
8975
8976         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8977         (( $nfiles == 2 )) ||
8978                 error "(2) lfs find expected 2 files, got $nfiles"
8979
8980         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8981         (( $nfiles == 2 )) ||
8982                 error "(3) lfs find expected 2 files, got $nfiles"
8983 }
8984 run_test 56ef "lfs find with multiple paths"
8985
8986 test_57a() {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988         # note test will not do anything if MDS is not local
8989         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8990                 skip_env "ldiskfs only test"
8991         fi
8992         remote_mds_nodsh && skip "remote MDS with nodsh"
8993
8994         local MNTDEV="osd*.*MDT*.mntdev"
8995         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8996         [ -z "$DEV" ] && error "can't access $MNTDEV"
8997         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8998                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8999                         error "can't access $DEV"
9000                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9001                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9002                 rm $TMP/t57a.dump
9003         done
9004 }
9005 run_test 57a "verify MDS filesystem created with large inodes =="
9006
9007 test_57b() {
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9010                 skip_env "ldiskfs only test"
9011         fi
9012         remote_mds_nodsh && skip "remote MDS with nodsh"
9013
9014         local dir=$DIR/$tdir
9015         local filecount=100
9016         local file1=$dir/f1
9017         local fileN=$dir/f$filecount
9018
9019         rm -rf $dir || error "removing $dir"
9020         test_mkdir -c1 $dir
9021         local mdtidx=$($LFS getstripe -m $dir)
9022         local mdtname=MDT$(printf %04x $mdtidx)
9023         local facet=mds$((mdtidx + 1))
9024
9025         echo "mcreating $filecount files"
9026         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9027
9028         # verify that files do not have EAs yet
9029         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9030                 error "$file1 has an EA"
9031         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9032                 error "$fileN has an EA"
9033
9034         sync
9035         sleep 1
9036         df $dir  #make sure we get new statfs data
9037         local mdsfree=$(do_facet $facet \
9038                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9039         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9040         local file
9041
9042         echo "opening files to create objects/EAs"
9043         for file in $(seq -f $dir/f%g 1 $filecount); do
9044                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9045                         error "opening $file"
9046         done
9047
9048         # verify that files have EAs now
9049         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9050                 error "$file1 missing EA"
9051         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9052                 error "$fileN missing EA"
9053
9054         sleep 1  #make sure we get new statfs data
9055         df $dir
9056         local mdsfree2=$(do_facet $facet \
9057                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9058         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9059
9060         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9061                 if [ "$mdsfree" != "$mdsfree2" ]; then
9062                         error "MDC before $mdcfree != after $mdcfree2"
9063                 else
9064                         echo "MDC before $mdcfree != after $mdcfree2"
9065                         echo "unable to confirm if MDS has large inodes"
9066                 fi
9067         fi
9068         rm -rf $dir
9069 }
9070 run_test 57b "default LOV EAs are stored inside large inodes ==="
9071
9072 test_58() {
9073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9074         [ -z "$(which wiretest 2>/dev/null)" ] &&
9075                         skip_env "could not find wiretest"
9076
9077         wiretest
9078 }
9079 run_test 58 "verify cross-platform wire constants =============="
9080
9081 test_59() {
9082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9083
9084         echo "touch 130 files"
9085         createmany -o $DIR/f59- 130
9086         echo "rm 130 files"
9087         unlinkmany $DIR/f59- 130
9088         sync
9089         # wait for commitment of removal
9090         wait_delete_completed
9091 }
9092 run_test 59 "verify cancellation of llog records async ========="
9093
9094 TEST60_HEAD="test_60 run $RANDOM"
9095 test_60a() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097         remote_mgs_nodsh && skip "remote MGS with nodsh"
9098         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9099                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9100                         skip_env "missing subtest run-llog.sh"
9101
9102         log "$TEST60_HEAD - from kernel mode"
9103         do_facet mgs "$LCTL dk > /dev/null"
9104         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9105         do_facet mgs $LCTL dk > $TMP/$tfile
9106
9107         # LU-6388: test llog_reader
9108         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9109         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9110         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9111                         skip_env "missing llog_reader"
9112         local fstype=$(facet_fstype mgs)
9113         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9114                 skip_env "Only for ldiskfs or zfs type mgs"
9115
9116         local mntpt=$(facet_mntpt mgs)
9117         local mgsdev=$(mgsdevname 1)
9118         local fid_list
9119         local fid
9120         local rec_list
9121         local rec
9122         local rec_type
9123         local obj_file
9124         local path
9125         local seq
9126         local oid
9127         local pass=true
9128
9129         #get fid and record list
9130         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9131                 tail -n 4))
9132         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9133                 tail -n 4))
9134         #remount mgs as ldiskfs or zfs type
9135         stop mgs || error "stop mgs failed"
9136         mount_fstype mgs || error "remount mgs failed"
9137         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9138                 fid=${fid_list[i]}
9139                 rec=${rec_list[i]}
9140                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9141                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9142                 oid=$((16#$oid))
9143
9144                 case $fstype in
9145                         ldiskfs )
9146                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9147                         zfs )
9148                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9149                 esac
9150                 echo "obj_file is $obj_file"
9151                 do_facet mgs $llog_reader $obj_file
9152
9153                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9154                         awk '{ print $3 }' | sed -e "s/^type=//g")
9155                 if [ $rec_type != $rec ]; then
9156                         echo "FAILED test_60a wrong record type $rec_type," \
9157                               "should be $rec"
9158                         pass=false
9159                         break
9160                 fi
9161
9162                 #check obj path if record type is LLOG_LOGID_MAGIC
9163                 if [ "$rec" == "1064553b" ]; then
9164                         path=$(do_facet mgs $llog_reader $obj_file |
9165                                 grep "path=" | awk '{ print $NF }' |
9166                                 sed -e "s/^path=//g")
9167                         if [ $obj_file != $mntpt/$path ]; then
9168                                 echo "FAILED test_60a wrong obj path" \
9169                                       "$montpt/$path, should be $obj_file"
9170                                 pass=false
9171                                 break
9172                         fi
9173                 fi
9174         done
9175         rm -f $TMP/$tfile
9176         #restart mgs before "error", otherwise it will block the next test
9177         stop mgs || error "stop mgs failed"
9178         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9179         $pass || error "test failed, see FAILED test_60a messages for specifics"
9180 }
9181 run_test 60a "llog_test run from kernel module and test llog_reader"
9182
9183 test_60b() { # bug 6411
9184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9185
9186         dmesg > $DIR/$tfile
9187         LLOG_COUNT=$(do_facet mgs dmesg |
9188                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9189                           /llog_[a-z]*.c:[0-9]/ {
9190                                 if (marker)
9191                                         from_marker++
9192                                 from_begin++
9193                           }
9194                           END {
9195                                 if (marker)
9196                                         print from_marker
9197                                 else
9198                                         print from_begin
9199                           }")
9200
9201         [[ $LLOG_COUNT -gt 120 ]] &&
9202                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9203 }
9204 run_test 60b "limit repeated messages from CERROR/CWARN"
9205
9206 test_60c() {
9207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9208
9209         echo "create 5000 files"
9210         createmany -o $DIR/f60c- 5000
9211 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9212         lctl set_param fail_loc=0x80000137
9213         unlinkmany $DIR/f60c- 5000
9214         lctl set_param fail_loc=0
9215 }
9216 run_test 60c "unlink file when mds full"
9217
9218 test_60d() {
9219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9220
9221         SAVEPRINTK=$(lctl get_param -n printk)
9222         # verify "lctl mark" is even working"
9223         MESSAGE="test message ID $RANDOM $$"
9224         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9225         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9226
9227         lctl set_param printk=0 || error "set lnet.printk failed"
9228         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9229         MESSAGE="new test message ID $RANDOM $$"
9230         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9231         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9232         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9233
9234         lctl set_param -n printk="$SAVEPRINTK"
9235 }
9236 run_test 60d "test printk console message masking"
9237
9238 test_60e() {
9239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9240         remote_mds_nodsh && skip "remote MDS with nodsh"
9241
9242         touch $DIR/$tfile
9243 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9244         do_facet mds1 lctl set_param fail_loc=0x15b
9245         rm $DIR/$tfile
9246 }
9247 run_test 60e "no space while new llog is being created"
9248
9249 test_60f() {
9250         local old_path=$($LCTL get_param -n debug_path)
9251
9252         stack_trap "$LCTL set_param debug_path=$old_path"
9253         stack_trap "rm -f $TMP/$tfile*"
9254         rm -f $TMP/$tfile* 2> /dev/null
9255         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9256         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9257         test_mkdir $DIR/$tdir
9258         # retry in case the open is cached and not released
9259         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9260                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9261                 sleep 0.1
9262         done
9263         ls $TMP/$tfile*
9264         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9265 }
9266 run_test 60f "change debug_path works"
9267
9268 test_60g() {
9269         local pid
9270         local i
9271
9272         test_mkdir -c $MDSCOUNT $DIR/$tdir
9273
9274         (
9275                 local index=0
9276                 while true; do
9277                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9278                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9279                                 2>/dev/null
9280                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9281                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9282                         index=$((index + 1))
9283                 done
9284         ) &
9285
9286         pid=$!
9287
9288         for i in {0..100}; do
9289                 # define OBD_FAIL_OSD_TXN_START    0x19a
9290                 local index=$((i % MDSCOUNT + 1))
9291
9292                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9293                         > /dev/null
9294                 sleep 0.01
9295         done
9296
9297         kill -9 $pid
9298
9299         for i in $(seq $MDSCOUNT); do
9300                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9301         done
9302
9303         mkdir $DIR/$tdir/new || error "mkdir failed"
9304         rmdir $DIR/$tdir/new || error "rmdir failed"
9305
9306         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9307                 -t namespace
9308         for i in $(seq $MDSCOUNT); do
9309                 wait_update_facet mds$i "$LCTL get_param -n \
9310                         mdd.$(facet_svc mds$i).lfsck_namespace |
9311                         awk '/^status/ { print \\\$2 }'" "completed"
9312         done
9313
9314         ls -R $DIR/$tdir
9315         rm -rf $DIR/$tdir || error "rmdir failed"
9316 }
9317 run_test 60g "transaction abort won't cause MDT hung"
9318
9319 test_60h() {
9320         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9321                 skip "Need MDS version at least 2.12.52"
9322         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9323
9324         local f
9325
9326         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9327         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9328         for fail_loc in 0x80000188 0x80000189; do
9329                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9330                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9331                         error "mkdir $dir-$fail_loc failed"
9332                 for i in {0..10}; do
9333                         # create may fail on missing stripe
9334                         echo $i > $DIR/$tdir-$fail_loc/$i
9335                 done
9336                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9337                         error "getdirstripe $tdir-$fail_loc failed"
9338                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9339                         error "migrate $tdir-$fail_loc failed"
9340                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9341                         error "getdirstripe $tdir-$fail_loc failed"
9342                 pushd $DIR/$tdir-$fail_loc
9343                 for f in *; do
9344                         echo $f | cmp $f - || error "$f data mismatch"
9345                 done
9346                 popd
9347                 rm -rf $DIR/$tdir-$fail_loc
9348         done
9349 }
9350 run_test 60h "striped directory with missing stripes can be accessed"
9351
9352 function t60i_load() {
9353         mkdir $DIR/$tdir
9354         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9355         $LCTL set_param fail_loc=0x131c fail_val=1
9356         for ((i=0; i<5000; i++)); do
9357                 touch $DIR/$tdir/f$i
9358         done
9359 }
9360
9361 test_60i() {
9362         changelog_register || error "changelog_register failed"
9363         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9364         changelog_users $SINGLEMDS | grep -q $cl_user ||
9365                 error "User $cl_user not found in changelog_users"
9366         changelog_chmask "ALL"
9367         t60i_load &
9368         local PID=$!
9369         for((i=0; i<100; i++)); do
9370                 changelog_dump >/dev/null ||
9371                         error "can't read changelog"
9372         done
9373         kill $PID
9374         wait $PID
9375         changelog_deregister || error "changelog_deregister failed"
9376         $LCTL set_param fail_loc=0
9377 }
9378 run_test 60i "llog: new record vs reader race"
9379
9380 test_60j() {
9381         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9382                 skip "need MDS version at least 2.15.50"
9383         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9384         remote_mds_nodsh && skip "remote MDS with nodsh"
9385         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9386
9387         changelog_users $SINGLEMDS | grep "^cl" &&
9388                 skip "active changelog user"
9389
9390         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9391
9392         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9393                 skip_env "missing llog_reader"
9394
9395         mkdir_on_mdt0 $DIR/$tdir
9396
9397         local f=$DIR/$tdir/$tfile
9398         local mdt_dev
9399         local tmpfile
9400         local plain
9401
9402         changelog_register || error "cannot register changelog user"
9403
9404         # set changelog_mask to ALL
9405         changelog_chmask "ALL"
9406         changelog_clear
9407
9408         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9409         unlinkmany ${f}- 100 || error "unlinkmany failed"
9410
9411         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9412         mdt_dev=$(facet_device $SINGLEMDS)
9413
9414         do_facet $SINGLEMDS sync
9415         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9416                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9417                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9418
9419         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9420
9421         # if $tmpfile is not on EXT3 filesystem for some reason
9422         [[ ${plain:0:1} == 'O' ]] ||
9423                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9424
9425         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9426                 $mdt_dev; stat -c %s $tmpfile")
9427         echo "Truncate llog from $size to $((size - size % 8192))"
9428         size=$((size - size % 8192))
9429         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9430         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9431                 grep -c 'in bitmap only')
9432         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9433
9434         size=$((size - 9000))
9435         echo "Corrupt llog in the middle at $size"
9436         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9437                 count=333 conv=notrunc
9438         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9439                 grep -c 'next chunk')
9440         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9441 }
9442 run_test 60j "llog_reader reports corruptions"
9443
9444 test_61a() {
9445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9446
9447         f="$DIR/f61"
9448         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9449         cancel_lru_locks osc
9450         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9451         sync
9452 }
9453 run_test 61a "mmap() writes don't make sync hang ================"
9454
9455 test_61b() {
9456         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9457 }
9458 run_test 61b "mmap() of unstriped file is successful"
9459
9460 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9461 # Though this test is irrelevant anymore, it helped to reveal some
9462 # other grant bugs (LU-4482), let's keep it.
9463 test_63a() {   # was test_63
9464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9465
9466         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9467
9468         for i in `seq 10` ; do
9469                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9470                 sleep 5
9471                 kill $!
9472                 sleep 1
9473         done
9474
9475         rm -f $DIR/f63 || true
9476 }
9477 run_test 63a "Verify oig_wait interruption does not crash ======="
9478
9479 # bug 2248 - async write errors didn't return to application on sync
9480 # bug 3677 - async write errors left page locked
9481 test_63b() {
9482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9483
9484         debugsave
9485         lctl set_param debug=-1
9486
9487         # ensure we have a grant to do async writes
9488         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9489         rm $DIR/$tfile
9490
9491         sync    # sync lest earlier test intercept the fail_loc
9492
9493         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9494         lctl set_param fail_loc=0x80000406
9495         $MULTIOP $DIR/$tfile Owy && \
9496                 error "sync didn't return ENOMEM"
9497         sync; sleep 2; sync     # do a real sync this time to flush page
9498         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9499                 error "locked page left in cache after async error" || true
9500         debugrestore
9501 }
9502 run_test 63b "async write errors should be returned to fsync ==="
9503
9504 test_64a () {
9505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9506
9507         lfs df $DIR
9508         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9509 }
9510 run_test 64a "verify filter grant calculations (in kernel) ====="
9511
9512 test_64b () {
9513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9514
9515         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9516 }
9517 run_test 64b "check out-of-space detection on client"
9518
9519 test_64c() {
9520         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9521 }
9522 run_test 64c "verify grant shrink"
9523
9524 import_param() {
9525         local tgt=$1
9526         local param=$2
9527
9528         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9529 }
9530
9531 # this does exactly what osc_request.c:osc_announce_cached() does in
9532 # order to calculate max amount of grants to ask from server
9533 want_grant() {
9534         local tgt=$1
9535
9536         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9537         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9538
9539         ((rpc_in_flight++));
9540         nrpages=$((nrpages * rpc_in_flight))
9541
9542         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9543
9544         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9545
9546         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9547         local undirty=$((nrpages * PAGE_SIZE))
9548
9549         local max_extent_pages
9550         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9551         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9552         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9553         local grant_extent_tax
9554         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9555
9556         undirty=$((undirty + nrextents * grant_extent_tax))
9557
9558         echo $undirty
9559 }
9560
9561 # this is size of unit for grant allocation. It should be equal to
9562 # what tgt_grant.c:tgt_grant_chunk() calculates
9563 grant_chunk() {
9564         local tgt=$1
9565         local max_brw_size
9566         local grant_extent_tax
9567
9568         max_brw_size=$(import_param $tgt max_brw_size)
9569
9570         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9571
9572         echo $(((max_brw_size + grant_extent_tax) * 2))
9573 }
9574
9575 test_64d() {
9576         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9577                 skip "OST < 2.10.55 doesn't limit grants enough"
9578
9579         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9580
9581         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9582                 skip "no grant_param connect flag"
9583
9584         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9585
9586         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9587         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9588
9589
9590         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9591         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9592
9593         $LFS setstripe $DIR/$tfile -i 0 -c 1
9594         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9595         ddpid=$!
9596
9597         while kill -0 $ddpid; do
9598                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9599
9600                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9601                         kill $ddpid
9602                         error "cur_grant $cur_grant > $max_cur_granted"
9603                 fi
9604
9605                 sleep 1
9606         done
9607 }
9608 run_test 64d "check grant limit exceed"
9609
9610 check_grants() {
9611         local tgt=$1
9612         local expected=$2
9613         local msg=$3
9614         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9615
9616         ((cur_grants == expected)) ||
9617                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9618 }
9619
9620 round_up_p2() {
9621         echo $((($1 + $2 - 1) & ~($2 - 1)))
9622 }
9623
9624 test_64e() {
9625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9626         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9627                 skip "Need OSS version at least 2.11.56"
9628
9629         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9630         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9631         $LCTL set_param debug=+cache
9632
9633         # Remount client to reset grant
9634         remount_client $MOUNT || error "failed to remount client"
9635         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9636
9637         local init_grants=$(import_param $osc_tgt initial_grant)
9638
9639         check_grants $osc_tgt $init_grants "init grants"
9640
9641         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9642         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9643         local gbs=$(import_param $osc_tgt grant_block_size)
9644
9645         # write random number of bytes from max_brw_size / 4 to max_brw_size
9646         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9647         # align for direct io
9648         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9649         # round to grant consumption unit
9650         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9651
9652         local grants=$((wb_round_up + extent_tax))
9653
9654         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9655         stack_trap "rm -f $DIR/$tfile"
9656
9657         # define OBD_FAIL_TGT_NO_GRANT 0x725
9658         # make the server not grant more back
9659         do_facet ost1 $LCTL set_param fail_loc=0x725
9660         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9661
9662         do_facet ost1 $LCTL set_param fail_loc=0
9663
9664         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9665
9666         rm -f $DIR/$tfile || error "rm failed"
9667
9668         # Remount client to reset grant
9669         remount_client $MOUNT || error "failed to remount client"
9670         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9671
9672         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9673
9674         # define OBD_FAIL_TGT_NO_GRANT 0x725
9675         # make the server not grant more back
9676         do_facet ost1 $LCTL set_param fail_loc=0x725
9677         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9678         do_facet ost1 $LCTL set_param fail_loc=0
9679
9680         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9681 }
9682 run_test 64e "check grant consumption (no grant allocation)"
9683
9684 test_64f() {
9685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9686
9687         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9688         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9689         $LCTL set_param debug=+cache
9690
9691         # Remount client to reset grant
9692         remount_client $MOUNT || error "failed to remount client"
9693         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9694
9695         local init_grants=$(import_param $osc_tgt initial_grant)
9696         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9697         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9698         local gbs=$(import_param $osc_tgt grant_block_size)
9699         local chunk=$(grant_chunk $osc_tgt)
9700
9701         # write random number of bytes from max_brw_size / 4 to max_brw_size
9702         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9703         # align for direct io
9704         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9705         # round to grant consumption unit
9706         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9707
9708         local grants=$((wb_round_up + extent_tax))
9709
9710         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9711         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9712                 error "error writing to $DIR/$tfile"
9713
9714         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9715                 "direct io with grant allocation"
9716
9717         rm -f $DIR/$tfile || error "rm failed"
9718
9719         # Remount client to reset grant
9720         remount_client $MOUNT || error "failed to remount client"
9721         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9722
9723         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9724
9725         # Testing that buffered IO consumes grant on the client
9726
9727         # Delay the RPC on the server so it's guaranteed to not complete even
9728         # if the RPC is sent from the client
9729         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9730         $LCTL set_param fail_loc=0x50a fail_val=3
9731         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9732                 error "error writing to $DIR/$tfile with buffered IO"
9733
9734         check_grants $osc_tgt $((init_grants - grants)) \
9735                 "buffered io, not write rpc"
9736
9737         # Clear the fail loc and do a sync on the client
9738         $LCTL set_param fail_loc=0 fail_val=0
9739         sync
9740
9741         # RPC is now known to have sent
9742         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9743                 "buffered io, one RPC"
9744 }
9745 run_test 64f "check grant consumption (with grant allocation)"
9746
9747 test_64g() {
9748         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9749                 skip "Need MDS version at least 2.14.56"
9750
9751         local mdts=$(comma_list $(mdts_nodes))
9752
9753         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9754                         tr '\n' ' ')
9755         stack_trap "$LCTL set_param $old"
9756
9757         # generate dirty pages and increase dirty granted on MDT
9758         stack_trap "rm -f $DIR/$tfile-*"
9759         for (( i = 0; i < 10; i++)); do
9760                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9761                         error "can't set stripe"
9762                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9763                         error "can't dd"
9764                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9765                         $LFS getstripe $DIR/$tfile-$i
9766                         error "not DoM file"
9767                 }
9768         done
9769
9770         # flush dirty pages
9771         sync
9772
9773         # wait until grant shrink reset grant dirty on MDTs
9774         for ((i = 0; i < 120; i++)); do
9775                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9776                         awk '{sum=sum+$1} END {print sum}')
9777                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9778                 echo "$grant_dirty grants, $vm_dirty pages"
9779                 (( grant_dirty + vm_dirty == 0 )) && break
9780                 (( i == 3 )) && sync &&
9781                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9782                 sleep 1
9783         done
9784
9785         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9786                 awk '{sum=sum+$1} END {print sum}')
9787         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9788 }
9789 run_test 64g "grant shrink on MDT"
9790
9791 test_64h() {
9792         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9793                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9794
9795         local instance=$($LFS getname -i $DIR)
9796         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9797         local num_exps=$(do_facet ost1 \
9798             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9799         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9800         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9801         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9802
9803         # 10MiB is for file to be written, max_brw_size * 16 *
9804         # num_exps is space reserve so that tgt_grant_shrink() decided
9805         # to not shrink
9806         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9807         (( avail * 1024 < expect )) &&
9808                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9809
9810         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9811         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9812         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9813         $LCTL set_param osc.*OST0000*.grant_shrink=1
9814         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9815
9816         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9817         stack_trap "rm -f $DIR/$tfile"
9818         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9819
9820         # drop cache so that coming read would do rpc
9821         cancel_lru_locks osc
9822
9823         # shrink interval is set to 10, pause for 7 seconds so that
9824         # grant thread did not wake up yet but coming read entered
9825         # shrink mode for rpc (osc_should_shrink_grant())
9826         sleep 7
9827
9828         declare -a cur_grant_bytes
9829         declare -a tot_granted
9830         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9831         tot_granted[0]=$(do_facet ost1 \
9832             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9833
9834         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9835
9836         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9837         tot_granted[1]=$(do_facet ost1 \
9838             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9839
9840         # grant change should be equal on both sides
9841         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9842                 tot_granted[0] - tot_granted[1])) ||
9843                 error "grant change mismatch, "                                \
9844                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9845                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9846 }
9847 run_test 64h "grant shrink on read"
9848
9849 test_64i() {
9850         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9851                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9852
9853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9854         remote_ost_nodsh && skip "remote OSTs with nodsh"
9855
9856         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9857         stack_trap "rm -f $DIR/$tfile"
9858
9859         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9860
9861         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9862         local instance=$($LFS getname -i $DIR)
9863
9864         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9865         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9866
9867         # shrink grants and simulate rpc loss
9868         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9869         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9870         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9871
9872         fail ost1
9873
9874         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9875
9876         local testid=$(echo $TESTNAME | tr '_' ' ')
9877
9878         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9879                 grep "GRANT, real grant" &&
9880                 error "client has more grants then it owns" || true
9881 }
9882 run_test 64i "shrink on reconnect"
9883
9884 # bug 1414 - set/get directories' stripe info
9885 test_65a() {
9886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9887
9888         test_mkdir $DIR/$tdir
9889         touch $DIR/$tdir/f1
9890         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9891 }
9892 run_test 65a "directory with no stripe info"
9893
9894 test_65b() {
9895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9896
9897         test_mkdir $DIR/$tdir
9898         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9899
9900         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9901                                                 error "setstripe"
9902         touch $DIR/$tdir/f2
9903         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9904 }
9905 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9906
9907 test_65c() {
9908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9909         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9910
9911         test_mkdir $DIR/$tdir
9912         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9913
9914         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9915                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9916         touch $DIR/$tdir/f3
9917         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9918 }
9919 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9920
9921 test_65d() {
9922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9923
9924         test_mkdir $DIR/$tdir
9925         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9926         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9927
9928         if [[ $STRIPECOUNT -le 0 ]]; then
9929                 sc=1
9930         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9931                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9932                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9933         else
9934                 sc=$(($STRIPECOUNT - 1))
9935         fi
9936         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9937         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9938         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9939                 error "lverify failed"
9940 }
9941 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9942
9943 test_65e() {
9944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9945
9946         # LU-16904 delete layout when root is set as PFL layout
9947         save_layout_restore_at_exit $MOUNT
9948         $LFS setstripe -d $MOUNT || error "setstripe failed"
9949
9950         test_mkdir $DIR/$tdir
9951
9952         $LFS setstripe $DIR/$tdir || error "setstripe"
9953         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9954                                         error "no stripe info failed"
9955         touch $DIR/$tdir/f6
9956         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9957 }
9958 run_test 65e "directory setstripe defaults"
9959
9960 test_65f() {
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962
9963         test_mkdir $DIR/${tdir}f
9964         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9965                 error "setstripe succeeded" || true
9966 }
9967 run_test 65f "dir setstripe permission (should return error) ==="
9968
9969 test_65g() {
9970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9971
9972         # LU-16904 delete layout when root is set as PFL layout
9973         save_layout_restore_at_exit $MOUNT
9974         $LFS setstripe -d $MOUNT || error "setstripe failed"
9975
9976         test_mkdir $DIR/$tdir
9977         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9978
9979         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9980                 error "setstripe -S failed"
9981         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9982         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9983                 error "delete default stripe failed"
9984 }
9985 run_test 65g "directory setstripe -d"
9986
9987 test_65h() {
9988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9989
9990         test_mkdir $DIR/$tdir
9991         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9992
9993         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9994                 error "setstripe -S failed"
9995         test_mkdir $DIR/$tdir/dd1
9996         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9997                 error "stripe info inherit failed"
9998 }
9999 run_test 65h "directory stripe info inherit ===================="
10000
10001 test_65i() {
10002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10003
10004         save_layout_restore_at_exit $MOUNT
10005
10006         # bug6367: set non-default striping on root directory
10007         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10008
10009         # bug12836: getstripe on -1 default directory striping
10010         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10011
10012         # bug12836: getstripe -v on -1 default directory striping
10013         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10014
10015         # bug12836: new find on -1 default directory striping
10016         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10017 }
10018 run_test 65i "various tests to set root directory striping"
10019
10020 test_65j() { # bug6367
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022
10023         sync; sleep 1
10024
10025         # if we aren't already remounting for each test, do so for this test
10026         if [ "$I_MOUNTED" = "yes" ]; then
10027                 cleanup || error "failed to unmount"
10028                 setup
10029         fi
10030
10031         save_layout_restore_at_exit $MOUNT
10032
10033         $LFS setstripe -d $MOUNT || error "setstripe failed"
10034 }
10035 run_test 65j "set default striping on root directory (bug 6367)="
10036
10037 cleanup_65k() {
10038         rm -rf $DIR/$tdir
10039         wait_delete_completed
10040         do_facet $SINGLEMDS "lctl set_param -n \
10041                 osp.$ost*MDT0000.max_create_count=$max_count"
10042         do_facet $SINGLEMDS "lctl set_param -n \
10043                 osp.$ost*MDT0000.create_count=$count"
10044         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10045         echo $INACTIVE_OSC "is Activate"
10046
10047         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10048 }
10049
10050 test_65k() { # bug11679
10051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10052         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10053         remote_mds_nodsh && skip "remote MDS with nodsh"
10054
10055         local disable_precreate=true
10056         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10057                 disable_precreate=false
10058
10059         echo "Check OST status: "
10060         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10061                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10062
10063         for OSC in $MDS_OSCS; do
10064                 echo $OSC "is active"
10065                 do_facet $SINGLEMDS lctl --device %$OSC activate
10066         done
10067
10068         for INACTIVE_OSC in $MDS_OSCS; do
10069                 local ost=$(osc_to_ost $INACTIVE_OSC)
10070                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10071                                lov.*md*.target_obd |
10072                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10073
10074                 mkdir -p $DIR/$tdir
10075                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10076                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10077
10078                 echo "Deactivate: " $INACTIVE_OSC
10079                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10080
10081                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10082                               osp.$ost*MDT0000.create_count")
10083                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10084                                   osp.$ost*MDT0000.max_create_count")
10085                 $disable_precreate &&
10086                         do_facet $SINGLEMDS "lctl set_param -n \
10087                                 osp.$ost*MDT0000.max_create_count=0"
10088
10089                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10090                         [ -f $DIR/$tdir/$idx ] && continue
10091                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10092                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10093                                 { cleanup_65k;
10094                                   error "setstripe $idx should succeed"; }
10095                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10096                 done
10097                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10098                 rmdir $DIR/$tdir
10099
10100                 do_facet $SINGLEMDS "lctl set_param -n \
10101                         osp.$ost*MDT0000.max_create_count=$max_count"
10102                 do_facet $SINGLEMDS "lctl set_param -n \
10103                         osp.$ost*MDT0000.create_count=$count"
10104                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10105                 echo $INACTIVE_OSC "is Activate"
10106
10107                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10108         done
10109 }
10110 run_test 65k "validate manual striping works properly with deactivated OSCs"
10111
10112 test_65l() { # bug 12836
10113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10114
10115         test_mkdir -p $DIR/$tdir/test_dir
10116         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10117         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10118 }
10119 run_test 65l "lfs find on -1 stripe dir ========================"
10120
10121 test_65m() {
10122         local layout=$(save_layout $MOUNT)
10123         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10124                 restore_layout $MOUNT $layout
10125                 error "setstripe should fail by non-root users"
10126         }
10127         true
10128 }
10129 run_test 65m "normal user can't set filesystem default stripe"
10130
10131 test_65n() {
10132         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10133         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10134                 skip "Need MDS version at least 2.12.50"
10135         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10136
10137         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10138         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10139         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10140
10141         save_layout_restore_at_exit $MOUNT
10142
10143         # new subdirectory under root directory should not inherit
10144         # the default layout from root
10145         # LU-16904 check if the root is set as PFL layout
10146         local numcomp=$($LFS getstripe --component-count $MOUNT)
10147
10148         if [[ $numcomp -eq 0 ]]; then
10149                 local dir1=$MOUNT/$tdir-1
10150                 mkdir $dir1 || error "mkdir $dir1 failed"
10151                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10152                         error "$dir1 shouldn't have LOV EA"
10153         fi
10154
10155         # delete the default layout on root directory
10156         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10157
10158         local dir2=$MOUNT/$tdir-2
10159         mkdir $dir2 || error "mkdir $dir2 failed"
10160         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10161                 error "$dir2 shouldn't have LOV EA"
10162
10163         # set a new striping pattern on root directory
10164         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10165         local new_def_stripe_size=$((def_stripe_size * 2))
10166         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10167                 error "set stripe size on $MOUNT failed"
10168
10169         # new file created in $dir2 should inherit the new stripe size from
10170         # the filesystem default
10171         local file2=$dir2/$tfile-2
10172         touch $file2 || error "touch $file2 failed"
10173
10174         local file2_stripe_size=$($LFS getstripe -S $file2)
10175         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10176         {
10177                 echo "file2_stripe_size: '$file2_stripe_size'"
10178                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10179                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10180         }
10181
10182         local dir3=$MOUNT/$tdir-3
10183         mkdir $dir3 || error "mkdir $dir3 failed"
10184         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10185         # the root layout, which is the actual default layout that will be used
10186         # when new files are created in $dir3.
10187         local dir3_layout=$(get_layout_param $dir3)
10188         local root_dir_layout=$(get_layout_param $MOUNT)
10189         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10190         {
10191                 echo "dir3_layout: '$dir3_layout'"
10192                 echo "root_dir_layout: '$root_dir_layout'"
10193                 error "$dir3 should show the default layout from $MOUNT"
10194         }
10195
10196         # set OST pool on root directory
10197         local pool=$TESTNAME
10198         pool_add $pool || error "add $pool failed"
10199         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10200                 error "add targets to $pool failed"
10201
10202         $LFS setstripe -p $pool $MOUNT ||
10203                 error "set OST pool on $MOUNT failed"
10204
10205         # new file created in $dir3 should inherit the pool from
10206         # the filesystem default
10207         local file3=$dir3/$tfile-3
10208         touch $file3 || error "touch $file3 failed"
10209
10210         local file3_pool=$($LFS getstripe -p $file3)
10211         [[ "$file3_pool" = "$pool" ]] ||
10212                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10213
10214         local dir4=$MOUNT/$tdir-4
10215         mkdir $dir4 || error "mkdir $dir4 failed"
10216         local dir4_layout=$(get_layout_param $dir4)
10217         root_dir_layout=$(get_layout_param $MOUNT)
10218         echo "$LFS getstripe -d $dir4"
10219         $LFS getstripe -d $dir4
10220         echo "$LFS getstripe -d $MOUNT"
10221         $LFS getstripe -d $MOUNT
10222         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10223         {
10224                 echo "dir4_layout: '$dir4_layout'"
10225                 echo "root_dir_layout: '$root_dir_layout'"
10226                 error "$dir4 should show the default layout from $MOUNT"
10227         }
10228
10229         # new file created in $dir4 should inherit the pool from
10230         # the filesystem default
10231         local file4=$dir4/$tfile-4
10232         touch $file4 || error "touch $file4 failed"
10233
10234         local file4_pool=$($LFS getstripe -p $file4)
10235         [[ "$file4_pool" = "$pool" ]] ||
10236                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10237
10238         # new subdirectory under non-root directory should inherit
10239         # the default layout from its parent directory
10240         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10241                 error "set directory layout on $dir4 failed"
10242
10243         local dir5=$dir4/$tdir-5
10244         mkdir $dir5 || error "mkdir $dir5 failed"
10245
10246         dir4_layout=$(get_layout_param $dir4)
10247         local dir5_layout=$(get_layout_param $dir5)
10248         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10249         {
10250                 echo "dir4_layout: '$dir4_layout'"
10251                 echo "dir5_layout: '$dir5_layout'"
10252                 error "$dir5 should inherit the default layout from $dir4"
10253         }
10254
10255         # though subdir under ROOT doesn't inherit default layout, but
10256         # its sub dir/file should be created with default layout.
10257         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10258         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10259                 skip "Need MDS version at least 2.12.59"
10260
10261         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10262         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10263         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10264
10265         if [ $default_lmv_hash == "none" ]; then
10266                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10267         else
10268                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10269                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10270         fi
10271
10272         $LFS setdirstripe -D -c 2 $MOUNT ||
10273                 error "setdirstripe -D -c 2 failed"
10274         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10275         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10276         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10277
10278         # $dir4 layout includes pool
10279         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10280         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10281                 error "pool lost on setstripe"
10282         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10283         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10284                 error "pool lost on compound layout setstripe"
10285 }
10286 run_test 65n "don't inherit default layout from root for new subdirectories"
10287
10288 test_65o() {
10289         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10290                 skip "need MDS version at least 2.14.57"
10291
10292         # set OST pool on root directory
10293         local pool=$TESTNAME
10294
10295         pool_add $pool || error "add $pool failed"
10296         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10297                 error "add targets to $pool failed"
10298
10299         local dir1=$MOUNT/$tdir
10300
10301         mkdir $dir1 || error "mkdir $dir1 failed"
10302
10303         # set a new striping pattern on root directory
10304         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10305
10306         $LFS setstripe -p $pool $dir1 ||
10307                 error "set directory layout on $dir1 failed"
10308
10309         # $dir1 layout includes pool
10310         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10311         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10312                 error "pool lost on setstripe"
10313         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10314         $LFS getstripe $dir1
10315         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10316                 error "pool lost on compound layout setstripe"
10317
10318         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10319                 error "setdirstripe failed on sub-dir with inherited pool"
10320         $LFS getstripe $dir1/dir2
10321         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10322                 error "pool lost on compound layout setdirstripe"
10323
10324         $LFS setstripe -E -1 -c 1 $dir1
10325         $LFS getstripe -d $dir1
10326         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10327                 error "pool lost on setstripe"
10328 }
10329 run_test 65o "pool inheritance for mdt component"
10330
10331 test_65p () { # LU-16152
10332         local src_dir=$DIR/$tdir/src_dir
10333         local dst_dir=$DIR/$tdir/dst_dir
10334         local yaml_file=$DIR/$tdir/layout.yaml
10335         local border
10336
10337         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10338                 skip "Need at least version 2.15.51"
10339
10340         test_mkdir -p $src_dir
10341         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10342                 error "failed to setstripe"
10343         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10344                 error "failed to getstripe"
10345
10346         test_mkdir -p $dst_dir
10347         $LFS setstripe --yaml $yaml_file $dst_dir ||
10348                 error "failed to setstripe with yaml file"
10349         border=$($LFS getstripe -d $dst_dir |
10350                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10351                 error "failed to getstripe"
10352
10353         # 2048M is 0x80000000, or 2147483648
10354         (( $border == 2147483648 )) ||
10355                 error "failed to handle huge number in yaml layout"
10356 }
10357 run_test 65p "setstripe with yaml file and huge number"
10358
10359 test_65p () { # LU-16194
10360         local src_dir=$DIR/$tdir/src_dir
10361
10362         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10363                 skip "Need at least version 2.15.51"
10364
10365         test_mkdir -p $src_dir
10366         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10367         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10368                 error "should fail if extent start/end >=8E"
10369
10370         # EOF should work as before
10371         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10372                 error "failed to setstripe normally"
10373 }
10374 run_test 65p "setstripe with >=8E offset should fail"
10375
10376 # bug 2543 - update blocks count on client
10377 test_66() {
10378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10379
10380         local COUNT=${COUNT:-8}
10381         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10382         sync; sync_all_data; sync; sync_all_data
10383         cancel_lru_locks osc
10384         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10385         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10386 }
10387 run_test 66 "update inode blocks count on client ==============="
10388
10389 meminfo() {
10390         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10391 }
10392
10393 swap_used() {
10394         swapon -s | awk '($1 == "'$1'") { print $4 }'
10395 }
10396
10397 # bug5265, obdfilter oa2dentry return -ENOENT
10398 # #define OBD_FAIL_SRV_ENOENT 0x217
10399 test_69() {
10400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10401         remote_ost_nodsh && skip "remote OST with nodsh"
10402
10403         f="$DIR/$tfile"
10404         $LFS setstripe -c 1 -i 0 $f
10405         stack_trap "rm -f $f ${f}.2"
10406
10407         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10408
10409         do_facet ost1 lctl set_param fail_loc=0x217
10410         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10411         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10412
10413         do_facet ost1 lctl set_param fail_loc=0
10414         $DIRECTIO write $f 0 2 || error "write error"
10415
10416         cancel_lru_locks osc
10417         $DIRECTIO read $f 0 1 || error "read error"
10418
10419         do_facet ost1 lctl set_param fail_loc=0x217
10420         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10421
10422         do_facet ost1 lctl set_param fail_loc=0
10423 }
10424 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10425
10426 test_71() {
10427         test_mkdir $DIR/$tdir
10428         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10429         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10430 }
10431 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10432
10433 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10435         [ "$RUNAS_ID" = "$UID" ] &&
10436                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10437         # Check that testing environment is properly set up. Skip if not
10438         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10439                 skip_env "User $RUNAS_ID does not exist - skipping"
10440
10441         touch $DIR/$tfile
10442         chmod 777 $DIR/$tfile
10443         chmod ug+s $DIR/$tfile
10444         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10445                 error "$RUNAS dd $DIR/$tfile failed"
10446         # See if we are still setuid/sgid
10447         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10448                 error "S/gid is not dropped on write"
10449         # Now test that MDS is updated too
10450         cancel_lru_locks mdc
10451         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10452                 error "S/gid is not dropped on MDS"
10453         rm -f $DIR/$tfile
10454 }
10455 run_test 72a "Test that remove suid works properly (bug5695) ===="
10456
10457 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10458         local perm
10459
10460         [ "$RUNAS_ID" = "$UID" ] &&
10461                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10462         [ "$RUNAS_ID" -eq 0 ] &&
10463                 skip_env "RUNAS_ID = 0 -- skipping"
10464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10465         # Check that testing environment is properly set up. Skip if not
10466         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10467                 skip_env "User $RUNAS_ID does not exist - skipping"
10468
10469         touch $DIR/${tfile}-f{g,u}
10470         test_mkdir $DIR/${tfile}-dg
10471         test_mkdir $DIR/${tfile}-du
10472         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10473         chmod g+s $DIR/${tfile}-{f,d}g
10474         chmod u+s $DIR/${tfile}-{f,d}u
10475         for perm in 777 2777 4777; do
10476                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10477                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10478                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10479                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10480         done
10481         true
10482 }
10483 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10484
10485 # bug 3462 - multiple simultaneous MDC requests
10486 test_73() {
10487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10488
10489         test_mkdir $DIR/d73-1
10490         test_mkdir $DIR/d73-2
10491         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10492         pid1=$!
10493
10494         lctl set_param fail_loc=0x80000129
10495         $MULTIOP $DIR/d73-1/f73-2 Oc &
10496         sleep 1
10497         lctl set_param fail_loc=0
10498
10499         $MULTIOP $DIR/d73-2/f73-3 Oc &
10500         pid3=$!
10501
10502         kill -USR1 $pid1
10503         wait $pid1 || return 1
10504
10505         sleep 25
10506
10507         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10508         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10509         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10510
10511         rm -rf $DIR/d73-*
10512 }
10513 run_test 73 "multiple MDC requests (should not deadlock)"
10514
10515 test_74a() { # bug 6149, 6184
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517
10518         touch $DIR/f74a
10519         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10520         #
10521         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10522         # will spin in a tight reconnection loop
10523         $LCTL set_param fail_loc=0x8000030e
10524         # get any lock that won't be difficult - lookup works.
10525         ls $DIR/f74a
10526         $LCTL set_param fail_loc=0
10527         rm -f $DIR/f74a
10528         true
10529 }
10530 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10531
10532 test_74b() { # bug 13310
10533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10534
10535         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10536         #
10537         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10538         # will spin in a tight reconnection loop
10539         $LCTL set_param fail_loc=0x8000030e
10540         # get a "difficult" lock
10541         touch $DIR/f74b
10542         $LCTL set_param fail_loc=0
10543         rm -f $DIR/f74b
10544         true
10545 }
10546 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10547
10548 test_74c() {
10549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10550
10551         #define OBD_FAIL_LDLM_NEW_LOCK
10552         $LCTL set_param fail_loc=0x319
10553         touch $DIR/$tfile && error "touch successful"
10554         $LCTL set_param fail_loc=0
10555         true
10556 }
10557 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10558
10559 slab_lic=/sys/kernel/slab/lustre_inode_cache
10560 num_objects() {
10561         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10562         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10563                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10564 }
10565
10566 test_76a() { # Now for b=20433, added originally in b=1443
10567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10568
10569         cancel_lru_locks osc
10570         # there may be some slab objects cached per core
10571         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10572         local before=$(num_objects)
10573         local count=$((512 * cpus))
10574         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10575         local margin=$((count / 10))
10576         if [[ -f $slab_lic/aliases ]]; then
10577                 local aliases=$(cat $slab_lic/aliases)
10578                 (( aliases > 0 )) && margin=$((margin * aliases))
10579         fi
10580
10581         echo "before slab objects: $before"
10582         for i in $(seq $count); do
10583                 touch $DIR/$tfile
10584                 rm -f $DIR/$tfile
10585         done
10586         cancel_lru_locks osc
10587         local after=$(num_objects)
10588         echo "created: $count, after slab objects: $after"
10589         # shared slab counts are not very accurate, allow significant margin
10590         # the main goal is that the cache growth is not permanently > $count
10591         while (( after > before + margin )); do
10592                 sleep 1
10593                 after=$(num_objects)
10594                 wait=$((wait + 1))
10595                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10596                 if (( wait > 60 )); then
10597                         error "inode slab grew from $before+$margin to $after"
10598                 fi
10599         done
10600 }
10601 run_test 76a "confirm clients recycle inodes properly ===="
10602
10603 test_76b() {
10604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10605         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10606
10607         local count=512
10608         local before=$(num_objects)
10609
10610         for i in $(seq $count); do
10611                 mkdir $DIR/$tdir
10612                 rmdir $DIR/$tdir
10613         done
10614
10615         local after=$(num_objects)
10616         local wait=0
10617
10618         while (( after > before )); do
10619                 sleep 1
10620                 after=$(num_objects)
10621                 wait=$((wait + 1))
10622                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10623                 if (( wait > 60 )); then
10624                         error "inode slab grew from $before to $after"
10625                 fi
10626         done
10627
10628         echo "slab objects before: $before, after: $after"
10629 }
10630 run_test 76b "confirm clients recycle directory inodes properly ===="
10631
10632 export ORIG_CSUM=""
10633 set_checksums()
10634 {
10635         # Note: in sptlrpc modes which enable its own bulk checksum, the
10636         # original crc32_le bulk checksum will be automatically disabled,
10637         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10638         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10639         # In this case set_checksums() will not be no-op, because sptlrpc
10640         # bulk checksum will be enabled all through the test.
10641
10642         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10643         lctl set_param -n osc.*.checksums $1
10644         return 0
10645 }
10646
10647 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10648                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10649 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10650                              tr -d [] | head -n1)}
10651 set_checksum_type()
10652 {
10653         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10654         rc=$?
10655         log "set checksum type to $1, rc = $rc"
10656         return $rc
10657 }
10658
10659 get_osc_checksum_type()
10660 {
10661         # arugment 1: OST name, like OST0000
10662         ost=$1
10663         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10664                         sed 's/.*\[\(.*\)\].*/\1/g')
10665         rc=$?
10666         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10667         echo $checksum_type
10668 }
10669
10670 F77_TMP=$TMP/f77-temp
10671 F77SZ=8
10672 setup_f77() {
10673         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10674                 error "error writing to $F77_TMP"
10675 }
10676
10677 test_77a() { # bug 10889
10678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10679         $GSS && skip_env "could not run with gss"
10680
10681         [ ! -f $F77_TMP ] && setup_f77
10682         set_checksums 1
10683         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10684         set_checksums 0
10685         rm -f $DIR/$tfile
10686 }
10687 run_test 77a "normal checksum read/write operation"
10688
10689 test_77b() { # bug 10889
10690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10691         $GSS && skip_env "could not run with gss"
10692
10693         [ ! -f $F77_TMP ] && setup_f77
10694         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10695         $LCTL set_param fail_loc=0x80000409
10696         set_checksums 1
10697
10698         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10699                 error "dd error: $?"
10700         $LCTL set_param fail_loc=0
10701
10702         for algo in $CKSUM_TYPES; do
10703                 cancel_lru_locks osc
10704                 set_checksum_type $algo
10705                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10706                 $LCTL set_param fail_loc=0x80000408
10707                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10708                 $LCTL set_param fail_loc=0
10709         done
10710         set_checksums 0
10711         set_checksum_type $ORIG_CSUM_TYPE
10712         rm -f $DIR/$tfile
10713 }
10714 run_test 77b "checksum error on client write, read"
10715
10716 cleanup_77c() {
10717         trap 0
10718         set_checksums 0
10719         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10720         $check_ost &&
10721                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10722         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10723         $check_ost && [ -n "$ost_file_prefix" ] &&
10724                 do_facet ost1 rm -f ${ost_file_prefix}\*
10725 }
10726
10727 test_77c() {
10728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10729         $GSS && skip_env "could not run with gss"
10730         remote_ost_nodsh && skip "remote OST with nodsh"
10731
10732         local bad1
10733         local osc_file_prefix
10734         local osc_file
10735         local check_ost=false
10736         local ost_file_prefix
10737         local ost_file
10738         local orig_cksum
10739         local dump_cksum
10740         local fid
10741
10742         # ensure corruption will occur on first OSS/OST
10743         $LFS setstripe -i 0 $DIR/$tfile
10744
10745         [ ! -f $F77_TMP ] && setup_f77
10746         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10747                 error "dd write error: $?"
10748         fid=$($LFS path2fid $DIR/$tfile)
10749
10750         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10751         then
10752                 check_ost=true
10753                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10754                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10755         else
10756                 echo "OSS do not support bulk pages dump upon error"
10757         fi
10758
10759         osc_file_prefix=$($LCTL get_param -n debug_path)
10760         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10761
10762         trap cleanup_77c EXIT
10763
10764         set_checksums 1
10765         # enable bulk pages dump upon error on Client
10766         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10767         # enable bulk pages dump upon error on OSS
10768         $check_ost &&
10769                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10770
10771         # flush Client cache to allow next read to reach OSS
10772         cancel_lru_locks osc
10773
10774         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10775         $LCTL set_param fail_loc=0x80000408
10776         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10777         $LCTL set_param fail_loc=0
10778
10779         rm -f $DIR/$tfile
10780
10781         # check cksum dump on Client
10782         osc_file=$(ls ${osc_file_prefix}*)
10783         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10784         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10785         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10786         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10787         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10788                      cksum)
10789         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10790         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10791                 error "dump content does not match on Client"
10792
10793         $check_ost || skip "No need to check cksum dump on OSS"
10794
10795         # check cksum dump on OSS
10796         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10797         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10798         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10799         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10800         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10801                 error "dump content does not match on OSS"
10802
10803         cleanup_77c
10804 }
10805 run_test 77c "checksum error on client read with debug"
10806
10807 test_77d() { # bug 10889
10808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10809         $GSS && skip_env "could not run with gss"
10810
10811         stack_trap "rm -f $DIR/$tfile"
10812         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10813         $LCTL set_param fail_loc=0x80000409
10814         set_checksums 1
10815         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10816                 error "direct write: rc=$?"
10817         $LCTL set_param fail_loc=0
10818         set_checksums 0
10819
10820         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10821         $LCTL set_param fail_loc=0x80000408
10822         set_checksums 1
10823         cancel_lru_locks osc
10824         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10825                 error "direct read: rc=$?"
10826         $LCTL set_param fail_loc=0
10827         set_checksums 0
10828 }
10829 run_test 77d "checksum error on OST direct write, read"
10830
10831 test_77f() { # bug 10889
10832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10833         $GSS && skip_env "could not run with gss"
10834
10835         set_checksums 1
10836         stack_trap "rm -f $DIR/$tfile"
10837         for algo in $CKSUM_TYPES; do
10838                 cancel_lru_locks osc
10839                 set_checksum_type $algo
10840                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10841                 $LCTL set_param fail_loc=0x409
10842                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10843                         error "direct write succeeded"
10844                 $LCTL set_param fail_loc=0
10845         done
10846         set_checksum_type $ORIG_CSUM_TYPE
10847         set_checksums 0
10848 }
10849 run_test 77f "repeat checksum error on write (expect error)"
10850
10851 test_77g() { # bug 10889
10852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10853         $GSS && skip_env "could not run with gss"
10854         remote_ost_nodsh && skip "remote OST with nodsh"
10855
10856         [ ! -f $F77_TMP ] && setup_f77
10857
10858         local file=$DIR/$tfile
10859         stack_trap "rm -f $file" EXIT
10860
10861         $LFS setstripe -c 1 -i 0 $file
10862         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10863         do_facet ost1 lctl set_param fail_loc=0x8000021a
10864         set_checksums 1
10865         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10866                 error "write error: rc=$?"
10867         do_facet ost1 lctl set_param fail_loc=0
10868         set_checksums 0
10869
10870         cancel_lru_locks osc
10871         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10872         do_facet ost1 lctl set_param fail_loc=0x8000021b
10873         set_checksums 1
10874         cmp $F77_TMP $file || error "file compare failed"
10875         do_facet ost1 lctl set_param fail_loc=0
10876         set_checksums 0
10877 }
10878 run_test 77g "checksum error on OST write, read"
10879
10880 test_77k() { # LU-10906
10881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10882         $GSS && skip_env "could not run with gss"
10883
10884         local cksum_param="osc.$FSNAME*.checksums"
10885         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10886         local checksum
10887         local i
10888
10889         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10890         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10891         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10892
10893         for i in 0 1; do
10894                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10895                         error "failed to set checksum=$i on MGS"
10896                 wait_update $HOSTNAME "$get_checksum" $i
10897                 #remount
10898                 echo "remount client, checksum should be $i"
10899                 remount_client $MOUNT || error "failed to remount client"
10900                 checksum=$(eval $get_checksum)
10901                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10902         done
10903         # remove persistent param to avoid races with checksum mountopt below
10904         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10905                 error "failed to delete checksum on MGS"
10906
10907         for opt in "checksum" "nochecksum"; do
10908                 #remount with mount option
10909                 echo "remount client with option $opt, checksum should be $i"
10910                 umount_client $MOUNT || error "failed to umount client"
10911                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10912                         error "failed to mount client with option '$opt'"
10913                 checksum=$(eval $get_checksum)
10914                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10915                 i=$((i - 1))
10916         done
10917
10918         remount_client $MOUNT || error "failed to remount client"
10919 }
10920 run_test 77k "enable/disable checksum correctly"
10921
10922 test_77l() {
10923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10924         $GSS && skip_env "could not run with gss"
10925
10926         set_checksums 1
10927         stack_trap "set_checksums $ORIG_CSUM" EXIT
10928         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10929
10930         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10931
10932         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10933         for algo in $CKSUM_TYPES; do
10934                 set_checksum_type $algo || error "fail to set checksum type $algo"
10935                 osc_algo=$(get_osc_checksum_type OST0000)
10936                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10937
10938                 # no locks, no reqs to let the connection idle
10939                 cancel_lru_locks osc
10940                 lru_resize_disable osc
10941                 wait_osc_import_state client ost1 IDLE
10942
10943                 # ensure ost1 is connected
10944                 stat $DIR/$tfile >/dev/null || error "can't stat"
10945                 wait_osc_import_state client ost1 FULL
10946
10947                 osc_algo=$(get_osc_checksum_type OST0000)
10948                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10949         done
10950         return 0
10951 }
10952 run_test 77l "preferred checksum type is remembered after reconnected"
10953
10954 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10955 rm -f $F77_TMP
10956 unset F77_TMP
10957
10958 test_77m() {
10959         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10960                 skip "Need at least version 2.14.52"
10961         local param=checksum_speed
10962
10963         $LCTL get_param $param || error "reading $param failed"
10964
10965         csum_speeds=$($LCTL get_param -n $param)
10966
10967         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10968                 error "known checksum types are missing"
10969 }
10970 run_test 77m "Verify checksum_speed is correctly read"
10971
10972 check_filefrag_77n() {
10973         local nr_ext=0
10974         local starts=()
10975         local ends=()
10976
10977         while read extidx a b start end rest; do
10978                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10979                         nr_ext=$(( $nr_ext + 1 ))
10980                         starts+=( ${start%..} )
10981                         ends+=( ${end%:} )
10982                 fi
10983         done < <( filefrag -sv $1 )
10984
10985         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10986         return 1
10987 }
10988
10989 test_77n() {
10990         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10991
10992         touch $DIR/$tfile
10993         $TRUNCATE $DIR/$tfile 0
10994         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10995         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10996         check_filefrag_77n $DIR/$tfile ||
10997                 skip "$tfile blocks not contiguous around hole"
10998
10999         set_checksums 1
11000         stack_trap "set_checksums $ORIG_CSUM" EXIT
11001         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11002         stack_trap "rm -f $DIR/$tfile"
11003
11004         for algo in $CKSUM_TYPES; do
11005                 if [[ "$algo" =~ ^t10 ]]; then
11006                         set_checksum_type $algo ||
11007                                 error "fail to set checksum type $algo"
11008                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11009                                 error "fail to read $tfile with $algo"
11010                 fi
11011         done
11012         rm -f $DIR/$tfile
11013         return 0
11014 }
11015 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11016
11017 test_77o() {
11018         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11019                 skip "Need MDS version at least 2.14.55"
11020         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11021                 skip "Need OST version at least 2.14.55"
11022         local ofd=obdfilter
11023         local mdt=mdt
11024
11025         # print OST checksum_type
11026         echo "$ofd.$FSNAME-*.checksum_type:"
11027         do_nodes $(comma_list $(osts_nodes)) \
11028                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11029
11030         # print MDT checksum_type
11031         echo "$mdt.$FSNAME-*.checksum_type:"
11032         do_nodes $(comma_list $(mdts_nodes)) \
11033                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11034
11035         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11036                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11037
11038         (( $o_count == $OSTCOUNT )) ||
11039                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11040
11041         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11042                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11043
11044         (( $m_count == $MDSCOUNT )) ||
11045                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11046 }
11047 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11048
11049 cleanup_test_78() {
11050         trap 0
11051         rm -f $DIR/$tfile
11052 }
11053
11054 test_78() { # bug 10901
11055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11056         remote_ost || skip_env "local OST"
11057
11058         NSEQ=5
11059         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11060         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11061         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11062         echo "MemTotal: $MEMTOTAL"
11063
11064         # reserve 256MB of memory for the kernel and other running processes,
11065         # and then take 1/2 of the remaining memory for the read/write buffers.
11066         if [ $MEMTOTAL -gt 512 ] ;then
11067                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11068         else
11069                 # for those poor memory-starved high-end clusters...
11070                 MEMTOTAL=$((MEMTOTAL / 2))
11071         fi
11072         echo "Mem to use for directio: $MEMTOTAL"
11073
11074         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11075         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11076         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11077         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11078                 head -n1)
11079         echo "Smallest OST: $SMALLESTOST"
11080         [[ $SMALLESTOST -lt 10240 ]] &&
11081                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11082
11083         trap cleanup_test_78 EXIT
11084
11085         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11086                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11087
11088         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11089         echo "File size: $F78SIZE"
11090         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11091         for i in $(seq 1 $NSEQ); do
11092                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11093                 echo directIO rdwr round $i of $NSEQ
11094                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11095         done
11096
11097         cleanup_test_78
11098 }
11099 run_test 78 "handle large O_DIRECT writes correctly ============"
11100
11101 test_79() { # bug 12743
11102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11103
11104         wait_delete_completed
11105
11106         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11107         BKFREE=$(calc_osc_kbytes kbytesfree)
11108         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11109
11110         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11111         DFTOTAL=`echo $STRING | cut -d, -f1`
11112         DFUSED=`echo $STRING  | cut -d, -f2`
11113         DFAVAIL=`echo $STRING | cut -d, -f3`
11114         DFFREE=$(($DFTOTAL - $DFUSED))
11115
11116         ALLOWANCE=$((64 * $OSTCOUNT))
11117
11118         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11119            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11120                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11121         fi
11122         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11123            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11124                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11125         fi
11126         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11127            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11128                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11129         fi
11130 }
11131 run_test 79 "df report consistency check ======================="
11132
11133 test_80() { # bug 10718
11134         remote_ost_nodsh && skip "remote OST with nodsh"
11135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11136
11137         # relax strong synchronous semantics for slow backends like ZFS
11138         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11139                 local soc="obdfilter.*.sync_lock_cancel"
11140                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11141
11142                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11143                 if [ -z "$save" ]; then
11144                         soc="obdfilter.*.sync_on_lock_cancel"
11145                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11146                 fi
11147
11148                 if [ "$save" != "never" ]; then
11149                         local hosts=$(comma_list $(osts_nodes))
11150
11151                         do_nodes $hosts $LCTL set_param $soc=never
11152                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11153                 fi
11154         fi
11155
11156         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11157         sync; sleep 1; sync
11158         local before=$(date +%s)
11159         cancel_lru_locks osc
11160         local after=$(date +%s)
11161         local diff=$((after - before))
11162         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11163
11164         rm -f $DIR/$tfile
11165 }
11166 run_test 80 "Page eviction is equally fast at high offsets too"
11167
11168 test_81a() { # LU-456
11169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11170         remote_ost_nodsh && skip "remote OST with nodsh"
11171
11172         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11173         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11174         do_facet ost1 lctl set_param fail_loc=0x80000228
11175
11176         # write should trigger a retry and success
11177         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11178         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11179         RC=$?
11180         if [ $RC -ne 0 ] ; then
11181                 error "write should success, but failed for $RC"
11182         fi
11183 }
11184 run_test 81a "OST should retry write when get -ENOSPC ==============="
11185
11186 test_81b() { # LU-456
11187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11188         remote_ost_nodsh && skip "remote OST with nodsh"
11189
11190         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11191         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11192         do_facet ost1 lctl set_param fail_loc=0x228
11193
11194         # write should retry several times and return -ENOSPC finally
11195         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11196         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11197         RC=$?
11198         ENOSPC=28
11199         if [ $RC -ne $ENOSPC ] ; then
11200                 error "dd should fail for -ENOSPC, but succeed."
11201         fi
11202 }
11203 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11204
11205 test_99() {
11206         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11207
11208         test_mkdir $DIR/$tdir.cvsroot
11209         chown $RUNAS_ID $DIR/$tdir.cvsroot
11210
11211         cd $TMP
11212         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11213
11214         cd /etc/init.d
11215         # some versions of cvs import exit(1) when asked to import links or
11216         # files they can't read.  ignore those files.
11217         local toignore=$(find . -type l -printf '-I %f\n' -o \
11218                          ! -perm /4 -printf '-I %f\n')
11219         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11220                 $tdir.reposname vtag rtag
11221
11222         cd $DIR
11223         test_mkdir $DIR/$tdir.reposname
11224         chown $RUNAS_ID $DIR/$tdir.reposname
11225         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11226
11227         cd $DIR/$tdir.reposname
11228         $RUNAS touch foo99
11229         $RUNAS cvs add -m 'addmsg' foo99
11230         $RUNAS cvs update
11231         $RUNAS cvs commit -m 'nomsg' foo99
11232         rm -fr $DIR/$tdir.cvsroot
11233 }
11234 run_test 99 "cvs strange file/directory operations"
11235
11236 test_100() {
11237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11238         [[ "$NETTYPE" =~ tcp ]] ||
11239                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11240         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11241         remote_ost_nodsh && skip "remote OST with nodsh"
11242         remote_mds_nodsh && skip "remote MDS with nodsh"
11243         remote_servers || skip "useless for local single node setup"
11244
11245         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11246                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11247
11248                 rc=0
11249                 if (( ${LOCAL/*:/} >= 1024 )); then
11250                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11251                         ss -tna
11252                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11253                 fi
11254         done
11255         (( $rc == 0 )) || error "privileged port not found" )
11256 }
11257 run_test 100 "check local port using privileged port"
11258
11259 function get_named_value()
11260 {
11261     local tag=$1
11262
11263     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11264 }
11265
11266 test_101a() {
11267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11268
11269         local s
11270         local discard
11271         local nreads=10000
11272         local cache_limit=32
11273
11274         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11275         $LCTL set_param -n llite.*.read_ahead_stats=0
11276         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11277                               awk '/^max_cached_mb/ { print $2 }')
11278         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11279         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11280
11281         #
11282         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11283         #
11284         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11285         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11286
11287         discard=0
11288         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11289                    get_named_value 'read.but.discarded'); do
11290                         discard=$(($discard + $s))
11291         done
11292
11293         $LCTL get_param osc.*-osc*.rpc_stats
11294         $LCTL get_param llite.*.read_ahead_stats
11295
11296         # Discard is generally zero, but sometimes a few random reads line up
11297         # and trigger larger readahead, which is wasted & leads to discards.
11298         if [[ $(($discard)) -gt $nreads ]]; then
11299                 error "too many ($discard) discarded pages"
11300         fi
11301         rm -f $DIR/$tfile || true
11302 }
11303 run_test 101a "check read-ahead for random reads"
11304
11305 setup_test101bc() {
11306         test_mkdir $DIR/$tdir
11307         local ssize=$1
11308         local FILE_LENGTH=$2
11309         STRIPE_OFFSET=0
11310
11311         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11312
11313         local list=$(comma_list $(osts_nodes))
11314         set_osd_param $list '' read_cache_enable 0
11315         set_osd_param $list '' writethrough_cache_enable 0
11316
11317         trap cleanup_test101bc EXIT
11318         # prepare the read-ahead file
11319         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11320
11321         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11322                                 count=$FILE_SIZE_MB 2> /dev/null
11323
11324 }
11325
11326 cleanup_test101bc() {
11327         trap 0
11328         rm -rf $DIR/$tdir
11329         rm -f $DIR/$tfile
11330
11331         local list=$(comma_list $(osts_nodes))
11332         set_osd_param $list '' read_cache_enable 1
11333         set_osd_param $list '' writethrough_cache_enable 1
11334 }
11335
11336 ra_check_101() {
11337         local read_size=$1
11338         local stripe_size=$2
11339         local stride_length=$((stripe_size / read_size))
11340         local stride_width=$((stride_length * OSTCOUNT))
11341         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11342                                 (stride_width - stride_length) ))
11343         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11344                   get_named_value 'read.but.discarded' | calc_sum)
11345
11346         if [[ $discard -gt $discard_limit ]]; then
11347                 $LCTL get_param llite.*.read_ahead_stats
11348                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11349         else
11350                 echo "Read-ahead success for size ${read_size}"
11351         fi
11352 }
11353
11354 test_101b() {
11355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11356         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11357
11358         local STRIPE_SIZE=1048576
11359         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11360
11361         if [ $SLOW == "yes" ]; then
11362                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11363         else
11364                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11365         fi
11366
11367         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11368
11369         # prepare the read-ahead file
11370         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11371         cancel_lru_locks osc
11372         for BIDX in 2 4 8 16 32 64 128 256
11373         do
11374                 local BSIZE=$((BIDX*4096))
11375                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11376                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11377                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11378                 $LCTL set_param -n llite.*.read_ahead_stats=0
11379                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11380                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11381                 cancel_lru_locks osc
11382                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11383         done
11384         cleanup_test101bc
11385         true
11386 }
11387 run_test 101b "check stride-io mode read-ahead ================="
11388
11389 test_101c() {
11390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11391
11392         local STRIPE_SIZE=1048576
11393         local FILE_LENGTH=$((STRIPE_SIZE*100))
11394         local nreads=10000
11395         local rsize=65536
11396         local osc_rpc_stats
11397
11398         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11399
11400         cancel_lru_locks osc
11401         $LCTL set_param osc.*.rpc_stats=0
11402         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11403         $LCTL get_param osc.*.rpc_stats
11404         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11405                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11406                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11407                 local size
11408
11409                 if [ $lines -le 20 ]; then
11410                         echo "continue debug"
11411                         continue
11412                 fi
11413                 for size in 1 2 4 8; do
11414                         local rpc=$(echo "$stats" |
11415                                     awk '($1 == "'$size':") {print $2; exit; }')
11416                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11417                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11418                 done
11419                 echo "$osc_rpc_stats check passed!"
11420         done
11421         cleanup_test101bc
11422         true
11423 }
11424 run_test 101c "check stripe_size aligned read-ahead"
11425
11426 test_101d() {
11427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11428
11429         local file=$DIR/$tfile
11430         local sz_MB=${FILESIZE_101d:-80}
11431         local ra_MB=${READAHEAD_MB:-40}
11432
11433         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11434         [ $free_MB -lt $sz_MB ] &&
11435                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11436
11437         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11438         $LFS setstripe -c -1 $file || error "setstripe failed"
11439
11440         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11441         echo Cancel LRU locks on lustre client to flush the client cache
11442         cancel_lru_locks osc
11443
11444         echo Disable read-ahead
11445         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11446         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11447         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11448         $LCTL get_param -n llite.*.max_read_ahead_mb
11449
11450         echo "Reading the test file $file with read-ahead disabled"
11451         local sz_KB=$((sz_MB * 1024 / 4))
11452         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11453         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11454         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11455                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11456
11457         echo "Cancel LRU locks on lustre client to flush the client cache"
11458         cancel_lru_locks osc
11459         echo Enable read-ahead with ${ra_MB}MB
11460         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11461
11462         echo "Reading the test file $file with read-ahead enabled"
11463         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11464                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11465
11466         echo "read-ahead disabled time read $raOFF"
11467         echo "read-ahead enabled time read $raON"
11468
11469         rm -f $file
11470         wait_delete_completed
11471
11472         # use awk for this check instead of bash because it handles decimals
11473         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11474                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11475 }
11476 run_test 101d "file read with and without read-ahead enabled"
11477
11478 test_101e() {
11479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11480
11481         local file=$DIR/$tfile
11482         local size_KB=500  #KB
11483         local count=100
11484         local bsize=1024
11485
11486         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11487         local need_KB=$((count * size_KB))
11488         [[ $free_KB -le $need_KB ]] &&
11489                 skip_env "Need free space $need_KB, have $free_KB"
11490
11491         echo "Creating $count ${size_KB}K test files"
11492         for ((i = 0; i < $count; i++)); do
11493                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11494         done
11495
11496         echo "Cancel LRU locks on lustre client to flush the client cache"
11497         cancel_lru_locks $OSC
11498
11499         echo "Reset readahead stats"
11500         $LCTL set_param -n llite.*.read_ahead_stats=0
11501
11502         for ((i = 0; i < $count; i++)); do
11503                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11504         done
11505
11506         $LCTL get_param llite.*.max_cached_mb
11507         $LCTL get_param llite.*.read_ahead_stats
11508         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11509                      get_named_value 'misses' | calc_sum)
11510
11511         for ((i = 0; i < $count; i++)); do
11512                 rm -rf $file.$i 2>/dev/null
11513         done
11514
11515         #10000 means 20% reads are missing in readahead
11516         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11517 }
11518 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11519
11520 test_101f() {
11521         which iozone || skip_env "no iozone installed"
11522
11523         local old_debug=$($LCTL get_param debug)
11524         old_debug=${old_debug#*=}
11525         $LCTL set_param debug="reada mmap"
11526
11527         # create a test file
11528         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11529
11530         echo Cancel LRU locks on lustre client to flush the client cache
11531         cancel_lru_locks osc
11532
11533         echo Reset readahead stats
11534         $LCTL set_param -n llite.*.read_ahead_stats=0
11535
11536         echo mmap read the file with small block size
11537         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11538                 > /dev/null 2>&1
11539
11540         echo checking missing pages
11541         $LCTL get_param llite.*.read_ahead_stats
11542         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11543                         get_named_value 'misses' | calc_sum)
11544
11545         $LCTL set_param debug="$old_debug"
11546         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11547         rm -f $DIR/$tfile
11548 }
11549 run_test 101f "check mmap read performance"
11550
11551 test_101g_brw_size_test() {
11552         local mb=$1
11553         local pages=$((mb * 1048576 / PAGE_SIZE))
11554         local file=$DIR/$tfile
11555
11556         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11557                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11558         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11559                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11560                         return 2
11561         done
11562
11563         stack_trap "rm -f $file" EXIT
11564         $LCTL set_param -n osc.*.rpc_stats=0
11565
11566         # 10 RPCs should be enough for the test
11567         local count=10
11568         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11569                 { error "dd write ${mb} MB blocks failed"; return 3; }
11570         cancel_lru_locks osc
11571         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11572                 { error "dd write ${mb} MB blocks failed"; return 4; }
11573
11574         # calculate number of full-sized read and write RPCs
11575         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11576                 sed -n '/pages per rpc/,/^$/p' |
11577                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11578                 END { print reads,writes }'))
11579         # allow one extra full-sized read RPC for async readahead
11580         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11581                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11582         [[ ${rpcs[1]} == $count ]] ||
11583                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11584 }
11585
11586 test_101g() {
11587         remote_ost_nodsh && skip "remote OST with nodsh"
11588
11589         local rpcs
11590         local osts=$(get_facets OST)
11591         local list=$(comma_list $(osts_nodes))
11592         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11593         local brw_size="obdfilter.*.brw_size"
11594
11595         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11596
11597         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11598
11599         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11600                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11601                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11602            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11603                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11604                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11605
11606                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11607                         suffix="M"
11608
11609                 if [[ $orig_mb -lt 16 ]]; then
11610                         save_lustre_params $osts "$brw_size" > $p
11611                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11612                                 error "set 16MB RPC size failed"
11613
11614                         echo "remount client to enable new RPC size"
11615                         remount_client $MOUNT || error "remount_client failed"
11616                 fi
11617
11618                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11619                 # should be able to set brw_size=12, but no rpc_stats for that
11620                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11621         fi
11622
11623         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11624
11625         if [[ $orig_mb -lt 16 ]]; then
11626                 restore_lustre_params < $p
11627                 remount_client $MOUNT || error "remount_client restore failed"
11628         fi
11629
11630         rm -f $p $DIR/$tfile
11631 }
11632 run_test 101g "Big bulk(4/16 MiB) readahead"
11633
11634 test_101h() {
11635         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11636
11637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11638                 error "dd 70M file failed"
11639         echo Cancel LRU locks on lustre client to flush the client cache
11640         cancel_lru_locks osc
11641
11642         echo "Reset readahead stats"
11643         $LCTL set_param -n llite.*.read_ahead_stats 0
11644
11645         echo "Read 10M of data but cross 64M bundary"
11646         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11647         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11648                      get_named_value 'misses' | calc_sum)
11649         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11650         rm -f $p $DIR/$tfile
11651 }
11652 run_test 101h "Readahead should cover current read window"
11653
11654 test_101i() {
11655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11656                 error "dd 10M file failed"
11657
11658         local max_per_file_mb=$($LCTL get_param -n \
11659                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11660         cancel_lru_locks osc
11661         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11662         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11663                 error "set max_read_ahead_per_file_mb to 1 failed"
11664
11665         echo "Reset readahead stats"
11666         $LCTL set_param llite.*.read_ahead_stats=0
11667
11668         dd if=$DIR/$tfile of=/dev/null bs=2M
11669
11670         $LCTL get_param llite.*.read_ahead_stats
11671         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11672                      awk '/misses/ { print $2 }')
11673         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11674         rm -f $DIR/$tfile
11675 }
11676 run_test 101i "allow current readahead to exceed reservation"
11677
11678 test_101j() {
11679         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11680                 error "setstripe $DIR/$tfile failed"
11681         local file_size=$((1048576 * 16))
11682         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11683         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11684
11685         echo Disable read-ahead
11686         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11687
11688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11689         for blk in $PAGE_SIZE 1048576 $file_size; do
11690                 cancel_lru_locks osc
11691                 echo "Reset readahead stats"
11692                 $LCTL set_param -n llite.*.read_ahead_stats=0
11693                 local count=$(($file_size / $blk))
11694                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11695                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11696                              get_named_value 'failed.to.fast.read' | calc_sum)
11697                 $LCTL get_param -n llite.*.read_ahead_stats
11698                 [ $miss -eq $count ] || error "expected $count got $miss"
11699         done
11700
11701         rm -f $p $DIR/$tfile
11702 }
11703 run_test 101j "A complete read block should be submitted when no RA"
11704
11705 test_readahead_base() {
11706         local file=$DIR/$tfile
11707         local size=$1
11708         local iosz
11709         local ramax
11710         local ranum
11711
11712         $LCTL set_param -n llite.*.read_ahead_stats=0
11713         # The first page is not accounted into readahead
11714         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11715         iosz=$(((size + 1048575) / 1048576 * 1048576))
11716         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11717
11718         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11719         fallocate -l $size $file || error "failed to fallocate $file"
11720         cancel_lru_locks osc
11721         $MULTIOP $file or${iosz}c || error "failed to read $file"
11722         $LCTL get_param -n llite.*.read_ahead_stats
11723         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11724                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11725         (( $ranum <= $ramax )) ||
11726                 error "read-ahead pages is $ranum more than $ramax"
11727         rm -rf $file || error "failed to remove $file"
11728 }
11729
11730 test_101m()
11731 {
11732         local file=$DIR/$tfile
11733         local ramax
11734         local ranum
11735         local size
11736         local iosz
11737
11738         check_set_fallocate_or_skip
11739         stack_trap "rm -f $file" EXIT
11740
11741         test_readahead_base 4096
11742
11743         # file size: 16K = 16384
11744         test_readahead_base 16384
11745         test_readahead_base 16385
11746         test_readahead_base 16383
11747
11748         # file size: 1M + 1 = 1048576 + 1
11749         test_readahead_base 1048577
11750         # file size: 1M + 16K
11751         test_readahead_base $((1048576 + 16384))
11752
11753         # file size: stripe_size * (stripe_count - 1) + 16K
11754         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11755         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11756         # file size: stripe_size * stripe_count + 16K
11757         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11758         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11759         # file size: 2 * stripe_size * stripe_count + 16K
11760         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11761         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11762 }
11763 run_test 101m "read ahead for small file and last stripe of the file"
11764
11765 setup_test102() {
11766         test_mkdir $DIR/$tdir
11767         chown $RUNAS_ID $DIR/$tdir
11768         STRIPE_SIZE=65536
11769         STRIPE_OFFSET=1
11770         STRIPE_COUNT=$OSTCOUNT
11771         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11772
11773         trap cleanup_test102 EXIT
11774         cd $DIR
11775         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11776         cd $DIR/$tdir
11777         for num in 1 2 3 4; do
11778                 for count in $(seq 1 $STRIPE_COUNT); do
11779                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11780                                 local size=`expr $STRIPE_SIZE \* $num`
11781                                 local file=file"$num-$idx-$count"
11782                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11783                         done
11784                 done
11785         done
11786
11787         cd $DIR
11788         $1 tar cf $TMP/f102.tar $tdir --xattrs
11789 }
11790
11791 cleanup_test102() {
11792         trap 0
11793         rm -f $TMP/f102.tar
11794         rm -rf $DIR/d0.sanity/d102
11795 }
11796
11797 test_102a() {
11798         [ "$UID" != 0 ] && skip "must run as root"
11799         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11800                 skip_env "must have user_xattr"
11801
11802         [ -z "$(which setfattr 2>/dev/null)" ] &&
11803                 skip_env "could not find setfattr"
11804
11805         local testfile=$DIR/$tfile
11806
11807         touch $testfile
11808         echo "set/get xattr..."
11809         setfattr -n trusted.name1 -v value1 $testfile ||
11810                 error "setfattr -n trusted.name1=value1 $testfile failed"
11811         getfattr -n trusted.name1 $testfile 2> /dev/null |
11812           grep "trusted.name1=.value1" ||
11813                 error "$testfile missing trusted.name1=value1"
11814
11815         setfattr -n user.author1 -v author1 $testfile ||
11816                 error "setfattr -n user.author1=author1 $testfile failed"
11817         getfattr -n user.author1 $testfile 2> /dev/null |
11818           grep "user.author1=.author1" ||
11819                 error "$testfile missing trusted.author1=author1"
11820
11821         echo "listxattr..."
11822         setfattr -n trusted.name2 -v value2 $testfile ||
11823                 error "$testfile unable to set trusted.name2"
11824         setfattr -n trusted.name3 -v value3 $testfile ||
11825                 error "$testfile unable to set trusted.name3"
11826         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11827             grep "trusted.name" | wc -l) -eq 3 ] ||
11828                 error "$testfile missing 3 trusted.name xattrs"
11829
11830         setfattr -n user.author2 -v author2 $testfile ||
11831                 error "$testfile unable to set user.author2"
11832         setfattr -n user.author3 -v author3 $testfile ||
11833                 error "$testfile unable to set user.author3"
11834         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11835             grep "user.author" | wc -l) -eq 3 ] ||
11836                 error "$testfile missing 3 user.author xattrs"
11837
11838         echo "remove xattr..."
11839         setfattr -x trusted.name1 $testfile ||
11840                 error "$testfile error deleting trusted.name1"
11841         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11842                 error "$testfile did not delete trusted.name1 xattr"
11843
11844         setfattr -x user.author1 $testfile ||
11845                 error "$testfile error deleting user.author1"
11846         echo "set lustre special xattr ..."
11847         $LFS setstripe -c1 $testfile
11848         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11849                 awk -F "=" '/trusted.lov/ { print $2 }' )
11850         setfattr -n "trusted.lov" -v $lovea $testfile ||
11851                 error "$testfile doesn't ignore setting trusted.lov again"
11852         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11853                 error "$testfile allow setting invalid trusted.lov"
11854         rm -f $testfile
11855 }
11856 run_test 102a "user xattr test =================================="
11857
11858 check_102b_layout() {
11859         local layout="$*"
11860         local testfile=$DIR/$tfile
11861
11862         echo "test layout '$layout'"
11863         $LFS setstripe $layout $testfile || error "setstripe failed"
11864         $LFS getstripe -y $testfile
11865
11866         echo "get/set/list trusted.lov xattr ..." # b=10930
11867         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11868         [[ "$value" =~ "trusted.lov" ]] ||
11869                 error "can't get trusted.lov from $testfile"
11870         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11871                 error "getstripe failed"
11872
11873         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11874
11875         value=$(cut -d= -f2 <<<$value)
11876         # LU-13168: truncated xattr should fail if short lov_user_md header
11877         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11878                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11879         for len in $lens; do
11880                 echo "setfattr $len $testfile.2"
11881                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11882                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11883         done
11884         local stripe_size=$($LFS getstripe -S $testfile.2)
11885         local stripe_count=$($LFS getstripe -c $testfile.2)
11886         [[ $stripe_size -eq 65536 ]] ||
11887                 error "stripe size $stripe_size != 65536"
11888         [[ $stripe_count -eq $stripe_count_orig ]] ||
11889                 error "stripe count $stripe_count != $stripe_count_orig"
11890         rm $testfile $testfile.2
11891 }
11892
11893 test_102b() {
11894         [ -z "$(which setfattr 2>/dev/null)" ] &&
11895                 skip_env "could not find setfattr"
11896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11897
11898         # check plain layout
11899         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11900
11901         # and also check composite layout
11902         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11903
11904 }
11905 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11906
11907 test_102c() {
11908         [ -z "$(which setfattr 2>/dev/null)" ] &&
11909                 skip_env "could not find setfattr"
11910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11911
11912         # b10930: get/set/list lustre.lov xattr
11913         echo "get/set/list lustre.lov xattr ..."
11914         test_mkdir $DIR/$tdir
11915         chown $RUNAS_ID $DIR/$tdir
11916         local testfile=$DIR/$tdir/$tfile
11917         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11918                 error "setstripe failed"
11919         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11920                 error "getstripe failed"
11921         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11922         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11923
11924         local testfile2=${testfile}2
11925         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11926                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11927
11928         $RUNAS $MCREATE $testfile2
11929         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11930         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11931         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11932         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11933         [ $stripe_count -eq $STRIPECOUNT ] ||
11934                 error "stripe count $stripe_count != $STRIPECOUNT"
11935 }
11936 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11937
11938 compare_stripe_info1() {
11939         local stripe_index_all_zero=true
11940
11941         for num in 1 2 3 4; do
11942                 for count in $(seq 1 $STRIPE_COUNT); do
11943                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11944                                 local size=$((STRIPE_SIZE * num))
11945                                 local file=file"$num-$offset-$count"
11946                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11947                                 [[ $stripe_size -ne $size ]] &&
11948                                     error "$file: size $stripe_size != $size"
11949                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11950                                 # allow fewer stripes to be created, ORI-601
11951                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11952                                     error "$file: count $stripe_count != $count"
11953                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11954                                 [[ $stripe_index -ne 0 ]] &&
11955                                         stripe_index_all_zero=false
11956                         done
11957                 done
11958         done
11959         $stripe_index_all_zero &&
11960                 error "all files are being extracted starting from OST index 0"
11961         return 0
11962 }
11963
11964 have_xattrs_include() {
11965         tar --help | grep -q xattrs-include &&
11966                 echo --xattrs-include="lustre.*"
11967 }
11968
11969 test_102d() {
11970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11972
11973         XINC=$(have_xattrs_include)
11974         setup_test102
11975         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11976         cd $DIR/$tdir/$tdir
11977         compare_stripe_info1
11978 }
11979 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11980
11981 test_102f() {
11982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11984
11985         XINC=$(have_xattrs_include)
11986         setup_test102
11987         test_mkdir $DIR/$tdir.restore
11988         cd $DIR
11989         tar cf - --xattrs $tdir | tar xf - \
11990                 -C $DIR/$tdir.restore --xattrs $XINC
11991         cd $DIR/$tdir.restore/$tdir
11992         compare_stripe_info1
11993 }
11994 run_test 102f "tar copy files, not keep osts"
11995
11996 grow_xattr() {
11997         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11998                 skip "must have user_xattr"
11999         [ -z "$(which setfattr 2>/dev/null)" ] &&
12000                 skip_env "could not find setfattr"
12001         [ -z "$(which getfattr 2>/dev/null)" ] &&
12002                 skip_env "could not find getfattr"
12003
12004         local xsize=${1:-1024}  # in bytes
12005         local file=$DIR/$tfile
12006         local value="$(generate_string $xsize)"
12007         local xbig=trusted.big
12008         local toobig=$2
12009
12010         touch $file
12011         log "save $xbig on $file"
12012         if [ -z "$toobig" ]
12013         then
12014                 setfattr -n $xbig -v $value $file ||
12015                         error "saving $xbig on $file failed"
12016         else
12017                 setfattr -n $xbig -v $value $file &&
12018                         error "saving $xbig on $file succeeded"
12019                 return 0
12020         fi
12021
12022         local orig=$(get_xattr_value $xbig $file)
12023         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12024
12025         local xsml=trusted.sml
12026         log "save $xsml on $file"
12027         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12028
12029         local new=$(get_xattr_value $xbig $file)
12030         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12031
12032         log "grow $xsml on $file"
12033         setfattr -n $xsml -v "$value" $file ||
12034                 error "growing $xsml on $file failed"
12035
12036         new=$(get_xattr_value $xbig $file)
12037         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12038         log "$xbig still valid after growing $xsml"
12039
12040         rm -f $file
12041 }
12042
12043 test_102h() { # bug 15777
12044         grow_xattr 1024
12045 }
12046 run_test 102h "grow xattr from inside inode to external block"
12047
12048 test_102ha() {
12049         large_xattr_enabled || skip_env "ea_inode feature disabled"
12050
12051         echo "setting xattr of max xattr size: $(max_xattr_size)"
12052         grow_xattr $(max_xattr_size)
12053
12054         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12055         echo "This should fail:"
12056         grow_xattr $(($(max_xattr_size) + 10)) 1
12057 }
12058 run_test 102ha "grow xattr from inside inode to external inode"
12059
12060 test_102i() { # bug 17038
12061         [ -z "$(which getfattr 2>/dev/null)" ] &&
12062                 skip "could not find getfattr"
12063
12064         touch $DIR/$tfile
12065         ln -s $DIR/$tfile $DIR/${tfile}link
12066         getfattr -n trusted.lov $DIR/$tfile ||
12067                 error "lgetxattr on $DIR/$tfile failed"
12068         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12069                 grep -i "no such attr" ||
12070                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12071         rm -f $DIR/$tfile $DIR/${tfile}link
12072 }
12073 run_test 102i "lgetxattr test on symbolic link ============"
12074
12075 test_102j() {
12076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12078
12079         XINC=$(have_xattrs_include)
12080         setup_test102 "$RUNAS"
12081         chown $RUNAS_ID $DIR/$tdir
12082         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12083         cd $DIR/$tdir/$tdir
12084         compare_stripe_info1 "$RUNAS"
12085 }
12086 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12087
12088 test_102k() {
12089         [ -z "$(which setfattr 2>/dev/null)" ] &&
12090                 skip "could not find setfattr"
12091
12092         touch $DIR/$tfile
12093         # b22187 just check that does not crash for regular file.
12094         setfattr -n trusted.lov $DIR/$tfile
12095         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12096         local test_kdir=$DIR/$tdir
12097         test_mkdir $test_kdir
12098         local default_size=$($LFS getstripe -S $test_kdir)
12099         local default_count=$($LFS getstripe -c $test_kdir)
12100         local default_offset=$($LFS getstripe -i $test_kdir)
12101         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12102                 error 'dir setstripe failed'
12103         setfattr -n trusted.lov $test_kdir
12104         local stripe_size=$($LFS getstripe -S $test_kdir)
12105         local stripe_count=$($LFS getstripe -c $test_kdir)
12106         local stripe_offset=$($LFS getstripe -i $test_kdir)
12107         [ $stripe_size -eq $default_size ] ||
12108                 error "stripe size $stripe_size != $default_size"
12109         [ $stripe_count -eq $default_count ] ||
12110                 error "stripe count $stripe_count != $default_count"
12111         [ $stripe_offset -eq $default_offset ] ||
12112                 error "stripe offset $stripe_offset != $default_offset"
12113         rm -rf $DIR/$tfile $test_kdir
12114 }
12115 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12116
12117 test_102l() {
12118         [ -z "$(which getfattr 2>/dev/null)" ] &&
12119                 skip "could not find getfattr"
12120
12121         # LU-532 trusted. xattr is invisible to non-root
12122         local testfile=$DIR/$tfile
12123
12124         touch $testfile
12125
12126         echo "listxattr as user..."
12127         chown $RUNAS_ID $testfile
12128         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12129             grep -q "trusted" &&
12130                 error "$testfile trusted xattrs are user visible"
12131
12132         return 0;
12133 }
12134 run_test 102l "listxattr size test =================================="
12135
12136 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12137         local path=$DIR/$tfile
12138         touch $path
12139
12140         listxattr_size_check $path || error "listattr_size_check $path failed"
12141 }
12142 run_test 102m "Ensure listxattr fails on small bufffer ========"
12143
12144 cleanup_test102
12145
12146 getxattr() { # getxattr path name
12147         # Return the base64 encoding of the value of xattr name on path.
12148         local path=$1
12149         local name=$2
12150
12151         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12152         # file: $path
12153         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12154         #
12155         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12156
12157         getfattr --absolute-names --encoding=base64 --name=$name $path |
12158                 awk -F= -v name=$name '$1 == name {
12159                         print substr($0, index($0, "=") + 1);
12160         }'
12161 }
12162
12163 test_102n() { # LU-4101 mdt: protect internal xattrs
12164         [ -z "$(which setfattr 2>/dev/null)" ] &&
12165                 skip "could not find setfattr"
12166         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12167         then
12168                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12169         fi
12170
12171         local file0=$DIR/$tfile.0
12172         local file1=$DIR/$tfile.1
12173         local xattr0=$TMP/$tfile.0
12174         local xattr1=$TMP/$tfile.1
12175         local namelist="lov lma lmv link fid version som hsm"
12176         local name
12177         local value
12178
12179         rm -rf $file0 $file1 $xattr0 $xattr1
12180         touch $file0 $file1
12181
12182         # Get 'before' xattrs of $file1.
12183         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12184
12185         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12186                 namelist+=" lfsck_namespace"
12187         for name in $namelist; do
12188                 # Try to copy xattr from $file0 to $file1.
12189                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12190
12191                 setfattr --name=trusted.$name --value="$value" $file1 ||
12192                         error "setxattr 'trusted.$name' failed"
12193
12194                 # Try to set a garbage xattr.
12195                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12196
12197                 if [[ x$name == "xlov" ]]; then
12198                         setfattr --name=trusted.lov --value="$value" $file1 &&
12199                         error "setxattr invalid 'trusted.lov' success"
12200                 else
12201                         setfattr --name=trusted.$name --value="$value" $file1 ||
12202                                 error "setxattr invalid 'trusted.$name' failed"
12203                 fi
12204
12205                 # Try to remove the xattr from $file1. We don't care if this
12206                 # appears to succeed or fail, we just don't want there to be
12207                 # any changes or crashes.
12208                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12209         done
12210
12211         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12212         then
12213                 name="lfsck_ns"
12214                 # Try to copy xattr from $file0 to $file1.
12215                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12216
12217                 setfattr --name=trusted.$name --value="$value" $file1 ||
12218                         error "setxattr 'trusted.$name' failed"
12219
12220                 # Try to set a garbage xattr.
12221                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12222
12223                 setfattr --name=trusted.$name --value="$value" $file1 ||
12224                         error "setxattr 'trusted.$name' failed"
12225
12226                 # Try to remove the xattr from $file1. We don't care if this
12227                 # appears to succeed or fail, we just don't want there to be
12228                 # any changes or crashes.
12229                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12230         fi
12231
12232         # Get 'after' xattrs of file1.
12233         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12234
12235         if ! diff $xattr0 $xattr1; then
12236                 error "before and after xattrs of '$file1' differ"
12237         fi
12238
12239         rm -rf $file0 $file1 $xattr0 $xattr1
12240
12241         return 0
12242 }
12243 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12244
12245 test_102p() { # LU-4703 setxattr did not check ownership
12246         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12247                 skip "MDS needs to be at least 2.5.56"
12248
12249         local testfile=$DIR/$tfile
12250
12251         touch $testfile
12252
12253         echo "setfacl as user..."
12254         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12255         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12256
12257         echo "setfattr as user..."
12258         setfacl -m "u:$RUNAS_ID:---" $testfile
12259         $RUNAS setfattr -x system.posix_acl_access $testfile
12260         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12261 }
12262 run_test 102p "check setxattr(2) correctly fails without permission"
12263
12264 test_102q() {
12265         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12266                 skip "MDS needs to be at least 2.6.92"
12267
12268         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12269 }
12270 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12271
12272 test_102r() {
12273         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12274                 skip "MDS needs to be at least 2.6.93"
12275
12276         touch $DIR/$tfile || error "touch"
12277         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12278         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12279         rm $DIR/$tfile || error "rm"
12280
12281         #normal directory
12282         mkdir -p $DIR/$tdir || error "mkdir"
12283         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12284         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12285         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12286                 error "$testfile error deleting user.author1"
12287         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12288                 grep "user.$(basename $tdir)" &&
12289                 error "$tdir did not delete user.$(basename $tdir)"
12290         rmdir $DIR/$tdir || error "rmdir"
12291
12292         #striped directory
12293         test_mkdir $DIR/$tdir
12294         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12295         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12296         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12297                 error "$testfile error deleting user.author1"
12298         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12299                 grep "user.$(basename $tdir)" &&
12300                 error "$tdir did not delete user.$(basename $tdir)"
12301         rmdir $DIR/$tdir || error "rm striped dir"
12302 }
12303 run_test 102r "set EAs with empty values"
12304
12305 test_102s() {
12306         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12307                 skip "MDS needs to be at least 2.11.52"
12308
12309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12310
12311         save_lustre_params client "llite.*.xattr_cache" > $save
12312
12313         for cache in 0 1; do
12314                 lctl set_param llite.*.xattr_cache=$cache
12315
12316                 rm -f $DIR/$tfile
12317                 touch $DIR/$tfile || error "touch"
12318                 for prefix in lustre security system trusted user; do
12319                         # Note getxattr() may fail with 'Operation not
12320                         # supported' or 'No such attribute' depending
12321                         # on prefix and cache.
12322                         getfattr -n $prefix.n102s $DIR/$tfile &&
12323                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12324                 done
12325         done
12326
12327         restore_lustre_params < $save
12328 }
12329 run_test 102s "getting nonexistent xattrs should fail"
12330
12331 test_102t() {
12332         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12333                 skip "MDS needs to be at least 2.11.52"
12334
12335         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12336
12337         save_lustre_params client "llite.*.xattr_cache" > $save
12338
12339         for cache in 0 1; do
12340                 lctl set_param llite.*.xattr_cache=$cache
12341
12342                 for buf_size in 0 256; do
12343                         rm -f $DIR/$tfile
12344                         touch $DIR/$tfile || error "touch"
12345                         setfattr -n user.multiop $DIR/$tfile
12346                         $MULTIOP $DIR/$tfile oa$buf_size ||
12347                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12348                 done
12349         done
12350
12351         restore_lustre_params < $save
12352 }
12353 run_test 102t "zero length xattr values handled correctly"
12354
12355 run_acl_subtest()
12356 {
12357         local test=$LUSTRE/tests/acl/$1.test
12358         local tmp=$(mktemp -t $1-XXXXXX).test
12359         local bin=$2
12360         local dmn=$3
12361         local grp=$4
12362         local nbd=$5
12363         export LANG=C
12364
12365
12366         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12367         local sedgroups="-e s/:users/:$grp/g"
12368         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12369
12370         sed $sedusers $sedgroups < $test > $tmp
12371         stack_trap "rm -f $tmp"
12372         [[ -s $tmp ]] || error "sed failed to create test script"
12373
12374         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12375         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12376 }
12377
12378 test_103a() {
12379         [ "$UID" != 0 ] && skip "must run as root"
12380         $GSS && skip_env "could not run under gss"
12381         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12382                 skip_env "must have acl enabled"
12383         which setfacl || skip_env "could not find setfacl"
12384         remote_mds_nodsh && skip "remote MDS with nodsh"
12385
12386         local mdts=$(comma_list $(mdts_nodes))
12387         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12388
12389         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12390         stack_trap "[[ -z \"$saved\" ]] || \
12391                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12392
12393         ACLBIN=${ACLBIN:-"bin"}
12394         ACLDMN=${ACLDMN:-"daemon"}
12395         ACLGRP=${ACLGRP:-"users"}
12396         ACLNBD=${ACLNBD:-"nobody"}
12397
12398         if ! id $ACLBIN ||
12399            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12400                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12401                 ACLBIN=$USER0
12402                 if ! id $ACLBIN ; then
12403                         cat /etc/passwd
12404                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12405                 fi
12406         fi
12407         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12408            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12409                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12410                 ACLDMN=$USER1
12411                 if ! id $ACLDMN ; then
12412                         cat /etc/passwd
12413                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12414                 fi
12415         fi
12416         if ! getent group $ACLGRP; then
12417                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12418                 ACLGRP="$TSTUSR"
12419                 if ! getent group $ACLGRP; then
12420                         echo "cannot find group '$ACLGRP', adding it"
12421                         cat /etc/group
12422                         add_group 60000 $ACLGRP
12423                 fi
12424         fi
12425
12426         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12427         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12428         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12429
12430         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12431                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12432                 ACLGRP="$TSTUSR"
12433                 if ! getent group $ACLGRP; then
12434                         echo "cannot find group '$ACLGRP', adding it"
12435                         cat /etc/group
12436                         add_group 60000 $ACLGRP
12437                 fi
12438                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12439                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12440                         cat /etc/group
12441                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12442                 fi
12443         fi
12444
12445         gpasswd -a $ACLDMN $ACLBIN ||
12446                 error "setting client group failed"             # LU-5641
12447         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12448                 error "setting MDS group failed"                # LU-5641
12449
12450         declare -a identity_old
12451
12452         for ((num = 1; num <= $MDSCOUNT; num++)); do
12453                 switch_identity $num true || identity_old[$num]=$?
12454         done
12455
12456         SAVE_UMASK=$(umask)
12457         umask 0022
12458         mkdir -p $DIR/$tdir
12459         cd $DIR/$tdir
12460
12461         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12462         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12463         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12464         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12465         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12466         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12467         if ! id -u $ACLNBD ||
12468            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12469                 ACLNBD="nfsnobody"
12470                 if ! id -u $ACLNBD; then
12471                         ACLNBD=""
12472                 fi
12473         fi
12474         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12475                 add_group $(id -u $ACLNBD) $ACLNBD
12476                 if ! getent group $ACLNBD; then
12477                         ACLNBD=""
12478                 fi
12479         fi
12480         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12481            [[ -n "$ACLNBD" ]] && which setfattr; then
12482                 run_acl_subtest permissions_xattr \
12483                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12484         elif [[ -z "$ACLNBD" ]]; then
12485                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12486         else
12487                 echo "skip 'permission_xattr' test - missing setfattr command"
12488         fi
12489         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12490
12491         # inheritance test got from HP
12492         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12493         chmod +x make-tree || error "chmod +x failed"
12494         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12495         rm -f make-tree
12496
12497         echo "LU-974 ignore umask when acl is enabled..."
12498         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12499         if [ $MDSCOUNT -ge 2 ]; then
12500                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12501         fi
12502
12503         echo "LU-2561 newly created file is same size as directory..."
12504         if [ "$mds1_FSTYPE" != "zfs" ]; then
12505                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12506         else
12507                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12508         fi
12509
12510         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12511
12512         cd $SAVE_PWD
12513         umask $SAVE_UMASK
12514
12515         for ((num = 1; num <= $MDSCOUNT; num++)); do
12516                 if [[ "${identity_old[$num]}" == 1 ]]; then
12517                         switch_identity $num false || identity_old[$num]=$?
12518                 fi
12519         done
12520 }
12521 run_test 103a "acl test"
12522
12523 test_103b() {
12524         declare -a pids
12525         local U
12526
12527         stack_trap "rm -f $DIR/$tfile.*"
12528         for U in {0..511}; do
12529                 {
12530                 local O=$(printf "%04o" $U)
12531
12532                 umask $(printf "%04o" $((511 ^ $O)))
12533                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12534                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12535
12536                 (( $S == ($O & 0666) )) ||
12537                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12538
12539                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12540                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12541                 (( $S == ($O & 0666) )) ||
12542                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12543
12544                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12545                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12546                 (( $S == ($O & 0666) )) ||
12547                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12548                 rm -f $DIR/$tfile.[smp]$0
12549                 } &
12550                 local pid=$!
12551
12552                 # limit the concurrently running threads to 64. LU-11878
12553                 local idx=$((U % 64))
12554                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12555                 pids[idx]=$pid
12556         done
12557         wait
12558 }
12559 run_test 103b "umask lfs setstripe"
12560
12561 test_103c() {
12562         mkdir -p $DIR/$tdir
12563         cp -rp $DIR/$tdir $DIR/$tdir.bak
12564
12565         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12566                 error "$DIR/$tdir shouldn't contain default ACL"
12567         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12568                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12569         true
12570 }
12571 run_test 103c "'cp -rp' won't set empty acl"
12572
12573 test_103e() {
12574         local numacl
12575         local fileacl
12576         local saved_debug=$($LCTL get_param -n debug)
12577
12578         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12579                 skip "MDS needs to be at least 2.14.52"
12580
12581         large_xattr_enabled || skip_env "ea_inode feature disabled"
12582
12583         mkdir -p $DIR/$tdir
12584         # add big LOV EA to cause reply buffer overflow earlier
12585         $LFS setstripe -C 1000 $DIR/$tdir
12586         lctl set_param mdc.*-mdc*.stats=clear
12587
12588         $LCTL set_param debug=0
12589         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12590         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12591
12592         # add a large number of default ACLs (expect 8000+ for 2.13+)
12593         for U in {2..7000}; do
12594                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12595                         error "Able to add just $U default ACLs"
12596         done
12597         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12598         echo "$numacl default ACLs created"
12599
12600         stat $DIR/$tdir || error "Cannot stat directory"
12601         # check file creation
12602         touch $DIR/$tdir/$tfile ||
12603                 error "failed to create $tfile with $numacl default ACLs"
12604         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12605         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12606         echo "$fileacl ACLs were inherited"
12607         (( $fileacl == $numacl )) ||
12608                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12609         # check that new ACLs creation adds new ACLs to inherited ACLs
12610         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12611                 error "Cannot set new ACL"
12612         numacl=$((numacl + 1))
12613         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12614         (( $fileacl == $numacl )) ||
12615                 error "failed to add new ACL: $fileacl != $numacl as expected"
12616         # adds more ACLs to a file to reach their maximum at 8000+
12617         numacl=0
12618         for U in {20000..25000}; do
12619                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12620                 numacl=$((numacl + 1))
12621         done
12622         echo "Added $numacl more ACLs to the file"
12623         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12624         echo "Total $fileacl ACLs in file"
12625         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12626         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12627         rmdir $DIR/$tdir || error "Cannot remove directory"
12628 }
12629 run_test 103e "inheritance of big amount of default ACLs"
12630
12631 test_103f() {
12632         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12633                 skip "MDS needs to be at least 2.14.51"
12634
12635         large_xattr_enabled || skip_env "ea_inode feature disabled"
12636
12637         # enable changelog to consume more internal MDD buffers
12638         changelog_register
12639
12640         mkdir -p $DIR/$tdir
12641         # add big LOV EA
12642         $LFS setstripe -C 1000 $DIR/$tdir
12643         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12644         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12645         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12646         rmdir $DIR/$tdir || error "Cannot remove directory"
12647 }
12648 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12649
12650 test_104a() {
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652
12653         touch $DIR/$tfile
12654         lfs df || error "lfs df failed"
12655         lfs df -ih || error "lfs df -ih failed"
12656         lfs df -h $DIR || error "lfs df -h $DIR failed"
12657         lfs df -i $DIR || error "lfs df -i $DIR failed"
12658         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12659         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12660
12661         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12662         lctl --device %$OSC deactivate
12663         lfs df || error "lfs df with deactivated OSC failed"
12664         lctl --device %$OSC activate
12665         # wait the osc back to normal
12666         wait_osc_import_ready client ost
12667
12668         lfs df || error "lfs df with reactivated OSC failed"
12669         rm -f $DIR/$tfile
12670 }
12671 run_test 104a "lfs df [-ih] [path] test ========================="
12672
12673 test_104b() {
12674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12675         [ $RUNAS_ID -eq $UID ] &&
12676                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12677
12678         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12679                         grep "Permission denied" | wc -l)))
12680         if [ $denied_cnt -ne 0 ]; then
12681                 error "lfs check servers test failed"
12682         fi
12683 }
12684 run_test 104b "$RUNAS lfs check servers test ===================="
12685
12686 #
12687 # Verify $1 is within range of $2.
12688 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12689 # $1 is <= 2% of $2. Else Fail.
12690 #
12691 value_in_range() {
12692         # Strip all units (M, G, T)
12693         actual=$(echo $1 | tr -d A-Z)
12694         expect=$(echo $2 | tr -d A-Z)
12695
12696         expect_lo=$(($expect * 98 / 100)) # 2% below
12697         expect_hi=$(($expect * 102 / 100)) # 2% above
12698
12699         # permit 2% drift above and below
12700         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12701 }
12702
12703 test_104c() {
12704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12705         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12706
12707         local ost_param="osd-zfs.$FSNAME-OST0000."
12708         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12709         local ofacets=$(get_facets OST)
12710         local mfacets=$(get_facets MDS)
12711         local saved_ost_blocks=
12712         local saved_mdt_blocks=
12713
12714         echo "Before recordsize change"
12715         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12716         df=($(df -h | grep "$MOUNT"$))
12717
12718         # For checking.
12719         echo "lfs output : ${lfs_df[*]}"
12720         echo "df  output : ${df[*]}"
12721
12722         for facet in ${ofacets//,/ }; do
12723                 if [ -z $saved_ost_blocks ]; then
12724                         saved_ost_blocks=$(do_facet $facet \
12725                                 lctl get_param -n $ost_param.blocksize)
12726                         echo "OST Blocksize: $saved_ost_blocks"
12727                 fi
12728                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12729                 do_facet $facet zfs set recordsize=32768 $ost
12730         done
12731
12732         # BS too small. Sufficient for functional testing.
12733         for facet in ${mfacets//,/ }; do
12734                 if [ -z $saved_mdt_blocks ]; then
12735                         saved_mdt_blocks=$(do_facet $facet \
12736                                 lctl get_param -n $mdt_param.blocksize)
12737                         echo "MDT Blocksize: $saved_mdt_blocks"
12738                 fi
12739                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12740                 do_facet $facet zfs set recordsize=32768 $mdt
12741         done
12742
12743         # Give new values chance to reflect change
12744         sleep 2
12745
12746         echo "After recordsize change"
12747         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12748         df_after=($(df -h | grep "$MOUNT"$))
12749
12750         # For checking.
12751         echo "lfs output : ${lfs_df_after[*]}"
12752         echo "df  output : ${df_after[*]}"
12753
12754         # Verify lfs df
12755         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12756                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12757         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12758                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12759         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12760                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12761
12762         # Verify df
12763         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12764                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12765         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12766                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12767         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12768                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12769
12770         # Restore MDT recordize back to original
12771         for facet in ${mfacets//,/ }; do
12772                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12773                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12774         done
12775
12776         # Restore OST recordize back to original
12777         for facet in ${ofacets//,/ }; do
12778                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12779                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12780         done
12781
12782         return 0
12783 }
12784 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12785
12786 test_104d() {
12787         (( $RUNAS_ID != $UID )) ||
12788                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12789
12790         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12791                 skip "lustre version doesn't support lctl dl with non-root"
12792
12793         # debugfs only allows root users to access files, so the
12794         # previous move of the "devices" file to debugfs broke
12795         # "lctl dl" for non-root users. The LU-9680 Netlink
12796         # interface again allows non-root users to list devices.
12797         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12798                 error "lctl dl doesn't work for non root"
12799
12800         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12801         [ "$ost_count" -eq $OSTCOUNT ]  ||
12802                 error "lctl dl reports wrong number of OST devices"
12803
12804         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12805         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12806                 error "lctl dl reports wrong number of MDT devices"
12807 }
12808 run_test 104d "$RUNAS lctl dl test"
12809
12810 test_105a() {
12811         # doesn't work on 2.4 kernels
12812         touch $DIR/$tfile
12813         if $(flock_is_enabled); then
12814                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12815         else
12816                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12817         fi
12818         rm -f $DIR/$tfile
12819 }
12820 run_test 105a "flock when mounted without -o flock test ========"
12821
12822 test_105b() {
12823         touch $DIR/$tfile
12824         if $(flock_is_enabled); then
12825                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12826         else
12827                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12828         fi
12829         rm -f $DIR/$tfile
12830 }
12831 run_test 105b "fcntl when mounted without -o flock test ========"
12832
12833 test_105c() {
12834         touch $DIR/$tfile
12835         if $(flock_is_enabled); then
12836                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12837         else
12838                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12839         fi
12840         rm -f $DIR/$tfile
12841 }
12842 run_test 105c "lockf when mounted without -o flock test"
12843
12844 test_105d() { # bug 15924
12845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12846
12847         test_mkdir $DIR/$tdir
12848         flock_is_enabled || skip_env "mount w/o flock enabled"
12849         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12850         $LCTL set_param fail_loc=0x80000315
12851         flocks_test 2 $DIR/$tdir
12852 }
12853 run_test 105d "flock race (should not freeze) ========"
12854
12855 test_105e() { # bug 22660 && 22040
12856         flock_is_enabled || skip_env "mount w/o flock enabled"
12857
12858         touch $DIR/$tfile
12859         flocks_test 3 $DIR/$tfile
12860 }
12861 run_test 105e "Two conflicting flocks from same process"
12862
12863 test_106() { #bug 10921
12864         test_mkdir $DIR/$tdir
12865         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12866         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12867 }
12868 run_test 106 "attempt exec of dir followed by chown of that dir"
12869
12870 test_107() {
12871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12872
12873         CDIR=`pwd`
12874         local file=core
12875
12876         cd $DIR
12877         rm -f $file
12878
12879         local save_pattern=$(sysctl -n kernel.core_pattern)
12880         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12881         sysctl -w kernel.core_pattern=$file
12882         sysctl -w kernel.core_uses_pid=0
12883
12884         ulimit -c unlimited
12885         sleep 60 &
12886         SLEEPPID=$!
12887
12888         sleep 1
12889
12890         kill -s 11 $SLEEPPID
12891         wait $SLEEPPID
12892         if [ -e $file ]; then
12893                 size=`stat -c%s $file`
12894                 [ $size -eq 0 ] && error "Fail to create core file $file"
12895         else
12896                 error "Fail to create core file $file"
12897         fi
12898         rm -f $file
12899         sysctl -w kernel.core_pattern=$save_pattern
12900         sysctl -w kernel.core_uses_pid=$save_uses_pid
12901         cd $CDIR
12902 }
12903 run_test 107 "Coredump on SIG"
12904
12905 test_110() {
12906         test_mkdir $DIR/$tdir
12907         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12908         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12909                 error "mkdir with 256 char should fail, but did not"
12910         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12911                 error "create with 255 char failed"
12912         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12913                 error "create with 256 char should fail, but did not"
12914
12915         ls -l $DIR/$tdir
12916         rm -rf $DIR/$tdir
12917 }
12918 run_test 110 "filename length checking"
12919
12920 test_116a() { # was previously test_116()
12921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12923         remote_mds_nodsh && skip "remote MDS with nodsh"
12924
12925         echo -n "Free space priority "
12926         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12927                 head -n1
12928         declare -a AVAIL
12929         free_min_max
12930
12931         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12932         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12933         stack_trap simple_cleanup_common
12934
12935         # Check if we need to generate uneven OSTs
12936         test_mkdir -p $DIR/$tdir/OST${MINI}
12937         local FILL=$((MINV / 4))
12938         local DIFF=$((MAXV - MINV))
12939         local DIFF2=$((DIFF * 100 / MINV))
12940
12941         local threshold=$(do_facet $SINGLEMDS \
12942                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12943         threshold=${threshold%%%}
12944         echo -n "Check for uneven OSTs: "
12945         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12946
12947         if [[ $DIFF2 -gt $threshold ]]; then
12948                 echo "ok"
12949                 echo "Don't need to fill OST$MINI"
12950         else
12951                 # generate uneven OSTs. Write 2% over the QOS threshold value
12952                 echo "no"
12953                 DIFF=$((threshold - DIFF2 + 2))
12954                 DIFF2=$((MINV * DIFF / 100))
12955                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12956                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12957                         error "setstripe failed"
12958                 DIFF=$((DIFF2 / 2048))
12959                 i=0
12960                 while [ $i -lt $DIFF ]; do
12961                         i=$((i + 1))
12962                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12963                                 bs=2M count=1 2>/dev/null
12964                         echo -n .
12965                 done
12966                 echo .
12967                 sync
12968                 sleep_maxage
12969                 free_min_max
12970         fi
12971
12972         DIFF=$((MAXV - MINV))
12973         DIFF2=$((DIFF * 100 / MINV))
12974         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12975         if [ $DIFF2 -gt $threshold ]; then
12976                 echo "ok"
12977         else
12978                 skip "QOS imbalance criteria not met"
12979         fi
12980
12981         MINI1=$MINI
12982         MINV1=$MINV
12983         MAXI1=$MAXI
12984         MAXV1=$MAXV
12985
12986         # now fill using QOS
12987         $LFS setstripe -c 1 $DIR/$tdir
12988         FILL=$((FILL / 200))
12989         if [ $FILL -gt 600 ]; then
12990                 FILL=600
12991         fi
12992         echo "writing $FILL files to QOS-assigned OSTs"
12993         i=0
12994         while [ $i -lt $FILL ]; do
12995                 i=$((i + 1))
12996                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12997                         count=1 2>/dev/null
12998                 echo -n .
12999         done
13000         echo "wrote $i 200k files"
13001         sync
13002         sleep_maxage
13003
13004         echo "Note: free space may not be updated, so measurements might be off"
13005         free_min_max
13006         DIFF2=$((MAXV - MINV))
13007         echo "free space delta: orig $DIFF final $DIFF2"
13008         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13009         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13010         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13011         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13012         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13013         if [[ $DIFF -gt 0 ]]; then
13014                 FILL=$((DIFF2 * 100 / DIFF - 100))
13015                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13016         fi
13017
13018         # Figure out which files were written where
13019         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13020                awk '/'$MINI1': / {print $2; exit}')
13021         echo $UUID
13022         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13023         echo "$MINC files created on smaller OST $MINI1"
13024         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13025                awk '/'$MAXI1': / {print $2; exit}')
13026         echo $UUID
13027         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13028         echo "$MAXC files created on larger OST $MAXI1"
13029         if [[ $MINC -gt 0 ]]; then
13030                 FILL=$((MAXC * 100 / MINC - 100))
13031                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13032         fi
13033         [[ $MAXC -gt $MINC ]] ||
13034                 error_ignore LU-9 "stripe QOS didn't balance free space"
13035 }
13036 run_test 116a "stripe QOS: free space balance ==================="
13037
13038 test_116b() { # LU-2093
13039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13040         remote_mds_nodsh && skip "remote MDS with nodsh"
13041
13042 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13043         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13044                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13045         [ -z "$old_rr" ] && skip "no QOS"
13046         do_facet $SINGLEMDS lctl set_param \
13047                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13048         mkdir -p $DIR/$tdir
13049         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13050         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13051         do_facet $SINGLEMDS lctl set_param fail_loc=0
13052         rm -rf $DIR/$tdir
13053         do_facet $SINGLEMDS lctl set_param \
13054                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13055 }
13056 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13057
13058 test_117() # bug 10891
13059 {
13060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13061
13062         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13063         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13064         lctl set_param fail_loc=0x21e
13065         > $DIR/$tfile || error "truncate failed"
13066         lctl set_param fail_loc=0
13067         echo "Truncate succeeded."
13068         rm -f $DIR/$tfile
13069 }
13070 run_test 117 "verify osd extend =========="
13071
13072 NO_SLOW_RESENDCOUNT=4
13073 export OLD_RESENDCOUNT=""
13074 set_resend_count () {
13075         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13076         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13077         lctl set_param -n $PROC_RESENDCOUNT $1
13078         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13079 }
13080
13081 # for reduce test_118* time (b=14842)
13082 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13083
13084 # Reset async IO behavior after error case
13085 reset_async() {
13086         FILE=$DIR/reset_async
13087
13088         # Ensure all OSCs are cleared
13089         $LFS setstripe -c -1 $FILE
13090         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13091         sync
13092         rm $FILE
13093 }
13094
13095 test_118a() #bug 11710
13096 {
13097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13098
13099         reset_async
13100
13101         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13102         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13103         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13104
13105         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13106                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13107                 return 1;
13108         fi
13109         rm -f $DIR/$tfile
13110 }
13111 run_test 118a "verify O_SYNC works =========="
13112
13113 test_118b()
13114 {
13115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13116         remote_ost_nodsh && skip "remote OST with nodsh"
13117
13118         reset_async
13119
13120         #define OBD_FAIL_SRV_ENOENT 0x217
13121         set_nodes_failloc "$(osts_nodes)" 0x217
13122         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13123         RC=$?
13124         set_nodes_failloc "$(osts_nodes)" 0
13125         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13126         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13127                     grep -c writeback)
13128
13129         if [[ $RC -eq 0 ]]; then
13130                 error "Must return error due to dropped pages, rc=$RC"
13131                 return 1;
13132         fi
13133
13134         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13135                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13136                 return 1;
13137         fi
13138
13139         echo "Dirty pages not leaked on ENOENT"
13140
13141         # Due to the above error the OSC will issue all RPCs syncronously
13142         # until a subsequent RPC completes successfully without error.
13143         $MULTIOP $DIR/$tfile Ow4096yc
13144         rm -f $DIR/$tfile
13145
13146         return 0
13147 }
13148 run_test 118b "Reclaim dirty pages on fatal error =========="
13149
13150 test_118c()
13151 {
13152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13153
13154         # for 118c, restore the original resend count, LU-1940
13155         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13156                                 set_resend_count $OLD_RESENDCOUNT
13157         remote_ost_nodsh && skip "remote OST with nodsh"
13158
13159         reset_async
13160
13161         #define OBD_FAIL_OST_EROFS               0x216
13162         set_nodes_failloc "$(osts_nodes)" 0x216
13163
13164         # multiop should block due to fsync until pages are written
13165         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13166         MULTIPID=$!
13167         sleep 1
13168
13169         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13170                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13171         fi
13172
13173         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13174                     grep -c writeback)
13175         if [[ $WRITEBACK -eq 0 ]]; then
13176                 error "No page in writeback, writeback=$WRITEBACK"
13177         fi
13178
13179         set_nodes_failloc "$(osts_nodes)" 0
13180         wait $MULTIPID
13181         RC=$?
13182         if [[ $RC -ne 0 ]]; then
13183                 error "Multiop fsync failed, rc=$RC"
13184         fi
13185
13186         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13187         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13188                     grep -c writeback)
13189         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13190                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13191         fi
13192
13193         rm -f $DIR/$tfile
13194         echo "Dirty pages flushed via fsync on EROFS"
13195         return 0
13196 }
13197 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13198
13199 # continue to use small resend count to reduce test_118* time (b=14842)
13200 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13201
13202 test_118d()
13203 {
13204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13205         remote_ost_nodsh && skip "remote OST with nodsh"
13206
13207         reset_async
13208
13209         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13210         set_nodes_failloc "$(osts_nodes)" 0x214
13211         # multiop should block due to fsync until pages are written
13212         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13213         MULTIPID=$!
13214         sleep 1
13215
13216         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13217                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13218         fi
13219
13220         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13221                     grep -c writeback)
13222         if [[ $WRITEBACK -eq 0 ]]; then
13223                 error "No page in writeback, writeback=$WRITEBACK"
13224         fi
13225
13226         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13227         set_nodes_failloc "$(osts_nodes)" 0
13228
13229         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13230         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13231                     grep -c writeback)
13232         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13233                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13234         fi
13235
13236         rm -f $DIR/$tfile
13237         echo "Dirty pages gaurenteed flushed via fsync"
13238         return 0
13239 }
13240 run_test 118d "Fsync validation inject a delay of the bulk =========="
13241
13242 test_118f() {
13243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13244
13245         reset_async
13246
13247         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13248         lctl set_param fail_loc=0x8000040a
13249
13250         # Should simulate EINVAL error which is fatal
13251         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13252         RC=$?
13253         if [[ $RC -eq 0 ]]; then
13254                 error "Must return error due to dropped pages, rc=$RC"
13255         fi
13256
13257         lctl set_param fail_loc=0x0
13258
13259         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13260         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13261         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13262                     grep -c writeback)
13263         if [[ $LOCKED -ne 0 ]]; then
13264                 error "Locked pages remain in cache, locked=$LOCKED"
13265         fi
13266
13267         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13268                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13269         fi
13270
13271         rm -f $DIR/$tfile
13272         echo "No pages locked after fsync"
13273
13274         reset_async
13275         return 0
13276 }
13277 run_test 118f "Simulate unrecoverable OSC side error =========="
13278
13279 test_118g() {
13280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13281
13282         reset_async
13283
13284         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13285         lctl set_param fail_loc=0x406
13286
13287         # simulate local -ENOMEM
13288         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13289         RC=$?
13290
13291         lctl set_param fail_loc=0
13292         if [[ $RC -eq 0 ]]; then
13293                 error "Must return error due to dropped pages, rc=$RC"
13294         fi
13295
13296         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13297         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13298         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13299                         grep -c writeback)
13300         if [[ $LOCKED -ne 0 ]]; then
13301                 error "Locked pages remain in cache, locked=$LOCKED"
13302         fi
13303
13304         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13305                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13306         fi
13307
13308         rm -f $DIR/$tfile
13309         echo "No pages locked after fsync"
13310
13311         reset_async
13312         return 0
13313 }
13314 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13315
13316 test_118h() {
13317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13318         remote_ost_nodsh && skip "remote OST with nodsh"
13319
13320         reset_async
13321
13322         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13323         set_nodes_failloc "$(osts_nodes)" 0x20e
13324         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13325         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13326         RC=$?
13327
13328         set_nodes_failloc "$(osts_nodes)" 0
13329         if [[ $RC -eq 0 ]]; then
13330                 error "Must return error due to dropped pages, rc=$RC"
13331         fi
13332
13333         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13334         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13335         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13336                     grep -c writeback)
13337         if [[ $LOCKED -ne 0 ]]; then
13338                 error "Locked pages remain in cache, locked=$LOCKED"
13339         fi
13340
13341         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13342                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13343         fi
13344
13345         rm -f $DIR/$tfile
13346         echo "No pages locked after fsync"
13347
13348         return 0
13349 }
13350 run_test 118h "Verify timeout in handling recoverables errors  =========="
13351
13352 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13353
13354 test_118i() {
13355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13356         remote_ost_nodsh && skip "remote OST with nodsh"
13357
13358         reset_async
13359
13360         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13361         set_nodes_failloc "$(osts_nodes)" 0x20e
13362
13363         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13364         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13365         PID=$!
13366         sleep 5
13367         set_nodes_failloc "$(osts_nodes)" 0
13368
13369         wait $PID
13370         RC=$?
13371         if [[ $RC -ne 0 ]]; then
13372                 error "got error, but should be not, rc=$RC"
13373         fi
13374
13375         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13376         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13377         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13378         if [[ $LOCKED -ne 0 ]]; then
13379                 error "Locked pages remain in cache, locked=$LOCKED"
13380         fi
13381
13382         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13383                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13384         fi
13385
13386         rm -f $DIR/$tfile
13387         echo "No pages locked after fsync"
13388
13389         return 0
13390 }
13391 run_test 118i "Fix error before timeout in recoverable error  =========="
13392
13393 [ "$SLOW" = "no" ] && set_resend_count 4
13394
13395 test_118j() {
13396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13397         remote_ost_nodsh && skip "remote OST with nodsh"
13398
13399         reset_async
13400
13401         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13402         set_nodes_failloc "$(osts_nodes)" 0x220
13403
13404         # return -EIO from OST
13405         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13406         RC=$?
13407         set_nodes_failloc "$(osts_nodes)" 0x0
13408         if [[ $RC -eq 0 ]]; then
13409                 error "Must return error due to dropped pages, rc=$RC"
13410         fi
13411
13412         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13413         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13414         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13415         if [[ $LOCKED -ne 0 ]]; then
13416                 error "Locked pages remain in cache, locked=$LOCKED"
13417         fi
13418
13419         # in recoverable error on OST we want resend and stay until it finished
13420         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13421                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13422         fi
13423
13424         rm -f $DIR/$tfile
13425         echo "No pages locked after fsync"
13426
13427         return 0
13428 }
13429 run_test 118j "Simulate unrecoverable OST side error =========="
13430
13431 test_118k()
13432 {
13433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13434         remote_ost_nodsh && skip "remote OSTs with nodsh"
13435
13436         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13437         set_nodes_failloc "$(osts_nodes)" 0x20e
13438         test_mkdir $DIR/$tdir
13439
13440         for ((i=0;i<10;i++)); do
13441                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13442                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13443                 SLEEPPID=$!
13444                 sleep 0.500s
13445                 kill $SLEEPPID
13446                 wait $SLEEPPID
13447         done
13448
13449         set_nodes_failloc "$(osts_nodes)" 0
13450         rm -rf $DIR/$tdir
13451 }
13452 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13453
13454 test_118l() # LU-646
13455 {
13456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13457
13458         test_mkdir $DIR/$tdir
13459         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13460         rm -rf $DIR/$tdir
13461 }
13462 run_test 118l "fsync dir"
13463
13464 test_118m() # LU-3066
13465 {
13466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13467
13468         test_mkdir $DIR/$tdir
13469         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13470         rm -rf $DIR/$tdir
13471 }
13472 run_test 118m "fdatasync dir ========="
13473
13474 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13475
13476 test_118n()
13477 {
13478         local begin
13479         local end
13480
13481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13482         remote_ost_nodsh && skip "remote OSTs with nodsh"
13483
13484         # Sleep to avoid a cached response.
13485         #define OBD_STATFS_CACHE_SECONDS 1
13486         sleep 2
13487
13488         # Inject a 10 second delay in the OST_STATFS handler.
13489         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13490         set_nodes_failloc "$(osts_nodes)" 0x242
13491
13492         begin=$SECONDS
13493         stat --file-system $MOUNT > /dev/null
13494         end=$SECONDS
13495
13496         set_nodes_failloc "$(osts_nodes)" 0
13497
13498         if ((end - begin > 20)); then
13499             error "statfs took $((end - begin)) seconds, expected 10"
13500         fi
13501 }
13502 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13503
13504 test_119a() # bug 11737
13505 {
13506         BSIZE=$((512 * 1024))
13507         directio write $DIR/$tfile 0 1 $BSIZE
13508         # We ask to read two blocks, which is more than a file size.
13509         # directio will indicate an error when requested and actual
13510         # sizes aren't equeal (a normal situation in this case) and
13511         # print actual read amount.
13512         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13513         if [ "$NOB" != "$BSIZE" ]; then
13514                 error "read $NOB bytes instead of $BSIZE"
13515         fi
13516         rm -f $DIR/$tfile
13517 }
13518 run_test 119a "Short directIO read must return actual read amount"
13519
13520 test_119b() # bug 11737
13521 {
13522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13523
13524         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13525         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13526         sync
13527         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13528                 error "direct read failed"
13529         rm -f $DIR/$tfile
13530 }
13531 run_test 119b "Sparse directIO read must return actual read amount"
13532
13533 test_119c() # bug 13099
13534 {
13535         BSIZE=1048576
13536         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13537         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13538         rm -f $DIR/$tfile
13539 }
13540 run_test 119c "Testing for direct read hitting hole"
13541
13542 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13543 # Maloo test history
13544
13545 test_119e()
13546 {
13547         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13548                 skip "Need server version at least 2.15.58"
13549         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13550
13551         local stripe_size=$((1024 * 1024)) #1 MiB
13552         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13553         local file_size=$((25 * stripe_size))
13554         local bsizes
13555
13556         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13557         stack_trap "rm -f $DIR/$tfile*"
13558
13559         # Just a bit bigger than the largest size in the test set below
13560         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13561                 error "buffered i/o to create file failed"
13562
13563         # trivial test of unaligned DIO
13564         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13565                 iflag=direct oflag=direct ||
13566                 error "trivial unaligned dio failed"
13567
13568         # Clean up before next part of test
13569         rm -f $DIR/$tfile.2
13570
13571         if zfs_or_rotational; then
13572                 # DIO on ZFS can take up to 2 seconds per IO
13573                 # rotational is better, but still slow.
13574                 # Limit testing on those media to larger sizes
13575                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13576                         $((stripe_size + 1024))"
13577         else
13578                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13579                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13580                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13581                         $((stripe_size - 1)) $stripe_size \
13582                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13583                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13584         fi
13585
13586         for bs in $bsizes; do
13587                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13588                 echo "Read/write with DIO at size $bs"
13589                 # Read and write with DIO from source to dest
13590                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13591                         iflag=direct oflag=direct ||
13592                         error "dio failed"
13593
13594                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13595                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13596                         error "size incorrect, file copy read/write bsize: $bs"
13597                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13598                         error "files differ, bsize $bs"
13599                 rm -f $DIR/$tfile.2
13600         done
13601 }
13602 run_test 119e "Basic tests of dio read and write at various sizes"
13603
13604 test_119f()
13605 {
13606         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13607
13608         local stripe_size=$((1024 * 1024)) #1 MiB
13609         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13610         local file_size=$((25 * stripe_size))
13611         local bsizes
13612
13613         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13614         stack_trap "rm -f $DIR/$tfile*"
13615
13616         # Just a bit bigger than the largest size in the test set below
13617         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13618                 error "buffered i/o to create file failed"
13619
13620         if zfs_or_rotational; then
13621                 # DIO on ZFS can take up to 2 seconds per IO
13622                 # rotational is better, but still slow.
13623                 # Limit testing on those media to larger sizes
13624                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13625                         $((stripe_size + 1024))"
13626         else
13627                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13628                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13629                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13630                         $((stripe_size - 1)) $stripe_size \
13631                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13632                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13633         fi
13634
13635         for bs in $bsizes; do
13636                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13637                 # Read and write with DIO from source to dest in two
13638                 # threads - should give correct copy of file
13639
13640                 echo "bs: $bs"
13641                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13642                         oflag=direct conv=notrunc &
13643                 pid_dio1=$!
13644                 # Note block size is different here for a more interesting race
13645                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13646                         iflag=direct oflag=direct conv=notrunc &
13647                 pid_dio2=$!
13648                 wait $pid_dio1
13649                 rc1=$?
13650                 wait $pid_dio2
13651                 rc2=$?
13652                 if (( rc1 != 0 )); then
13653                         error "dio copy 1 w/bsize $bs failed: $rc1"
13654                 fi
13655                 if (( rc2 != 0 )); then
13656                         error "dio copy 2 w/bsize $bs failed: $rc2"
13657                 fi
13658
13659
13660                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13661                         error "size incorrect, file copy read/write bsize: $bs"
13662                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13663                         error "files differ, bsize $bs"
13664                 rm -f $DIR/$tfile.2
13665         done
13666 }
13667 run_test 119f "dio vs dio race"
13668
13669 test_119g()
13670 {
13671         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13672
13673         local stripe_size=$((1024 * 1024)) #1 MiB
13674         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13675         local file_size=$((25 * stripe_size))
13676         local bsizes
13677
13678         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13679         stack_trap "rm -f $DIR/$tfile*"
13680
13681         # Just a bit bigger than the largest size in the test set below
13682         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13683                 error "buffered i/o to create file failed"
13684
13685         if zfs_or_rotational; then
13686                 # DIO on ZFS can take up to 2 seconds per IO
13687                 # rotational is better, but still slow.
13688                 # Limit testing on those media to larger sizes
13689                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13690                         $((stripe_size + 1024))"
13691         else
13692                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13693                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13694                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13695                         $((stripe_size - 1)) $stripe_size \
13696                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13697                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13698         fi
13699
13700         for bs in $bsizes; do
13701                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13702                 echo "bs: $bs"
13703                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13704                         oflag=direct conv=notrunc &
13705                 pid_dio1=$!
13706                 # Buffered I/O with similar but not the same block size
13707                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13708                 pid_bio2=$!
13709                 wait $pid_dio1
13710                 rc1=$?
13711                 wait $pid_bio2
13712                 rc2=$?
13713                 if (( rc1 != 0 )); then
13714                         error "dio copy 1 w/bsize $bs failed: $rc1"
13715                 fi
13716                 if (( rc2 != 0 )); then
13717                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13718                 fi
13719
13720                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13721                         error "size incorrect"
13722                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13723                         error "files differ, bsize $bs"
13724                 rm -f $DIR/$tfile.2
13725         done
13726 }
13727 run_test 119g "dio vs buffered I/O race"
13728
13729 test_119h()
13730 {
13731         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13732
13733         local stripe_size=$((1024 * 1024)) #1 MiB
13734         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13735         local file_size=$((25 * stripe_size))
13736         local bsizes
13737
13738         stack_trap "rm -f $DIR/$tfile.*"
13739
13740         if zfs_or_rotational; then
13741                 # DIO on ZFS can take up to 2 seconds per IO
13742                 # rotational is better, but still slow.
13743                 # Limit testing on those media to larger sizes
13744                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13745                         $((stripe_size + 1024))"
13746         else
13747                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13748                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13749                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13750                         $((stripe_size - 1)) $stripe_size \
13751                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13752                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13753         fi
13754
13755         for bs in $bsizes; do
13756                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13757                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13758                 echo "unaligned writes of blocksize: $bs"
13759                 # Write a file with unaligned DIO and regular DIO, and compare
13760                 # them
13761                 # with 'u', multiop randomly unaligns the io from the buffer
13762                 $MULTIOP $DIR/$tfile.1 \
13763                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13764                         error "multiop memory unaligned write failed, $bs"
13765                 $MULTIOP $DIR/$tfile.2 \
13766                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13767                         error "multiop memory aligned write failed, $bs"
13768
13769                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13770                         error "files differ, bsize $bs"
13771                 rm -f $DIR/$tfile.*
13772         done
13773
13774         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13775         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13776                 error "dd to create source file for read failed"
13777
13778         # Just a few quick tests to make sure unaligned DIO reads don't crash
13779         for bs in $bsizes; do
13780
13781                 echo "unaligned reads of blocksize: $bs"
13782                 # with 'u', multiop randomly unaligns the io from the buffer
13783                 $MULTIOP $DIR/$tfile.1 \
13784                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13785                         error "multiop memory unaligned read failed, $bs"
13786
13787         done
13788         rm -f $DIR/$tfile*
13789 }
13790 run_test 119h "basic tests of memory unaligned dio"
13791
13792 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13793 test_119i()
13794 {
13795         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13796         which aiocp || skip_env "no aiocp installed"
13797
13798         local stripe_size=$((1024 * 1024)) #1 MiB
13799         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13800         local file_size=$((25 * stripe_size))
13801         local bsizes
13802
13803         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13804         stack_trap "rm -f $DIR/$tfile.*"
13805
13806         # Just a bit bigger than the largest size in the test set below
13807         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13808                 error "buffered i/o to create file failed"
13809
13810         if zfs_or_rotational; then
13811                 # DIO on ZFS can take up to 2 seconds per IO
13812                 # rotational is better, but still slow.
13813                 # Limit testing on those media to larger sizes
13814                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13815                         $((stripe_size + 1024))"
13816         else
13817                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13818                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13819                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13820                         $((stripe_size - 1)) $stripe_size \
13821                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13822                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13823         fi
13824
13825         # Do page aligned and NOT page aligned AIO
13826         for align in 8 512 $((PAGE_SIZE)); do
13827         # Deliberately includes a few aligned sizes
13828         for bs in $bsizes; do
13829                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13830
13831                 echo "bs: $bs, align: $align, file_size $file_size"
13832                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13833                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13834                         error "unaligned aio failed, bs: $bs, align: $align"
13835
13836                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13837                         error "size incorrect"
13838                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13839                         error "files differ"
13840                 rm -f $DIR/$tfile.2
13841         done
13842         done
13843 }
13844 run_test 119i "test unaligned aio at varying sizes"
13845
13846 test_120a() {
13847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13848         remote_mds_nodsh && skip "remote MDS with nodsh"
13849         test_mkdir -i0 -c1 $DIR/$tdir
13850         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13851                 skip_env "no early lock cancel on server"
13852
13853         lru_resize_disable mdc
13854         lru_resize_disable osc
13855         cancel_lru_locks mdc
13856         # asynchronous object destroy at MDT could cause bl ast to client
13857         cancel_lru_locks osc
13858
13859         stat $DIR/$tdir > /dev/null
13860         can1=$(do_facet mds1 \
13861                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13862                awk '/ldlm_cancel/ {print $2}')
13863         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13864                awk '/ldlm_bl_callback/ {print $2}')
13865         test_mkdir -i0 -c1 $DIR/$tdir/d1
13866         can2=$(do_facet mds1 \
13867                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13868                awk '/ldlm_cancel/ {print $2}')
13869         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13870                awk '/ldlm_bl_callback/ {print $2}')
13871         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13872         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13873         lru_resize_enable mdc
13874         lru_resize_enable osc
13875 }
13876 run_test 120a "Early Lock Cancel: mkdir test"
13877
13878 test_120b() {
13879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13880         remote_mds_nodsh && skip "remote MDS with nodsh"
13881         test_mkdir $DIR/$tdir
13882         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13883                 skip_env "no early lock cancel on server"
13884
13885         lru_resize_disable mdc
13886         lru_resize_disable osc
13887         cancel_lru_locks mdc
13888         stat $DIR/$tdir > /dev/null
13889         can1=$(do_facet $SINGLEMDS \
13890                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13891                awk '/ldlm_cancel/ {print $2}')
13892         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13893                awk '/ldlm_bl_callback/ {print $2}')
13894         touch $DIR/$tdir/f1
13895         can2=$(do_facet $SINGLEMDS \
13896                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13897                awk '/ldlm_cancel/ {print $2}')
13898         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13899                awk '/ldlm_bl_callback/ {print $2}')
13900         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13901         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13902         lru_resize_enable mdc
13903         lru_resize_enable osc
13904 }
13905 run_test 120b "Early Lock Cancel: create test"
13906
13907 test_120c() {
13908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13909         remote_mds_nodsh && skip "remote MDS with nodsh"
13910         test_mkdir -i0 -c1 $DIR/$tdir
13911         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13912                 skip "no early lock cancel on server"
13913
13914         lru_resize_disable mdc
13915         lru_resize_disable osc
13916         test_mkdir -i0 -c1 $DIR/$tdir/d1
13917         test_mkdir -i0 -c1 $DIR/$tdir/d2
13918         touch $DIR/$tdir/d1/f1
13919         cancel_lru_locks mdc
13920         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13921         can1=$(do_facet mds1 \
13922                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13923                awk '/ldlm_cancel/ {print $2}')
13924         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13925                awk '/ldlm_bl_callback/ {print $2}')
13926         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13927         can2=$(do_facet mds1 \
13928                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13929                awk '/ldlm_cancel/ {print $2}')
13930         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13931                awk '/ldlm_bl_callback/ {print $2}')
13932         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13933         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13934         lru_resize_enable mdc
13935         lru_resize_enable osc
13936 }
13937 run_test 120c "Early Lock Cancel: link test"
13938
13939 test_120d() {
13940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13941         remote_mds_nodsh && skip "remote MDS with nodsh"
13942         test_mkdir -i0 -c1 $DIR/$tdir
13943         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13944                 skip_env "no early lock cancel on server"
13945
13946         lru_resize_disable mdc
13947         lru_resize_disable osc
13948         touch $DIR/$tdir
13949         cancel_lru_locks mdc
13950         stat $DIR/$tdir > /dev/null
13951         can1=$(do_facet mds1 \
13952                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13953                awk '/ldlm_cancel/ {print $2}')
13954         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13955                awk '/ldlm_bl_callback/ {print $2}')
13956         chmod a+x $DIR/$tdir
13957         can2=$(do_facet mds1 \
13958                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13959                awk '/ldlm_cancel/ {print $2}')
13960         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13961                awk '/ldlm_bl_callback/ {print $2}')
13962         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13963         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13964         lru_resize_enable mdc
13965         lru_resize_enable osc
13966 }
13967 run_test 120d "Early Lock Cancel: setattr test"
13968
13969 test_120e() {
13970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13971         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13972                 skip_env "no early lock cancel on server"
13973         remote_mds_nodsh && skip "remote MDS with nodsh"
13974
13975         local dlmtrace_set=false
13976
13977         test_mkdir -i0 -c1 $DIR/$tdir
13978         lru_resize_disable mdc
13979         lru_resize_disable osc
13980         ! $LCTL get_param debug | grep -q dlmtrace &&
13981                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13982         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13983         cancel_lru_locks mdc
13984         cancel_lru_locks osc
13985         dd if=$DIR/$tdir/f1 of=/dev/null
13986         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13987         # XXX client can not do early lock cancel of OST lock
13988         # during unlink (LU-4206), so cancel osc lock now.
13989         sleep 2
13990         cancel_lru_locks osc
13991         can1=$(do_facet mds1 \
13992                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13993                awk '/ldlm_cancel/ {print $2}')
13994         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13995                awk '/ldlm_bl_callback/ {print $2}')
13996         unlink $DIR/$tdir/f1
13997         sleep 5
13998         can2=$(do_facet mds1 \
13999                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14000                awk '/ldlm_cancel/ {print $2}')
14001         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14002                awk '/ldlm_bl_callback/ {print $2}')
14003         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14004                 $LCTL dk $TMP/cancel.debug.txt
14005         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14006                 $LCTL dk $TMP/blocking.debug.txt
14007         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14008         lru_resize_enable mdc
14009         lru_resize_enable osc
14010 }
14011 run_test 120e "Early Lock Cancel: unlink test"
14012
14013 test_120f() {
14014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14015         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14016                 skip_env "no early lock cancel on server"
14017         remote_mds_nodsh && skip "remote MDS with nodsh"
14018
14019         test_mkdir -i0 -c1 $DIR/$tdir
14020         lru_resize_disable mdc
14021         lru_resize_disable osc
14022         test_mkdir -i0 -c1 $DIR/$tdir/d1
14023         test_mkdir -i0 -c1 $DIR/$tdir/d2
14024         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14025         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14026         cancel_lru_locks mdc
14027         cancel_lru_locks osc
14028         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14029         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14030         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14031         # XXX client can not do early lock cancel of OST lock
14032         # during rename (LU-4206), so cancel osc lock now.
14033         sleep 2
14034         cancel_lru_locks osc
14035         can1=$(do_facet mds1 \
14036                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14037                awk '/ldlm_cancel/ {print $2}')
14038         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14039                awk '/ldlm_bl_callback/ {print $2}')
14040         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14041         sleep 5
14042         can2=$(do_facet mds1 \
14043                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14044                awk '/ldlm_cancel/ {print $2}')
14045         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14046                awk '/ldlm_bl_callback/ {print $2}')
14047         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14048         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14049         lru_resize_enable mdc
14050         lru_resize_enable osc
14051 }
14052 run_test 120f "Early Lock Cancel: rename test"
14053
14054 test_120g() {
14055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14056         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14057                 skip_env "no early lock cancel on server"
14058         remote_mds_nodsh && skip "remote MDS with nodsh"
14059
14060         lru_resize_disable mdc
14061         lru_resize_disable osc
14062         count=10000
14063         echo create $count files
14064         test_mkdir $DIR/$tdir
14065         cancel_lru_locks mdc
14066         cancel_lru_locks osc
14067         t0=$(date +%s)
14068
14069         can0=$(do_facet $SINGLEMDS \
14070                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14071                awk '/ldlm_cancel/ {print $2}')
14072         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14073                awk '/ldlm_bl_callback/ {print $2}')
14074         createmany -o $DIR/$tdir/f $count
14075         sync
14076         can1=$(do_facet $SINGLEMDS \
14077                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14078                awk '/ldlm_cancel/ {print $2}')
14079         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14080                awk '/ldlm_bl_callback/ {print $2}')
14081         t1=$(date +%s)
14082         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14083         echo rm $count files
14084         rm -r $DIR/$tdir
14085         sync
14086         can2=$(do_facet $SINGLEMDS \
14087                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14088                awk '/ldlm_cancel/ {print $2}')
14089         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14090                awk '/ldlm_bl_callback/ {print $2}')
14091         t2=$(date +%s)
14092         echo total: $count removes in $((t2-t1))
14093         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14094         sleep 2
14095         # wait for commitment of removal
14096         lru_resize_enable mdc
14097         lru_resize_enable osc
14098 }
14099 run_test 120g "Early Lock Cancel: performance test"
14100
14101 test_121() { #bug #10589
14102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14103
14104         rm -rf $DIR/$tfile
14105         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14106 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14107         lctl set_param fail_loc=0x310
14108         cancel_lru_locks osc > /dev/null
14109         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14110         lctl set_param fail_loc=0
14111         [[ $reads -eq $writes ]] ||
14112                 error "read $reads blocks, must be $writes blocks"
14113 }
14114 run_test 121 "read cancel race ========="
14115
14116 test_123a_base() { # was test 123, statahead(bug 11401)
14117         local lsx="$1"
14118
14119         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14120
14121         SLOWOK=0
14122         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14123                 log "testing UP system. Performance may be lower than expected."
14124                 SLOWOK=1
14125         fi
14126         running_in_vm && SLOWOK=1
14127
14128         $LCTL set_param mdc.*.batch_stats=0
14129
14130         rm -rf $DIR/$tdir
14131         test_mkdir $DIR/$tdir
14132         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14133         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14134         MULT=10
14135         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14136                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14137
14138                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14139                 lctl set_param -n llite.*.statahead_max 0
14140                 lctl get_param llite.*.statahead_max
14141                 cancel_lru_locks mdc
14142                 cancel_lru_locks osc
14143                 stime=$(date +%s)
14144                 time $lsx $DIR/$tdir | wc -l
14145                 etime=$(date +%s)
14146                 delta=$((etime - stime))
14147                 log "$lsx $i files without statahead: $delta sec"
14148                 lctl set_param llite.*.statahead_max=$max
14149
14150                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14151                          awk '/statahead.wrong:/ { print $NF }')
14152                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14153                 cancel_lru_locks mdc
14154                 cancel_lru_locks osc
14155                 stime=$(date +%s)
14156                 time $lsx $DIR/$tdir | wc -l
14157                 etime=$(date +%s)
14158                 delta_sa=$((etime - stime))
14159                 log "$lsx $i files with statahead: $delta_sa sec"
14160                 lctl get_param -n llite.*.statahead_stats
14161                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14162                          awk '/statahead.wrong:/ { print $NF }')
14163
14164                 [[ $swrong -lt $ewrong ]] &&
14165                         log "statahead was stopped, maybe too many locks held!"
14166                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14167
14168                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14169                         max=$(lctl get_param -n llite.*.statahead_max |
14170                                 head -n 1)
14171                         lctl set_param -n llite.*.statahead_max 0
14172                         lctl get_param llite.*.statahead_max
14173                         cancel_lru_locks mdc
14174                         cancel_lru_locks osc
14175                         stime=$(date +%s)
14176                         time $lsx $DIR/$tdir | wc -l
14177                         etime=$(date +%s)
14178                         delta=$((etime - stime))
14179                         log "$lsx $i files again without statahead: $delta sec"
14180                         lctl set_param llite.*.statahead_max=$max
14181                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14182                                 if [ $SLOWOK -eq 0 ]; then
14183                                         error "$lsx $i files is slower with statahead!"
14184                                 else
14185                                         log "$lsx $i files is slower with statahead!"
14186                                 fi
14187                                 break
14188                         fi
14189                 fi
14190
14191                 [ $delta -gt 20 ] && break
14192                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14193                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14194         done
14195         log "$lsx done"
14196
14197         stime=$(date +%s)
14198         rm -r $DIR/$tdir
14199         sync
14200         etime=$(date +%s)
14201         delta=$((etime - stime))
14202         log "rm -r $DIR/$tdir/: $delta seconds"
14203         log "rm done"
14204         lctl get_param -n llite.*.statahead_stats
14205         $LCTL get_param mdc.*.batch_stats
14206 }
14207
14208 test_123aa() {
14209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14210
14211         test_123a_base "ls -l"
14212 }
14213 run_test 123aa "verify statahead work"
14214
14215 test_123ab() {
14216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14217
14218         statx_supported || skip_env "Test must be statx() syscall supported"
14219
14220         test_123a_base "$STATX -l"
14221 }
14222 run_test 123ab "verify statahead work by using statx"
14223
14224 test_123ac() {
14225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14226
14227         statx_supported || skip_env "Test must be statx() syscall supported"
14228
14229         local rpcs_before
14230         local rpcs_after
14231         local agl_before
14232         local agl_after
14233
14234         cancel_lru_locks $OSC
14235         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14236         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14237                      awk '/agl.total:/ { print $NF }')
14238         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14239         test_123a_base "$STATX --cached=always -D"
14240         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14241                     awk '/agl.total:/ { print $NF }')
14242         [ $agl_before -eq $agl_after ] ||
14243                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14244         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14245         [ $rpcs_after -eq $rpcs_before ] ||
14246                 error "$STATX should not send glimpse RPCs to $OSC"
14247 }
14248 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14249
14250 test_batch_statahead() {
14251         local max=$1
14252         local batch_max=$2
14253         local num=10000
14254         local batch_rpcs
14255         local unbatch_rpcs
14256         local hit_total
14257
14258         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14259         $LCTL set_param mdc.*.batch_stats=0
14260         $LCTL set_param llite.*.statahead_max=$max
14261         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14262         # Verify that batched statahead is faster than one without statahead
14263         test_123a_base "ls -l"
14264
14265         stack_trap "rm -rf $DIR/$tdir" EXIT
14266         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14267         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14268
14269         # unbatched statahead
14270         $LCTL set_param llite.*.statahead_batch_max=0
14271         $LCTL set_param llite.*.statahead_stats=clear
14272         $LCTL set_param mdc.*.stats=clear
14273         cancel_lru_locks mdc
14274         cancel_lru_locks osc
14275         time ls -l $DIR/$tdir | wc -l
14276         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14277         sleep 2
14278         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14279                     awk '/hit.total:/ { print $NF }')
14280         # hit ratio should be larger than 75% (7500).
14281         (( $hit_total > 7500 )) ||
14282                 error "unbatched statahead hit count ($hit_total) is too low"
14283
14284         # batched statahead
14285         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14286         $LCTL set_param llite.*.statahead_stats=clear
14287         $LCTL set_param mdc.*.batch_stats=clear
14288         $LCTL set_param mdc.*.stats=clear
14289         cancel_lru_locks mdc
14290         cancel_lru_locks osc
14291         time ls -l $DIR/$tdir | wc -l
14292         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14293         # wait for statahead thread to quit and update statahead stats
14294         sleep 2
14295         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14296                     awk '/hit.total:/ { print $NF }')
14297         # hit ratio should be larger than 75% (7500).
14298         (( $hit_total > 7500 )) ||
14299                 error "batched statahead hit count ($hit_total) is too low"
14300
14301         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14302         (( $unbatch_rpcs > $batch_rpcs )) ||
14303                 error "batched statahead does not reduce RPC count"
14304         $LCTL get_param mdc.*.batch_stats
14305 }
14306
14307 test_123ad() {
14308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14309
14310         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14311                 skip "Need server version at least 2.15.53"
14312
14313         local max
14314         local batch_max
14315
14316         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14317         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14318
14319         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14320         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14321
14322         test_batch_statahead 32 32
14323         test_batch_statahead 2048 256
14324 }
14325 run_test 123ad "Verify batching statahead works correctly"
14326
14327 test_123b () { # statahead(bug 15027)
14328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14329
14330         test_mkdir $DIR/$tdir
14331         createmany -o $DIR/$tdir/$tfile-%d 1000
14332
14333         cancel_lru_locks mdc
14334         cancel_lru_locks osc
14335
14336 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14337         lctl set_param fail_loc=0x80000803
14338         ls -lR $DIR/$tdir > /dev/null
14339         log "ls done"
14340         lctl set_param fail_loc=0x0
14341         lctl get_param -n llite.*.statahead_stats
14342         rm -r $DIR/$tdir
14343         sync
14344
14345 }
14346 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14347
14348 test_123c() {
14349         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14350
14351         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14352         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14353         touch $DIR/$tdir.1/{1..3}
14354         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14355
14356         remount_client $MOUNT
14357
14358         $MULTIOP $DIR/$tdir.0 Q
14359
14360         # let statahead to complete
14361         ls -l $DIR/$tdir.0 > /dev/null
14362
14363         testid=$(echo $TESTNAME | tr '_' ' ')
14364         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14365                 error "statahead warning" || true
14366 }
14367 run_test 123c "Can not initialize inode warning on DNE statahead"
14368
14369 test_123d() {
14370         local num=100
14371         local swrong
14372         local ewrong
14373
14374         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14375         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14376                 error "setdirstripe $DIR/$tdir failed"
14377         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14378         remount_client $MOUNT
14379         $LCTL get_param llite.*.statahead_max
14380         $LCTL set_param llite.*.statahead_stats=0 ||
14381                 error "clear statahead_stats failed"
14382         swrong=$(lctl get_param -n llite.*.statahead_stats |
14383                  awk '/statahead.wrong:/ { print $NF }')
14384         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14385         # wait for statahead thread finished to update hit/miss stats.
14386         sleep 1
14387         $LCTL get_param -n llite.*.statahead_stats
14388         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14389                  awk '/statahead.wrong:/ { print $NF }')
14390         (( $swrong == $ewrong )) ||
14391                 log "statahead was stopped, maybe too many locks held!"
14392 }
14393 run_test 123d "Statahead on striped directories works correctly"
14394
14395 test_123e() {
14396         local max
14397         local batch_max
14398         local dir=$DIR/$tdir
14399
14400         mkdir $dir || error "mkdir $dir failed"
14401         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14402         stack_trap "rm -rf $dir"
14403
14404         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14405
14406         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14407         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14408         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14409         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14410
14411         $LCTL set_param llite.*.statahead_max=2048
14412         $LCTL set_param llite.*.statahead_batch_max=1024
14413
14414         ls -l $dir
14415         $LCTL get_param mdc.*.batch_stats
14416         $LCTL get_param llite.*.statahead_*
14417 }
14418 run_test 123e "statahead with large wide striping"
14419
14420 test_123f() {
14421         local max
14422         local batch_max
14423         local dir=$DIR/$tdir
14424
14425         mkdir $dir || error "mkdir $dir failed"
14426         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14427         stack_trap "rm -rf $dir"
14428
14429         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14430
14431         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14432         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14433
14434         $LCTL set_param llite.*.statahead_max=64
14435         $LCTL set_param llite.*.statahead_batch_max=64
14436
14437         ls -l $dir
14438         lctl get_param mdc.*.batch_stats
14439         lctl get_param llite.*.statahead_*
14440
14441         $LCTL set_param llite.*.statahead_max=$max
14442         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14443 }
14444 run_test 123f "Retry mechanism with large wide striping files"
14445
14446 test_124a() {
14447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14448         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14449                 skip_env "no lru resize on server"
14450
14451         local NR=2000
14452
14453         test_mkdir $DIR/$tdir
14454
14455         log "create $NR files at $DIR/$tdir"
14456         createmany -o $DIR/$tdir/f $NR ||
14457                 error "failed to create $NR files in $DIR/$tdir"
14458
14459         cancel_lru_locks mdc
14460         ls -l $DIR/$tdir > /dev/null
14461
14462         local NSDIR=""
14463         local LRU_SIZE=0
14464         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14465                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14466                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14467                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14468                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14469                         log "NSDIR=$NSDIR"
14470                         log "NS=$(basename $NSDIR)"
14471                         break
14472                 fi
14473         done
14474
14475         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14476                 skip "Not enough cached locks created!"
14477         fi
14478         log "LRU=$LRU_SIZE"
14479
14480         local SLEEP=30
14481
14482         # We know that lru resize allows one client to hold $LIMIT locks
14483         # for 10h. After that locks begin to be killed by client.
14484         local MAX_HRS=10
14485         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14486         log "LIMIT=$LIMIT"
14487         if [ $LIMIT -lt $LRU_SIZE ]; then
14488                 skip "Limit is too small $LIMIT"
14489         fi
14490
14491         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14492         # killing locks. Some time was spent for creating locks. This means
14493         # that up to the moment of sleep finish we must have killed some of
14494         # them (10-100 locks). This depends on how fast ther were created.
14495         # Many of them were touched in almost the same moment and thus will
14496         # be killed in groups.
14497         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14498
14499         # Use $LRU_SIZE_B here to take into account real number of locks
14500         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14501         local LRU_SIZE_B=$LRU_SIZE
14502         log "LVF=$LVF"
14503         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14504         log "OLD_LVF=$OLD_LVF"
14505         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14506
14507         # Let's make sure that we really have some margin. Client checks
14508         # cached locks every 10 sec.
14509         SLEEP=$((SLEEP+20))
14510         log "Sleep ${SLEEP} sec"
14511         local SEC=0
14512         while ((SEC<$SLEEP)); do
14513                 echo -n "..."
14514                 sleep 5
14515                 SEC=$((SEC+5))
14516                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14517                 echo -n "$LRU_SIZE"
14518         done
14519         echo ""
14520         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14521         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14522
14523         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14524                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14525                 unlinkmany $DIR/$tdir/f $NR
14526                 return
14527         }
14528
14529         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14530         log "unlink $NR files at $DIR/$tdir"
14531         unlinkmany $DIR/$tdir/f $NR
14532 }
14533 run_test 124a "lru resize ======================================="
14534
14535 get_max_pool_limit()
14536 {
14537         local limit=$($LCTL get_param \
14538                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14539         local max=0
14540         for l in $limit; do
14541                 if [[ $l -gt $max ]]; then
14542                         max=$l
14543                 fi
14544         done
14545         echo $max
14546 }
14547
14548 test_124b() {
14549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14550         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14551                 skip_env "no lru resize on server"
14552
14553         LIMIT=$(get_max_pool_limit)
14554
14555         NR=$(($(default_lru_size)*20))
14556         if [[ $NR -gt $LIMIT ]]; then
14557                 log "Limit lock number by $LIMIT locks"
14558                 NR=$LIMIT
14559         fi
14560
14561         IFree=$(mdsrate_inodes_available)
14562         if [ $IFree -lt $NR ]; then
14563                 log "Limit lock number by $IFree inodes"
14564                 NR=$IFree
14565         fi
14566
14567         lru_resize_disable mdc
14568         test_mkdir -p $DIR/$tdir/disable_lru_resize
14569
14570         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14571         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14572         cancel_lru_locks mdc
14573         stime=`date +%s`
14574         PID=""
14575         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14576         PID="$PID $!"
14577         sleep 2
14578         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14579         PID="$PID $!"
14580         sleep 2
14581         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14582         PID="$PID $!"
14583         wait $PID
14584         etime=`date +%s`
14585         nolruresize_delta=$((etime-stime))
14586         log "ls -la time: $nolruresize_delta seconds"
14587         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14588         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14589
14590         lru_resize_enable mdc
14591         test_mkdir -p $DIR/$tdir/enable_lru_resize
14592
14593         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14594         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14595         cancel_lru_locks mdc
14596         stime=`date +%s`
14597         PID=""
14598         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14599         PID="$PID $!"
14600         sleep 2
14601         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14602         PID="$PID $!"
14603         sleep 2
14604         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14605         PID="$PID $!"
14606         wait $PID
14607         etime=`date +%s`
14608         lruresize_delta=$((etime-stime))
14609         log "ls -la time: $lruresize_delta seconds"
14610         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14611
14612         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14613                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14614         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14615                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14616         else
14617                 log "lru resize performs the same with no lru resize"
14618         fi
14619         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14620 }
14621 run_test 124b "lru resize (performance test) ======================="
14622
14623 test_124c() {
14624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14625         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14626                 skip_env "no lru resize on server"
14627
14628         # cache ununsed locks on client
14629         local nr=100
14630         cancel_lru_locks mdc
14631         test_mkdir $DIR/$tdir
14632         createmany -o $DIR/$tdir/f $nr ||
14633                 error "failed to create $nr files in $DIR/$tdir"
14634         ls -l $DIR/$tdir > /dev/null
14635
14636         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14637         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14638         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14639         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14640         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14641
14642         # set lru_max_age to 1 sec
14643         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14644         echo "sleep $((recalc_p * 2)) seconds..."
14645         sleep $((recalc_p * 2))
14646
14647         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14648         # restore lru_max_age
14649         $LCTL set_param -n $nsdir.lru_max_age $max_age
14650         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14651         unlinkmany $DIR/$tdir/f $nr
14652 }
14653 run_test 124c "LRUR cancel very aged locks"
14654
14655 test_124d() {
14656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14657         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14658                 skip_env "no lru resize on server"
14659
14660         # cache ununsed locks on client
14661         local nr=100
14662
14663         lru_resize_disable mdc
14664         stack_trap "lru_resize_enable mdc" EXIT
14665
14666         cancel_lru_locks mdc
14667
14668         # asynchronous object destroy at MDT could cause bl ast to client
14669         test_mkdir $DIR/$tdir
14670         createmany -o $DIR/$tdir/f $nr ||
14671                 error "failed to create $nr files in $DIR/$tdir"
14672         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14673
14674         ls -l $DIR/$tdir > /dev/null
14675
14676         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14677         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14678         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14679         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14680
14681         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14682
14683         # set lru_max_age to 1 sec
14684         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14685         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14686
14687         echo "sleep $((recalc_p * 2)) seconds..."
14688         sleep $((recalc_p * 2))
14689
14690         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14691
14692         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14693 }
14694 run_test 124d "cancel very aged locks if lru-resize disabled"
14695
14696 test_125() { # 13358
14697         $LCTL get_param -n llite.*.client_type | grep -q local ||
14698                 skip "must run as local client"
14699         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14700                 skip_env "must have acl enabled"
14701         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14702         id $USER0 || skip_env "missing user $USER0"
14703
14704         test_mkdir $DIR/$tdir
14705         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14706         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14707                 error "setfacl $DIR/$tdir failed"
14708         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14709 }
14710 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14711
14712 test_126() { # bug 12829/13455
14713         $GSS && skip_env "must run as gss disabled"
14714         $LCTL get_param -n llite.*.client_type | grep -q local ||
14715                 skip "must run as local client"
14716         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14717
14718         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14719         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14720         rm -f $DIR/$tfile
14721         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14722 }
14723 run_test 126 "check that the fsgid provided by the client is taken into account"
14724
14725 test_127a() { # bug 15521
14726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14727         local name count samp unit min max sum sumsq
14728         local tmpfile=$TMP/$tfile.tmp
14729
14730         # enable stats header if it is disabled
14731         $LCTL set_param enable_stats_header=1
14732
14733         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14734         echo "stats before reset"
14735         stack_trap "rm -f $tmpfile"
14736         local now=$(date +%s)
14737
14738         $LCTL get_param osc.*.stats | tee $tmpfile
14739
14740         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14741         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14742         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14743         local uptime=$(awk '{ print $1 }' /proc/uptime)
14744
14745         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14746         (( ${snapshot_time%\.*} >= $now - 5 &&
14747            ${snapshot_time%\.*} <= $now + 5 )) ||
14748                 error "snapshot_time=$snapshot_time != now=$now"
14749         # elapsed _should_ be from mount, but at least less than uptime
14750         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14751                 error "elapsed=$elapsed > uptime=$uptime"
14752         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14753            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14754                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14755
14756         $LCTL set_param osc.*.stats=0
14757         local reset=$(date +%s)
14758         local fsize=$((2048 * 1024))
14759
14760         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14761         cancel_lru_locks osc
14762         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14763
14764         now=$(date +%s)
14765         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14766         while read name count samp unit min max sum sumsq; do
14767                 [[ "$samp" == "samples" ]] || continue
14768
14769                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14770                 [ ! $min ] && error "Missing min value for $name proc entry"
14771                 eval $name=$count || error "Wrong proc format"
14772
14773                 case $name in
14774                 read_bytes|write_bytes)
14775                         [[ "$unit" =~ "bytes" ]] ||
14776                                 error "unit is not 'bytes': $unit"
14777                         (( $min >= 4096 )) || error "min is too small: $min"
14778                         (( $min <= $fsize )) || error "min is too big: $min"
14779                         (( $max >= 4096 )) || error "max is too small: $max"
14780                         (( $max <= $fsize )) || error "max is too big: $max"
14781                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14782                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14783                                 error "sumsquare is too small: $sumsq"
14784                         (( $sumsq <= $fsize * $fsize )) ||
14785                                 error "sumsquare is too big: $sumsq"
14786                         ;;
14787                 ost_read|ost_write)
14788                         [[ "$unit" =~ "usec" ]] ||
14789                                 error "unit is not 'usec': $unit"
14790                         ;;
14791                 *)      ;;
14792                 esac
14793         done < $tmpfile
14794
14795         #check that we actually got some stats
14796         [ "$read_bytes" ] || error "Missing read_bytes stats"
14797         [ "$write_bytes" ] || error "Missing write_bytes stats"
14798         [ "$read_bytes" != 0 ] || error "no read done"
14799         [ "$write_bytes" != 0 ] || error "no write done"
14800
14801         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14802         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14803         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14804
14805         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14806         (( ${snapshot_time%\.*} >= $now - 5 &&
14807            ${snapshot_time%\.*} <= $now + 5 )) ||
14808                 error "reset snapshot_time=$snapshot_time != now=$now"
14809         # elapsed should be from time of stats reset
14810         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14811            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14812                 error "reset elapsed=$elapsed > $now - $reset"
14813         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14814            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14815                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14816 }
14817 run_test 127a "verify the client stats are sane"
14818
14819 test_127b() { # bug LU-333
14820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14821         local name count samp unit min max sum sumsq
14822
14823         echo "stats before reset"
14824         $LCTL get_param llite.*.stats
14825         $LCTL set_param llite.*.stats=0
14826
14827         # perform 2 reads and writes so MAX is different from SUM.
14828         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14829         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14830         cancel_lru_locks osc
14831         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14832         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14833
14834         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14835         stack_trap "rm -f $TMP/$tfile.tmp"
14836         while read name count samp unit min max sum sumsq; do
14837                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14838                 eval $name=$count || error "Wrong proc format"
14839
14840                 case $name in
14841                 read_bytes|write_bytes)
14842                         [[ "$unit" =~ "bytes" ]] ||
14843                                 error "unit is not 'bytes': $unit"
14844                         (( $count == 2 )) || error "count is not 2: $count"
14845                         (( $min == $PAGE_SIZE )) ||
14846                                 error "min is not $PAGE_SIZE: $min"
14847                         (( $max == $PAGE_SIZE )) ||
14848                                 error "max is not $PAGE_SIZE: $max"
14849                         (( $sum == $PAGE_SIZE * 2 )) ||
14850                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14851                         ;;
14852                 read|write)
14853                         [[ "$unit" =~ "usec" ]] ||
14854                                 error "unit is not 'usec': $unit"
14855                         ;;
14856                 *)      ;;
14857                 esac
14858         done < $TMP/$tfile.tmp
14859
14860         #check that we actually got some stats
14861         [ "$read_bytes" ] || error "Missing read_bytes stats"
14862         [ "$write_bytes" ] || error "Missing write_bytes stats"
14863         [ "$read_bytes" != 0 ] || error "no read done"
14864         [ "$write_bytes" != 0 ] || error "no write done"
14865 }
14866 run_test 127b "verify the llite client stats are sane"
14867
14868 test_127c() { # LU-12394
14869         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14870         local size
14871         local bsize
14872         local reads
14873         local writes
14874         local count
14875
14876         $LCTL set_param llite.*.extents_stats=1
14877         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14878
14879         # Use two stripes so there is enough space in default config
14880         $LFS setstripe -c 2 $DIR/$tfile
14881
14882         # Extent stats start at 0-4K and go in power of two buckets
14883         # LL_HIST_START = 12 --> 2^12 = 4K
14884         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14885         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14886         # small configs
14887         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14888                 do
14889                 # Write and read, 2x each, second time at a non-zero offset
14890                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14891                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14892                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14893                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14894                 rm -f $DIR/$tfile
14895         done
14896
14897         $LCTL get_param llite.*.extents_stats
14898
14899         count=2
14900         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14901                 do
14902                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14903                                 grep -m 1 $bsize)
14904                 reads=$(echo $bucket | awk '{print $5}')
14905                 writes=$(echo $bucket | awk '{print $9}')
14906                 [ "$reads" -eq $count ] ||
14907                         error "$reads reads in < $bsize bucket, expect $count"
14908                 [ "$writes" -eq $count ] ||
14909                         error "$writes writes in < $bsize bucket, expect $count"
14910         done
14911
14912         # Test mmap write and read
14913         $LCTL set_param llite.*.extents_stats=c
14914         size=512
14915         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14916         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14917         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14918
14919         $LCTL get_param llite.*.extents_stats
14920
14921         count=$(((size*1024) / PAGE_SIZE))
14922
14923         bsize=$((2 * PAGE_SIZE / 1024))K
14924
14925         bucket=$($LCTL get_param -n llite.*.extents_stats |
14926                         grep -m 1 $bsize)
14927         reads=$(echo $bucket | awk '{print $5}')
14928         writes=$(echo $bucket | awk '{print $9}')
14929         # mmap writes fault in the page first, creating an additonal read
14930         [ "$reads" -eq $((2 * count)) ] ||
14931                 error "$reads reads in < $bsize bucket, expect $count"
14932         [ "$writes" -eq $count ] ||
14933                 error "$writes writes in < $bsize bucket, expect $count"
14934 }
14935 run_test 127c "test llite extent stats with regular & mmap i/o"
14936
14937 test_128() { # bug 15212
14938         touch $DIR/$tfile
14939         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14940                 find $DIR/$tfile
14941                 find $DIR/$tfile
14942         EOF
14943
14944         result=$(grep error $TMP/$tfile.log)
14945         rm -f $DIR/$tfile $TMP/$tfile.log
14946         [ -z "$result" ] ||
14947                 error "consecutive find's under interactive lfs failed"
14948 }
14949 run_test 128 "interactive lfs for 2 consecutive find's"
14950
14951 set_dir_limits () {
14952         local mntdev
14953         local canondev
14954         local node
14955
14956         local ldproc=/proc/fs/ldiskfs
14957         local facets=$(get_facets MDS)
14958
14959         for facet in ${facets//,/ }; do
14960                 canondev=$(ldiskfs_canon \
14961                            *.$(convert_facet2label $facet).mntdev $facet)
14962                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14963                         ldproc=/sys/fs/ldiskfs
14964                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14965                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14966         done
14967 }
14968
14969 check_mds_dmesg() {
14970         local facets=$(get_facets MDS)
14971         for facet in ${facets//,/ }; do
14972                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14973         done
14974         return 1
14975 }
14976
14977 test_129() {
14978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14979         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14980                 skip "Need MDS version with at least 2.5.56"
14981         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14982                 skip_env "ldiskfs only test"
14983         fi
14984         remote_mds_nodsh && skip "remote MDS with nodsh"
14985
14986         local ENOSPC=28
14987         local has_warning=false
14988
14989         rm -rf $DIR/$tdir
14990         mkdir -p $DIR/$tdir
14991
14992         # block size of mds1
14993         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14994         set_dir_limits $maxsize $((maxsize * 6 / 8))
14995         stack_trap "set_dir_limits 0 0"
14996         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14997         local dirsize=$(stat -c%s "$DIR/$tdir")
14998         local nfiles=0
14999         while (( $dirsize <= $maxsize )); do
15000                 $MCREATE $DIR/$tdir/file_base_$nfiles
15001                 rc=$?
15002                 # check two errors:
15003                 # ENOSPC for ext4 max_dir_size, which has been used since
15004                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15005                 if (( rc == ENOSPC )); then
15006                         set_dir_limits 0 0
15007                         echo "rc=$rc returned as expected after $nfiles files"
15008
15009                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15010                                 error "create failed w/o dir size limit"
15011
15012                         # messages may be rate limited if test is run repeatedly
15013                         check_mds_dmesg '"is approaching max"' ||
15014                                 echo "warning message should be output"
15015                         check_mds_dmesg '"has reached max"' ||
15016                                 echo "reached message should be output"
15017
15018                         dirsize=$(stat -c%s "$DIR/$tdir")
15019
15020                         [[ $dirsize -ge $maxsize ]] && return 0
15021                         error "dirsize $dirsize < $maxsize after $nfiles files"
15022                 elif (( rc != 0 )); then
15023                         break
15024                 fi
15025                 nfiles=$((nfiles + 1))
15026                 dirsize=$(stat -c%s "$DIR/$tdir")
15027         done
15028
15029         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15030 }
15031 run_test 129 "test directory size limit ========================"
15032
15033 OLDIFS="$IFS"
15034 cleanup_130() {
15035         trap 0
15036         IFS="$OLDIFS"
15037         rm -f $DIR/$tfile
15038 }
15039
15040 test_130a() {
15041         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15042         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15043
15044         trap cleanup_130 EXIT RETURN
15045
15046         local fm_file=$DIR/$tfile
15047         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15048         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15049                 error "dd failed for $fm_file"
15050
15051         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15052         filefrag -ves $fm_file
15053         local rc=$?
15054         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15055                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15056         (( $rc == 0 )) || error "filefrag $fm_file failed"
15057
15058         filefrag_op=$(filefrag -ve -k $fm_file |
15059                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15060         local lun=$($LFS getstripe -i $fm_file)
15061
15062         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15063         IFS=$'\n'
15064         local tot_len=0
15065         for line in $filefrag_op; do
15066                 local frag_lun=$(echo $line | cut -d: -f5)
15067                 local ext_len=$(echo $line | cut -d: -f4)
15068
15069                 if (( $frag_lun != $lun )); then
15070                         error "FIEMAP on 1-stripe file($fm_file) failed"
15071                         return
15072                 fi
15073                 (( tot_len += ext_len ))
15074         done
15075
15076         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15077                 error "FIEMAP on 1-stripe file($fm_file) failed"
15078                 return
15079         fi
15080
15081         echo "FIEMAP on single striped file succeeded"
15082 }
15083 run_test 130a "FIEMAP (1-stripe file)"
15084
15085 test_130b() {
15086         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15087
15088         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15089         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15090         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15091                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15092
15093         trap cleanup_130 EXIT RETURN
15094
15095         local fm_file=$DIR/$tfile
15096         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15097                 error "setstripe on $fm_file"
15098
15099         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15100                 error "dd failed on $fm_file"
15101
15102         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15103         filefrag_op=$(filefrag -ve -k $fm_file |
15104                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15105
15106         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15107                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15108
15109         IFS=$'\n'
15110         local tot_len=0
15111         local num_luns=1
15112
15113         for line in $filefrag_op; do
15114                 local frag_lun=$(echo $line | cut -d: -f5 |
15115                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15116                 local ext_len=$(echo $line | cut -d: -f4)
15117                 if (( $frag_lun != $last_lun )); then
15118                         if (( tot_len != 1024 )); then
15119                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15120                                 return
15121                         else
15122                                 (( num_luns += 1 ))
15123                                 tot_len=0
15124                         fi
15125                 fi
15126                 (( tot_len += ext_len ))
15127                 last_lun=$frag_lun
15128         done
15129         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15130                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15131                 return
15132         fi
15133
15134         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15135 }
15136 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15137
15138 test_130c() {
15139         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15140
15141         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15142         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15143         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15144                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15145
15146         trap cleanup_130 EXIT RETURN
15147
15148         local fm_file=$DIR/$tfile
15149         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15150
15151         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15152                 error "dd failed on $fm_file"
15153
15154         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15155         filefrag_op=$(filefrag -ve -k $fm_file |
15156                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15157
15158         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15159                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15160
15161         IFS=$'\n'
15162         local tot_len=0
15163         local num_luns=1
15164         for line in $filefrag_op; do
15165                 local frag_lun=$(echo $line | cut -d: -f5 |
15166                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15167                 local ext_len=$(echo $line | cut -d: -f4)
15168                 if (( $frag_lun != $last_lun )); then
15169                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15170                         if (( logical != 512 )); then
15171                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15172                                 return
15173                         fi
15174                         if (( tot_len != 512 )); then
15175                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15176                                 return
15177                         else
15178                                 (( num_luns += 1 ))
15179                                 tot_len=0
15180                         fi
15181                 fi
15182                 (( tot_len += ext_len ))
15183                 last_lun=$frag_lun
15184         done
15185         if (( num_luns != 2 || tot_len != 512 )); then
15186                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15187                 return
15188         fi
15189
15190         echo "FIEMAP on 2-stripe file with hole succeeded"
15191 }
15192 run_test 130c "FIEMAP (2-stripe file with hole)"
15193
15194 test_130d() {
15195         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15196
15197         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15198         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15199         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15200                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15201
15202         trap cleanup_130 EXIT RETURN
15203
15204         local fm_file=$DIR/$tfile
15205         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15206                         error "setstripe on $fm_file"
15207
15208         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15209         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15210                 error "dd failed on $fm_file"
15211
15212         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15213         filefrag_op=$(filefrag -ve -k $fm_file |
15214                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15215
15216         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15217                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15218
15219         IFS=$'\n'
15220         local tot_len=0
15221         local num_luns=1
15222         for line in $filefrag_op; do
15223                 local frag_lun=$(echo $line | cut -d: -f5 |
15224                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15225                 local ext_len=$(echo $line | cut -d: -f4)
15226                 if (( $frag_lun != $last_lun )); then
15227                         if (( tot_len != 1024 )); then
15228                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15229                                 return
15230                         else
15231                                 (( num_luns += 1 ))
15232                                 local tot_len=0
15233                         fi
15234                 fi
15235                 (( tot_len += ext_len ))
15236                 last_lun=$frag_lun
15237         done
15238         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15239                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15240                 return
15241         fi
15242
15243         echo "FIEMAP on N-stripe file succeeded"
15244 }
15245 run_test 130d "FIEMAP (N-stripe file)"
15246
15247 test_130e() {
15248         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15249
15250         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15251         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15252         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15253                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15254
15255         trap cleanup_130 EXIT RETURN
15256
15257         local fm_file=$DIR/$tfile
15258         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15259         stack_trap "rm -f $fm_file"
15260
15261         local num_blks=512
15262         local expected_len=$(( (num_blks / 2) * 64 ))
15263         for ((i = 0; i < $num_blks; i++)); do
15264                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15265                         conv=notrunc > /dev/null 2>&1
15266         done
15267
15268         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15269         filefrag_op=$(filefrag -ve -k $fm_file |
15270                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15271
15272         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15273
15274         IFS=$'\n'
15275         local tot_len=0
15276         local num_luns=1
15277         for line in $filefrag_op; do
15278                 local frag_lun=$(echo $line | cut -d: -f5)
15279                 local ext_len=$(echo $line | cut -d: -f4)
15280                 if (( $frag_lun != $last_lun )); then
15281                         if (( tot_len != $expected_len )); then
15282                                 error "OST$last_lun $tot_len != $expected_len"
15283                         else
15284                                 (( num_luns += 1 ))
15285                                 tot_len=0
15286                         fi
15287                 fi
15288                 (( tot_len += ext_len ))
15289                 last_lun=$frag_lun
15290         done
15291         if (( num_luns != 2 || tot_len != $expected_len )); then
15292                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15293         fi
15294
15295         echo "FIEMAP with continuation calls succeeded"
15296 }
15297 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15298
15299 test_130f() {
15300         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15301         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15302         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15303                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15304
15305         local fm_file=$DIR/$tfile
15306         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15307                 error "multiop create with lov_delay_create on $fm_file"
15308
15309         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15310         filefrag_extents=$(filefrag -vek $fm_file |
15311                            awk '/extents? found/ { print $2 }')
15312         if (( $filefrag_extents != 0 )); then
15313                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15314         fi
15315
15316         rm -f $fm_file
15317 }
15318 run_test 130f "FIEMAP (unstriped file)"
15319
15320 test_130g() {
15321         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15322                 skip "Need MDS version with at least 2.12.53 for overstriping"
15323         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15324         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15325         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15326                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15327
15328         local file=$DIR/$tfile
15329         local nr=$((OSTCOUNT * 100))
15330
15331         $LFS setstripe -C $nr -S1M $file ||
15332                 error "failed to setstripe -C $nr $file"
15333
15334         stack_trap "rm -f $file"
15335         dd if=/dev/zero of=$file count=$nr bs=1M
15336         sync
15337         nr=$($LFS getstripe -c $file)
15338
15339         local extents=$(filefrag -v $file |
15340                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15341
15342         echo "filefrag list $extents extents in file with stripecount $nr"
15343         if (( extents < nr )); then
15344                 $LFS getstripe $file
15345                 filefrag -v $file
15346                 error "filefrag printed $extents < $nr extents"
15347         fi
15348 }
15349 run_test 130g "FIEMAP (overstripe file)"
15350
15351 # Test for writev/readv
15352 test_131a() {
15353         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15354                 error "writev test failed"
15355         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15356                 error "readv failed"
15357         rm -f $DIR/$tfile
15358 }
15359 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15360
15361 test_131b() {
15362         local fsize=$((524288 + 1048576 + 1572864))
15363         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15364                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15365                         error "append writev test failed"
15366
15367         ((fsize += 1572864 + 1048576))
15368         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15369                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15370                         error "append writev test failed"
15371         rm -f $DIR/$tfile
15372 }
15373 run_test 131b "test append writev"
15374
15375 test_131c() {
15376         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15377         error "NOT PASS"
15378 }
15379 run_test 131c "test read/write on file w/o objects"
15380
15381 test_131d() {
15382         rwv -f $DIR/$tfile -w -n 1 1572864
15383         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15384         if [ "$NOB" != 1572864 ]; then
15385                 error "Short read filed: read $NOB bytes instead of 1572864"
15386         fi
15387         rm -f $DIR/$tfile
15388 }
15389 run_test 131d "test short read"
15390
15391 test_131e() {
15392         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15393         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15394         error "read hitting hole failed"
15395         rm -f $DIR/$tfile
15396 }
15397 run_test 131e "test read hitting hole"
15398
15399 check_stats() {
15400         local facet=$1
15401         local op=$2
15402         local want=${3:-0}
15403         local res
15404
15405         # open             11 samples [usecs] 468 4793 13658 35791898
15406         case $facet in
15407         mds*) res=($(do_facet $facet \
15408                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15409                  ;;
15410         ost*) res=($(do_facet $facet \
15411                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15412                  ;;
15413         *) error "Wrong facet '$facet'" ;;
15414         esac
15415         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15416         # if $want is zero, it means any stat increment is ok.
15417         if (( $want > 0 )); then
15418                 local count=${res[1]}
15419
15420                 if (( $count != $want )); then
15421                         if [[ $facet =~ "mds" ]]; then
15422                                 do_nodes $(comma_list $(mdts_nodes)) \
15423                                         $LCTL get_param mdt.*.md_stats
15424                         else
15425                                 do_nodes $(comma_list $(osts-nodes)) \
15426                                         $LCTL get_param obdfilter.*.stats
15427                         fi
15428                         error "The $op counter on $facet is $count, not $want"
15429                 fi
15430         fi
15431 }
15432
15433 test_133a() {
15434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15435         remote_ost_nodsh && skip "remote OST with nodsh"
15436         remote_mds_nodsh && skip "remote MDS with nodsh"
15437         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15438                 skip_env "MDS doesn't support rename stats"
15439
15440         local testdir=$DIR/${tdir}/stats_testdir
15441
15442         mkdir -p $DIR/${tdir}
15443
15444         # clear stats.
15445         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15446         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15447
15448         # verify mdt stats first.
15449         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15450         check_stats $SINGLEMDS "mkdir" 1
15451
15452         # clear "open" from "lfs mkdir" above
15453         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15454         touch ${testdir}/${tfile} || error "touch failed"
15455         check_stats $SINGLEMDS "open" 1
15456         check_stats $SINGLEMDS "close" 1
15457         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15458                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15459                 check_stats $SINGLEMDS "mknod" 2
15460         }
15461         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15462         check_stats $SINGLEMDS "unlink" 1
15463         rm -f ${testdir}/${tfile} || error "file remove failed"
15464         check_stats $SINGLEMDS "unlink" 2
15465
15466         # remove working dir and check mdt stats again.
15467         rmdir ${testdir} || error "rmdir failed"
15468         check_stats $SINGLEMDS "rmdir" 1
15469
15470         local testdir1=$DIR/${tdir}/stats_testdir1
15471         mkdir_on_mdt0 -p ${testdir}
15472         mkdir_on_mdt0 -p ${testdir1}
15473         touch ${testdir1}/test1
15474         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15475         check_stats $SINGLEMDS "crossdir_rename" 1
15476
15477         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15478         check_stats $SINGLEMDS "samedir_rename" 1
15479
15480         rm -rf $DIR/${tdir}
15481 }
15482 run_test 133a "Verifying MDT stats ========================================"
15483
15484 test_133b() {
15485         local res
15486
15487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15488         remote_ost_nodsh && skip "remote OST with nodsh"
15489         remote_mds_nodsh && skip "remote MDS with nodsh"
15490
15491         local testdir=$DIR/${tdir}/stats_testdir
15492
15493         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15494         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15495         touch ${testdir}/${tfile} || error "touch failed"
15496         cancel_lru_locks mdc
15497
15498         # clear stats.
15499         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15500         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15501
15502         # extra mdt stats verification.
15503         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15504         check_stats $SINGLEMDS "setattr" 1
15505         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15506         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15507         then            # LU-1740
15508                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15509                 check_stats $SINGLEMDS "getattr" 1
15510         fi
15511         rm -rf $DIR/${tdir}
15512
15513         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15514         # so the check below is not reliable
15515         [ $MDSCOUNT -eq 1 ] || return 0
15516
15517         # Sleep to avoid a cached response.
15518         #define OBD_STATFS_CACHE_SECONDS 1
15519         sleep 2
15520         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15521         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15522         $LFS df || error "lfs failed"
15523         check_stats $SINGLEMDS "statfs" 1
15524
15525         # check aggregated statfs (LU-10018)
15526         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15527                 return 0
15528         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15529                 return 0
15530         sleep 2
15531         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15532         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15533         df $DIR
15534         check_stats $SINGLEMDS "statfs" 1
15535
15536         # We want to check that the client didn't send OST_STATFS to
15537         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15538         # extra care is needed here.
15539         if remote_mds; then
15540                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15541                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15542
15543                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15544                 [ "$res" ] && error "OST got STATFS"
15545         fi
15546
15547         return 0
15548 }
15549 run_test 133b "Verifying extra MDT stats =================================="
15550
15551 test_133c() {
15552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15553         remote_ost_nodsh && skip "remote OST with nodsh"
15554         remote_mds_nodsh && skip "remote MDS with nodsh"
15555
15556         local testdir=$DIR/$tdir/stats_testdir
15557
15558         test_mkdir -p $testdir
15559
15560         # verify obdfilter stats.
15561         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15562         sync
15563         cancel_lru_locks osc
15564         wait_delete_completed
15565
15566         # clear stats.
15567         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15568         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15569
15570         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15571                 error "dd failed"
15572         sync
15573         cancel_lru_locks osc
15574         check_stats ost1 "write" 1
15575
15576         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15577         check_stats ost1 "read" 1
15578
15579         > $testdir/$tfile || error "truncate failed"
15580         check_stats ost1 "punch" 1
15581
15582         rm -f $testdir/$tfile || error "file remove failed"
15583         wait_delete_completed
15584         check_stats ost1 "destroy" 1
15585
15586         rm -rf $DIR/$tdir
15587 }
15588 run_test 133c "Verifying OST stats ========================================"
15589
15590 order_2() {
15591         local value=$1
15592         local orig=$value
15593         local order=1
15594
15595         while [ $value -ge 2 ]; do
15596                 order=$((order*2))
15597                 value=$((value/2))
15598         done
15599
15600         if [ $orig -gt $order ]; then
15601                 order=$((order*2))
15602         fi
15603         echo $order
15604 }
15605
15606 size_in_KMGT() {
15607     local value=$1
15608     local size=('K' 'M' 'G' 'T');
15609     local i=0
15610     local size_string=$value
15611
15612     while [ $value -ge 1024 ]; do
15613         if [ $i -gt 3 ]; then
15614             #T is the biggest unit we get here, if that is bigger,
15615             #just return XXXT
15616             size_string=${value}T
15617             break
15618         fi
15619         value=$((value >> 10))
15620         if [ $value -lt 1024 ]; then
15621             size_string=${value}${size[$i]}
15622             break
15623         fi
15624         i=$((i + 1))
15625     done
15626
15627     echo $size_string
15628 }
15629
15630 get_rename_size() {
15631         local size=$1
15632         local context=${2:-.}
15633         local sample=$(do_facet $SINGLEMDS $LCTL \
15634                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15635                 grep -A1 $context |
15636                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15637         echo $sample
15638 }
15639
15640 test_133d() {
15641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15642         remote_ost_nodsh && skip "remote OST with nodsh"
15643         remote_mds_nodsh && skip "remote MDS with nodsh"
15644         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15645                 skip_env "MDS doesn't support rename stats"
15646
15647         local testdir1=$DIR/${tdir}/stats_testdir1
15648         local testdir2=$DIR/${tdir}/stats_testdir2
15649         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15650
15651         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15652
15653         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15654         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15655
15656         createmany -o $testdir1/test 512 || error "createmany failed"
15657
15658         # check samedir rename size
15659         mv ${testdir1}/test0 ${testdir1}/test_0
15660
15661         local testdir1_size=$(ls -l $DIR/${tdir} |
15662                 awk '/stats_testdir1/ {print $5}')
15663         local testdir2_size=$(ls -l $DIR/${tdir} |
15664                 awk '/stats_testdir2/ {print $5}')
15665
15666         testdir1_size=$(order_2 $testdir1_size)
15667         testdir2_size=$(order_2 $testdir2_size)
15668
15669         testdir1_size=$(size_in_KMGT $testdir1_size)
15670         testdir2_size=$(size_in_KMGT $testdir2_size)
15671
15672         echo "source rename dir size: ${testdir1_size}"
15673         echo "target rename dir size: ${testdir2_size}"
15674
15675         local cmd="do_facet $SINGLEMDS $LCTL "
15676         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15677
15678         eval $cmd || error "$cmd failed"
15679         local samedir=$($cmd | grep 'same_dir')
15680         local same_sample=$(get_rename_size $testdir1_size)
15681         [ -z "$samedir" ] && error "samedir_rename_size count error"
15682         [[ $same_sample -eq 1 ]] ||
15683                 error "samedir_rename_size error $same_sample"
15684         echo "Check same dir rename stats success"
15685
15686         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15687
15688         # check crossdir rename size
15689         mv ${testdir1}/test_0 ${testdir2}/test_0
15690
15691         testdir1_size=$(ls -l $DIR/${tdir} |
15692                 awk '/stats_testdir1/ {print $5}')
15693         testdir2_size=$(ls -l $DIR/${tdir} |
15694                 awk '/stats_testdir2/ {print $5}')
15695
15696         testdir1_size=$(order_2 $testdir1_size)
15697         testdir2_size=$(order_2 $testdir2_size)
15698
15699         testdir1_size=$(size_in_KMGT $testdir1_size)
15700         testdir2_size=$(size_in_KMGT $testdir2_size)
15701
15702         echo "source rename dir size: ${testdir1_size}"
15703         echo "target rename dir size: ${testdir2_size}"
15704
15705         eval $cmd || error "$cmd failed"
15706         local crossdir=$($cmd | grep 'crossdir')
15707         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15708         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15709         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15710         [[ $src_sample -eq 1 ]] ||
15711                 error "crossdir_rename_size error $src_sample"
15712         [[ $tgt_sample -eq 1 ]] ||
15713                 error "crossdir_rename_size error $tgt_sample"
15714         echo "Check cross dir rename stats success"
15715         rm -rf $DIR/${tdir}
15716 }
15717 run_test 133d "Verifying rename_stats ========================================"
15718
15719 test_133e() {
15720         remote_mds_nodsh && skip "remote MDS with nodsh"
15721         remote_ost_nodsh && skip "remote OST with nodsh"
15722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15723
15724         local testdir=$DIR/${tdir}/stats_testdir
15725         local ctr f0 f1 bs=32768 count=42 sum
15726
15727         mkdir -p ${testdir} || error "mkdir failed"
15728
15729         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15730
15731         for ctr in {write,read}_bytes; do
15732                 sync
15733                 cancel_lru_locks osc
15734
15735                 do_facet ost1 $LCTL set_param -n \
15736                         "obdfilter.*.exports.clear=clear"
15737
15738                 if [ $ctr = write_bytes ]; then
15739                         f0=/dev/zero
15740                         f1=${testdir}/${tfile}
15741                 else
15742                         f0=${testdir}/${tfile}
15743                         f1=/dev/null
15744                 fi
15745
15746                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15747                         error "dd failed"
15748                 sync
15749                 cancel_lru_locks osc
15750
15751                 sum=$(do_facet ost1 $LCTL get_param \
15752                         "obdfilter.*.exports.*.stats" |
15753                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15754                                 $1 == ctr { sum += $7 }
15755                                 END { printf("%0.0f", sum) }')
15756
15757                 if ((sum != bs * count)); then
15758                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15759                 fi
15760         done
15761
15762         rm -rf $DIR/${tdir}
15763 }
15764 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15765
15766 test_133f() {
15767         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15768                 skip "too old lustre for get_param -R ($facet_ver)"
15769
15770         # verifying readability.
15771         $LCTL get_param -R '*' &> /dev/null
15772
15773         # Verifing writability with badarea_io.
15774         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15775         local skipped_params='force_lbug|changelog_mask|daemon_file'
15776         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15777                 egrep -v "$skipped_params" |
15778                 xargs -n 1 find $proc_dirs -name |
15779                 xargs -n 1 badarea_io ||
15780                 error "client badarea_io failed"
15781
15782         # remount the FS in case writes/reads /proc break the FS
15783         cleanup || error "failed to unmount"
15784         setup || error "failed to setup"
15785 }
15786 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15787
15788 test_133g() {
15789         remote_mds_nodsh && skip "remote MDS with nodsh"
15790         remote_ost_nodsh && skip "remote OST with nodsh"
15791
15792         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15793         local proc_dirs_str=$(eval echo $proc_dirs)
15794         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15795         local facet
15796         for facet in mds1 ost1; do
15797                 local facet_ver=$(lustre_version_code $facet)
15798                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15799                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15800                 else
15801                         log "$facet: too old lustre for get_param -R"
15802                 fi
15803                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15804                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15805                                 tr -d = | egrep -v $skipped_params |
15806                                 xargs -n 1 find $proc_dirs_str -name |
15807                                 xargs -n 1 badarea_io" ||
15808                                         error "$facet badarea_io failed"
15809                 else
15810                         skip_noexit "$facet: too old lustre for get_param -R"
15811                 fi
15812         done
15813
15814         # remount the FS in case writes/reads /proc break the FS
15815         cleanup || error "failed to unmount"
15816         setup || error "failed to setup"
15817 }
15818 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15819
15820 test_133h() {
15821         remote_mds_nodsh && skip "remote MDS with nodsh"
15822         remote_ost_nodsh && skip "remote OST with nodsh"
15823         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15824                 skip "Need MDS version at least 2.9.54"
15825
15826         local facet
15827         for facet in client mds1 ost1; do
15828                 # Get the list of files that are missing the terminating newline
15829                 local plist=$(do_facet $facet
15830                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15831                 local ent
15832                 for ent in $plist; do
15833                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15834                                 awk -v FS='\v' -v RS='\v\v' \
15835                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15836                                         print FILENAME}'" 2>/dev/null)
15837                         [ -z $missing ] || {
15838                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15839                                 error "file does not end with newline: $facet-$ent"
15840                         }
15841                 done
15842         done
15843 }
15844 run_test 133h "Proc files should end with newlines"
15845
15846 test_134a() {
15847         remote_mds_nodsh && skip "remote MDS with nodsh"
15848         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15849                 skip "Need MDS version at least 2.7.54"
15850
15851         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15852         cancel_lru_locks mdc
15853
15854         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15855         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15856         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15857
15858         local nr=1000
15859         createmany -o $DIR/$tdir/f $nr ||
15860                 error "failed to create $nr files in $DIR/$tdir"
15861         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15862
15863         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15864         do_facet mds1 $LCTL set_param fail_loc=0x327
15865         do_facet mds1 $LCTL set_param fail_val=500
15866         touch $DIR/$tdir/m
15867
15868         echo "sleep 10 seconds ..."
15869         sleep 10
15870         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15871
15872         do_facet mds1 $LCTL set_param fail_loc=0
15873         do_facet mds1 $LCTL set_param fail_val=0
15874         [ $lck_cnt -lt $unused ] ||
15875                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15876
15877         rm $DIR/$tdir/m
15878         unlinkmany $DIR/$tdir/f $nr
15879 }
15880 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15881
15882 test_134b() {
15883         remote_mds_nodsh && skip "remote MDS with nodsh"
15884         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15885                 skip "Need MDS version at least 2.7.54"
15886
15887         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15888         cancel_lru_locks mdc
15889
15890         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15891                         ldlm.lock_reclaim_threshold_mb)
15892         # disable reclaim temporarily
15893         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15894
15895         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15896         do_facet mds1 $LCTL set_param fail_loc=0x328
15897         do_facet mds1 $LCTL set_param fail_val=500
15898
15899         $LCTL set_param debug=+trace
15900
15901         local nr=600
15902         createmany -o $DIR/$tdir/f $nr &
15903         local create_pid=$!
15904
15905         echo "Sleep $TIMEOUT seconds ..."
15906         sleep $TIMEOUT
15907         if ! ps -p $create_pid  > /dev/null 2>&1; then
15908                 do_facet mds1 $LCTL set_param fail_loc=0
15909                 do_facet mds1 $LCTL set_param fail_val=0
15910                 do_facet mds1 $LCTL set_param \
15911                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15912                 error "createmany finished incorrectly!"
15913         fi
15914         do_facet mds1 $LCTL set_param fail_loc=0
15915         do_facet mds1 $LCTL set_param fail_val=0
15916         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15917         wait $create_pid || return 1
15918
15919         unlinkmany $DIR/$tdir/f $nr
15920 }
15921 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15922
15923 test_135() {
15924         remote_mds_nodsh && skip "remote MDS with nodsh"
15925         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15926                 skip "Need MDS version at least 2.13.50"
15927         local fname
15928
15929         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15930
15931 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15932         #set only one record at plain llog
15933         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15934
15935         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15936
15937         #fill already existed plain llog each 64767
15938         #wrapping whole catalog
15939         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15940
15941         createmany -o $DIR/$tdir/$tfile_ 64700
15942         for (( i = 0; i < 64700; i = i + 2 ))
15943         do
15944                 rm $DIR/$tdir/$tfile_$i &
15945                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15946                 local pid=$!
15947                 wait $pid
15948         done
15949
15950         #waiting osp synchronization
15951         wait_delete_completed
15952 }
15953 run_test 135 "Race catalog processing"
15954
15955 test_136() {
15956         remote_mds_nodsh && skip "remote MDS with nodsh"
15957         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15958                 skip "Need MDS version at least 2.13.50"
15959         local fname
15960
15961         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15962         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15963         #set only one record at plain llog
15964 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15965         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15966
15967         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15968
15969         #fill already existed 2 plain llogs each 64767
15970         #wrapping whole catalog
15971         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15972         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15973         wait_delete_completed
15974
15975         createmany -o $DIR/$tdir/$tfile_ 10
15976         sleep 25
15977
15978         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15979         for (( i = 0; i < 10; i = i + 3 ))
15980         do
15981                 rm $DIR/$tdir/$tfile_$i &
15982                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15983                 local pid=$!
15984                 wait $pid
15985                 sleep 7
15986                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15987         done
15988
15989         #waiting osp synchronization
15990         wait_delete_completed
15991 }
15992 run_test 136 "Race catalog processing 2"
15993
15994 test_140() { #bug-17379
15995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15996
15997         test_mkdir $DIR/$tdir
15998         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15999         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16000
16001         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16002         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16003         local i=0
16004         while i=$((i + 1)); do
16005                 test_mkdir $i
16006                 cd $i || error "Changing to $i"
16007                 ln -s ../stat stat || error "Creating stat symlink"
16008                 # Read the symlink until ELOOP present,
16009                 # not LBUGing the system is considered success,
16010                 # we didn't overrun the stack.
16011                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16012                 if [ $ret -ne 0 ]; then
16013                         if [ $ret -eq 40 ]; then
16014                                 break  # -ELOOP
16015                         else
16016                                 error "Open stat symlink"
16017                                         return
16018                         fi
16019                 fi
16020         done
16021         i=$((i - 1))
16022         echo "The symlink depth = $i"
16023         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16024                 error "Invalid symlink depth"
16025
16026         # Test recursive symlink
16027         ln -s symlink_self symlink_self
16028         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16029         echo "open symlink_self returns $ret"
16030         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16031 }
16032 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16033
16034 test_150a() {
16035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16036
16037         local TF="$TMP/$tfile"
16038
16039         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16040         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16041         cp $TF $DIR/$tfile
16042         cancel_lru_locks $OSC
16043         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16044         remount_client $MOUNT
16045         df -P $MOUNT
16046         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16047
16048         $TRUNCATE $TF 6000
16049         $TRUNCATE $DIR/$tfile 6000
16050         cancel_lru_locks $OSC
16051         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16052
16053         echo "12345" >>$TF
16054         echo "12345" >>$DIR/$tfile
16055         cancel_lru_locks $OSC
16056         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16057
16058         echo "12345" >>$TF
16059         echo "12345" >>$DIR/$tfile
16060         cancel_lru_locks $OSC
16061         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16062 }
16063 run_test 150a "truncate/append tests"
16064
16065 test_150b() {
16066         check_set_fallocate_or_skip
16067         local out
16068
16069         touch $DIR/$tfile
16070         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16071         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16072                 skip_eopnotsupp "$out|check_fallocate failed"
16073 }
16074 run_test 150b "Verify fallocate (prealloc) functionality"
16075
16076 test_150bb() {
16077         check_set_fallocate_or_skip
16078
16079         touch $DIR/$tfile
16080         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16081         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16082         > $DIR/$tfile
16083         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16084         # precomputed md5sum for 20MB of zeroes
16085         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16086         local sum=($(md5sum $DIR/$tfile))
16087
16088         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16089
16090         check_set_fallocate 1
16091
16092         > $DIR/$tfile
16093         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16094         sum=($(md5sum $DIR/$tfile))
16095
16096         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16097 }
16098 run_test 150bb "Verify fallocate modes both zero space"
16099
16100 test_150c() {
16101         check_set_fallocate_or_skip
16102         local striping="-c2"
16103
16104         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16105         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16106         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16107         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16108         local want=$((OSTCOUNT * 1048576))
16109
16110         # Must allocate all requested space, not more than 5% extra
16111         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16112                 error "bytes $bytes is not $want"
16113
16114         rm -f $DIR/$tfile
16115
16116         echo "verify fallocate on PFL file"
16117
16118         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16119
16120         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16121                 error "Create $DIR/$tfile failed"
16122         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16123         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16124         want=$((512 * 1048576))
16125
16126         # Must allocate all requested space, not more than 5% extra
16127         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16128                 error "bytes $bytes is not $want"
16129 }
16130 run_test 150c "Verify fallocate Size and Blocks"
16131
16132 test_150d() {
16133         check_set_fallocate_or_skip
16134         local striping="-c2"
16135
16136         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16137
16138         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16139         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16140                 error "setstripe failed"
16141         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16142         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16143         local want=$((OSTCOUNT * 1048576))
16144
16145         # Must allocate all requested space, not more than 5% extra
16146         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16147                 error "bytes $bytes is not $want"
16148 }
16149 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16150
16151 test_150e() {
16152         check_set_fallocate_or_skip
16153
16154         echo "df before:"
16155         $LFS df
16156         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16157         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16158                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16159
16160         # Find OST with Minimum Size
16161         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16162                        sort -un | head -1)
16163
16164         # Get 100MB per OST of the available space to reduce run time
16165         # else 60% of the available space if we are running SLOW tests
16166         if [ $SLOW == "no" ]; then
16167                 local space=$((1024 * 100 * OSTCOUNT))
16168         else
16169                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16170         fi
16171
16172         fallocate -l${space}k $DIR/$tfile ||
16173                 error "fallocate ${space}k $DIR/$tfile failed"
16174         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16175
16176         # get size immediately after fallocate. This should be correctly
16177         # updated
16178         local size=$(stat -c '%s' $DIR/$tfile)
16179         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16180
16181         # Sleep for a while for statfs to get updated. And not pull from cache.
16182         sleep 2
16183
16184         echo "df after fallocate:"
16185         $LFS df
16186
16187         (( size / 1024 == space )) || error "size $size != requested $space"
16188         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16189                 error "used $used < space $space"
16190
16191         rm $DIR/$tfile || error "rm failed"
16192         sync
16193         wait_delete_completed
16194
16195         echo "df after unlink:"
16196         $LFS df
16197 }
16198 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16199
16200 test_150f() {
16201         local size
16202         local blocks
16203         local want_size_before=20480 # in bytes
16204         local want_blocks_before=40 # 512 sized blocks
16205         local want_blocks_after=24  # 512 sized blocks
16206         local length=$(((want_blocks_before - want_blocks_after) * 512))
16207
16208         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16209                 skip "need at least 2.14.0 for fallocate punch"
16210
16211         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16212                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16213         fi
16214
16215         check_set_fallocate_or_skip
16216         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16217
16218         [[ "x$DOM" == "xyes" ]] &&
16219                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16220
16221         echo "Verify fallocate punch: Range within the file range"
16222         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16223                 error "dd failed for bs 4096 and count 5"
16224
16225         # Call fallocate with punch range which is within the file range
16226         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16227                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16228         # client must see changes immediately after fallocate
16229         size=$(stat -c '%s' $DIR/$tfile)
16230         blocks=$(stat -c '%b' $DIR/$tfile)
16231
16232         # Verify punch worked.
16233         (( blocks == want_blocks_after )) ||
16234                 error "punch failed: blocks $blocks != $want_blocks_after"
16235
16236         (( size == want_size_before )) ||
16237                 error "punch failed: size $size != $want_size_before"
16238
16239         # Verify there is hole in file
16240         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16241         # precomputed md5sum
16242         local expect="4a9a834a2db02452929c0a348273b4aa"
16243
16244         cksum=($(md5sum $DIR/$tfile))
16245         [[ "${cksum[0]}" == "$expect" ]] ||
16246                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16247
16248         # Start second sub-case for fallocate punch.
16249         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16250         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16251                 error "dd failed for bs 4096 and count 5"
16252
16253         # Punch range less than block size will have no change in block count
16254         want_blocks_after=40  # 512 sized blocks
16255
16256         # Punch overlaps two blocks and less than blocksize
16257         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16258                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16259         size=$(stat -c '%s' $DIR/$tfile)
16260         blocks=$(stat -c '%b' $DIR/$tfile)
16261
16262         # Verify punch worked.
16263         (( blocks == want_blocks_after )) ||
16264                 error "punch failed: blocks $blocks != $want_blocks_after"
16265
16266         (( size == want_size_before )) ||
16267                 error "punch failed: size $size != $want_size_before"
16268
16269         # Verify if range is really zero'ed out. We expect Zeros.
16270         # precomputed md5sum
16271         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16272         cksum=($(md5sum $DIR/$tfile))
16273         [[ "${cksum[0]}" == "$expect" ]] ||
16274                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16275 }
16276 run_test 150f "Verify fallocate punch functionality"
16277
16278 test_150g() {
16279         local space
16280         local size
16281         local blocks
16282         local blocks_after
16283         local size_after
16284         local BS=4096 # Block size in bytes
16285
16286         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16287                 skip "need at least 2.14.0 for fallocate punch"
16288
16289         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16290                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16291         fi
16292
16293         check_set_fallocate_or_skip
16294         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16295
16296         if [[ "x$DOM" == "xyes" ]]; then
16297                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16298                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16299         else
16300                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16301                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16302         fi
16303
16304         # Get 100MB per OST of the available space to reduce run time
16305         # else 60% of the available space if we are running SLOW tests
16306         if [ $SLOW == "no" ]; then
16307                 space=$((1024 * 100 * OSTCOUNT))
16308         else
16309                 # Find OST with Minimum Size
16310                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16311                         sort -un | head -1)
16312                 echo "min size OST: $space"
16313                 space=$(((space * 60)/100 * OSTCOUNT))
16314         fi
16315         # space in 1k units, round to 4k blocks
16316         local blkcount=$((space * 1024 / $BS))
16317
16318         echo "Verify fallocate punch: Very large Range"
16319         fallocate -l${space}k $DIR/$tfile ||
16320                 error "fallocate ${space}k $DIR/$tfile failed"
16321         # write 1M at the end, start and in the middle
16322         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16323                 error "dd failed: bs $BS count 256"
16324         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16325                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16326         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16327                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16328
16329         # Gather stats.
16330         size=$(stat -c '%s' $DIR/$tfile)
16331
16332         # gather punch length.
16333         local punch_size=$((size - (BS * 2)))
16334
16335         echo "punch_size = $punch_size"
16336         echo "size - punch_size: $((size - punch_size))"
16337         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16338
16339         # Call fallocate to punch all except 2 blocks. We leave the
16340         # first and the last block
16341         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16342         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16343                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16344
16345         size_after=$(stat -c '%s' $DIR/$tfile)
16346         blocks_after=$(stat -c '%b' $DIR/$tfile)
16347
16348         # Verify punch worked.
16349         # Size should be kept
16350         (( size == size_after )) ||
16351                 error "punch failed: size $size != $size_after"
16352
16353         # two 4k data blocks to remain plus possible 1 extra extent block
16354         (( blocks_after <= ((BS / 512) * 3) )) ||
16355                 error "too many blocks remains: $blocks_after"
16356
16357         # Verify that file has hole between the first and the last blocks
16358         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16359         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16360
16361         echo "Hole at [$hole_start, $hole_end)"
16362         (( hole_start == BS )) ||
16363                 error "no hole at offset $BS after punch"
16364
16365         (( hole_end == BS + punch_size )) ||
16366                 error "data at offset $hole_end < $((BS + punch_size))"
16367 }
16368 run_test 150g "Verify fallocate punch on large range"
16369
16370 test_150h() {
16371         local file=$DIR/$tfile
16372         local size
16373
16374         check_set_fallocate_or_skip
16375         statx_supported || skip_env "Test must be statx() syscall supported"
16376
16377         # fallocate() does not update the size information on the MDT
16378         fallocate -l 16K $file || error "failed to fallocate $file"
16379         cancel_lru_locks $OSC
16380         # STATX with cached-always mode will not send glimpse RPCs to OST,
16381         # it uses the caching attrs on the client side as much as possible.
16382         size=$($STATX --cached=always -c %s $file)
16383         [ $size == 16384 ] ||
16384                 error "size after fallocate() is $size, expected 16384"
16385 }
16386 run_test 150h "Verify extend fallocate updates the file size"
16387
16388 #LU-2902 roc_hit was not able to read all values from lproc
16389 function roc_hit_init() {
16390         local list=$(comma_list $(osts_nodes))
16391         local dir=$DIR/$tdir-check
16392         local file=$dir/$tfile
16393         local BEFORE
16394         local AFTER
16395         local idx
16396
16397         test_mkdir $dir
16398         #use setstripe to do a write to every ost
16399         for i in $(seq 0 $((OSTCOUNT-1))); do
16400                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16401                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16402                 idx=$(printf %04x $i)
16403                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16404                         awk '$1 == "cache_access" {sum += $7}
16405                                 END { printf("%0.0f", sum) }')
16406
16407                 cancel_lru_locks osc
16408                 cat $file >/dev/null
16409
16410                 AFTER=$(get_osd_param $list *OST*$idx stats |
16411                         awk '$1 == "cache_access" {sum += $7}
16412                                 END { printf("%0.0f", sum) }')
16413
16414                 echo BEFORE:$BEFORE AFTER:$AFTER
16415                 if ! let "AFTER - BEFORE == 4"; then
16416                         rm -rf $dir
16417                         error "roc_hit is not safe to use"
16418                 fi
16419                 rm $file
16420         done
16421
16422         rm -rf $dir
16423 }
16424
16425 function roc_hit() {
16426         local list=$(comma_list $(osts_nodes))
16427         echo $(get_osd_param $list '' stats |
16428                 awk '$1 == "cache_hit" {sum += $7}
16429                         END { printf("%0.0f", sum) }')
16430 }
16431
16432 function set_cache() {
16433         local on=1
16434
16435         if [ "$2" == "off" ]; then
16436                 on=0;
16437         fi
16438         local list=$(comma_list $(osts_nodes))
16439         set_osd_param $list '' $1_cache_enable $on
16440
16441         cancel_lru_locks osc
16442 }
16443
16444 test_151() {
16445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16446         remote_ost_nodsh && skip "remote OST with nodsh"
16447         (( CLIENT_VERSION == OST1_VERSION )) ||
16448                 skip "LU-13081: no interop testing for OSS cache"
16449
16450         local CPAGES=3
16451         local list=$(comma_list $(osts_nodes))
16452
16453         # check whether obdfilter is cache capable at all
16454         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16455                 skip "not cache-capable obdfilter"
16456         fi
16457
16458         # check cache is enabled on all obdfilters
16459         if get_osd_param $list '' read_cache_enable | grep 0; then
16460                 skip "oss cache is disabled"
16461         fi
16462
16463         set_osd_param $list '' writethrough_cache_enable 1
16464
16465         # check write cache is enabled on all obdfilters
16466         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16467                 skip "oss write cache is NOT enabled"
16468         fi
16469
16470         roc_hit_init
16471
16472         #define OBD_FAIL_OBD_NO_LRU  0x609
16473         do_nodes $list $LCTL set_param fail_loc=0x609
16474
16475         # pages should be in the case right after write
16476         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16477                 error "dd failed"
16478
16479         local BEFORE=$(roc_hit)
16480         cancel_lru_locks osc
16481         cat $DIR/$tfile >/dev/null
16482         local AFTER=$(roc_hit)
16483
16484         do_nodes $list $LCTL set_param fail_loc=0
16485
16486         if ! let "AFTER - BEFORE == CPAGES"; then
16487                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16488         fi
16489
16490         cancel_lru_locks osc
16491         # invalidates OST cache
16492         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16493         set_osd_param $list '' read_cache_enable 0
16494         cat $DIR/$tfile >/dev/null
16495
16496         # now data shouldn't be found in the cache
16497         BEFORE=$(roc_hit)
16498         cancel_lru_locks osc
16499         cat $DIR/$tfile >/dev/null
16500         AFTER=$(roc_hit)
16501         if let "AFTER - BEFORE != 0"; then
16502                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16503         fi
16504
16505         set_osd_param $list '' read_cache_enable 1
16506         rm -f $DIR/$tfile
16507 }
16508 run_test 151 "test cache on oss and controls ==============================="
16509
16510 test_152() {
16511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16512
16513         local TF="$TMP/$tfile"
16514
16515         # simulate ENOMEM during write
16516 #define OBD_FAIL_OST_NOMEM      0x226
16517         lctl set_param fail_loc=0x80000226
16518         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16519         cp $TF $DIR/$tfile
16520         sync || error "sync failed"
16521         lctl set_param fail_loc=0
16522
16523         # discard client's cache
16524         cancel_lru_locks osc
16525
16526         # simulate ENOMEM during read
16527         lctl set_param fail_loc=0x80000226
16528         cmp $TF $DIR/$tfile || error "cmp failed"
16529         lctl set_param fail_loc=0
16530
16531         rm -f $TF
16532 }
16533 run_test 152 "test read/write with enomem ============================"
16534
16535 test_153() {
16536         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16537 }
16538 run_test 153 "test if fdatasync does not crash ======================="
16539
16540 dot_lustre_fid_permission_check() {
16541         local fid=$1
16542         local ffid=$MOUNT/.lustre/fid/$fid
16543         local test_dir=$2
16544
16545         echo "stat fid $fid"
16546         stat $ffid || error "stat $ffid failed."
16547         echo "touch fid $fid"
16548         touch $ffid || error "touch $ffid failed."
16549         echo "write to fid $fid"
16550         cat /etc/hosts > $ffid || error "write $ffid failed."
16551         echo "read fid $fid"
16552         diff /etc/hosts $ffid || error "read $ffid failed."
16553         echo "append write to fid $fid"
16554         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16555         echo "rename fid $fid"
16556         mv $ffid $test_dir/$tfile.1 &&
16557                 error "rename $ffid to $tfile.1 should fail."
16558         touch $test_dir/$tfile.1
16559         mv $test_dir/$tfile.1 $ffid &&
16560                 error "rename $tfile.1 to $ffid should fail."
16561         rm -f $test_dir/$tfile.1
16562         echo "truncate fid $fid"
16563         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16564         echo "link fid $fid"
16565         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16566         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16567                 id $USER0 || skip_env "missing user $USER0"
16568                 echo "setfacl fid $fid"
16569                 setfacl -R -m u:$USER0:rwx $ffid ||
16570                         error "setfacl $ffid failed"
16571                 echo "getfacl fid $fid"
16572                 getfacl $ffid || error "getfacl $ffid failed."
16573         fi
16574         echo "unlink fid $fid"
16575         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16576         echo "mknod fid $fid"
16577         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16578
16579         fid=[0xf00000400:0x1:0x0]
16580         ffid=$MOUNT/.lustre/fid/$fid
16581
16582         echo "stat non-exist fid $fid"
16583         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16584         echo "write to non-exist fid $fid"
16585         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16586         echo "link new fid $fid"
16587         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16588
16589         mkdir -p $test_dir/$tdir
16590         touch $test_dir/$tdir/$tfile
16591         fid=$($LFS path2fid $test_dir/$tdir)
16592         rc=$?
16593         [ $rc -ne 0 ] &&
16594                 error "error: could not get fid for $test_dir/$dir/$tfile."
16595
16596         ffid=$MOUNT/.lustre/fid/$fid
16597
16598         echo "ls $fid"
16599         ls $ffid || error "ls $ffid failed."
16600         echo "touch $fid/$tfile.1"
16601         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16602
16603         echo "touch $MOUNT/.lustre/fid/$tfile"
16604         touch $MOUNT/.lustre/fid/$tfile && \
16605                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16606
16607         echo "setxattr to $MOUNT/.lustre/fid"
16608         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16609
16610         echo "listxattr for $MOUNT/.lustre/fid"
16611         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16612
16613         echo "delxattr from $MOUNT/.lustre/fid"
16614         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16615
16616         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16617         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16618                 error "touch invalid fid should fail."
16619
16620         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16621         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16622                 error "touch non-normal fid should fail."
16623
16624         echo "rename $tdir to $MOUNT/.lustre/fid"
16625         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16626                 error "rename to $MOUNT/.lustre/fid should fail."
16627
16628         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16629         then            # LU-3547
16630                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16631                 local new_obf_mode=777
16632
16633                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16634                 chmod $new_obf_mode $DIR/.lustre/fid ||
16635                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16636
16637                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16638                 [ $obf_mode -eq $new_obf_mode ] ||
16639                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16640
16641                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16642                 chmod $old_obf_mode $DIR/.lustre/fid ||
16643                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16644         fi
16645
16646         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16647         fid=$($LFS path2fid $test_dir/$tfile-2)
16648
16649         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16650         then # LU-5424
16651                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16652                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16653                         error "create lov data thru .lustre failed"
16654         fi
16655         echo "cp /etc/passwd $test_dir/$tfile-2"
16656         cp /etc/passwd $test_dir/$tfile-2 ||
16657                 error "copy to $test_dir/$tfile-2 failed."
16658         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16659         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16660                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16661
16662         rm -rf $test_dir/tfile.lnk
16663         rm -rf $test_dir/$tfile-2
16664 }
16665
16666 test_154A() {
16667         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16668                 skip "Need MDS version at least 2.4.1"
16669
16670         local tf=$DIR/$tfile
16671         touch $tf
16672
16673         local fid=$($LFS path2fid $tf)
16674         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16675
16676         # check that we get the same pathname back
16677         local rootpath
16678         local found
16679         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16680                 echo "$rootpath $fid"
16681                 found=$($LFS fid2path $rootpath "$fid")
16682                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16683                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16684         done
16685
16686         # check wrong root path format
16687         rootpath=$MOUNT"_wrong"
16688         found=$($LFS fid2path $rootpath "$fid")
16689         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16690 }
16691 run_test 154A "lfs path2fid and fid2path basic checks"
16692
16693 test_154B() {
16694         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16695                 skip "Need MDS version at least 2.4.1"
16696
16697         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16698         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16699         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16700         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16701
16702         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16703         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16704
16705         # check that we get the same pathname
16706         echo "PFID: $PFID, name: $name"
16707         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16708         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16709         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16710                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16711
16712         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16713 }
16714 run_test 154B "verify the ll_decode_linkea tool"
16715
16716 test_154a() {
16717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16718         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16719         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16720                 skip "Need MDS version at least 2.2.51"
16721         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16722
16723         cp /etc/hosts $DIR/$tfile
16724
16725         fid=$($LFS path2fid $DIR/$tfile)
16726         rc=$?
16727         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16728
16729         dot_lustre_fid_permission_check "$fid" $DIR ||
16730                 error "dot lustre permission check $fid failed"
16731
16732         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16733
16734         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16735
16736         touch $MOUNT/.lustre/file &&
16737                 error "creation is not allowed under .lustre"
16738
16739         mkdir $MOUNT/.lustre/dir &&
16740                 error "mkdir is not allowed under .lustre"
16741
16742         rm -rf $DIR/$tfile
16743 }
16744 run_test 154a "Open-by-FID"
16745
16746 test_154b() {
16747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16748         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16750         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16751                 skip "Need MDS version at least 2.2.51"
16752
16753         local remote_dir=$DIR/$tdir/remote_dir
16754         local MDTIDX=1
16755         local rc=0
16756
16757         mkdir -p $DIR/$tdir
16758         $LFS mkdir -i $MDTIDX $remote_dir ||
16759                 error "create remote directory failed"
16760
16761         cp /etc/hosts $remote_dir/$tfile
16762
16763         fid=$($LFS path2fid $remote_dir/$tfile)
16764         rc=$?
16765         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16766
16767         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16768                 error "dot lustre permission check $fid failed"
16769         rm -rf $DIR/$tdir
16770 }
16771 run_test 154b "Open-by-FID for remote directory"
16772
16773 test_154c() {
16774         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16775                 skip "Need MDS version at least 2.4.1"
16776
16777         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16778         local FID1=$($LFS path2fid $DIR/$tfile.1)
16779         local FID2=$($LFS path2fid $DIR/$tfile.2)
16780         local FID3=$($LFS path2fid $DIR/$tfile.3)
16781
16782         local N=1
16783         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16784                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16785                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16786                 local want=FID$N
16787                 [ "$FID" = "${!want}" ] ||
16788                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16789                 N=$((N + 1))
16790         done
16791
16792         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16793         do
16794                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16795                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16796                 N=$((N + 1))
16797         done
16798 }
16799 run_test 154c "lfs path2fid and fid2path multiple arguments"
16800
16801 test_154d() {
16802         remote_mds_nodsh && skip "remote MDS with nodsh"
16803         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16804                 skip "Need MDS version at least 2.5.53"
16805
16806         if remote_mds; then
16807                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16808         else
16809                 nid="0@lo"
16810         fi
16811         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16812         local fd
16813         local cmd
16814
16815         rm -f $DIR/$tfile
16816         touch $DIR/$tfile
16817
16818         local fid=$($LFS path2fid $DIR/$tfile)
16819         # Open the file
16820         fd=$(free_fd)
16821         cmd="exec $fd<$DIR/$tfile"
16822         eval $cmd
16823         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16824         echo "$fid_list" | grep "$fid"
16825         rc=$?
16826
16827         cmd="exec $fd>/dev/null"
16828         eval $cmd
16829         if [ $rc -ne 0 ]; then
16830                 error "FID $fid not found in open files list $fid_list"
16831         fi
16832 }
16833 run_test 154d "Verify open file fid"
16834
16835 test_154e()
16836 {
16837         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16838                 skip "Need MDS version at least 2.6.50"
16839
16840         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16841                 error ".lustre returned by readdir"
16842         fi
16843 }
16844 run_test 154e ".lustre is not returned by readdir"
16845
16846 test_154f() {
16847         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16848
16849         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16850         mkdir_on_mdt0 $DIR/$tdir
16851         # test dirs inherit from its stripe
16852         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16853         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16854         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16855         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16856         touch $DIR/f
16857
16858         # get fid of parents
16859         local FID0=$($LFS path2fid $DIR/$tdir)
16860         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16861         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16862         local FID3=$($LFS path2fid $DIR)
16863
16864         # check that path2fid --parents returns expected <parent_fid>/name
16865         # 1) test for a directory (single parent)
16866         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16867         [ "$parent" == "$FID0/foo1" ] ||
16868                 error "expected parent: $FID0/foo1, got: $parent"
16869
16870         # 2) test for a file with nlink > 1 (multiple parents)
16871         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16872         echo "$parent" | grep -F "$FID1/$tfile" ||
16873                 error "$FID1/$tfile not returned in parent list"
16874         echo "$parent" | grep -F "$FID2/link" ||
16875                 error "$FID2/link not returned in parent list"
16876
16877         # 3) get parent by fid
16878         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16879         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16880         echo "$parent" | grep -F "$FID1/$tfile" ||
16881                 error "$FID1/$tfile not returned in parent list (by fid)"
16882         echo "$parent" | grep -F "$FID2/link" ||
16883                 error "$FID2/link not returned in parent list (by fid)"
16884
16885         # 4) test for entry in root directory
16886         parent=$($LFS path2fid --parents $DIR/f)
16887         echo "$parent" | grep -F "$FID3/f" ||
16888                 error "$FID3/f not returned in parent list"
16889
16890         # 5) test it on root directory
16891         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16892                 error "$MOUNT should not have parents"
16893
16894         # enable xattr caching and check that linkea is correctly updated
16895         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16896         save_lustre_params client "llite.*.xattr_cache" > $save
16897         lctl set_param llite.*.xattr_cache 1
16898
16899         # 6.1) linkea update on rename
16900         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16901
16902         # get parents by fid
16903         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16904         # foo1 should no longer be returned in parent list
16905         echo "$parent" | grep -F "$FID1" &&
16906                 error "$FID1 should no longer be in parent list"
16907         # the new path should appear
16908         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16909                 error "$FID2/$tfile.moved is not in parent list"
16910
16911         # 6.2) linkea update on unlink
16912         rm -f $DIR/$tdir/foo2/link
16913         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16914         # foo2/link should no longer be returned in parent list
16915         echo "$parent" | grep -F "$FID2/link" &&
16916                 error "$FID2/link should no longer be in parent list"
16917         true
16918
16919         rm -f $DIR/f
16920         restore_lustre_params < $save
16921         rm -f $save
16922 }
16923 run_test 154f "get parent fids by reading link ea"
16924
16925 test_154g()
16926 {
16927         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16928            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16929                 skip "Need MDS version at least 2.6.92"
16930
16931         mkdir_on_mdt0 $DIR/$tdir
16932         llapi_fid_test -d $DIR/$tdir
16933 }
16934 run_test 154g "various llapi FID tests"
16935
16936 test_154h()
16937 {
16938         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16939                 skip "Need client at least version 2.15.55.1"
16940
16941         # Create an empty file
16942         touch $DIR/$tfile
16943
16944         # Get FID (interactive mode) and save under $TMP/$tfile.log
16945         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16946                 path2fid $DIR/$tfile
16947         EOF
16948
16949         fid=$(cat $TMP/$tfile.log)
16950         # $fid should not be empty
16951         [[ ! -z $fid ]] || error "FID is empty"
16952         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16953 }
16954 run_test 154h "Verify interactive path2fid"
16955
16956 test_155_small_load() {
16957     local temp=$TMP/$tfile
16958     local file=$DIR/$tfile
16959
16960     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16961         error "dd of=$temp bs=6096 count=1 failed"
16962     cp $temp $file
16963     cancel_lru_locks $OSC
16964     cmp $temp $file || error "$temp $file differ"
16965
16966     $TRUNCATE $temp 6000
16967     $TRUNCATE $file 6000
16968     cmp $temp $file || error "$temp $file differ (truncate1)"
16969
16970     echo "12345" >>$temp
16971     echo "12345" >>$file
16972     cmp $temp $file || error "$temp $file differ (append1)"
16973
16974     echo "12345" >>$temp
16975     echo "12345" >>$file
16976     cmp $temp $file || error "$temp $file differ (append2)"
16977
16978     rm -f $temp $file
16979     true
16980 }
16981
16982 test_155_big_load() {
16983         remote_ost_nodsh && skip "remote OST with nodsh"
16984
16985         local temp=$TMP/$tfile
16986         local file=$DIR/$tfile
16987
16988         free_min_max
16989         local cache_size=$(do_facet ost$((MAXI+1)) \
16990                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16991
16992         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16993         # pre-set value
16994         if [ -z "$cache_size" ]; then
16995                 cache_size=256
16996         fi
16997         local large_file_size=$((cache_size * 2))
16998
16999         echo "OSS cache size: $cache_size KB"
17000         echo "Large file size: $large_file_size KB"
17001
17002         [ $MAXV -le $large_file_size ] &&
17003                 skip_env "max available OST size needs > $large_file_size KB"
17004
17005         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17006
17007         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17008                 error "dd of=$temp bs=$large_file_size count=1k failed"
17009         cp $temp $file
17010         ls -lh $temp $file
17011         cancel_lru_locks osc
17012         cmp $temp $file || error "$temp $file differ"
17013
17014         rm -f $temp $file
17015         true
17016 }
17017
17018 save_writethrough() {
17019         local facets=$(get_facets OST)
17020
17021         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17022 }
17023
17024 test_155a() {
17025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17026
17027         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17028
17029         save_writethrough $p
17030
17031         set_cache read on
17032         set_cache writethrough on
17033         test_155_small_load
17034         restore_lustre_params < $p
17035         rm -f $p
17036 }
17037 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17038
17039 test_155b() {
17040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17041
17042         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17043
17044         save_writethrough $p
17045
17046         set_cache read on
17047         set_cache writethrough off
17048         test_155_small_load
17049         restore_lustre_params < $p
17050         rm -f $p
17051 }
17052 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17053
17054 test_155c() {
17055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17056
17057         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17058
17059         save_writethrough $p
17060
17061         set_cache read off
17062         set_cache writethrough on
17063         test_155_small_load
17064         restore_lustre_params < $p
17065         rm -f $p
17066 }
17067 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17068
17069 test_155d() {
17070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17071
17072         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17073
17074         save_writethrough $p
17075
17076         set_cache read off
17077         set_cache writethrough off
17078         test_155_small_load
17079         restore_lustre_params < $p
17080         rm -f $p
17081 }
17082 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17083
17084 test_155e() {
17085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17086
17087         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17088
17089         save_writethrough $p
17090
17091         set_cache read on
17092         set_cache writethrough on
17093         test_155_big_load
17094         restore_lustre_params < $p
17095         rm -f $p
17096 }
17097 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17098
17099 test_155f() {
17100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17101
17102         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17103
17104         save_writethrough $p
17105
17106         set_cache read on
17107         set_cache writethrough off
17108         test_155_big_load
17109         restore_lustre_params < $p
17110         rm -f $p
17111 }
17112 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17113
17114 test_155g() {
17115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17116
17117         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17118
17119         save_writethrough $p
17120
17121         set_cache read off
17122         set_cache writethrough on
17123         test_155_big_load
17124         restore_lustre_params < $p
17125         rm -f $p
17126 }
17127 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17128
17129 test_155h() {
17130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17131
17132         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17133
17134         save_writethrough $p
17135
17136         set_cache read off
17137         set_cache writethrough off
17138         test_155_big_load
17139         restore_lustre_params < $p
17140         rm -f $p
17141 }
17142 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17143
17144 test_156() {
17145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17146         remote_ost_nodsh && skip "remote OST with nodsh"
17147         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17148                 skip "stats not implemented on old servers"
17149         [ "$ost1_FSTYPE" = "zfs" ] &&
17150                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17151         (( CLIENT_VERSION == OST1_VERSION )) ||
17152                 skip "LU-13081: no interop testing for OSS cache"
17153
17154         local CPAGES=3
17155         local BEFORE
17156         local AFTER
17157         local file="$DIR/$tfile"
17158         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17159
17160         save_writethrough $p
17161         roc_hit_init
17162
17163         log "Turn on read and write cache"
17164         set_cache read on
17165         set_cache writethrough on
17166
17167         log "Write data and read it back."
17168         log "Read should be satisfied from the cache."
17169         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17170         BEFORE=$(roc_hit)
17171         cancel_lru_locks osc
17172         cat $file >/dev/null
17173         AFTER=$(roc_hit)
17174         if ! let "AFTER - BEFORE == CPAGES"; then
17175                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17176         else
17177                 log "cache hits: before: $BEFORE, after: $AFTER"
17178         fi
17179
17180         log "Read again; it should be satisfied from the cache."
17181         BEFORE=$AFTER
17182         cancel_lru_locks osc
17183         cat $file >/dev/null
17184         AFTER=$(roc_hit)
17185         if ! let "AFTER - BEFORE == CPAGES"; then
17186                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17187         else
17188                 log "cache hits:: before: $BEFORE, after: $AFTER"
17189         fi
17190
17191         log "Turn off the read cache and turn on the write cache"
17192         set_cache read off
17193         set_cache writethrough on
17194
17195         log "Read again; it should be satisfied from the cache."
17196         BEFORE=$(roc_hit)
17197         cancel_lru_locks osc
17198         cat $file >/dev/null
17199         AFTER=$(roc_hit)
17200         if ! let "AFTER - BEFORE == CPAGES"; then
17201                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17202         else
17203                 log "cache hits:: before: $BEFORE, after: $AFTER"
17204         fi
17205
17206         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17207                 # > 2.12.56 uses pagecache if cached
17208                 log "Read again; it should not be satisfied from the cache."
17209                 BEFORE=$AFTER
17210                 cancel_lru_locks osc
17211                 cat $file >/dev/null
17212                 AFTER=$(roc_hit)
17213                 if ! let "AFTER - BEFORE == 0"; then
17214                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17215                 else
17216                         log "cache hits:: before: $BEFORE, after: $AFTER"
17217                 fi
17218         fi
17219
17220         log "Write data and read it back."
17221         log "Read should be satisfied from the cache."
17222         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17223         BEFORE=$(roc_hit)
17224         cancel_lru_locks osc
17225         cat $file >/dev/null
17226         AFTER=$(roc_hit)
17227         if ! let "AFTER - BEFORE == CPAGES"; then
17228                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17229         else
17230                 log "cache hits:: before: $BEFORE, after: $AFTER"
17231         fi
17232
17233         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17234                 # > 2.12.56 uses pagecache if cached
17235                 log "Read again; it should not be satisfied from the cache."
17236                 BEFORE=$AFTER
17237                 cancel_lru_locks osc
17238                 cat $file >/dev/null
17239                 AFTER=$(roc_hit)
17240                 if ! let "AFTER - BEFORE == 0"; then
17241                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17242                 else
17243                         log "cache hits:: before: $BEFORE, after: $AFTER"
17244                 fi
17245         fi
17246
17247         log "Turn off read and write cache"
17248         set_cache read off
17249         set_cache writethrough off
17250
17251         log "Write data and read it back"
17252         log "It should not be satisfied from the cache."
17253         rm -f $file
17254         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17255         cancel_lru_locks osc
17256         BEFORE=$(roc_hit)
17257         cat $file >/dev/null
17258         AFTER=$(roc_hit)
17259         if ! let "AFTER - BEFORE == 0"; then
17260                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17261         else
17262                 log "cache hits:: before: $BEFORE, after: $AFTER"
17263         fi
17264
17265         log "Turn on the read cache and turn off the write cache"
17266         set_cache read on
17267         set_cache writethrough off
17268
17269         log "Write data and read it back"
17270         log "It should not be satisfied from the cache."
17271         rm -f $file
17272         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17273         BEFORE=$(roc_hit)
17274         cancel_lru_locks osc
17275         cat $file >/dev/null
17276         AFTER=$(roc_hit)
17277         if ! let "AFTER - BEFORE == 0"; then
17278                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17279         else
17280                 log "cache hits:: before: $BEFORE, after: $AFTER"
17281         fi
17282
17283         log "Read again; it should be satisfied from the cache."
17284         BEFORE=$(roc_hit)
17285         cancel_lru_locks osc
17286         cat $file >/dev/null
17287         AFTER=$(roc_hit)
17288         if ! let "AFTER - BEFORE == CPAGES"; then
17289                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17290         else
17291                 log "cache hits:: before: $BEFORE, after: $AFTER"
17292         fi
17293
17294         restore_lustre_params < $p
17295         rm -f $p $file
17296 }
17297 run_test 156 "Verification of tunables"
17298
17299 test_160a() {
17300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17301         remote_mds_nodsh && skip "remote MDS with nodsh"
17302         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17303                 skip "Need MDS version at least 2.2.0"
17304
17305         changelog_register || error "changelog_register failed"
17306         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17307         changelog_users $SINGLEMDS | grep -q $cl_user ||
17308                 error "User $cl_user not found in changelog_users"
17309
17310         mkdir_on_mdt0 $DIR/$tdir
17311
17312         # change something
17313         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17314         changelog_clear 0 || error "changelog_clear failed"
17315         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17316         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17317         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17318         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17319         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17320         rm $DIR/$tdir/pics/desktop.jpg
17321
17322         echo "verifying changelog mask"
17323         changelog_chmask "-MKDIR"
17324         changelog_chmask "-CLOSE"
17325
17326         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17327         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17328
17329         changelog_chmask "+MKDIR"
17330         changelog_chmask "+CLOSE"
17331
17332         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17333         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17334
17335         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17336         CLOSES=$(changelog_dump | grep -c "CLOSE")
17337         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17338         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17339
17340         # verify contents
17341         echo "verifying target fid"
17342         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17343         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17344         [ "$fidc" == "$fidf" ] ||
17345                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17346         echo "verifying parent fid"
17347         # The FID returned from the Changelog may be the directory shard on
17348         # a different MDT, and not the FID returned by path2fid on the parent.
17349         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17350         # since this is what will matter when recreating this file in the tree.
17351         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17352         local pathp=$($LFS fid2path $MOUNT "$fidp")
17353         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17354                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17355
17356         echo "getting records for $cl_user"
17357         changelog_users $SINGLEMDS
17358         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17359         local nclr=3
17360         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17361                 error "changelog_clear failed"
17362         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17363         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17364         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17365                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17366
17367         local min0_rec=$(changelog_users $SINGLEMDS |
17368                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17369         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17370                           awk '{ print $1; exit; }')
17371
17372         changelog_dump | tail -n 5
17373         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17374         [ $first_rec == $((min0_rec + 1)) ] ||
17375                 error "first index should be $min0_rec + 1 not $first_rec"
17376
17377         # LU-3446 changelog index reset on MDT restart
17378         local cur_rec1=$(changelog_users $SINGLEMDS |
17379                          awk '/^current.index:/ { print $NF }')
17380         changelog_clear 0 ||
17381                 error "clear all changelog records for $cl_user failed"
17382         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17383         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17384                 error "Fail to start $SINGLEMDS"
17385         local cur_rec2=$(changelog_users $SINGLEMDS |
17386                          awk '/^current.index:/ { print $NF }')
17387         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17388         [ $cur_rec1 == $cur_rec2 ] ||
17389                 error "current index should be $cur_rec1 not $cur_rec2"
17390
17391         echo "verifying users from this test are deregistered"
17392         changelog_deregister || error "changelog_deregister failed"
17393         changelog_users $SINGLEMDS | grep -q $cl_user &&
17394                 error "User '$cl_user' still in changelog_users"
17395
17396         # lctl get_param -n mdd.*.changelog_users
17397         # current_index: 144
17398         # ID    index (idle seconds)
17399         # cl3   144   (2) mask=<list>
17400         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17401                 # this is the normal case where all users were deregistered
17402                 # make sure no new records are added when no users are present
17403                 local last_rec1=$(changelog_users $SINGLEMDS |
17404                                   awk '/^current.index:/ { print $NF }')
17405                 touch $DIR/$tdir/chloe
17406                 local last_rec2=$(changelog_users $SINGLEMDS |
17407                                   awk '/^current.index:/ { print $NF }')
17408                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17409                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17410         else
17411                 # any changelog users must be leftovers from a previous test
17412                 changelog_users $SINGLEMDS
17413                 echo "other changelog users; can't verify off"
17414         fi
17415 }
17416 run_test 160a "changelog sanity"
17417
17418 test_160b() { # LU-3587
17419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17420         remote_mds_nodsh && skip "remote MDS with nodsh"
17421         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17422                 skip "Need MDS version at least 2.2.0"
17423
17424         changelog_register || error "changelog_register failed"
17425         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17426         changelog_users $SINGLEMDS | grep -q $cl_user ||
17427                 error "User '$cl_user' not found in changelog_users"
17428
17429         local longname1=$(str_repeat a 255)
17430         local longname2=$(str_repeat b 255)
17431
17432         cd $DIR
17433         echo "creating very long named file"
17434         touch $longname1 || error "create of '$longname1' failed"
17435         echo "renaming very long named file"
17436         mv $longname1 $longname2
17437
17438         changelog_dump | grep RENME | tail -n 5
17439         rm -f $longname2
17440 }
17441 run_test 160b "Verify that very long rename doesn't crash in changelog"
17442
17443 test_160c() {
17444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17445         remote_mds_nodsh && skip "remote MDS with nodsh"
17446
17447         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17448                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17449                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17450                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17451
17452         local rc=0
17453
17454         # Registration step
17455         changelog_register || error "changelog_register failed"
17456
17457         rm -rf $DIR/$tdir
17458         mkdir -p $DIR/$tdir
17459         $MCREATE $DIR/$tdir/foo_160c
17460         changelog_chmask "-TRUNC"
17461         $TRUNCATE $DIR/$tdir/foo_160c 200
17462         changelog_chmask "+TRUNC"
17463         $TRUNCATE $DIR/$tdir/foo_160c 199
17464         changelog_dump | tail -n 5
17465         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17466         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17467 }
17468 run_test 160c "verify that changelog log catch the truncate event"
17469
17470 test_160d() {
17471         remote_mds_nodsh && skip "remote MDS with nodsh"
17472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17474         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17475                 skip "Need MDS version at least 2.7.60"
17476
17477         # Registration step
17478         changelog_register || error "changelog_register failed"
17479
17480         mkdir -p $DIR/$tdir/migrate_dir
17481         changelog_clear 0 || error "changelog_clear failed"
17482
17483         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17484         changelog_dump | tail -n 5
17485         local migrates=$(changelog_dump | grep -c "MIGRT")
17486         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17487 }
17488 run_test 160d "verify that changelog log catch the migrate event"
17489
17490 test_160e() {
17491         remote_mds_nodsh && skip "remote MDS with nodsh"
17492
17493         # Create a user
17494         changelog_register || error "changelog_register failed"
17495
17496         local MDT0=$(facet_svc $SINGLEMDS)
17497         local rc
17498
17499         # No user (expect fail)
17500         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17501         rc=$?
17502         if [ $rc -eq 0 ]; then
17503                 error "Should fail without user"
17504         elif [ $rc -ne 4 ]; then
17505                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17506         fi
17507
17508         # Delete a future user (expect fail)
17509         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17510         rc=$?
17511         if [ $rc -eq 0 ]; then
17512                 error "Deleted non-existant user cl77"
17513         elif [ $rc -ne 2 ]; then
17514                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17515         fi
17516
17517         # Clear to a bad index (1 billion should be safe)
17518         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17519         rc=$?
17520
17521         if [ $rc -eq 0 ]; then
17522                 error "Successfully cleared to invalid CL index"
17523         elif [ $rc -ne 22 ]; then
17524                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17525         fi
17526 }
17527 run_test 160e "changelog negative testing (should return errors)"
17528
17529 test_160f() {
17530         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17531         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17532                 skip "Need MDS version at least 2.10.56"
17533
17534         local mdts=$(comma_list $(mdts_nodes))
17535
17536         # Create a user
17537         changelog_register || error "first changelog_register failed"
17538         changelog_register || error "second changelog_register failed"
17539         local cl_users
17540         declare -A cl_user1
17541         declare -A cl_user2
17542         local user_rec1
17543         local user_rec2
17544         local i
17545
17546         # generate some changelog records to accumulate on each MDT
17547         # use all_char because created files should be evenly distributed
17548         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17549                 error "test_mkdir $tdir failed"
17550         log "$(date +%s): creating first files"
17551         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17552                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17553                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17554         done
17555
17556         # check changelogs have been generated
17557         local start=$SECONDS
17558         local idle_time=$((MDSCOUNT * 5 + 5))
17559         local nbcl=$(changelog_dump | wc -l)
17560         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17561
17562         for param in "changelog_max_idle_time=$idle_time" \
17563                      "changelog_gc=1" \
17564                      "changelog_min_gc_interval=2" \
17565                      "changelog_min_free_cat_entries=3"; do
17566                 local MDT0=$(facet_svc $SINGLEMDS)
17567                 local var="${param%=*}"
17568                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17569
17570                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17571                 do_nodes $mdts $LCTL set_param mdd.*.$param
17572         done
17573
17574         # force cl_user2 to be idle (1st part), but also cancel the
17575         # cl_user1 records so that it is not evicted later in the test.
17576         local sleep1=$((idle_time / 2))
17577         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17578         sleep $sleep1
17579
17580         # simulate changelog catalog almost full
17581         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17582         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17583
17584         for i in $(seq $MDSCOUNT); do
17585                 cl_users=(${CL_USERS[mds$i]})
17586                 cl_user1[mds$i]="${cl_users[0]}"
17587                 cl_user2[mds$i]="${cl_users[1]}"
17588
17589                 [ -n "${cl_user1[mds$i]}" ] ||
17590                         error "mds$i: no user registered"
17591                 [ -n "${cl_user2[mds$i]}" ] ||
17592                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17593
17594                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17595                 [ -n "$user_rec1" ] ||
17596                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17597                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17598                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17599                 [ -n "$user_rec2" ] ||
17600                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17601                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17602                      "$user_rec1 + 2 == $user_rec2"
17603                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17604                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17605                               "$user_rec1 + 2, but is $user_rec2"
17606                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17607                 [ -n "$user_rec2" ] ||
17608                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17609                 [ $user_rec1 == $user_rec2 ] ||
17610                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17611                               "$user_rec1, but is $user_rec2"
17612         done
17613
17614         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17615         local sleep2=$((idle_time - (SECONDS - start) + 1))
17616         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17617         sleep $sleep2
17618
17619         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17620         # cl_user1 should be OK because it recently processed records.
17621         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17622         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17623                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17624                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17625         done
17626
17627         # ensure gc thread is done
17628         for i in $(mdts_nodes); do
17629                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17630                         error "$i: GC-thread not done"
17631         done
17632
17633         local first_rec
17634         for (( i = 1; i <= MDSCOUNT; i++ )); do
17635                 # check cl_user1 still registered
17636                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17637                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17638                 # check cl_user2 unregistered
17639                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17640                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17641
17642                 # check changelogs are present and starting at $user_rec1 + 1
17643                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17644                 [ -n "$user_rec1" ] ||
17645                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17646                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17647                             awk '{ print $1; exit; }')
17648
17649                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17650                 [ $((user_rec1 + 1)) == $first_rec ] ||
17651                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17652         done
17653 }
17654 run_test 160f "changelog garbage collect (timestamped users)"
17655
17656 test_160g() {
17657         remote_mds_nodsh && skip "remote MDS with nodsh"
17658         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17659                 skip "Need MDS version at least 2.14.55"
17660
17661         local mdts=$(comma_list $(mdts_nodes))
17662
17663         # Create a user
17664         changelog_register || error "first changelog_register failed"
17665         changelog_register || error "second changelog_register failed"
17666         local cl_users
17667         declare -A cl_user1
17668         declare -A cl_user2
17669         local user_rec1
17670         local user_rec2
17671         local i
17672
17673         # generate some changelog records to accumulate on each MDT
17674         # use all_char because created files should be evenly distributed
17675         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17676                 error "test_mkdir $tdir failed"
17677         for ((i = 0; i < MDSCOUNT; i++)); do
17678                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17679                         error "create $DIR/$tdir/d$i.1 failed"
17680         done
17681
17682         # check changelogs have been generated
17683         local nbcl=$(changelog_dump | wc -l)
17684         (( $nbcl > 0 )) || error "no changelogs found"
17685
17686         # reduce the max_idle_indexes value to make sure we exceed it
17687         for param in "changelog_max_idle_indexes=2" \
17688                      "changelog_gc=1" \
17689                      "changelog_min_gc_interval=2"; do
17690                 local MDT0=$(facet_svc $SINGLEMDS)
17691                 local var="${param%=*}"
17692                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17693
17694                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17695                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17696                         error "unable to set mdd.*.$param"
17697         done
17698
17699         local start=$SECONDS
17700         for i in $(seq $MDSCOUNT); do
17701                 cl_users=(${CL_USERS[mds$i]})
17702                 cl_user1[mds$i]="${cl_users[0]}"
17703                 cl_user2[mds$i]="${cl_users[1]}"
17704
17705                 [ -n "${cl_user1[mds$i]}" ] ||
17706                         error "mds$i: user1 is not registered"
17707                 [ -n "${cl_user2[mds$i]}" ] ||
17708                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17709
17710                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17711                 [ -n "$user_rec1" ] ||
17712                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17713                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17714                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17715                 [ -n "$user_rec2" ] ||
17716                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17717                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17718                      "$user_rec1 + 2 == $user_rec2"
17719                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17720                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17721                               "expected $user_rec1 + 2, but is $user_rec2"
17722                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17723                 [ -n "$user_rec2" ] ||
17724                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17725                 [ $user_rec1 == $user_rec2 ] ||
17726                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17727                               "expected $user_rec1, but is $user_rec2"
17728         done
17729
17730         # ensure we are past the previous changelog_min_gc_interval set above
17731         local sleep2=$((start + 2 - SECONDS))
17732         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17733         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17734         # cl_user1 should be OK because it recently processed records.
17735         for ((i = 0; i < MDSCOUNT; i++)); do
17736                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17737                         error "create $DIR/$tdir/d$i.3 failed"
17738         done
17739
17740         # ensure gc thread is done
17741         for i in $(mdts_nodes); do
17742                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17743                         error "$i: GC-thread not done"
17744         done
17745
17746         local first_rec
17747         for (( i = 1; i <= MDSCOUNT; i++ )); do
17748                 # check cl_user1 still registered
17749                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17750                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17751                 # check cl_user2 unregistered
17752                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17753                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17754
17755                 # check changelogs are present and starting at $user_rec1 + 1
17756                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17757                 [ -n "$user_rec1" ] ||
17758                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17759                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17760                             awk '{ print $1; exit; }')
17761
17762                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17763                 [ $((user_rec1 + 1)) == $first_rec ] ||
17764                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17765         done
17766 }
17767 run_test 160g "changelog garbage collect on idle records"
17768
17769 test_160h() {
17770         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17771         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17772                 skip "Need MDS version at least 2.10.56"
17773
17774         local mdts=$(comma_list $(mdts_nodes))
17775
17776         # Create a user
17777         changelog_register || error "first changelog_register failed"
17778         changelog_register || error "second changelog_register failed"
17779         local cl_users
17780         declare -A cl_user1
17781         declare -A cl_user2
17782         local user_rec1
17783         local user_rec2
17784         local i
17785
17786         # generate some changelog records to accumulate on each MDT
17787         # use all_char because created files should be evenly distributed
17788         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17789                 error "test_mkdir $tdir failed"
17790         for ((i = 0; i < MDSCOUNT; i++)); do
17791                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17792                         error "create $DIR/$tdir/d$i.1 failed"
17793         done
17794
17795         # check changelogs have been generated
17796         local nbcl=$(changelog_dump | wc -l)
17797         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17798
17799         for param in "changelog_max_idle_time=10" \
17800                      "changelog_gc=1" \
17801                      "changelog_min_gc_interval=2"; do
17802                 local MDT0=$(facet_svc $SINGLEMDS)
17803                 local var="${param%=*}"
17804                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17805
17806                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17807                 do_nodes $mdts $LCTL set_param mdd.*.$param
17808         done
17809
17810         # force cl_user2 to be idle (1st part)
17811         sleep 9
17812
17813         for i in $(seq $MDSCOUNT); do
17814                 cl_users=(${CL_USERS[mds$i]})
17815                 cl_user1[mds$i]="${cl_users[0]}"
17816                 cl_user2[mds$i]="${cl_users[1]}"
17817
17818                 [ -n "${cl_user1[mds$i]}" ] ||
17819                         error "mds$i: no user registered"
17820                 [ -n "${cl_user2[mds$i]}" ] ||
17821                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17822
17823                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17824                 [ -n "$user_rec1" ] ||
17825                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17826                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17827                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17828                 [ -n "$user_rec2" ] ||
17829                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17830                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17831                      "$user_rec1 + 2 == $user_rec2"
17832                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17833                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17834                               "$user_rec1 + 2, but is $user_rec2"
17835                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17836                 [ -n "$user_rec2" ] ||
17837                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17838                 [ $user_rec1 == $user_rec2 ] ||
17839                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17840                               "$user_rec1, but is $user_rec2"
17841         done
17842
17843         # force cl_user2 to be idle (2nd part) and to reach
17844         # changelog_max_idle_time
17845         sleep 2
17846
17847         # force each GC-thread start and block then
17848         # one per MDT/MDD, set fail_val accordingly
17849         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17850         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17851
17852         # generate more changelogs to trigger fail_loc
17853         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17854                 error "create $DIR/$tdir/${tfile}bis failed"
17855
17856         # stop MDT to stop GC-thread, should be done in back-ground as it will
17857         # block waiting for the thread to be released and exit
17858         declare -A stop_pids
17859         for i in $(seq $MDSCOUNT); do
17860                 stop mds$i &
17861                 stop_pids[mds$i]=$!
17862         done
17863
17864         for i in $(mdts_nodes); do
17865                 local facet
17866                 local nb=0
17867                 local facets=$(facets_up_on_host $i)
17868
17869                 for facet in ${facets//,/ }; do
17870                         if [[ $facet == mds* ]]; then
17871                                 nb=$((nb + 1))
17872                         fi
17873                 done
17874                 # ensure each MDS's gc threads are still present and all in "R"
17875                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17876                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17877                         error "$i: expected $nb GC-thread"
17878                 wait_update $i \
17879                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17880                         "R" 20 ||
17881                         error "$i: GC-thread not found in R-state"
17882                 # check umounts of each MDT on MDS have reached kthread_stop()
17883                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17884                         error "$i: expected $nb umount"
17885                 wait_update $i \
17886                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17887                         error "$i: umount not found in D-state"
17888         done
17889
17890         # release all GC-threads
17891         do_nodes $mdts $LCTL set_param fail_loc=0
17892
17893         # wait for MDT stop to complete
17894         for i in $(seq $MDSCOUNT); do
17895                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17896         done
17897
17898         # XXX
17899         # may try to check if any orphan changelog records are present
17900         # via ldiskfs/zfs and llog_reader...
17901
17902         # re-start/mount MDTs
17903         for i in $(seq $MDSCOUNT); do
17904                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17905                         error "Fail to start mds$i"
17906         done
17907
17908         local first_rec
17909         for i in $(seq $MDSCOUNT); do
17910                 # check cl_user1 still registered
17911                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17912                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17913                 # check cl_user2 unregistered
17914                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17915                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17916
17917                 # check changelogs are present and starting at $user_rec1 + 1
17918                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17919                 [ -n "$user_rec1" ] ||
17920                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17921                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17922                             awk '{ print $1; exit; }')
17923
17924                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17925                 [ $((user_rec1 + 1)) == $first_rec ] ||
17926                         error "mds$i: first index should be $user_rec1 + 1, " \
17927                               "but is $first_rec"
17928         done
17929 }
17930 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17931               "during mount"
17932
17933 test_160i() {
17934
17935         local mdts=$(comma_list $(mdts_nodes))
17936
17937         changelog_register || error "first changelog_register failed"
17938
17939         # generate some changelog records to accumulate on each MDT
17940         # use all_char because created files should be evenly distributed
17941         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17942                 error "test_mkdir $tdir failed"
17943         for ((i = 0; i < MDSCOUNT; i++)); do
17944                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17945                         error "create $DIR/$tdir/d$i.1 failed"
17946         done
17947
17948         # check changelogs have been generated
17949         local nbcl=$(changelog_dump | wc -l)
17950         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17951
17952         # simulate race between register and unregister
17953         # XXX as fail_loc is set per-MDS, with DNE configs the race
17954         # simulation will only occur for one MDT per MDS and for the
17955         # others the normal race scenario will take place
17956         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17957         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17958         do_nodes $mdts $LCTL set_param fail_val=1
17959
17960         # unregister 1st user
17961         changelog_deregister &
17962         local pid1=$!
17963         # wait some time for deregister work to reach race rdv
17964         sleep 2
17965         # register 2nd user
17966         changelog_register || error "2nd user register failed"
17967
17968         wait $pid1 || error "1st user deregister failed"
17969
17970         local i
17971         local last_rec
17972         declare -A LAST_REC
17973         for i in $(seq $MDSCOUNT); do
17974                 if changelog_users mds$i | grep "^cl"; then
17975                         # make sure new records are added with one user present
17976                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17977                                           awk '/^current.index:/ { print $NF }')
17978                 else
17979                         error "mds$i has no user registered"
17980                 fi
17981         done
17982
17983         # generate more changelog records to accumulate on each MDT
17984         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17985                 error "create $DIR/$tdir/${tfile}bis failed"
17986
17987         for i in $(seq $MDSCOUNT); do
17988                 last_rec=$(changelog_users $SINGLEMDS |
17989                            awk '/^current.index:/ { print $NF }')
17990                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17991                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17992                         error "changelogs are off on mds$i"
17993         done
17994 }
17995 run_test 160i "changelog user register/unregister race"
17996
17997 test_160j() {
17998         remote_mds_nodsh && skip "remote MDS with nodsh"
17999         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18000                 skip "Need MDS version at least 2.12.56"
18001
18002         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18003         stack_trap "umount $MOUNT2" EXIT
18004
18005         changelog_register || error "first changelog_register failed"
18006         stack_trap "changelog_deregister" EXIT
18007
18008         # generate some changelog
18009         # use all_char because created files should be evenly distributed
18010         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18011                 error "mkdir $tdir failed"
18012         for ((i = 0; i < MDSCOUNT; i++)); do
18013                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18014                         error "create $DIR/$tdir/d$i.1 failed"
18015         done
18016
18017         # open the changelog device
18018         exec 3>/dev/changelog-$FSNAME-MDT0000
18019         stack_trap "exec 3>&-" EXIT
18020         exec 4</dev/changelog-$FSNAME-MDT0000
18021         stack_trap "exec 4<&-" EXIT
18022
18023         # umount the first lustre mount
18024         umount $MOUNT
18025         stack_trap "mount_client $MOUNT" EXIT
18026
18027         # read changelog, which may or may not fail, but should not crash
18028         cat <&4 >/dev/null
18029
18030         # clear changelog
18031         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18032         changelog_users $SINGLEMDS | grep -q $cl_user ||
18033                 error "User $cl_user not found in changelog_users"
18034
18035         printf 'clear:'$cl_user':0' >&3
18036 }
18037 run_test 160j "client can be umounted while its chanangelog is being used"
18038
18039 test_160k() {
18040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18041         remote_mds_nodsh && skip "remote MDS with nodsh"
18042
18043         mkdir -p $DIR/$tdir/1/1
18044
18045         changelog_register || error "changelog_register failed"
18046         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18047
18048         changelog_users $SINGLEMDS | grep -q $cl_user ||
18049                 error "User '$cl_user' not found in changelog_users"
18050 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18051         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18052         rmdir $DIR/$tdir/1/1 & sleep 1
18053         mkdir $DIR/$tdir/2
18054         touch $DIR/$tdir/2/2
18055         rm -rf $DIR/$tdir/2
18056
18057         wait
18058         sleep 4
18059
18060         changelog_dump | grep rmdir || error "rmdir not recorded"
18061 }
18062 run_test 160k "Verify that changelog records are not lost"
18063
18064 # Verifies that a file passed as a parameter has recently had an operation
18065 # performed on it that has generated an MTIME changelog which contains the
18066 # correct parent FID. As files might reside on a different MDT from the
18067 # parent directory in DNE configurations, the FIDs are translated to paths
18068 # before being compared, which should be identical
18069 compare_mtime_changelog() {
18070         local file="${1}"
18071         local mdtidx
18072         local mtime
18073         local cl_fid
18074         local pdir
18075         local dir
18076
18077         mdtidx=$($LFS getstripe --mdt-index $file)
18078         mdtidx=$(printf "%04x" $mdtidx)
18079
18080         # Obtain the parent FID from the MTIME changelog
18081         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18082         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18083
18084         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18085         [ -z "$cl_fid" ] && error "parent FID not present"
18086
18087         # Verify that the path for the parent FID is the same as the path for
18088         # the test directory
18089         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18090
18091         dir=$(dirname $1)
18092
18093         [[ "${pdir%/}" == "$dir" ]] ||
18094                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18095 }
18096
18097 test_160l() {
18098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18099
18100         remote_mds_nodsh && skip "remote MDS with nodsh"
18101         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18102                 skip "Need MDS version at least 2.13.55"
18103
18104         local cl_user
18105
18106         changelog_register || error "changelog_register failed"
18107         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18108
18109         changelog_users $SINGLEMDS | grep -q $cl_user ||
18110                 error "User '$cl_user' not found in changelog_users"
18111
18112         # Clear some types so that MTIME changelogs are generated
18113         changelog_chmask "-CREAT"
18114         changelog_chmask "-CLOSE"
18115
18116         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18117
18118         # Test CL_MTIME during setattr
18119         touch $DIR/$tdir/$tfile
18120         compare_mtime_changelog $DIR/$tdir/$tfile
18121
18122         # Test CL_MTIME during close
18123         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18124         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18125 }
18126 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18127
18128 test_160m() {
18129         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18130         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18131                 skip "Need MDS version at least 2.14.51"
18132         local cl_users
18133         local cl_user1
18134         local cl_user2
18135         local pid1
18136
18137         # Create a user
18138         changelog_register || error "first changelog_register failed"
18139         changelog_register || error "second changelog_register failed"
18140
18141         cl_users=(${CL_USERS[mds1]})
18142         cl_user1="${cl_users[0]}"
18143         cl_user2="${cl_users[1]}"
18144         # generate some changelog records to accumulate on MDT0
18145         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18146         createmany -m $DIR/$tdir/$tfile 50 ||
18147                 error "create $DIR/$tdir/$tfile failed"
18148         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18149         rm -f $DIR/$tdir
18150
18151         # check changelogs have been generated
18152         local nbcl=$(changelog_dump | wc -l)
18153         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18154
18155 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18156         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18157
18158         __changelog_clear mds1 $cl_user1 +10
18159         __changelog_clear mds1 $cl_user2 0 &
18160         pid1=$!
18161         sleep 2
18162         __changelog_clear mds1 $cl_user1 0 ||
18163                 error "fail to cancel record for $cl_user1"
18164         wait $pid1
18165         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18166 }
18167 run_test 160m "Changelog clear race"
18168
18169 test_160n() {
18170         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18171         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18172                 skip "Need MDS version at least 2.14.51"
18173         local cl_users
18174         local cl_user1
18175         local cl_user2
18176         local pid1
18177         local first_rec
18178         local last_rec=0
18179
18180         # Create a user
18181         changelog_register || error "first changelog_register failed"
18182
18183         cl_users=(${CL_USERS[mds1]})
18184         cl_user1="${cl_users[0]}"
18185
18186         # generate some changelog records to accumulate on MDT0
18187         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18188         first_rec=$(changelog_users $SINGLEMDS |
18189                         awk '/^current.index:/ { print $NF }')
18190         while (( last_rec < (( first_rec + 65000)) )); do
18191                 createmany -m $DIR/$tdir/$tfile 10000 ||
18192                         error "create $DIR/$tdir/$tfile failed"
18193
18194                 for i in $(seq 0 10000); do
18195                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18196                                 > /dev/null
18197                 done
18198
18199                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18200                         error "unlinkmany failed unlink"
18201                 last_rec=$(changelog_users $SINGLEMDS |
18202                         awk '/^current.index:/ { print $NF }')
18203                 echo last record $last_rec
18204                 (( last_rec == 0 )) && error "no changelog found"
18205         done
18206
18207 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18208         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18209
18210         __changelog_clear mds1 $cl_user1 0 &
18211         pid1=$!
18212         sleep 2
18213         __changelog_clear mds1 $cl_user1 0 ||
18214                 error "fail to cancel record for $cl_user1"
18215         wait $pid1
18216         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18217 }
18218 run_test 160n "Changelog destroy race"
18219
18220 test_160o() {
18221         local mdt="$(facet_svc $SINGLEMDS)"
18222
18223         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18224         remote_mds_nodsh && skip "remote MDS with nodsh"
18225         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18226                 skip "Need MDS version at least 2.14.52"
18227
18228         changelog_register --user test_160o -m unlnk+close+open ||
18229                 error "changelog_register failed"
18230
18231         do_facet $SINGLEMDS $LCTL --device $mdt \
18232                                 changelog_register -u "Tt3_-#" &&
18233                 error "bad symbols in name should fail"
18234
18235         do_facet $SINGLEMDS $LCTL --device $mdt \
18236                                 changelog_register -u test_160o &&
18237                 error "the same name registration should fail"
18238
18239         do_facet $SINGLEMDS $LCTL --device $mdt \
18240                         changelog_register -u test_160toolongname &&
18241                 error "too long name registration should fail"
18242
18243         changelog_chmask "MARK+HSM"
18244         lctl get_param mdd.*.changelog*mask
18245         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18246         changelog_users $SINGLEMDS | grep -q $cl_user ||
18247                 error "User $cl_user not found in changelog_users"
18248         #verify username
18249         echo $cl_user | grep -q test_160o ||
18250                 error "User $cl_user has no specific name 'test160o'"
18251
18252         # change something
18253         changelog_clear 0 || error "changelog_clear failed"
18254         # generate some changelog records to accumulate on MDT0
18255         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18256         touch $DIR/$tdir/$tfile                 # open 1
18257
18258         OPENS=$(changelog_dump | grep -c "OPEN")
18259         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18260
18261         # must be no MKDIR it wasn't set as user mask
18262         MKDIR=$(changelog_dump | grep -c "MKDIR")
18263         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18264
18265         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18266                                 mdd.$mdt.changelog_current_mask -n)
18267         # register maskless user
18268         changelog_register || error "changelog_register failed"
18269         # effective mask should be not changed because it is not minimal
18270         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18271                                 mdd.$mdt.changelog_current_mask -n)
18272         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18273         # set server mask to minimal value
18274         changelog_chmask "MARK"
18275         # check effective mask again, should be treated as DEFMASK now
18276         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18277                                 mdd.$mdt.changelog_current_mask -n)
18278         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18279
18280         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18281                 # set server mask back to some value
18282                 changelog_chmask "CLOSE,UNLNK"
18283                 # check effective mask again, should not remain as DEFMASK
18284                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18285                                 mdd.$mdt.changelog_current_mask -n)
18286                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18287         fi
18288
18289         do_facet $SINGLEMDS $LCTL --device $mdt \
18290                                 changelog_deregister -u test_160o ||
18291                 error "cannot deregister by name"
18292 }
18293 run_test 160o "changelog user name and mask"
18294
18295 test_160p() {
18296         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18297         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18298                 skip "Need MDS version at least 2.14.51"
18299         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18300         local cl_users
18301         local cl_user1
18302         local entry_count
18303
18304         # Create a user
18305         changelog_register || error "first changelog_register failed"
18306
18307         cl_users=(${CL_USERS[mds1]})
18308         cl_user1="${cl_users[0]}"
18309
18310         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18311         createmany -m $DIR/$tdir/$tfile 50 ||
18312                 error "create $DIR/$tdir/$tfile failed"
18313         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18314         rm -rf $DIR/$tdir
18315
18316         # check changelogs have been generated
18317         entry_count=$(changelog_dump | wc -l)
18318         ((entry_count != 0)) || error "no changelog entries found"
18319
18320         # remove changelog_users and check that orphan entries are removed
18321         stop mds1
18322         local dev=$(mdsdevname 1)
18323         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18324         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18325         entry_count=$(changelog_dump | wc -l)
18326         ((entry_count == 0)) ||
18327                 error "found $entry_count changelog entries, expected none"
18328 }
18329 run_test 160p "Changelog orphan cleanup with no users"
18330
18331 test_160q() {
18332         local mdt="$(facet_svc $SINGLEMDS)"
18333         local clu
18334
18335         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18336         remote_mds_nodsh && skip "remote MDS with nodsh"
18337         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18338                 skip "Need MDS version at least 2.14.54"
18339
18340         # set server mask to minimal value like server init does
18341         changelog_chmask "MARK"
18342         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18343                 error "changelog_register failed"
18344         # check effective mask again, should be treated as DEFMASK now
18345         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18346                                 mdd.$mdt.changelog_current_mask -n)
18347         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18348                 error "changelog_deregister failed"
18349         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18350 }
18351 run_test 160q "changelog effective mask is DEFMASK if not set"
18352
18353 test_160s() {
18354         remote_mds_nodsh && skip "remote MDS with nodsh"
18355         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18356                 skip "Need MDS version at least 2.14.55"
18357
18358         local mdts=$(comma_list $(mdts_nodes))
18359
18360         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18361         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18362                                        fail_val=$((24 * 3600 * 10))
18363
18364         # Create a user which is 10 days old
18365         changelog_register || error "first changelog_register failed"
18366         local cl_users
18367         declare -A cl_user1
18368         local i
18369
18370         # generate some changelog records to accumulate on each MDT
18371         # use all_char because created files should be evenly distributed
18372         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18373                 error "test_mkdir $tdir failed"
18374         for ((i = 0; i < MDSCOUNT; i++)); do
18375                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18376                         error "create $DIR/$tdir/d$i.1 failed"
18377         done
18378
18379         # check changelogs have been generated
18380         local nbcl=$(changelog_dump | wc -l)
18381         (( nbcl > 0 )) || error "no changelogs found"
18382
18383         # reduce the max_idle_indexes value to make sure we exceed it
18384         for param in "changelog_max_idle_indexes=2097446912" \
18385                      "changelog_max_idle_time=2592000" \
18386                      "changelog_gc=1" \
18387                      "changelog_min_gc_interval=2"; do
18388                 local MDT0=$(facet_svc $SINGLEMDS)
18389                 local var="${param%=*}"
18390                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18391
18392                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18393                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18394                         error "unable to set mdd.*.$param"
18395         done
18396
18397         local start=$SECONDS
18398         for i in $(seq $MDSCOUNT); do
18399                 cl_users=(${CL_USERS[mds$i]})
18400                 cl_user1[mds$i]="${cl_users[0]}"
18401
18402                 [[ -n "${cl_user1[mds$i]}" ]] ||
18403                         error "mds$i: no user registered"
18404         done
18405
18406         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18407         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18408
18409         # ensure we are past the previous changelog_min_gc_interval set above
18410         local sleep2=$((start + 2 - SECONDS))
18411         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18412
18413         # Generate one more changelog to trigger GC
18414         for ((i = 0; i < MDSCOUNT; i++)); do
18415                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18416                         error "create $DIR/$tdir/d$i.3 failed"
18417         done
18418
18419         # ensure gc thread is done
18420         for node in $(mdts_nodes); do
18421                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18422                         error "$node: GC-thread not done"
18423         done
18424
18425         do_nodes $mdts $LCTL set_param fail_loc=0
18426
18427         for (( i = 1; i <= MDSCOUNT; i++ )); do
18428                 # check cl_user1 is purged
18429                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18430                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18431         done
18432         return 0
18433 }
18434 run_test 160s "changelog garbage collect on idle records * time"
18435
18436 test_160t() {
18437         remote_mds_nodsh && skip "remote MDS with nodsh"
18438         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18439                 skip "Need MDS version at least 2.15.50"
18440
18441         local MDT0=$(facet_svc $SINGLEMDS)
18442         local cl_users
18443         local cl_user1
18444         local cl_user2
18445         local start
18446
18447         changelog_register --user user1 -m all ||
18448                 error "user1 failed to register"
18449
18450         mkdir_on_mdt0 $DIR/$tdir
18451         # create default overstripe to maximize changelog size
18452         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18453         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18454         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18455
18456         # user2 consumes less records so less space
18457         changelog_register --user user2 || error "user2 failed to register"
18458         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18459         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18460
18461         # check changelogs have been generated
18462         local nbcl=$(changelog_dump | wc -l)
18463         (( nbcl > 0 )) || error "no changelogs found"
18464
18465         # reduce the changelog_min_gc_interval to force check
18466         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18467                 local var="${param%=*}"
18468                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18469
18470                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18471                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18472                         error "unable to set mdd.*.$param"
18473         done
18474
18475         start=$SECONDS
18476         cl_users=(${CL_USERS[mds1]})
18477         cl_user1="${cl_users[0]}"
18478         cl_user2="${cl_users[1]}"
18479
18480         [[ -n $cl_user1 ]] ||
18481                 error "mds1: user #1 isn't registered"
18482         [[ -n $cl_user2 ]] ||
18483                 error "mds1: user #2 isn't registered"
18484
18485         # ensure we are past the previous changelog_min_gc_interval set above
18486         local sleep2=$((start + 2 - SECONDS))
18487         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18488
18489         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18490         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18491                         fail_val=$(((llog_size1 + llog_size2) / 2))
18492
18493         # Generate more changelog to trigger GC
18494         createmany -o $DIR/$tdir/u3_ 4 ||
18495                 error "create failed for more files"
18496
18497         # ensure gc thread is done
18498         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18499                 error "mds1: GC-thread not done"
18500
18501         do_facet mds1 $LCTL set_param fail_loc=0
18502
18503         # check cl_user1 is purged
18504         changelog_users mds1 | grep -q "$cl_user1" &&
18505                 error "User $cl_user1 is registered"
18506         # check cl_user2 is not purged
18507         changelog_users mds1 | grep -q "$cl_user2" ||
18508                 error "User $cl_user2 is not registered"
18509 }
18510 run_test 160t "changelog garbage collect on lack of space"
18511
18512 test_161a() {
18513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18514
18515         test_mkdir -c1 $DIR/$tdir
18516         cp /etc/hosts $DIR/$tdir/$tfile
18517         test_mkdir -c1 $DIR/$tdir/foo1
18518         test_mkdir -c1 $DIR/$tdir/foo2
18519         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18520         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18521         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18522         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18523         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18524         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18525                 $LFS fid2path $DIR $FID
18526                 error "bad link ea"
18527         fi
18528         # middle
18529         rm $DIR/$tdir/foo2/zachary
18530         # last
18531         rm $DIR/$tdir/foo2/thor
18532         # first
18533         rm $DIR/$tdir/$tfile
18534         # rename
18535         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18536         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18537                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18538         rm $DIR/$tdir/foo2/maggie
18539
18540         # overflow the EA
18541         local longname=$tfile.avg_len_is_thirty_two_
18542         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18543                 error_noexit 'failed to unlink many hardlinks'" EXIT
18544         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18545                 error "failed to hardlink many files"
18546         links=$($LFS fid2path $DIR $FID | wc -l)
18547         echo -n "${links}/1000 links in link EA"
18548         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18549 }
18550 run_test 161a "link ea sanity"
18551
18552 test_161b() {
18553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18554         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18555
18556         local MDTIDX=1
18557         local remote_dir=$DIR/$tdir/remote_dir
18558
18559         mkdir -p $DIR/$tdir
18560         $LFS mkdir -i $MDTIDX $remote_dir ||
18561                 error "create remote directory failed"
18562
18563         cp /etc/hosts $remote_dir/$tfile
18564         mkdir -p $remote_dir/foo1
18565         mkdir -p $remote_dir/foo2
18566         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18567         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18568         ln $remote_dir/$tfile $remote_dir/foo1/luna
18569         ln $remote_dir/$tfile $remote_dir/foo2/thor
18570
18571         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18572                      tr -d ']')
18573         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18574                 $LFS fid2path $DIR $FID
18575                 error "bad link ea"
18576         fi
18577         # middle
18578         rm $remote_dir/foo2/zachary
18579         # last
18580         rm $remote_dir/foo2/thor
18581         # first
18582         rm $remote_dir/$tfile
18583         # rename
18584         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18585         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18586         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18587                 $LFS fid2path $DIR $FID
18588                 error "bad link rename"
18589         fi
18590         rm $remote_dir/foo2/maggie
18591
18592         # overflow the EA
18593         local longname=filename_avg_len_is_thirty_two_
18594         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18595                 error "failed to hardlink many files"
18596         links=$($LFS fid2path $DIR $FID | wc -l)
18597         echo -n "${links}/1000 links in link EA"
18598         [[ ${links} -gt 60 ]] ||
18599                 error "expected at least 60 links in link EA"
18600         unlinkmany $remote_dir/foo2/$longname 1000 ||
18601         error "failed to unlink many hardlinks"
18602 }
18603 run_test 161b "link ea sanity under remote directory"
18604
18605 test_161c() {
18606         remote_mds_nodsh && skip "remote MDS with nodsh"
18607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18608         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18609                 skip "Need MDS version at least 2.1.5"
18610
18611         # define CLF_RENAME_LAST 0x0001
18612         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18613         changelog_register || error "changelog_register failed"
18614
18615         rm -rf $DIR/$tdir
18616         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18617         touch $DIR/$tdir/foo_161c
18618         touch $DIR/$tdir/bar_161c
18619         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18620         changelog_dump | grep RENME | tail -n 5
18621         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18622         changelog_clear 0 || error "changelog_clear failed"
18623         if [ x$flags != "x0x1" ]; then
18624                 error "flag $flags is not 0x1"
18625         fi
18626
18627         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18628         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18629         touch $DIR/$tdir/foo_161c
18630         touch $DIR/$tdir/bar_161c
18631         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18632         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18633         changelog_dump | grep RENME | tail -n 5
18634         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18635         changelog_clear 0 || error "changelog_clear failed"
18636         if [ x$flags != "x0x0" ]; then
18637                 error "flag $flags is not 0x0"
18638         fi
18639         echo "rename overwrite a target having nlink > 1," \
18640                 "changelog record has flags of $flags"
18641
18642         # rename doesn't overwrite a target (changelog flag 0x0)
18643         touch $DIR/$tdir/foo_161c
18644         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18645         changelog_dump | grep RENME | tail -n 5
18646         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18647         changelog_clear 0 || error "changelog_clear failed"
18648         if [ x$flags != "x0x0" ]; then
18649                 error "flag $flags is not 0x0"
18650         fi
18651         echo "rename doesn't overwrite a target," \
18652                 "changelog record has flags of $flags"
18653
18654         # define CLF_UNLINK_LAST 0x0001
18655         # unlink a file having nlink = 1 (changelog flag 0x1)
18656         rm -f $DIR/$tdir/foo2_161c
18657         changelog_dump | grep UNLNK | tail -n 5
18658         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18659         changelog_clear 0 || error "changelog_clear failed"
18660         if [ x$flags != "x0x1" ]; then
18661                 error "flag $flags is not 0x1"
18662         fi
18663         echo "unlink a file having nlink = 1," \
18664                 "changelog record has flags of $flags"
18665
18666         # unlink a file having nlink > 1 (changelog flag 0x0)
18667         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18668         rm -f $DIR/$tdir/foobar_161c
18669         changelog_dump | grep UNLNK | tail -n 5
18670         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18671         changelog_clear 0 || error "changelog_clear failed"
18672         if [ x$flags != "x0x0" ]; then
18673                 error "flag $flags is not 0x0"
18674         fi
18675         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18676 }
18677 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18678
18679 test_161d() {
18680         remote_mds_nodsh && skip "remote MDS with nodsh"
18681         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18682
18683         local pid
18684         local fid
18685
18686         changelog_register || error "changelog_register failed"
18687
18688         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18689         # interfer with $MOUNT/.lustre/fid/ access
18690         mkdir $DIR/$tdir
18691         [[ $? -eq 0 ]] || error "mkdir failed"
18692
18693         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18694         $LCTL set_param fail_loc=0x8000140c
18695         # 5s pause
18696         $LCTL set_param fail_val=5
18697
18698         # create file
18699         echo foofoo > $DIR/$tdir/$tfile &
18700         pid=$!
18701
18702         # wait for create to be delayed
18703         sleep 2
18704
18705         ps -p $pid
18706         [[ $? -eq 0 ]] || error "create should be blocked"
18707
18708         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18709         stack_trap "rm -f $tempfile"
18710         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18711         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18712         # some delay may occur during ChangeLog publishing and file read just
18713         # above, that could allow file write to happen finally
18714         [[ -s $tempfile ]] && echo "file should be empty"
18715
18716         $LCTL set_param fail_loc=0
18717
18718         wait $pid
18719         [[ $? -eq 0 ]] || error "create failed"
18720 }
18721 run_test 161d "create with concurrent .lustre/fid access"
18722
18723 check_path() {
18724         local expected="$1"
18725         shift
18726         local fid="$2"
18727
18728         local path
18729         path=$($LFS fid2path "$@")
18730         local rc=$?
18731
18732         if [ $rc -ne 0 ]; then
18733                 error "path looked up of '$expected' failed: rc=$rc"
18734         elif [ "$path" != "$expected" ]; then
18735                 error "path looked up '$path' instead of '$expected'"
18736         else
18737                 echo "FID '$fid' resolves to path '$path' as expected"
18738         fi
18739 }
18740
18741 test_162a() { # was test_162
18742         test_mkdir -p -c1 $DIR/$tdir/d2
18743         touch $DIR/$tdir/d2/$tfile
18744         touch $DIR/$tdir/d2/x1
18745         touch $DIR/$tdir/d2/x2
18746         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18747         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18748         # regular file
18749         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18750         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18751
18752         # softlink
18753         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18754         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18755         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18756
18757         # softlink to wrong file
18758         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18759         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18760         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18761
18762         # hardlink
18763         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18764         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18765         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18766         # fid2path dir/fsname should both work
18767         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18768         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18769
18770         # hardlink count: check that there are 2 links
18771         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18772         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18773
18774         # hardlink indexing: remove the first link
18775         rm $DIR/$tdir/d2/p/q/r/hlink
18776         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18777 }
18778 run_test 162a "path lookup sanity"
18779
18780 test_162b() {
18781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18782         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18783
18784         mkdir $DIR/$tdir
18785         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18786                                 error "create striped dir failed"
18787
18788         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18789                                         tail -n 1 | awk '{print $2}')
18790         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18791
18792         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18793         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18794
18795         # regular file
18796         for ((i=0;i<5;i++)); do
18797                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18798                         error "get fid for f$i failed"
18799                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18800
18801                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18802                         error "get fid for d$i failed"
18803                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18804         done
18805
18806         return 0
18807 }
18808 run_test 162b "striped directory path lookup sanity"
18809
18810 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18811 test_162c() {
18812         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18813                 skip "Need MDS version at least 2.7.51"
18814
18815         local lpath=$tdir.local
18816         local rpath=$tdir.remote
18817
18818         test_mkdir $DIR/$lpath
18819         test_mkdir $DIR/$rpath
18820
18821         for ((i = 0; i <= 101; i++)); do
18822                 lpath="$lpath/$i"
18823                 mkdir $DIR/$lpath
18824                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18825                         error "get fid for local directory $DIR/$lpath failed"
18826                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18827
18828                 rpath="$rpath/$i"
18829                 test_mkdir $DIR/$rpath
18830                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18831                         error "get fid for remote directory $DIR/$rpath failed"
18832                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18833         done
18834
18835         return 0
18836 }
18837 run_test 162c "fid2path works with paths 100 or more directories deep"
18838
18839 oalr_event_count() {
18840         local event="${1}"
18841         local trace="${2}"
18842
18843         awk -v name="${FSNAME}-OST0000" \
18844             -v event="${event}" \
18845             '$1 == "TRACE" && $2 == event && $3 == name' \
18846             "${trace}" |
18847         wc -l
18848 }
18849
18850 oalr_expect_event_count() {
18851         local event="${1}"
18852         local trace="${2}"
18853         local expect="${3}"
18854         local count
18855
18856         count=$(oalr_event_count "${event}" "${trace}")
18857         if ((count == expect)); then
18858                 return 0
18859         fi
18860
18861         error_noexit "${event} event count was '${count}', expected ${expect}"
18862         cat "${trace}" >&2
18863         exit 1
18864 }
18865
18866 cleanup_165() {
18867         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18868         stop ost1
18869         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18870 }
18871
18872 setup_165() {
18873         sync # Flush previous IOs so we can count log entries.
18874         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18875         stack_trap cleanup_165 EXIT
18876 }
18877
18878 test_165a() {
18879         local trace="/tmp/${tfile}.trace"
18880         local rc
18881         local count
18882
18883         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18884                 skip "OFD access log unsupported"
18885
18886         setup_165
18887         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18888         sleep 5
18889
18890         do_facet ost1 ofd_access_log_reader --list
18891         stop ost1
18892
18893         do_facet ost1 killall -TERM ofd_access_log_reader
18894         wait
18895         rc=$?
18896
18897         if ((rc != 0)); then
18898                 error "ofd_access_log_reader exited with rc = '${rc}'"
18899         fi
18900
18901         # Parse trace file for discovery events:
18902         oalr_expect_event_count alr_log_add "${trace}" 1
18903         oalr_expect_event_count alr_log_eof "${trace}" 1
18904         oalr_expect_event_count alr_log_free "${trace}" 1
18905 }
18906 run_test 165a "ofd access log discovery"
18907
18908 test_165b() {
18909         local trace="/tmp/${tfile}.trace"
18910         local file="${DIR}/${tfile}"
18911         local pfid1
18912         local pfid2
18913         local -a entry
18914         local rc
18915         local count
18916         local size
18917         local flags
18918
18919         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18920                 skip "OFD access log unsupported"
18921
18922         setup_165
18923         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18924         sleep 5
18925
18926         do_facet ost1 ofd_access_log_reader --list
18927
18928         lfs setstripe -c 1 -i 0 "${file}"
18929         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18930                 error "cannot create '${file}'"
18931
18932         sleep 5
18933         do_facet ost1 killall -TERM ofd_access_log_reader
18934         wait
18935         rc=$?
18936
18937         if ((rc != 0)); then
18938                 error "ofd_access_log_reader exited with rc = '${rc}'"
18939         fi
18940
18941         oalr_expect_event_count alr_log_entry "${trace}" 1
18942
18943         pfid1=$($LFS path2fid "${file}")
18944
18945         # 1     2             3   4    5     6   7    8    9     10
18946         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18947         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18948
18949         echo "entry = '${entry[*]}'" >&2
18950
18951         pfid2=${entry[4]}
18952         if [[ "${pfid1}" != "${pfid2}" ]]; then
18953                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18954         fi
18955
18956         size=${entry[8]}
18957         if ((size != 1048576)); then
18958                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18959         fi
18960
18961         flags=${entry[10]}
18962         if [[ "${flags}" != "w" ]]; then
18963                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18964         fi
18965
18966         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18967         sleep 5
18968
18969         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18970                 error "cannot read '${file}'"
18971         sleep 5
18972
18973         do_facet ost1 killall -TERM ofd_access_log_reader
18974         wait
18975         rc=$?
18976
18977         if ((rc != 0)); then
18978                 error "ofd_access_log_reader exited with rc = '${rc}'"
18979         fi
18980
18981         oalr_expect_event_count alr_log_entry "${trace}" 1
18982
18983         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18984         echo "entry = '${entry[*]}'" >&2
18985
18986         pfid2=${entry[4]}
18987         if [[ "${pfid1}" != "${pfid2}" ]]; then
18988                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18989         fi
18990
18991         size=${entry[8]}
18992         if ((size != 524288)); then
18993                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18994         fi
18995
18996         flags=${entry[10]}
18997         if [[ "${flags}" != "r" ]]; then
18998                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18999         fi
19000 }
19001 run_test 165b "ofd access log entries are produced and consumed"
19002
19003 test_165c() {
19004         local trace="/tmp/${tfile}.trace"
19005         local file="${DIR}/${tdir}/${tfile}"
19006
19007         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19008                 skip "OFD access log unsupported"
19009
19010         test_mkdir "${DIR}/${tdir}"
19011
19012         setup_165
19013         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19014         sleep 5
19015
19016         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19017
19018         # 4096 / 64 = 64. Create twice as many entries.
19019         for ((i = 0; i < 128; i++)); do
19020                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19021                         error "cannot create file"
19022         done
19023
19024         sync
19025
19026         do_facet ost1 killall -TERM ofd_access_log_reader
19027         wait
19028         rc=$?
19029         if ((rc != 0)); then
19030                 error "ofd_access_log_reader exited with rc = '${rc}'"
19031         fi
19032
19033         unlinkmany  "${file}-%d" 128
19034 }
19035 run_test 165c "full ofd access logs do not block IOs"
19036
19037 oal_get_read_count() {
19038         local stats="$1"
19039
19040         # STATS lustre-OST0001 alr_read_count 1
19041
19042         do_facet ost1 cat "${stats}" |
19043         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19044              END { print count; }'
19045 }
19046
19047 oal_expect_read_count() {
19048         local stats="$1"
19049         local count
19050         local expect="$2"
19051
19052         # Ask ofd_access_log_reader to write stats.
19053         do_facet ost1 killall -USR1 ofd_access_log_reader
19054
19055         # Allow some time for things to happen.
19056         sleep 1
19057
19058         count=$(oal_get_read_count "${stats}")
19059         if ((count == expect)); then
19060                 return 0
19061         fi
19062
19063         error_noexit "bad read count, got ${count}, expected ${expect}"
19064         do_facet ost1 cat "${stats}" >&2
19065         exit 1
19066 }
19067
19068 test_165d() {
19069         local stats="/tmp/${tfile}.stats"
19070         local file="${DIR}/${tdir}/${tfile}"
19071         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19072
19073         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19074                 skip "OFD access log unsupported"
19075
19076         test_mkdir "${DIR}/${tdir}"
19077
19078         setup_165
19079         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19080         sleep 5
19081
19082         lfs setstripe -c 1 -i 0 "${file}"
19083
19084         do_facet ost1 lctl set_param "${param}=rw"
19085         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19086                 error "cannot create '${file}'"
19087         oal_expect_read_count "${stats}" 1
19088
19089         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19090                 error "cannot read '${file}'"
19091         oal_expect_read_count "${stats}" 2
19092
19093         do_facet ost1 lctl set_param "${param}=r"
19094         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19095                 error "cannot create '${file}'"
19096         oal_expect_read_count "${stats}" 2
19097
19098         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19099                 error "cannot read '${file}'"
19100         oal_expect_read_count "${stats}" 3
19101
19102         do_facet ost1 lctl set_param "${param}=w"
19103         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19104                 error "cannot create '${file}'"
19105         oal_expect_read_count "${stats}" 4
19106
19107         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19108                 error "cannot read '${file}'"
19109         oal_expect_read_count "${stats}" 4
19110
19111         do_facet ost1 lctl set_param "${param}=0"
19112         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19113                 error "cannot create '${file}'"
19114         oal_expect_read_count "${stats}" 4
19115
19116         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19117                 error "cannot read '${file}'"
19118         oal_expect_read_count "${stats}" 4
19119
19120         do_facet ost1 killall -TERM ofd_access_log_reader
19121         wait
19122         rc=$?
19123         if ((rc != 0)); then
19124                 error "ofd_access_log_reader exited with rc = '${rc}'"
19125         fi
19126 }
19127 run_test 165d "ofd_access_log mask works"
19128
19129 test_165e() {
19130         local stats="/tmp/${tfile}.stats"
19131         local file0="${DIR}/${tdir}-0/${tfile}"
19132         local file1="${DIR}/${tdir}-1/${tfile}"
19133
19134         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19135                 skip "OFD access log unsupported"
19136
19137         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19138
19139         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19140         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19141
19142         lfs setstripe -c 1 -i 0 "${file0}"
19143         lfs setstripe -c 1 -i 0 "${file1}"
19144
19145         setup_165
19146         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19147         sleep 5
19148
19149         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19150                 error "cannot create '${file0}'"
19151         sync
19152         oal_expect_read_count "${stats}" 0
19153
19154         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19155                 error "cannot create '${file1}'"
19156         sync
19157         oal_expect_read_count "${stats}" 1
19158
19159         do_facet ost1 killall -TERM ofd_access_log_reader
19160         wait
19161         rc=$?
19162         if ((rc != 0)); then
19163                 error "ofd_access_log_reader exited with rc = '${rc}'"
19164         fi
19165 }
19166 run_test 165e "ofd_access_log MDT index filter works"
19167
19168 test_165f() {
19169         local trace="/tmp/${tfile}.trace"
19170         local rc
19171         local count
19172
19173         setup_165
19174         do_facet ost1 timeout 60 ofd_access_log_reader \
19175                 --exit-on-close --debug=- --trace=- > "${trace}" &
19176         sleep 5
19177         stop ost1
19178
19179         wait
19180         rc=$?
19181
19182         if ((rc != 0)); then
19183                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19184                 cat "${trace}"
19185                 exit 1
19186         fi
19187 }
19188 run_test 165f "ofd_access_log_reader --exit-on-close works"
19189
19190 test_169() {
19191         # do directio so as not to populate the page cache
19192         log "creating a 10 Mb file"
19193         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19194                 error "multiop failed while creating a file"
19195         log "starting reads"
19196         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19197         log "truncating the file"
19198         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19199                 error "multiop failed while truncating the file"
19200         log "killing dd"
19201         kill %+ || true # reads might have finished
19202         echo "wait until dd is finished"
19203         wait
19204         log "removing the temporary file"
19205         rm -rf $DIR/$tfile || error "tmp file removal failed"
19206 }
19207 run_test 169 "parallel read and truncate should not deadlock"
19208
19209 test_170() {
19210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19211
19212         $LCTL clear     # bug 18514
19213         $LCTL debug_daemon start $TMP/${tfile}_log_good
19214         touch $DIR/$tfile
19215         $LCTL debug_daemon stop
19216         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19217                 error "sed failed to read log_good"
19218
19219         $LCTL debug_daemon start $TMP/${tfile}_log_good
19220         rm -rf $DIR/$tfile
19221         $LCTL debug_daemon stop
19222
19223         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19224                error "lctl df log_bad failed"
19225
19226         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19227         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19228
19229         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19230         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19231
19232         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19233                 error "bad_line good_line1 good_line2 are empty"
19234
19235         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19236         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19237         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19238
19239         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19240         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19241         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19242
19243         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19244                 error "bad_line_new good_line_new are empty"
19245
19246         local expected_good=$((good_line1 + good_line2*2))
19247
19248         rm -f $TMP/${tfile}*
19249         # LU-231, short malformed line may not be counted into bad lines
19250         if [ $bad_line -ne $bad_line_new ] &&
19251                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19252                 error "expected $bad_line bad lines, but got $bad_line_new"
19253                 return 1
19254         fi
19255
19256         if [ $expected_good -ne $good_line_new ]; then
19257                 error "expected $expected_good good lines, but got $good_line_new"
19258                 return 2
19259         fi
19260         true
19261 }
19262 run_test 170 "test lctl df to handle corrupted log ====================="
19263
19264 test_171() { # bug20592
19265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19266
19267         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19268         $LCTL set_param fail_loc=0x50e
19269         $LCTL set_param fail_val=3000
19270         multiop_bg_pause $DIR/$tfile O_s || true
19271         local MULTIPID=$!
19272         kill -USR1 $MULTIPID
19273         # cause log dump
19274         sleep 3
19275         wait $MULTIPID
19276         if dmesg | grep "recursive fault"; then
19277                 error "caught a recursive fault"
19278         fi
19279         $LCTL set_param fail_loc=0
19280         true
19281 }
19282 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19283
19284 test_172() {
19285
19286         #define OBD_FAIL_OBD_CLEANUP  0x60e
19287         $LCTL set_param fail_loc=0x60e
19288         umount $MOUNT || error "umount $MOUNT failed"
19289         stack_trap "mount_client $MOUNT"
19290
19291         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19292                 error "no client OBDs are remained"
19293
19294         $LCTL dl | while read devno state type name foo; do
19295                 case $type in
19296                 lov|osc|lmv|mdc)
19297                         $LCTL --device $name cleanup
19298                         $LCTL --device $name detach
19299                         ;;
19300                 *)
19301                         # skip server devices
19302                         ;;
19303                 esac
19304         done
19305
19306         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19307                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19308                 error "some client OBDs are still remained"
19309         fi
19310
19311 }
19312 run_test 172 "manual device removal with lctl cleanup/detach ======"
19313
19314 # it would be good to share it with obdfilter-survey/iokit-libecho code
19315 setup_obdecho_osc () {
19316         local rc=0
19317         local ost_nid=$1
19318         local obdfilter_name=$2
19319         echo "Creating new osc for $obdfilter_name on $ost_nid"
19320         # make sure we can find loopback nid
19321         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19322
19323         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19324                            ${obdfilter_name}_osc_UUID || rc=2; }
19325         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19326                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19327         return $rc
19328 }
19329
19330 cleanup_obdecho_osc () {
19331         local obdfilter_name=$1
19332         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19333         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19334         return 0
19335 }
19336
19337 obdecho_test() {
19338         local OBD=$1
19339         local node=$2
19340         local pages=${3:-64}
19341         local rc=0
19342         local id
19343
19344         local count=10
19345         local obd_size=$(get_obd_size $node $OBD)
19346         local page_size=$(get_page_size $node)
19347         if [[ -n "$obd_size" ]]; then
19348                 local new_count=$((obd_size / (pages * page_size / 1024)))
19349                 [[ $new_count -ge $count ]] || count=$new_count
19350         fi
19351
19352         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19353         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19354                            rc=2; }
19355         if [ $rc -eq 0 ]; then
19356             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19357             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19358         fi
19359         echo "New object id is $id"
19360         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19361                            rc=4; }
19362         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19363                            "test_brw $count w v $pages $id" || rc=4; }
19364         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19365                            rc=4; }
19366         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19367                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19368         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19369                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19370         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19371         return $rc
19372 }
19373
19374 test_180a() {
19375         skip "obdecho on osc is no longer supported"
19376 }
19377 run_test 180a "test obdecho on osc"
19378
19379 test_180b() {
19380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19381         remote_ost_nodsh && skip "remote OST with nodsh"
19382
19383         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19384                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19385                 error "failed to load module obdecho"
19386
19387         local target=$(do_facet ost1 $LCTL dl |
19388                        awk '/obdfilter/ { print $4; exit; }')
19389
19390         if [ -n "$target" ]; then
19391                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19392         else
19393                 do_facet ost1 $LCTL dl
19394                 error "there is no obdfilter target on ost1"
19395         fi
19396 }
19397 run_test 180b "test obdecho directly on obdfilter"
19398
19399 test_180c() { # LU-2598
19400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19401         remote_ost_nodsh && skip "remote OST with nodsh"
19402         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19403                 skip "Need MDS version at least 2.4.0"
19404
19405         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19406                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19407                 error "failed to load module obdecho"
19408
19409         local target=$(do_facet ost1 $LCTL dl |
19410                        awk '/obdfilter/ { print $4; exit; }')
19411
19412         if [ -n "$target" ]; then
19413                 local pages=16384 # 64MB bulk I/O RPC size
19414
19415                 obdecho_test "$target" ost1 "$pages" ||
19416                         error "obdecho_test with pages=$pages failed with $?"
19417         else
19418                 do_facet ost1 $LCTL dl
19419                 error "there is no obdfilter target on ost1"
19420         fi
19421 }
19422 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19423
19424 test_181() { # bug 22177
19425         test_mkdir $DIR/$tdir
19426         # create enough files to index the directory
19427         createmany -o $DIR/$tdir/foobar 4000
19428         # print attributes for debug purpose
19429         lsattr -d .
19430         # open dir
19431         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19432         MULTIPID=$!
19433         # remove the files & current working dir
19434         unlinkmany $DIR/$tdir/foobar 4000
19435         rmdir $DIR/$tdir
19436         kill -USR1 $MULTIPID
19437         wait $MULTIPID
19438         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19439         return 0
19440 }
19441 run_test 181 "Test open-unlinked dir ========================"
19442
19443 test_182a() {
19444         local fcount=1000
19445         local tcount=10
19446
19447         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19448
19449         $LCTL set_param mdc.*.rpc_stats=clear
19450
19451         for (( i = 0; i < $tcount; i++ )) ; do
19452                 mkdir $DIR/$tdir/$i
19453         done
19454
19455         for (( i = 0; i < $tcount; i++ )) ; do
19456                 createmany -o $DIR/$tdir/$i/f- $fcount &
19457         done
19458         wait
19459
19460         for (( i = 0; i < $tcount; i++ )) ; do
19461                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19462         done
19463         wait
19464
19465         $LCTL get_param mdc.*.rpc_stats
19466
19467         rm -rf $DIR/$tdir
19468 }
19469 run_test 182a "Test parallel modify metadata operations from mdc"
19470
19471 test_182b() {
19472         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19473         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19474         local dcount=1000
19475         local tcount=10
19476         local stime
19477         local etime
19478         local delta
19479
19480         do_facet mds1 $LCTL list_param \
19481                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19482                 skip "MDS lacks parallel RPC handling"
19483
19484         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19485
19486         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19487                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19488
19489         stime=$(date +%s)
19490         createmany -i 0 -d $DIR/$tdir/t- $tcount
19491
19492         for (( i = 0; i < $tcount; i++ )) ; do
19493                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19494         done
19495         wait
19496         etime=$(date +%s)
19497         delta=$((etime - stime))
19498         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19499
19500         stime=$(date +%s)
19501         for (( i = 0; i < $tcount; i++ )) ; do
19502                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19503         done
19504         wait
19505         etime=$(date +%s)
19506         delta=$((etime - stime))
19507         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19508
19509         rm -rf $DIR/$tdir
19510
19511         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19512
19513         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19514
19515         stime=$(date +%s)
19516         createmany -i 0 -d $DIR/$tdir/t- $tcount
19517
19518         for (( i = 0; i < $tcount; i++ )) ; do
19519                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19520         done
19521         wait
19522         etime=$(date +%s)
19523         delta=$((etime - stime))
19524         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19525
19526         stime=$(date +%s)
19527         for (( i = 0; i < $tcount; i++ )) ; do
19528                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19529         done
19530         wait
19531         etime=$(date +%s)
19532         delta=$((etime - stime))
19533         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19534
19535         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19536 }
19537 run_test 182b "Test parallel modify metadata operations from osp"
19538
19539 test_183() { # LU-2275
19540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19541         remote_mds_nodsh && skip "remote MDS with nodsh"
19542         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19543                 skip "Need MDS version at least 2.3.56"
19544
19545         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19546         echo aaa > $DIR/$tdir/$tfile
19547
19548 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19549         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19550
19551         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19552         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19553
19554         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19555
19556         # Flush negative dentry cache
19557         touch $DIR/$tdir/$tfile
19558
19559         # We are not checking for any leaked references here, they'll
19560         # become evident next time we do cleanup with module unload.
19561         rm -rf $DIR/$tdir
19562 }
19563 run_test 183 "No crash or request leak in case of strange dispositions ========"
19564
19565 # test suite 184 is for LU-2016, LU-2017
19566 test_184a() {
19567         check_swap_layouts_support
19568
19569         dir0=$DIR/$tdir/$testnum
19570         test_mkdir -p -c1 $dir0
19571         ref1=/etc/passwd
19572         ref2=/etc/group
19573         file1=$dir0/f1
19574         file2=$dir0/f2
19575         $LFS setstripe -c1 $file1
19576         cp $ref1 $file1
19577         $LFS setstripe -c2 $file2
19578         cp $ref2 $file2
19579         gen1=$($LFS getstripe -g $file1)
19580         gen2=$($LFS getstripe -g $file2)
19581
19582         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19583         gen=$($LFS getstripe -g $file1)
19584         [[ $gen1 != $gen ]] ||
19585                 error "Layout generation on $file1 does not change"
19586         gen=$($LFS getstripe -g $file2)
19587         [[ $gen2 != $gen ]] ||
19588                 error "Layout generation on $file2 does not change"
19589
19590         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19591         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19592
19593         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19594 }
19595 run_test 184a "Basic layout swap"
19596
19597 test_184b() {
19598         check_swap_layouts_support
19599
19600         dir0=$DIR/$tdir/$testnum
19601         mkdir -p $dir0 || error "creating dir $dir0"
19602         file1=$dir0/f1
19603         file2=$dir0/f2
19604         file3=$dir0/f3
19605         dir1=$dir0/d1
19606         dir2=$dir0/d2
19607         mkdir $dir1 $dir2
19608         $LFS setstripe -c1 $file1
19609         $LFS setstripe -c2 $file2
19610         $LFS setstripe -c1 $file3
19611         chown $RUNAS_ID $file3
19612         gen1=$($LFS getstripe -g $file1)
19613         gen2=$($LFS getstripe -g $file2)
19614
19615         $LFS swap_layouts $dir1 $dir2 &&
19616                 error "swap of directories layouts should fail"
19617         $LFS swap_layouts $dir1 $file1 &&
19618                 error "swap of directory and file layouts should fail"
19619         $RUNAS $LFS swap_layouts $file1 $file2 &&
19620                 error "swap of file we cannot write should fail"
19621         $LFS swap_layouts $file1 $file3 &&
19622                 error "swap of file with different owner should fail"
19623         /bin/true # to clear error code
19624 }
19625 run_test 184b "Forbidden layout swap (will generate errors)"
19626
19627 test_184c() {
19628         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19629         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19630         check_swap_layouts_support
19631         check_swap_layout_no_dom $DIR
19632
19633         local dir0=$DIR/$tdir/$testnum
19634         mkdir -p $dir0 || error "creating dir $dir0"
19635
19636         local ref1=$dir0/ref1
19637         local ref2=$dir0/ref2
19638         local file1=$dir0/file1
19639         local file2=$dir0/file2
19640         # create a file large enough for the concurrent test
19641         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19642         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19643         echo "ref file size: ref1($(stat -c %s $ref1))," \
19644              "ref2($(stat -c %s $ref2))"
19645
19646         cp $ref2 $file2
19647         dd if=$ref1 of=$file1 bs=16k &
19648         local DD_PID=$!
19649
19650         # Make sure dd starts to copy file, but wait at most 5 seconds
19651         local loops=0
19652         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19653
19654         $LFS swap_layouts $file1 $file2
19655         local rc=$?
19656         wait $DD_PID
19657         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19658         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19659
19660         # how many bytes copied before swapping layout
19661         local copied=$(stat -c %s $file2)
19662         local remaining=$(stat -c %s $ref1)
19663         remaining=$((remaining - copied))
19664         echo "Copied $copied bytes before swapping layout..."
19665
19666         cmp -n $copied $file1 $ref2 | grep differ &&
19667                 error "Content mismatch [0, $copied) of ref2 and file1"
19668         cmp -n $copied $file2 $ref1 ||
19669                 error "Content mismatch [0, $copied) of ref1 and file2"
19670         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19671                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19672
19673         # clean up
19674         rm -f $ref1 $ref2 $file1 $file2
19675 }
19676 run_test 184c "Concurrent write and layout swap"
19677
19678 test_184d() {
19679         check_swap_layouts_support
19680         check_swap_layout_no_dom $DIR
19681         [ -z "$(which getfattr 2>/dev/null)" ] &&
19682                 skip_env "no getfattr command"
19683
19684         local file1=$DIR/$tdir/$tfile-1
19685         local file2=$DIR/$tdir/$tfile-2
19686         local file3=$DIR/$tdir/$tfile-3
19687         local lovea1
19688         local lovea2
19689
19690         mkdir -p $DIR/$tdir
19691         touch $file1 || error "create $file1 failed"
19692         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19693                 error "create $file2 failed"
19694         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19695                 error "create $file3 failed"
19696         lovea1=$(get_layout_param $file1)
19697
19698         $LFS swap_layouts $file2 $file3 ||
19699                 error "swap $file2 $file3 layouts failed"
19700         $LFS swap_layouts $file1 $file2 ||
19701                 error "swap $file1 $file2 layouts failed"
19702
19703         lovea2=$(get_layout_param $file2)
19704         echo "$lovea1"
19705         echo "$lovea2"
19706         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19707
19708         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19709         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19710 }
19711 run_test 184d "allow stripeless layouts swap"
19712
19713 test_184e() {
19714         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19715                 skip "Need MDS version at least 2.6.94"
19716         check_swap_layouts_support
19717         check_swap_layout_no_dom $DIR
19718         [ -z "$(which getfattr 2>/dev/null)" ] &&
19719                 skip_env "no getfattr command"
19720
19721         local file1=$DIR/$tdir/$tfile-1
19722         local file2=$DIR/$tdir/$tfile-2
19723         local file3=$DIR/$tdir/$tfile-3
19724         local lovea
19725
19726         mkdir -p $DIR/$tdir
19727         touch $file1 || error "create $file1 failed"
19728         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19729                 error "create $file2 failed"
19730         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19731                 error "create $file3 failed"
19732
19733         $LFS swap_layouts $file1 $file2 ||
19734                 error "swap $file1 $file2 layouts failed"
19735
19736         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19737         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19738
19739         echo 123 > $file1 || error "Should be able to write into $file1"
19740
19741         $LFS swap_layouts $file1 $file3 ||
19742                 error "swap $file1 $file3 layouts failed"
19743
19744         echo 123 > $file1 || error "Should be able to write into $file1"
19745
19746         rm -rf $file1 $file2 $file3
19747 }
19748 run_test 184e "Recreate layout after stripeless layout swaps"
19749
19750 test_184f() {
19751         # Create a file with name longer than sizeof(struct stat) ==
19752         # 144 to see if we can get chars from the file name to appear
19753         # in the returned striping. Note that 'f' == 0x66.
19754         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19755
19756         mkdir -p $DIR/$tdir
19757         mcreate $DIR/$tdir/$file
19758         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19759                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19760         fi
19761 }
19762 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19763
19764 test_185() { # LU-2441
19765         # LU-3553 - no volatile file support in old servers
19766         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19767                 skip "Need MDS version at least 2.3.60"
19768
19769         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19770         touch $DIR/$tdir/spoo
19771         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19772         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19773                 error "cannot create/write a volatile file"
19774         [ "$FILESET" == "" ] &&
19775         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19776                 error "FID is still valid after close"
19777
19778         multiop_bg_pause $DIR/$tdir Vw4096_c
19779         local multi_pid=$!
19780
19781         local OLD_IFS=$IFS
19782         IFS=":"
19783         local fidv=($fid)
19784         IFS=$OLD_IFS
19785         # assume that the next FID for this client is sequential, since stdout
19786         # is unfortunately eaten by multiop_bg_pause
19787         local n=$((${fidv[1]} + 1))
19788         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19789         if [ "$FILESET" == "" ]; then
19790                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19791                         error "FID is missing before close"
19792         fi
19793         kill -USR1 $multi_pid
19794         # 1 second delay, so if mtime change we will see it
19795         sleep 1
19796         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19797         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19798 }
19799 run_test 185 "Volatile file support"
19800
19801 function create_check_volatile() {
19802         local idx=$1
19803         local tgt
19804
19805         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19806         local PID=$!
19807         sleep 1
19808         local FID=$(cat /tmp/${tfile}.fid)
19809         [ "$FID" == "" ] && error "can't get FID for volatile"
19810         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19811         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19812         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19813         kill -USR1 $PID
19814         wait
19815         sleep 1
19816         cancel_lru_locks mdc # flush opencache
19817         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19818         return 0
19819 }
19820
19821 test_185a(){
19822         # LU-12516 - volatile creation via .lustre
19823         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19824                 skip "Need MDS version at least 2.3.55"
19825
19826         create_check_volatile 0
19827         [ $MDSCOUNT -lt 2 ] && return 0
19828
19829         # DNE case
19830         create_check_volatile 1
19831
19832         return 0
19833 }
19834 run_test 185a "Volatile file creation in .lustre/fid/"
19835
19836 test_187a() {
19837         remote_mds_nodsh && skip "remote MDS with nodsh"
19838         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19839                 skip "Need MDS version at least 2.3.0"
19840
19841         local dir0=$DIR/$tdir/$testnum
19842         mkdir -p $dir0 || error "creating dir $dir0"
19843
19844         local file=$dir0/file1
19845         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19846         stack_trap "rm -f $file"
19847         local dv1=$($LFS data_version $file)
19848         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19849         local dv2=$($LFS data_version $file)
19850         [[ $dv1 != $dv2 ]] ||
19851                 error "data version did not change on write $dv1 == $dv2"
19852 }
19853 run_test 187a "Test data version change"
19854
19855 test_187b() {
19856         remote_mds_nodsh && skip "remote MDS with nodsh"
19857         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19858                 skip "Need MDS version at least 2.3.0"
19859
19860         local dir0=$DIR/$tdir/$testnum
19861         mkdir -p $dir0 || error "creating dir $dir0"
19862
19863         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19864         [[ ${DV[0]} != ${DV[1]} ]] ||
19865                 error "data version did not change on write"\
19866                       " ${DV[0]} == ${DV[1]}"
19867
19868         # clean up
19869         rm -f $file1
19870 }
19871 run_test 187b "Test data version change on volatile file"
19872
19873 test_200() {
19874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19875         remote_mgs_nodsh && skip "remote MGS with nodsh"
19876         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19877
19878         local POOL=${POOL:-cea1}
19879         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19880         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19881         # Pool OST targets
19882         local first_ost=0
19883         local last_ost=$(($OSTCOUNT - 1))
19884         local ost_step=2
19885         local ost_list=$(seq $first_ost $ost_step $last_ost)
19886         local ost_range="$first_ost $last_ost $ost_step"
19887         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19888         local file_dir=$POOL_ROOT/file_tst
19889         local subdir=$test_path/subdir
19890         local rc=0
19891
19892         while : ; do
19893                 # former test_200a test_200b
19894                 pool_add $POOL                          || { rc=$? ; break; }
19895                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19896                 # former test_200c test_200d
19897                 mkdir -p $test_path
19898                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19899                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19900                 mkdir -p $subdir
19901                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19902                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19903                                                         || { rc=$? ; break; }
19904                 # former test_200e test_200f
19905                 local files=$((OSTCOUNT*3))
19906                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19907                                                         || { rc=$? ; break; }
19908                 pool_create_files $POOL $file_dir $files "$ost_list" \
19909                                                         || { rc=$? ; break; }
19910                 # former test_200g test_200h
19911                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19912                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19913
19914                 # former test_201a test_201b test_201c
19915                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19916
19917                 local f=$test_path/$tfile
19918                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19919                 pool_remove $POOL $f                    || { rc=$? ; break; }
19920                 break
19921         done
19922
19923         destroy_test_pools
19924
19925         return $rc
19926 }
19927 run_test 200 "OST pools"
19928
19929 # usage: default_attr <count | size | offset>
19930 default_attr() {
19931         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19932 }
19933
19934 # usage: check_default_stripe_attr
19935 check_default_stripe_attr() {
19936         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19937         case $1 in
19938         --stripe-count|-c)
19939                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19940         --stripe-size|-S)
19941                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19942         --stripe-index|-i)
19943                 EXPECTED=-1;;
19944         *)
19945                 error "unknown getstripe attr '$1'"
19946         esac
19947
19948         [ $ACTUAL == $EXPECTED ] ||
19949                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19950 }
19951
19952 test_204a() {
19953         test_mkdir $DIR/$tdir
19954         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19955
19956         check_default_stripe_attr --stripe-count
19957         check_default_stripe_attr --stripe-size
19958         check_default_stripe_attr --stripe-index
19959 }
19960 run_test 204a "Print default stripe attributes"
19961
19962 test_204b() {
19963         test_mkdir $DIR/$tdir
19964         $LFS setstripe --stripe-count 1 $DIR/$tdir
19965
19966         check_default_stripe_attr --stripe-size
19967         check_default_stripe_attr --stripe-index
19968 }
19969 run_test 204b "Print default stripe size and offset"
19970
19971 test_204c() {
19972         test_mkdir $DIR/$tdir
19973         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19974
19975         check_default_stripe_attr --stripe-count
19976         check_default_stripe_attr --stripe-index
19977 }
19978 run_test 204c "Print default stripe count and offset"
19979
19980 test_204d() {
19981         test_mkdir $DIR/$tdir
19982         $LFS setstripe --stripe-index 0 $DIR/$tdir
19983
19984         check_default_stripe_attr --stripe-count
19985         check_default_stripe_attr --stripe-size
19986 }
19987 run_test 204d "Print default stripe count and size"
19988
19989 test_204e() {
19990         test_mkdir $DIR/$tdir
19991         $LFS setstripe -d $DIR/$tdir
19992
19993         # LU-16904 check if root is set as PFL layout
19994         local numcomp=$($LFS getstripe --component-count $MOUNT)
19995
19996         if [[ $numcomp -gt 0 ]]; then
19997                 check_default_stripe_attr --stripe-count
19998         else
19999                 check_default_stripe_attr --stripe-count --raw
20000         fi
20001         check_default_stripe_attr --stripe-size --raw
20002         check_default_stripe_attr --stripe-index --raw
20003 }
20004 run_test 204e "Print raw stripe attributes"
20005
20006 test_204f() {
20007         test_mkdir $DIR/$tdir
20008         $LFS setstripe --stripe-count 1 $DIR/$tdir
20009
20010         check_default_stripe_attr --stripe-size --raw
20011         check_default_stripe_attr --stripe-index --raw
20012 }
20013 run_test 204f "Print raw stripe size and offset"
20014
20015 test_204g() {
20016         test_mkdir $DIR/$tdir
20017         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20018
20019         check_default_stripe_attr --stripe-count --raw
20020         check_default_stripe_attr --stripe-index --raw
20021 }
20022 run_test 204g "Print raw stripe count and offset"
20023
20024 test_204h() {
20025         test_mkdir $DIR/$tdir
20026         $LFS setstripe --stripe-index 0 $DIR/$tdir
20027
20028         check_default_stripe_attr --stripe-count --raw
20029         check_default_stripe_attr --stripe-size --raw
20030 }
20031 run_test 204h "Print raw stripe count and size"
20032
20033 # Figure out which job scheduler is being used, if any,
20034 # or use a fake one
20035 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20036         JOBENV=SLURM_JOB_ID
20037 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20038         JOBENV=LSB_JOBID
20039 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20040         JOBENV=PBS_JOBID
20041 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20042         JOBENV=LOADL_STEP_ID
20043 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20044         JOBENV=JOB_ID
20045 else
20046         $LCTL list_param jobid_name > /dev/null 2>&1
20047         if [ $? -eq 0 ]; then
20048                 JOBENV=nodelocal
20049         else
20050                 JOBENV=FAKE_JOBID
20051         fi
20052 fi
20053 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20054
20055 verify_jobstats() {
20056         local cmd=($1)
20057         shift
20058         local facets="$@"
20059
20060 # we don't really need to clear the stats for this test to work, since each
20061 # command has a unique jobid, but it makes debugging easier if needed.
20062 #       for facet in $facets; do
20063 #               local dev=$(convert_facet2label $facet)
20064 #               # clear old jobstats
20065 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20066 #       done
20067
20068         # use a new JobID for each test, or we might see an old one
20069         [ "$JOBENV" = "FAKE_JOBID" ] &&
20070                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20071
20072         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20073
20074         [ "$JOBENV" = "nodelocal" ] && {
20075                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20076                 $LCTL set_param jobid_name=$FAKE_JOBID
20077                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20078         }
20079
20080         log "Test: ${cmd[*]}"
20081         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20082
20083         if [ $JOBENV = "FAKE_JOBID" ]; then
20084                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20085         else
20086                 ${cmd[*]}
20087         fi
20088
20089         # all files are created on OST0000
20090         for facet in $facets; do
20091                 local stats="*.$(convert_facet2label $facet).job_stats"
20092
20093                 # strip out libtool wrappers for in-tree executables
20094                 if (( $(do_facet $facet lctl get_param $stats |
20095                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20096                         do_facet $facet lctl get_param $stats
20097                         error "No jobstats for $JOBVAL found on $facet::$stats"
20098                 fi
20099         done
20100 }
20101
20102 jobstats_set() {
20103         local new_jobenv=$1
20104
20105         set_persistent_param_and_check client "jobid_var" \
20106                 "$FSNAME.sys.jobid_var" $new_jobenv
20107 }
20108
20109 test_205a() { # Job stats
20110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20111         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20112                 skip "Need MDS version with at least 2.7.1"
20113         remote_mgs_nodsh && skip "remote MGS with nodsh"
20114         remote_mds_nodsh && skip "remote MDS with nodsh"
20115         remote_ost_nodsh && skip "remote OST with nodsh"
20116         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20117                 skip "Server doesn't support jobstats"
20118         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20119
20120         local old_jobenv=$($LCTL get_param -n jobid_var)
20121         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20122         stack_trap "jobstats_set $old_jobenv" EXIT
20123
20124         changelog_register
20125
20126         local old_jobid_name=$($LCTL get_param jobid_name)
20127         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20128
20129         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20130                                 mdt.*.job_cleanup_interval | head -n 1)
20131         local new_interval=5
20132         do_facet $SINGLEMDS \
20133                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20134         stack_trap "do_facet $SINGLEMDS \
20135                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20136         local start=$SECONDS
20137
20138         local cmd
20139         # mkdir
20140         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20141         verify_jobstats "$cmd" "$SINGLEMDS"
20142         # rmdir
20143         cmd="rmdir $DIR/$tdir"
20144         verify_jobstats "$cmd" "$SINGLEMDS"
20145         # mkdir on secondary MDT
20146         if [ $MDSCOUNT -gt 1 ]; then
20147                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20148                 verify_jobstats "$cmd" "mds2"
20149         fi
20150         # mknod
20151         cmd="mknod $DIR/$tfile c 1 3"
20152         verify_jobstats "$cmd" "$SINGLEMDS"
20153         # unlink
20154         cmd="rm -f $DIR/$tfile"
20155         verify_jobstats "$cmd" "$SINGLEMDS"
20156         # create all files on OST0000 so verify_jobstats can find OST stats
20157         # open & close
20158         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20159         verify_jobstats "$cmd" "$SINGLEMDS"
20160         # setattr
20161         cmd="touch $DIR/$tfile"
20162         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20163         # write
20164         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20165         verify_jobstats "$cmd" "ost1"
20166         # read
20167         cancel_lru_locks osc
20168         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20169         verify_jobstats "$cmd" "ost1"
20170         # truncate
20171         cmd="$TRUNCATE $DIR/$tfile 0"
20172         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20173         # rename
20174         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20175         verify_jobstats "$cmd" "$SINGLEMDS"
20176         # jobstats expiry - sleep until old stats should be expired
20177         local left=$((new_interval + 5 - (SECONDS - start)))
20178         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20179                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20180                         "0" $left
20181         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20182         verify_jobstats "$cmd" "$SINGLEMDS"
20183         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20184             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20185
20186         # Ensure that jobid are present in changelog (if supported by MDS)
20187         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20188                 changelog_dump | tail -10
20189                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20190                 [ $jobids -eq 9 ] ||
20191                         error "Wrong changelog jobid count $jobids != 9"
20192
20193                 # LU-5862
20194                 JOBENV="disable"
20195                 jobstats_set $JOBENV
20196                 touch $DIR/$tfile
20197                 changelog_dump | grep $tfile
20198                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20199                 [ $jobids -eq 0 ] ||
20200                         error "Unexpected jobids when jobid_var=$JOBENV"
20201         fi
20202
20203         # test '%j' access to environment variable - if supported
20204         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20205                 JOBENV="JOBCOMPLEX"
20206                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20207
20208                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20209         fi
20210
20211         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20212                 JOBENV="JOBCOMPLEX"
20213                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20214
20215                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20216         fi
20217
20218         # test '%j' access to per-session jobid - if supported
20219         if lctl list_param jobid_this_session > /dev/null 2>&1
20220         then
20221                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20222                 lctl set_param jobid_this_session=$USER
20223
20224                 JOBENV="JOBCOMPLEX"
20225                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20226
20227                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20228         fi
20229 }
20230 run_test 205a "Verify job stats"
20231
20232 # LU-13117, LU-13597, LU-16599
20233 test_205b() {
20234         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20235                 skip "Need MDS version at least 2.13.54.91"
20236
20237         local job_stats="mdt.*.job_stats"
20238         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20239
20240         do_facet mds1 $LCTL set_param $job_stats=clear
20241
20242         # Setting jobid_var to USER might not be supported
20243         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20244         $LCTL set_param jobid_var=USER || true
20245         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20246         $LCTL set_param jobid_name="%j.%e.%u"
20247
20248         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20249         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20250                 { do_facet mds1 $LCTL get_param $job_stats;
20251                   error "Unexpected jobid found"; }
20252         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20253                 { do_facet mds1 $LCTL get_param $job_stats;
20254                   error "wrong job_stats format found"; }
20255
20256         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20257                 echo "MDS does not yet escape jobid" && return 0
20258
20259         mkdir_on_mdt0 $DIR/$tdir
20260         $LCTL set_param jobid_var=TEST205b
20261         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20262         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20263                       awk '/has\\x20sp/ {print $3}')
20264         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20265                   error "jobid not escaped"; }
20266
20267         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20268                 # need to run such a command on mds1:
20269                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20270                 #
20271                 # there might be multiple MDTs on single mds server, so need to
20272                 # specifiy MDT0000. Or the command will fail due to other MDTs
20273                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20274                         error "cannot clear escaped jobid in job_stats";
20275         else
20276                 echo "MDS does not support clearing escaped jobid"
20277         fi
20278 }
20279 run_test 205b "Verify job stats jobid and output format"
20280
20281 # LU-13733
20282 test_205c() {
20283         $LCTL set_param llite.*.stats=0
20284         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20285         $LCTL get_param llite.*.stats
20286         $LCTL get_param llite.*.stats | grep \
20287                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20288                         error "wrong client stats format found"
20289 }
20290 run_test 205c "Verify client stats format"
20291
20292 test_205d() {
20293         local file=$DIR/$tdir/$tfile
20294
20295         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20296                 skip "need lustre >= 2.15.53 for lljobstat"
20297         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20298                 skip "need lustre >= 2.15.53 for lljobstat"
20299         verify_yaml_available || skip_env "YAML verification not installed"
20300
20301         test_mkdir -i 0 $DIR/$tdir
20302         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20303         stack_trap "rm -rf $DIR/$tdir"
20304
20305         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20306                 error "failed to write data to $file"
20307         mv $file $file.2
20308
20309         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20310         echo -n 'verify rename_stats...'
20311         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20312                 verify_yaml || error "rename_stats is not valid YAML"
20313         echo " OK"
20314
20315         echo -n 'verify mdt job_stats...'
20316         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20317                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20318         echo " OK"
20319
20320         echo -n 'verify ost job_stats...'
20321         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20322                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20323         echo " OK"
20324 }
20325 run_test 205d "verify the format of some stats files"
20326
20327 test_205e() {
20328         local ops_comma
20329         local file=$DIR/$tdir/$tfile
20330         local -a cli_params
20331
20332         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20333                 skip "need lustre >= 2.15.53 for lljobstat"
20334         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20335                 skip "need lustre >= 2.15.53 for lljobstat"
20336         verify_yaml_available || skip_env "YAML verification not installed"
20337
20338         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20339         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20340         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20341
20342         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20343         stack_trap "rm -rf $DIR/$tdir"
20344
20345         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20346                 error "failed to create $file on ost1"
20347         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20348                 error "failed to write data to $file"
20349
20350         do_facet mds1 "$LCTL get_param *.*.job_stats"
20351         do_facet ost1 "$LCTL get_param *.*.job_stats"
20352
20353         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20354         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20355                 error "The output of lljobstat is not an valid YAML"
20356
20357         # verify that job dd.0 does exist and has some ops on ost1
20358         # typically this line is like:
20359         # - 205e.dd.0:            {ops: 20, ...}
20360         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20361                     awk '$2=="205e.dd.0:" {print $4}')
20362
20363         (( ${ops_comma%,} >= 10 )) ||
20364                 error "cannot find job 205e.dd.0 with ops >= 10"
20365 }
20366 run_test 205e "verify the output of lljobstat"
20367
20368 test_205f() {
20369         verify_yaml_available || skip_env "YAML verification not installed"
20370
20371         # check both qos_ost_weights and qos_mdt_weights
20372         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20373         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20374                 error "qos_ost_weights is not valid YAML"
20375 }
20376 run_test 205f "verify qos_ost_weights YAML format "
20377
20378 __test_205_jobstats_dump() {
20379         local -a pids
20380         local nbr_instance=$1
20381
20382         while true; do
20383                 if (( ${#pids[@]} >= nbr_instance )); then
20384                         wait ${pids[@]}
20385                         pids=()
20386                 fi
20387
20388                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20389                 pids+=( $! )
20390         done
20391 }
20392
20393 __test_205_cleanup() {
20394         kill $@
20395         # Clear all job entries
20396         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20397 }
20398
20399 test_205g() {
20400         local -a mds1_params
20401         local -a cli_params
20402         local pids
20403         local interval=5
20404
20405         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20406         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20407         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20408
20409         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20410         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20411         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20412
20413         # start jobs loop
20414         export TEST205G_ID=205g
20415         stack_trap "unset TEST205G_ID" EXIT
20416         while true; do
20417                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20418         done & pids="$! "
20419
20420         __test_205_jobstats_dump 4 & pids+="$! "
20421         stack_trap "__test_205_cleanup $pids" EXIT INT
20422
20423         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20424 }
20425 run_test 205g "stress test for job_stats procfile"
20426
20427 test_205h() {
20428         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20429                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20430         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20431
20432         local dir=$DIR/$tdir
20433         local f=$dir/$tfile
20434         local f2=$dir/$tfile-2
20435         local f3=$dir/$tfile-3
20436         local subdir=$DIR/dir
20437         local val
20438
20439         local mdts=$(comma_list $(mdts_nodes))
20440         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20441         local client_saved=$($LCTL get_param -n jobid_var)
20442
20443         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20444         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20445
20446         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20447                 error "failed to set job_xattr parameter to user.job"
20448         $LCTL set_param jobid_var=procname.uid ||
20449                 error "failed to set jobid_var parameter"
20450
20451         test_mkdir $dir
20452
20453         touch $f
20454         val=$(getfattr -n user.job $f | grep user.job)
20455         [[ $val = user.job=\"touch.0\" ]] ||
20456                 error "expected user.job=\"touch.0\", got '$val'"
20457
20458         mkdir $subdir
20459         val=$(getfattr -n user.job $subdir | grep user.job)
20460         [[ $val = user.job=\"mkdir.0\" ]] ||
20461                 error "expected user.job=\"mkdir.0\", got '$val'"
20462
20463         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20464                 error "failed to set job_xattr parameter to NONE"
20465
20466         touch $f2
20467         val=$(getfattr -d $f2)
20468         [[ -z $val ]] ||
20469                 error "expected no user xattr, got '$val'"
20470
20471         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20472                 error "failed to set job_xattr parameter to trusted.job"
20473
20474         touch $f3
20475         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20476         [[ $val = trusted.job=\"touch.0\" ]] ||
20477                 error "expected trusted.job=\"touch.0\", got '$val'"
20478 }
20479 run_test 205h "check jobid xattr is stored correctly"
20480
20481 test_205i() {
20482         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20483                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20484
20485         local mdts=$(comma_list $(mdts_nodes))
20486         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20487
20488         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20489
20490         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20491                 error "failed to set mdt.*.job_xattr to user.1234567"
20492
20493         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20494                 error "failed to reject too long job_xattr name"
20495
20496         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20497                 error "failed to reject job_xattr name in bad format"
20498
20499         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20500                 error "failed to reject job_xattr name with invalid character"
20501
20502         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20503                         xargs $LCTL set_param" &&
20504                 error "failed to reject job_xattr name with non-ascii character"
20505
20506         return 0
20507 }
20508 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20509
20510 # LU-1480, LU-1773 and LU-1657
20511 test_206() {
20512         mkdir -p $DIR/$tdir
20513         $LFS setstripe -c -1 $DIR/$tdir
20514 #define OBD_FAIL_LOV_INIT 0x1403
20515         $LCTL set_param fail_loc=0xa0001403
20516         $LCTL set_param fail_val=1
20517         touch $DIR/$tdir/$tfile || true
20518 }
20519 run_test 206 "fail lov_init_raid0() doesn't lbug"
20520
20521 test_207a() {
20522         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20523         local fsz=`stat -c %s $DIR/$tfile`
20524         cancel_lru_locks mdc
20525
20526         # do not return layout in getattr intent
20527 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20528         $LCTL set_param fail_loc=0x170
20529         local sz=`stat -c %s $DIR/$tfile`
20530
20531         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20532
20533         rm -rf $DIR/$tfile
20534 }
20535 run_test 207a "can refresh layout at glimpse"
20536
20537 test_207b() {
20538         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20539         local cksum=`md5sum $DIR/$tfile`
20540         local fsz=`stat -c %s $DIR/$tfile`
20541         cancel_lru_locks mdc
20542         cancel_lru_locks osc
20543
20544         # do not return layout in getattr intent
20545 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20546         $LCTL set_param fail_loc=0x171
20547
20548         # it will refresh layout after the file is opened but before read issues
20549         echo checksum is "$cksum"
20550         echo "$cksum" |md5sum -c --quiet || error "file differs"
20551
20552         rm -rf $DIR/$tfile
20553 }
20554 run_test 207b "can refresh layout at open"
20555
20556 test_208() {
20557         # FIXME: in this test suite, only RD lease is used. This is okay
20558         # for now as only exclusive open is supported. After generic lease
20559         # is done, this test suite should be revised. - Jinshan
20560
20561         remote_mds_nodsh && skip "remote MDS with nodsh"
20562         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20563                 skip "Need MDS version at least 2.4.52"
20564
20565         echo "==== test 1: verify get lease work"
20566         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20567
20568         echo "==== test 2: verify lease can be broken by upcoming open"
20569         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20570         local PID=$!
20571         sleep 2
20572
20573         $MULTIOP $DIR/$tfile oO_RDWR:c
20574         kill -USR1 $PID && wait $PID || error "break lease error"
20575
20576         echo "==== test 3: verify lease can't be granted if an open already exists"
20577         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20578         local PID=$!
20579         sleep 2
20580
20581         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20582         kill -USR1 $PID && wait $PID || error "open file error"
20583
20584         echo "==== test 4: lease can sustain over recovery"
20585         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20586         PID=$!
20587         sleep 2
20588
20589         fail mds1
20590
20591         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20592
20593         echo "==== test 5: lease broken can't be regained by replay"
20594         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20595         PID=$!
20596         sleep 2
20597
20598         # open file to break lease and then recovery
20599         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20600         fail mds1
20601
20602         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20603
20604         rm -f $DIR/$tfile
20605 }
20606 run_test 208 "Exclusive open"
20607
20608 test_209() {
20609         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20610                 skip_env "must have disp_stripe"
20611
20612         touch $DIR/$tfile
20613         sync; sleep 5; sync;
20614
20615         echo 3 > /proc/sys/vm/drop_caches
20616         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20617                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20618         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20619
20620         # open/close 500 times
20621         for i in $(seq 500); do
20622                 cat $DIR/$tfile
20623         done
20624
20625         echo 3 > /proc/sys/vm/drop_caches
20626         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20627                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20628         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20629
20630         echo "before: $req_before, after: $req_after"
20631         [ $((req_after - req_before)) -ge 300 ] &&
20632                 error "open/close requests are not freed"
20633         return 0
20634 }
20635 run_test 209 "read-only open/close requests should be freed promptly"
20636
20637 test_210() {
20638         local pid
20639
20640         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20641         pid=$!
20642         sleep 1
20643
20644         $LFS getstripe $DIR/$tfile
20645         kill -USR1 $pid
20646         wait $pid || error "multiop failed"
20647
20648         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20649         pid=$!
20650         sleep 1
20651
20652         $LFS getstripe $DIR/$tfile
20653         kill -USR1 $pid
20654         wait $pid || error "multiop failed"
20655 }
20656 run_test 210 "lfs getstripe does not break leases"
20657
20658 function test_211() {
20659         local PID
20660         local id
20661         local rc
20662
20663         stack_trap "rm -f $DIR/$tfile" EXIT
20664         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20665                 error "can't create file"
20666         $LFS mirror extend -N $DIR/$tfile ||
20667                 error "can't create a replica"
20668         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20669         $LFS getstripe $DIR/$tfile
20670         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20671         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20672
20673         $MULTIOP $DIR/$tfile OeW_E+eUc &
20674         PID=$!
20675         sleep 0.3
20676
20677         id=$($LFS getstripe $DIR/$tfile |
20678                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20679         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20680                 error "removed last in-sync replica?"
20681
20682         kill -USR1 $PID
20683         wait $PID
20684         (( $? == 0 )) || error "failed split broke the lease"
20685 }
20686 run_test 211 "failed mirror split doesn't break write lease"
20687
20688 test_212() {
20689         size=`date +%s`
20690         size=$((size % 8192 + 1))
20691         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20692         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20693         rm -f $DIR/f212 $DIR/f212.xyz
20694 }
20695 run_test 212 "Sendfile test ============================================"
20696
20697 test_213() {
20698         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20699         cancel_lru_locks osc
20700         lctl set_param fail_loc=0x8000040f
20701         # generate a read lock
20702         cat $DIR/$tfile > /dev/null
20703         # write to the file, it will try to cancel the above read lock.
20704         cat /etc/hosts >> $DIR/$tfile
20705 }
20706 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20707
20708 test_214() { # for bug 20133
20709         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20710         for (( i=0; i < 340; i++ )) ; do
20711                 touch $DIR/$tdir/d214c/a$i
20712         done
20713
20714         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20715         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20716         ls $DIR/d214c || error "ls $DIR/d214c failed"
20717         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20718         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20719 }
20720 run_test 214 "hash-indexed directory test - bug 20133"
20721
20722 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20723 create_lnet_proc_files() {
20724         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20725 }
20726
20727 # counterpart of create_lnet_proc_files
20728 remove_lnet_proc_files() {
20729         rm -f $TMP/lnet_$1.sys
20730 }
20731
20732 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20733 # 3rd arg as regexp for body
20734 check_lnet_proc_stats() {
20735         local l=$(cat "$TMP/lnet_$1" |wc -l)
20736         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20737
20738         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20739 }
20740
20741 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20742 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20743 # optional and can be regexp for 2nd line (lnet.routes case)
20744 check_lnet_proc_entry() {
20745         local blp=2          # blp stands for 'position of 1st line of body'
20746         [ -z "$5" ] || blp=3 # lnet.routes case
20747
20748         local l=$(cat "$TMP/lnet_$1" |wc -l)
20749         # subtracting one from $blp because the body can be empty
20750         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20751
20752         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20753                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20754
20755         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20756                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20757
20758         # bail out if any unexpected line happened
20759         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20760         [ "$?" != 0 ] || error "$2 misformatted"
20761 }
20762
20763 test_215() { # for bugs 18102, 21079, 21517
20764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20765
20766         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20767         local P='[1-9][0-9]*'           # positive numeric
20768         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20769         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20770         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20771         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20772
20773         local L1 # regexp for 1st line
20774         local L2 # regexp for 2nd line (optional)
20775         local BR # regexp for the rest (body)
20776
20777         # lnet.stats should look as 11 space-separated non-negative numerics
20778         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20779         create_lnet_proc_files "stats"
20780         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20781         remove_lnet_proc_files "stats"
20782
20783         # lnet.routes should look like this:
20784         # Routing disabled/enabled
20785         # net hops priority state router
20786         # where net is a string like tcp0, hops > 0, priority >= 0,
20787         # state is up/down,
20788         # router is a string like 192.168.1.1@tcp2
20789         L1="^Routing (disabled|enabled)$"
20790         L2="^net +hops +priority +state +router$"
20791         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20792         create_lnet_proc_files "routes"
20793         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20794         remove_lnet_proc_files "routes"
20795
20796         # lnet.routers should look like this:
20797         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20798         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20799         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20800         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20801         L1="^ref +rtr_ref +alive +router$"
20802         BR="^$P +$P +(up|down) +$NID$"
20803         create_lnet_proc_files "routers"
20804         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20805         remove_lnet_proc_files "routers"
20806
20807         # lnet.peers should look like this:
20808         # nid refs state last max rtr min tx min queue
20809         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20810         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20811         # numeric (0 or >0 or <0), queue >= 0.
20812         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20813         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20814         create_lnet_proc_files "peers"
20815         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20816         remove_lnet_proc_files "peers"
20817
20818         # lnet.buffers  should look like this:
20819         # pages count credits min
20820         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20821         L1="^pages +count +credits +min$"
20822         BR="^ +$N +$N +$I +$I$"
20823         create_lnet_proc_files "buffers"
20824         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20825         remove_lnet_proc_files "buffers"
20826
20827         # lnet.nis should look like this:
20828         # nid status alive refs peer rtr max tx min
20829         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20830         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20831         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20832         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20833         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20834         create_lnet_proc_files "nis"
20835         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20836         remove_lnet_proc_files "nis"
20837
20838         # can we successfully write to lnet.stats?
20839         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20840 }
20841 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20842
20843 test_216() { # bug 20317
20844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20845         remote_ost_nodsh && skip "remote OST with nodsh"
20846
20847         local node
20848         local facets=$(get_facets OST)
20849         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20850
20851         save_lustre_params client "osc.*.contention_seconds" > $p
20852         save_lustre_params $facets \
20853                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20854         save_lustre_params $facets \
20855                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20856         save_lustre_params $facets \
20857                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20858         clear_stats osc.*.osc_stats
20859
20860         # agressive lockless i/o settings
20861         do_nodes $(comma_list $(osts_nodes)) \
20862                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20863                         ldlm.namespaces.filter-*.contended_locks=0 \
20864                         ldlm.namespaces.filter-*.contention_seconds=60"
20865         lctl set_param -n osc.*.contention_seconds=60
20866
20867         $DIRECTIO write $DIR/$tfile 0 10 4096
20868         $CHECKSTAT -s 40960 $DIR/$tfile
20869
20870         # disable lockless i/o
20871         do_nodes $(comma_list $(osts_nodes)) \
20872                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20873                         ldlm.namespaces.filter-*.contended_locks=32 \
20874                         ldlm.namespaces.filter-*.contention_seconds=0"
20875         lctl set_param -n osc.*.contention_seconds=0
20876         clear_stats osc.*.osc_stats
20877
20878         dd if=/dev/zero of=$DIR/$tfile count=0
20879         $CHECKSTAT -s 0 $DIR/$tfile
20880
20881         restore_lustre_params <$p
20882         rm -f $p
20883         rm $DIR/$tfile
20884 }
20885 run_test 216 "check lockless direct write updates file size and kms correctly"
20886
20887 test_217() { # bug 22430
20888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20889
20890         local node
20891
20892         for node in $(nodes_list); do
20893                 local nid=$(host_nids_address $node $NETTYPE)
20894                 local node_ip=$(do_node $node getent ahostsv4 $node |
20895                                 awk '{ print $1; exit; }')
20896
20897                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20898                 # if hostname matches any NID, use hostname for better testing
20899                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20900                         echo "lctl ping node $node@$NETTYPE"
20901                         lctl ping $node@$NETTYPE
20902                 else # otherwise, at least test 'lctl ping' is working
20903                         echo "lctl ping nid $(h2nettype $nid)"
20904                         lctl ping $(h2nettype $nid)
20905                         echo "skipping $node (no hyphen detected)"
20906                 fi
20907         done
20908 }
20909 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20910
20911 test_218() {
20912         # do directio so as not to populate the page cache
20913         log "creating a 10 Mb file"
20914         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20915                 error "multiop failed while creating a file"
20916         log "starting reads"
20917         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20918         log "truncating the file"
20919         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20920                 error "multiop failed while truncating the file"
20921         log "killing dd"
20922         kill %+ || true # reads might have finished
20923         echo "wait until dd is finished"
20924         wait
20925         log "removing the temporary file"
20926         rm -rf $DIR/$tfile || error "tmp file removal failed"
20927 }
20928 run_test 218 "parallel read and truncate should not deadlock"
20929
20930 test_219() {
20931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20932
20933         # write one partial page
20934         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20935         # set no grant so vvp_io_commit_write will do sync write
20936         $LCTL set_param fail_loc=0x411
20937         # write a full page at the end of file
20938         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20939
20940         $LCTL set_param fail_loc=0
20941         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20942         $LCTL set_param fail_loc=0x411
20943         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20944
20945         # LU-4201
20946         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20947         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20948 }
20949 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20950
20951 test_220() { #LU-325
20952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20953         remote_ost_nodsh && skip "remote OST with nodsh"
20954         remote_mds_nodsh && skip "remote MDS with nodsh"
20955         remote_mgs_nodsh && skip "remote MGS with nodsh"
20956
20957         local OSTIDX=0
20958
20959         # create on MDT0000 so the last_id and next_id are correct
20960         mkdir_on_mdt0 $DIR/$tdir
20961         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20962         OST=${OST%_UUID}
20963
20964         # on the mdt's osc
20965         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20966         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20967                         osp.$mdtosc_proc1.prealloc_last_id)
20968         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20969                         osp.$mdtosc_proc1.prealloc_next_id)
20970
20971         $LFS df -i
20972
20973         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20974         #define OBD_FAIL_OST_ENOINO              0x229
20975         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20976         create_pool $FSNAME.$TESTNAME || return 1
20977         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20978
20979         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20980
20981         MDSOBJS=$((last_id - next_id))
20982         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20983
20984         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20985         echo "OST still has $count kbytes free"
20986
20987         echo "create $MDSOBJS files @next_id..."
20988         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20989
20990         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20991                         osp.$mdtosc_proc1.prealloc_last_id)
20992         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20993                         osp.$mdtosc_proc1.prealloc_next_id)
20994
20995         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20996         $LFS df -i
20997
20998         echo "cleanup..."
20999
21000         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21001         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21002
21003         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21004                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21005         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21006                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21007         echo "unlink $MDSOBJS files @$next_id..."
21008         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21009 }
21010 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21011
21012 test_221() {
21013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21014
21015         dd if=`which date` of=$MOUNT/date oflag=sync
21016         chmod +x $MOUNT/date
21017
21018         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21019         $LCTL set_param fail_loc=0x80001401
21020
21021         $MOUNT/date > /dev/null
21022         rm -f $MOUNT/date
21023 }
21024 run_test 221 "make sure fault and truncate race to not cause OOM"
21025
21026 test_222a () {
21027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21028
21029         rm -rf $DIR/$tdir
21030         test_mkdir $DIR/$tdir
21031         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21032         createmany -o $DIR/$tdir/$tfile 10
21033         cancel_lru_locks mdc
21034         cancel_lru_locks osc
21035         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21036         $LCTL set_param fail_loc=0x31a
21037         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21038         $LCTL set_param fail_loc=0
21039         rm -r $DIR/$tdir
21040 }
21041 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21042
21043 test_222b () {
21044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21045
21046         rm -rf $DIR/$tdir
21047         test_mkdir $DIR/$tdir
21048         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21049         createmany -o $DIR/$tdir/$tfile 10
21050         cancel_lru_locks mdc
21051         cancel_lru_locks osc
21052         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21053         $LCTL set_param fail_loc=0x31a
21054         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21055         $LCTL set_param fail_loc=0
21056 }
21057 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21058
21059 test_223 () {
21060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21061
21062         rm -rf $DIR/$tdir
21063         test_mkdir $DIR/$tdir
21064         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21065         createmany -o $DIR/$tdir/$tfile 10
21066         cancel_lru_locks mdc
21067         cancel_lru_locks osc
21068         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21069         $LCTL set_param fail_loc=0x31b
21070         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21071         $LCTL set_param fail_loc=0
21072         rm -r $DIR/$tdir
21073 }
21074 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21075
21076 test_224a() { # LU-1039, MRP-303
21077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21078         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21079         $LCTL set_param fail_loc=0x508
21080         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21081         $LCTL set_param fail_loc=0
21082         df $DIR
21083 }
21084 run_test 224a "Don't panic on bulk IO failure"
21085
21086 test_224bd_sub() { # LU-1039, MRP-303
21087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21088         local timeout=$1
21089
21090         shift
21091         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21092
21093         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21094
21095         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21096         cancel_lru_locks osc
21097         set_checksums 0
21098         stack_trap "set_checksums $ORIG_CSUM" EXIT
21099         local at_max_saved=0
21100
21101         # adaptive timeouts may prevent seeing the issue
21102         if at_is_enabled; then
21103                 at_max_saved=$(at_max_get mds)
21104                 at_max_set 0 mds client
21105                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21106         fi
21107
21108         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21109         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21110         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21111
21112         do_facet ost1 $LCTL set_param fail_loc=0
21113         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21114         df $DIR
21115 }
21116
21117 test_224b() {
21118         test_224bd_sub 3 error "dd failed"
21119 }
21120 run_test 224b "Don't panic on bulk IO failure"
21121
21122 test_224c() { # LU-6441
21123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21124         remote_mds_nodsh && skip "remote MDS with nodsh"
21125
21126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21127         save_writethrough $p
21128         set_cache writethrough on
21129
21130         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21131         local at_max=$($LCTL get_param -n at_max)
21132         local timeout=$($LCTL get_param -n timeout)
21133         local test_at="at_max"
21134         local param_at="$FSNAME.sys.at_max"
21135         local test_timeout="timeout"
21136         local param_timeout="$FSNAME.sys.timeout"
21137
21138         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21139
21140         set_persistent_param_and_check client "$test_at" "$param_at" 0
21141         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21142
21143         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21144         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21145         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21146         stack_trap "rm -f $DIR/$tfile"
21147         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21148         sync
21149         do_facet ost1 "$LCTL set_param fail_loc=0"
21150
21151         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21152         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21153                 $timeout
21154
21155         $LCTL set_param -n $pages_per_rpc
21156         restore_lustre_params < $p
21157         rm -f $p
21158 }
21159 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21160
21161 test_224d() { # LU-11169
21162         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21163 }
21164 run_test 224d "Don't corrupt data on bulk IO timeout"
21165
21166 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21167 test_225a () {
21168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21169         if [ -z ${MDSSURVEY} ]; then
21170                 skip_env "mds-survey not found"
21171         fi
21172         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21173                 skip "Need MDS version at least 2.2.51"
21174
21175         local mds=$(facet_host $SINGLEMDS)
21176         local target=$(do_nodes $mds 'lctl dl' |
21177                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21178
21179         local cmd1="file_count=1000 thrhi=4"
21180         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21181         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21182         local cmd="$cmd1 $cmd2 $cmd3"
21183
21184         rm -f ${TMP}/mds_survey*
21185         echo + $cmd
21186         eval $cmd || error "mds-survey with zero-stripe failed"
21187         cat ${TMP}/mds_survey*
21188         rm -f ${TMP}/mds_survey*
21189 }
21190 run_test 225a "Metadata survey sanity with zero-stripe"
21191
21192 test_225b () {
21193         if [ -z ${MDSSURVEY} ]; then
21194                 skip_env "mds-survey not found"
21195         fi
21196         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21197                 skip "Need MDS version at least 2.2.51"
21198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21199         remote_mds_nodsh && skip "remote MDS with nodsh"
21200         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21201                 skip_env "Need to mount OST to test"
21202         fi
21203
21204         local mds=$(facet_host $SINGLEMDS)
21205         local target=$(do_nodes $mds 'lctl dl' |
21206                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21207
21208         local cmd1="file_count=1000 thrhi=4"
21209         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21210         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21211         local cmd="$cmd1 $cmd2 $cmd3"
21212
21213         rm -f ${TMP}/mds_survey*
21214         echo + $cmd
21215         eval $cmd || error "mds-survey with stripe_count failed"
21216         cat ${TMP}/mds_survey*
21217         rm -f ${TMP}/mds_survey*
21218 }
21219 run_test 225b "Metadata survey sanity with stripe_count = 1"
21220
21221 mcreate_path2fid () {
21222         local mode=$1
21223         local major=$2
21224         local minor=$3
21225         local name=$4
21226         local desc=$5
21227         local path=$DIR/$tdir/$name
21228         local fid
21229         local rc
21230         local fid_path
21231
21232         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21233                 error "cannot create $desc"
21234
21235         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21236         rc=$?
21237         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21238
21239         fid_path=$($LFS fid2path $MOUNT $fid)
21240         rc=$?
21241         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21242
21243         [ "$path" == "$fid_path" ] ||
21244                 error "fid2path returned $fid_path, expected $path"
21245
21246         echo "pass with $path and $fid"
21247 }
21248
21249 test_226a () {
21250         rm -rf $DIR/$tdir
21251         mkdir -p $DIR/$tdir
21252
21253         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21254         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21255         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21256         mcreate_path2fid 0040666 0 0 dir "directory"
21257         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21258         mcreate_path2fid 0100666 0 0 file "regular file"
21259         mcreate_path2fid 0120666 0 0 link "symbolic link"
21260         mcreate_path2fid 0140666 0 0 sock "socket"
21261 }
21262 run_test 226a "call path2fid and fid2path on files of all type"
21263
21264 test_226b () {
21265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21266
21267         local MDTIDX=1
21268
21269         rm -rf $DIR/$tdir
21270         mkdir -p $DIR/$tdir
21271         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21272                 error "create remote directory failed"
21273         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21274         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21275                                 "character special file (null)"
21276         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21277                                 "character special file (no device)"
21278         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21279         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21280                                 "block special file (loop)"
21281         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21282         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21283         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21284 }
21285 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21286
21287 test_226c () {
21288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21289         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21290                 skip "Need MDS version at least 2.13.55"
21291
21292         local submnt=/mnt/submnt
21293         local srcfile=/etc/passwd
21294         local dstfile=$submnt/passwd
21295         local path
21296         local fid
21297
21298         rm -rf $DIR/$tdir
21299         rm -rf $submnt
21300         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21301                 error "create remote directory failed"
21302         mkdir -p $submnt || error "create $submnt failed"
21303         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21304                 error "mount $submnt failed"
21305         stack_trap "umount $submnt" EXIT
21306
21307         cp $srcfile $dstfile
21308         fid=$($LFS path2fid $dstfile)
21309         path=$($LFS fid2path $submnt "$fid")
21310         [ "$path" = "$dstfile" ] ||
21311                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21312 }
21313 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21314
21315 test_226d () {
21316         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21317                 skip "Need client at least version 2.15.57"
21318
21319         # Define First test dataset
21320         local testdirs_01=$DIR/$tdir
21321         local testdata_01=$testdirs_01/${tdir}_01
21322         local testresult_01=${tdir}_01
21323         # Define Second test dataset
21324         local testdirs_02=$DIR/$tdir/$tdir
21325         local testdata_02=$testdirs_02/${tdir}_02
21326         local testresult_02=${tdir}_02
21327         # Define third test dataset (top level)
21328         local testdata_03=$DIR/${tdir}_03
21329         local testresult_03=${tdir}_03
21330
21331         # Create first test dataset
21332         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21333         touch $testdata_01 || error "cannot create file $testdata_01"
21334
21335         # Create second test dataset
21336         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21337         touch $testdata_02 || error "cannot create file $testdata_02"
21338
21339         # Create third test dataset
21340         touch $testdata_03 || error "cannot create file $testdata_03"
21341
21342         local fid01=$($LFS getstripe -F "$testdata_01") ||
21343                 error "getstripe failed on $testdata_01"
21344         local fid02=$($LFS getstripe -F "$testdata_02") ||
21345                 error "getstripe failed on $testdata_01"
21346         local fid03=$($LFS getstripe -F "$testdata_03") ||
21347                 error "getstripe failed on $testdata_03"
21348
21349         # Verify only -n option
21350         local out1=$($LFS fid2path -n $DIR $fid01) ||
21351                 error "fid2path failed on $fid01"
21352         local out2=$($LFS fid2path -n $DIR $fid02) ||
21353                 error "fid2path failed on $fid02"
21354         local out3=$($LFS fid2path -n $DIR $fid03) ||
21355                 error "fid2path failed on $fid03"
21356
21357         [[ "$out1" == "$testresult_01" ]] ||
21358                 error "fid2path failed: Expected $testresult_01 got $out1"
21359         [[ "$out2" == "$testresult_02" ]] ||
21360                 error "fid2path failed: Expected $testresult_02 got $out2"
21361         [[ "$out3" == "$testresult_03" ]] ||
21362                 error "fid2path failed: Expected $testresult_03 got $out3"
21363
21364         # Verify with option -fn together
21365         out1=$($LFS fid2path -fn $DIR $fid01) ||
21366                 error "fid2path -fn failed on $fid01"
21367         out2=$($LFS fid2path -fn $DIR $fid02) ||
21368                 error "fid2path -fn failed on $fid02"
21369         out3=$($LFS fid2path -fn $DIR $fid03) ||
21370                 error "fid2path -fn failed on $fid03"
21371
21372         local tmpout=$(echo $out1 | cut -d" " -f2)
21373         [[ "$tmpout" == "$testresult_01" ]] ||
21374                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21375
21376         tmpout=$(echo $out2 | cut -d" " -f2)
21377         [[ "$tmpout" == "$testresult_02" ]] ||
21378                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21379
21380         tmpout=$(echo $out3 | cut -d" " -f2)
21381         [[ "$tmpout" == "$testresult_03" ]] ||
21382                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21383 }
21384 run_test 226d "verify fid2path with -n and -fn option"
21385
21386 test_226e () {
21387         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21388                 skip "Need client at least version 2.15.56"
21389
21390         # Define filename with 'newline' and a space
21391         local testfile="Test"$'\n'"file 01"
21392         # Define link name with multiple 'newline' and a space
21393         local linkfile="Link"$'\n'"file "$'\n'"01"
21394         # Remove prior hard link
21395         rm -f $DIR/"$linkfile"
21396
21397         # Create file
21398         touch $DIR/"$testfile"
21399         # Create link
21400         ln $DIR/"$testfile" $DIR/"$linkfile"
21401
21402         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21403                 error "getstripe failed on $DIR/$testfile"
21404
21405         # Call with -0 option
21406         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21407                 echo "FILE:" | grep -c "FILE:")
21408
21409         # With -0 option the output should be exactly 2 lines.
21410         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21411 }
21412 run_test 226e "Verify path2fid -0 option with newline and space"
21413
21414 # LU-1299 Executing or running ldd on a truncated executable does not
21415 # cause an out-of-memory condition.
21416 test_227() {
21417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21418         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21419
21420         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21421         chmod +x $MOUNT/date
21422
21423         $MOUNT/date > /dev/null
21424         ldd $MOUNT/date > /dev/null
21425         rm -f $MOUNT/date
21426 }
21427 run_test 227 "running truncated executable does not cause OOM"
21428
21429 # LU-1512 try to reuse idle OI blocks
21430 test_228a() {
21431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21432         remote_mds_nodsh && skip "remote MDS with nodsh"
21433         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21434
21435         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21436         local myDIR=$DIR/$tdir
21437
21438         mkdir -p $myDIR
21439         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21440         $LCTL set_param fail_loc=0x80001002
21441         createmany -o $myDIR/t- 10000
21442         $LCTL set_param fail_loc=0
21443         # The guard is current the largest FID holder
21444         touch $myDIR/guard
21445         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21446                     tr -d '[')
21447         local IDX=$(($SEQ % 64))
21448
21449         do_facet $SINGLEMDS sync
21450         # Make sure journal flushed.
21451         sleep 6
21452         local blk1=$(do_facet $SINGLEMDS \
21453                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21454                      grep Blockcount | awk '{print $4}')
21455
21456         # Remove old files, some OI blocks will become idle.
21457         unlinkmany $myDIR/t- 10000
21458         # Create new files, idle OI blocks should be reused.
21459         createmany -o $myDIR/t- 2000
21460         do_facet $SINGLEMDS sync
21461         # Make sure journal flushed.
21462         sleep 6
21463         local blk2=$(do_facet $SINGLEMDS \
21464                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21465                      grep Blockcount | awk '{print $4}')
21466
21467         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21468 }
21469 run_test 228a "try to reuse idle OI blocks"
21470
21471 test_228b() {
21472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21473         remote_mds_nodsh && skip "remote MDS with nodsh"
21474         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21475
21476         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21477         local myDIR=$DIR/$tdir
21478
21479         mkdir -p $myDIR
21480         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21481         $LCTL set_param fail_loc=0x80001002
21482         createmany -o $myDIR/t- 10000
21483         $LCTL set_param fail_loc=0
21484         # The guard is current the largest FID holder
21485         touch $myDIR/guard
21486         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21487                     tr -d '[')
21488         local IDX=$(($SEQ % 64))
21489
21490         do_facet $SINGLEMDS sync
21491         # Make sure journal flushed.
21492         sleep 6
21493         local blk1=$(do_facet $SINGLEMDS \
21494                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21495                      grep Blockcount | awk '{print $4}')
21496
21497         # Remove old files, some OI blocks will become idle.
21498         unlinkmany $myDIR/t- 10000
21499
21500         # stop the MDT
21501         stop $SINGLEMDS || error "Fail to stop MDT."
21502         # remount the MDT
21503         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21504                 error "Fail to start MDT."
21505
21506         client_up || error "Fail to df."
21507         # Create new files, idle OI blocks should be reused.
21508         createmany -o $myDIR/t- 2000
21509         do_facet $SINGLEMDS sync
21510         # Make sure journal flushed.
21511         sleep 6
21512         local blk2=$(do_facet $SINGLEMDS \
21513                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21514                      grep Blockcount | awk '{print $4}')
21515
21516         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21517 }
21518 run_test 228b "idle OI blocks can be reused after MDT restart"
21519
21520 #LU-1881
21521 test_228c() {
21522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21523         remote_mds_nodsh && skip "remote MDS with nodsh"
21524         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21525
21526         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21527         local myDIR=$DIR/$tdir
21528
21529         mkdir -p $myDIR
21530         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21531         $LCTL set_param fail_loc=0x80001002
21532         # 20000 files can guarantee there are index nodes in the OI file
21533         createmany -o $myDIR/t- 20000
21534         $LCTL set_param fail_loc=0
21535         # The guard is current the largest FID holder
21536         touch $myDIR/guard
21537         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21538                     tr -d '[')
21539         local IDX=$(($SEQ % 64))
21540
21541         do_facet $SINGLEMDS sync
21542         # Make sure journal flushed.
21543         sleep 6
21544         local blk1=$(do_facet $SINGLEMDS \
21545                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21546                      grep Blockcount | awk '{print $4}')
21547
21548         # Remove old files, some OI blocks will become idle.
21549         unlinkmany $myDIR/t- 20000
21550         rm -f $myDIR/guard
21551         # The OI file should become empty now
21552
21553         # Create new files, idle OI blocks should be reused.
21554         createmany -o $myDIR/t- 2000
21555         do_facet $SINGLEMDS sync
21556         # Make sure journal flushed.
21557         sleep 6
21558         local blk2=$(do_facet $SINGLEMDS \
21559                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21560                      grep Blockcount | awk '{print $4}')
21561
21562         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21563 }
21564 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21565
21566 test_229() { # LU-2482, LU-3448
21567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21568         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21569         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21570                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21571
21572         rm -f $DIR/$tfile
21573
21574         # Create a file with a released layout and stripe count 2.
21575         $MULTIOP $DIR/$tfile H2c ||
21576                 error "failed to create file with released layout"
21577
21578         $LFS getstripe -v $DIR/$tfile
21579
21580         local pattern=$($LFS getstripe -L $DIR/$tfile)
21581         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21582
21583         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21584                 error "getstripe"
21585         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21586         stat $DIR/$tfile || error "failed to stat released file"
21587
21588         chown $RUNAS_ID $DIR/$tfile ||
21589                 error "chown $RUNAS_ID $DIR/$tfile failed"
21590
21591         chgrp $RUNAS_ID $DIR/$tfile ||
21592                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21593
21594         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21595         rm $DIR/$tfile || error "failed to remove released file"
21596 }
21597 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21598
21599 test_230a() {
21600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21602         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21603                 skip "Need MDS version at least 2.11.52"
21604
21605         local MDTIDX=1
21606
21607         test_mkdir $DIR/$tdir
21608         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21609         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21610         [ $mdt_idx -ne 0 ] &&
21611                 error "create local directory on wrong MDT $mdt_idx"
21612
21613         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21614                         error "create remote directory failed"
21615         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21616         [ $mdt_idx -ne $MDTIDX ] &&
21617                 error "create remote directory on wrong MDT $mdt_idx"
21618
21619         createmany -o $DIR/$tdir/test_230/t- 10 ||
21620                 error "create files on remote directory failed"
21621         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21622         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21623         rm -r $DIR/$tdir || error "unlink remote directory failed"
21624 }
21625 run_test 230a "Create remote directory and files under the remote directory"
21626
21627 test_230b() {
21628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21629         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21630         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21631                 skip "Need MDS version at least 2.11.52"
21632
21633         local MDTIDX=1
21634         local mdt_index
21635         local i
21636         local file
21637         local pid
21638         local stripe_count
21639         local migrate_dir=$DIR/$tdir/migrate_dir
21640         local other_dir=$DIR/$tdir/other_dir
21641
21642         test_mkdir $DIR/$tdir
21643         test_mkdir -i0 -c1 $migrate_dir
21644         test_mkdir -i0 -c1 $other_dir
21645         for ((i=0; i<10; i++)); do
21646                 mkdir -p $migrate_dir/dir_${i}
21647                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21648                         error "create files under remote dir failed $i"
21649         done
21650
21651         cp /etc/passwd $migrate_dir/$tfile
21652         cp /etc/passwd $other_dir/$tfile
21653         chattr +SAD $migrate_dir
21654         chattr +SAD $migrate_dir/$tfile
21655
21656         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21657         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21658         local old_dir_mode=$(stat -c%f $migrate_dir)
21659         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21660
21661         mkdir -p $migrate_dir/dir_default_stripe2
21662         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21663         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21664
21665         mkdir -p $other_dir
21666         ln $migrate_dir/$tfile $other_dir/luna
21667         ln $migrate_dir/$tfile $migrate_dir/sofia
21668         ln $other_dir/$tfile $migrate_dir/david
21669         ln -s $migrate_dir/$tfile $other_dir/zachary
21670         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21671         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21672
21673         local len
21674         local lnktgt
21675
21676         # inline symlink
21677         for len in 58 59 60; do
21678                 lnktgt=$(str_repeat 'l' $len)
21679                 touch $migrate_dir/$lnktgt
21680                 ln -s $lnktgt $migrate_dir/${len}char_ln
21681         done
21682
21683         # PATH_MAX
21684         for len in 4094 4095; do
21685                 lnktgt=$(str_repeat 'l' $len)
21686                 ln -s $lnktgt $migrate_dir/${len}char_ln
21687         done
21688
21689         # NAME_MAX
21690         for len in 254 255; do
21691                 touch $migrate_dir/$(str_repeat 'l' $len)
21692         done
21693
21694         $LFS migrate -m $MDTIDX $migrate_dir ||
21695                 error "fails on migrating remote dir to MDT1"
21696
21697         echo "migratate to MDT1, then checking.."
21698         for ((i = 0; i < 10; i++)); do
21699                 for file in $(find $migrate_dir/dir_${i}); do
21700                         mdt_index=$($LFS getstripe -m $file)
21701                         # broken symlink getstripe will fail
21702                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21703                                 error "$file is not on MDT${MDTIDX}"
21704                 done
21705         done
21706
21707         # the multiple link file should still in MDT0
21708         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21709         [ $mdt_index == 0 ] ||
21710                 error "$file is not on MDT${MDTIDX}"
21711
21712         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21713         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21714                 error " expect $old_dir_flag get $new_dir_flag"
21715
21716         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21717         [ "$old_file_flag" = "$new_file_flag" ] ||
21718                 error " expect $old_file_flag get $new_file_flag"
21719
21720         local new_dir_mode=$(stat -c%f $migrate_dir)
21721         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21722                 error "expect mode $old_dir_mode get $new_dir_mode"
21723
21724         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21725         [ "$old_file_mode" = "$new_file_mode" ] ||
21726                 error "expect mode $old_file_mode get $new_file_mode"
21727
21728         diff /etc/passwd $migrate_dir/$tfile ||
21729                 error "$tfile different after migration"
21730
21731         diff /etc/passwd $other_dir/luna ||
21732                 error "luna different after migration"
21733
21734         diff /etc/passwd $migrate_dir/sofia ||
21735                 error "sofia different after migration"
21736
21737         diff /etc/passwd $migrate_dir/david ||
21738                 error "david different after migration"
21739
21740         diff /etc/passwd $other_dir/zachary ||
21741                 error "zachary different after migration"
21742
21743         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21744                 error "${tfile}_ln different after migration"
21745
21746         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21747                 error "${tfile}_ln_other different after migration"
21748
21749         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21750         [ $stripe_count = 2 ] ||
21751                 error "dir strpe_count $d != 2 after migration."
21752
21753         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21754         [ $stripe_count = 2 ] ||
21755                 error "file strpe_count $d != 2 after migration."
21756
21757         #migrate back to MDT0
21758         MDTIDX=0
21759
21760         $LFS migrate -m $MDTIDX $migrate_dir ||
21761                 error "fails on migrating remote dir to MDT0"
21762
21763         echo "migrate back to MDT0, checking.."
21764         for file in $(find $migrate_dir); do
21765                 mdt_index=$($LFS getstripe -m $file)
21766                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21767                         error "$file is not on MDT${MDTIDX}"
21768         done
21769
21770         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21771         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21772                 error " expect $old_dir_flag get $new_dir_flag"
21773
21774         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21775         [ "$old_file_flag" = "$new_file_flag" ] ||
21776                 error " expect $old_file_flag get $new_file_flag"
21777
21778         local new_dir_mode=$(stat -c%f $migrate_dir)
21779         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21780                 error "expect mode $old_dir_mode get $new_dir_mode"
21781
21782         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21783         [ "$old_file_mode" = "$new_file_mode" ] ||
21784                 error "expect mode $old_file_mode get $new_file_mode"
21785
21786         diff /etc/passwd ${migrate_dir}/$tfile ||
21787                 error "$tfile different after migration"
21788
21789         diff /etc/passwd ${other_dir}/luna ||
21790                 error "luna different after migration"
21791
21792         diff /etc/passwd ${migrate_dir}/sofia ||
21793                 error "sofia different after migration"
21794
21795         diff /etc/passwd ${other_dir}/zachary ||
21796                 error "zachary different after migration"
21797
21798         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21799                 error "${tfile}_ln different after migration"
21800
21801         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21802                 error "${tfile}_ln_other different after migration"
21803
21804         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21805         [ $stripe_count = 2 ] ||
21806                 error "dir strpe_count $d != 2 after migration."
21807
21808         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21809         [ $stripe_count = 2 ] ||
21810                 error "file strpe_count $d != 2 after migration."
21811
21812         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21813 }
21814 run_test 230b "migrate directory"
21815
21816 test_230c() {
21817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21819         remote_mds_nodsh && skip "remote MDS with nodsh"
21820         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21821                 skip "Need MDS version at least 2.11.52"
21822
21823         local MDTIDX=1
21824         local total=3
21825         local mdt_index
21826         local file
21827         local migrate_dir=$DIR/$tdir/migrate_dir
21828
21829         #If migrating directory fails in the middle, all entries of
21830         #the directory is still accessiable.
21831         test_mkdir $DIR/$tdir
21832         test_mkdir -i0 -c1 $migrate_dir
21833         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21834         stat $migrate_dir
21835         createmany -o $migrate_dir/f $total ||
21836                 error "create files under ${migrate_dir} failed"
21837
21838         # fail after migrating top dir, and this will fail only once, so the
21839         # first sub file migration will fail (currently f3), others succeed.
21840         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21841         do_facet mds1 lctl set_param fail_loc=0x1801
21842         local t=$(ls $migrate_dir | wc -l)
21843         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21844                 error "migrate should fail"
21845         local u=$(ls $migrate_dir | wc -l)
21846         [ "$u" == "$t" ] || error "$u != $t during migration"
21847
21848         # add new dir/file should succeed
21849         mkdir $migrate_dir/dir ||
21850                 error "mkdir failed under migrating directory"
21851         touch $migrate_dir/file ||
21852                 error "create file failed under migrating directory"
21853
21854         # add file with existing name should fail
21855         for file in $migrate_dir/f*; do
21856                 stat $file > /dev/null || error "stat $file failed"
21857                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21858                         error "open(O_CREAT|O_EXCL) $file should fail"
21859                 $MULTIOP $file m && error "create $file should fail"
21860                 touch $DIR/$tdir/remote_dir/$tfile ||
21861                         error "touch $tfile failed"
21862                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21863                         error "link $file should fail"
21864                 mdt_index=$($LFS getstripe -m $file)
21865                 if [ $mdt_index == 0 ]; then
21866                         # file failed to migrate is not allowed to rename to
21867                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21868                                 error "rename to $file should fail"
21869                 else
21870                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21871                                 error "rename to $file failed"
21872                 fi
21873                 echo hello >> $file || error "write $file failed"
21874         done
21875
21876         # resume migration with different options should fail
21877         $LFS migrate -m 0 $migrate_dir &&
21878                 error "migrate -m 0 $migrate_dir should fail"
21879
21880         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21881                 error "migrate -c 2 $migrate_dir should fail"
21882
21883         # resume migration should succeed
21884         $LFS migrate -m $MDTIDX $migrate_dir ||
21885                 error "migrate $migrate_dir failed"
21886
21887         echo "Finish migration, then checking.."
21888         for file in $(find $migrate_dir); do
21889                 mdt_index=$($LFS getstripe -m $file)
21890                 [ $mdt_index == $MDTIDX ] ||
21891                         error "$file is not on MDT${MDTIDX}"
21892         done
21893
21894         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21895 }
21896 run_test 230c "check directory accessiblity if migration failed"
21897
21898 test_230d() {
21899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21900         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21901         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21902                 skip "Need MDS version at least 2.11.52"
21903         # LU-11235
21904         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21905
21906         local migrate_dir=$DIR/$tdir/migrate_dir
21907         local old_index
21908         local new_index
21909         local old_count
21910         local new_count
21911         local new_hash
21912         local mdt_index
21913         local i
21914         local j
21915
21916         old_index=$((RANDOM % MDSCOUNT))
21917         old_count=$((MDSCOUNT - old_index))
21918         new_index=$((RANDOM % MDSCOUNT))
21919         new_count=$((MDSCOUNT - new_index))
21920         new_hash=1 # for all_char
21921
21922         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21923         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21924
21925         test_mkdir $DIR/$tdir
21926         test_mkdir -i $old_index -c $old_count $migrate_dir
21927
21928         for ((i=0; i<100; i++)); do
21929                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21930                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21931                         error "create files under remote dir failed $i"
21932         done
21933
21934         echo -n "Migrate from MDT$old_index "
21935         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21936         echo -n "to MDT$new_index"
21937         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21938         echo
21939
21940         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21941         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21942                 error "migrate remote dir error"
21943
21944         echo "Finish migration, then checking.."
21945         for file in $(find $migrate_dir -maxdepth 1); do
21946                 mdt_index=$($LFS getstripe -m $file)
21947                 if [ $mdt_index -lt $new_index ] ||
21948                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21949                         error "$file is on MDT$mdt_index"
21950                 fi
21951         done
21952
21953         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21954 }
21955 run_test 230d "check migrate big directory"
21956
21957 test_230e() {
21958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21959         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21960         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21961                 skip "Need MDS version at least 2.11.52"
21962
21963         local i
21964         local j
21965         local a_fid
21966         local b_fid
21967
21968         mkdir_on_mdt0 $DIR/$tdir
21969         mkdir $DIR/$tdir/migrate_dir
21970         mkdir $DIR/$tdir/other_dir
21971         touch $DIR/$tdir/migrate_dir/a
21972         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21973         ls $DIR/$tdir/other_dir
21974
21975         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21976                 error "migrate dir fails"
21977
21978         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21979         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21980
21981         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21982         [ $mdt_index == 0 ] || error "a is not on MDT0"
21983
21984         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21985                 error "migrate dir fails"
21986
21987         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21988         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21989
21990         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21991         [ $mdt_index == 1 ] || error "a is not on MDT1"
21992
21993         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21994         [ $mdt_index == 1 ] || error "b is not on MDT1"
21995
21996         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21997         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21998
21999         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22000
22001         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22002 }
22003 run_test 230e "migrate mulitple local link files"
22004
22005 test_230f() {
22006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22008         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22009                 skip "Need MDS version at least 2.11.52"
22010
22011         local a_fid
22012         local ln_fid
22013
22014         mkdir -p $DIR/$tdir
22015         mkdir $DIR/$tdir/migrate_dir
22016         $LFS mkdir -i1 $DIR/$tdir/other_dir
22017         touch $DIR/$tdir/migrate_dir/a
22018         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22019         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22020         ls $DIR/$tdir/other_dir
22021
22022         # a should be migrated to MDT1, since no other links on MDT0
22023         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22024                 error "#1 migrate dir fails"
22025         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22026         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22027         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22028         [ $mdt_index == 1 ] || error "a is not on MDT1"
22029
22030         # a should stay on MDT1, because it is a mulitple link file
22031         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22032                 error "#2 migrate dir fails"
22033         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22034         [ $mdt_index == 1 ] || error "a is not on MDT1"
22035
22036         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22037                 error "#3 migrate dir fails"
22038
22039         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22040         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22041         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22042
22043         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22044         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22045
22046         # a should be migrated to MDT0, since no other links on MDT1
22047         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22048                 error "#4 migrate dir fails"
22049         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22050         [ $mdt_index == 0 ] || error "a is not on MDT0"
22051
22052         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22053 }
22054 run_test 230f "migrate mulitple remote link files"
22055
22056 test_230g() {
22057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22059         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22060                 skip "Need MDS version at least 2.11.52"
22061
22062         mkdir -p $DIR/$tdir/migrate_dir
22063
22064         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22065                 error "migrating dir to non-exist MDT succeeds"
22066         true
22067 }
22068 run_test 230g "migrate dir to non-exist MDT"
22069
22070 test_230h() {
22071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22072         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22073         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22074                 skip "Need MDS version at least 2.11.52"
22075
22076         local mdt_index
22077
22078         mkdir -p $DIR/$tdir/migrate_dir
22079
22080         $LFS migrate -m1 $DIR &&
22081                 error "migrating mountpoint1 should fail"
22082
22083         $LFS migrate -m1 $DIR/$tdir/.. &&
22084                 error "migrating mountpoint2 should fail"
22085
22086         # same as mv
22087         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22088                 error "migrating $tdir/migrate_dir/.. should fail"
22089
22090         true
22091 }
22092 run_test 230h "migrate .. and root"
22093
22094 test_230i() {
22095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22097         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22098                 skip "Need MDS version at least 2.11.52"
22099
22100         mkdir -p $DIR/$tdir/migrate_dir
22101
22102         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22103                 error "migration fails with a tailing slash"
22104
22105         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22106                 error "migration fails with two tailing slashes"
22107 }
22108 run_test 230i "lfs migrate -m tolerates trailing slashes"
22109
22110 test_230j() {
22111         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22112         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22113                 skip "Need MDS version at least 2.11.52"
22114
22115         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22116         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22117                 error "create $tfile failed"
22118         cat /etc/passwd > $DIR/$tdir/$tfile
22119
22120         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22121
22122         cmp /etc/passwd $DIR/$tdir/$tfile ||
22123                 error "DoM file mismatch after migration"
22124 }
22125 run_test 230j "DoM file data not changed after dir migration"
22126
22127 test_230k() {
22128         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22129         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22130                 skip "Need MDS version at least 2.11.56"
22131
22132         local total=20
22133         local files_on_starting_mdt=0
22134
22135         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22136         $LFS getdirstripe $DIR/$tdir
22137         for i in $(seq $total); do
22138                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22139                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22140                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22141         done
22142
22143         echo "$files_on_starting_mdt files on MDT0"
22144
22145         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22146         $LFS getdirstripe $DIR/$tdir
22147
22148         files_on_starting_mdt=0
22149         for i in $(seq $total); do
22150                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22151                         error "file $tfile.$i mismatch after migration"
22152                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22153                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22154         done
22155
22156         echo "$files_on_starting_mdt files on MDT1 after migration"
22157         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22158
22159         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22160         $LFS getdirstripe $DIR/$tdir
22161
22162         files_on_starting_mdt=0
22163         for i in $(seq $total); do
22164                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22165                         error "file $tfile.$i mismatch after 2nd migration"
22166                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22167                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22168         done
22169
22170         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22171         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22172
22173         true
22174 }
22175 run_test 230k "file data not changed after dir migration"
22176
22177 test_230l() {
22178         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22179         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22180                 skip "Need MDS version at least 2.11.56"
22181
22182         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22183         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22184                 error "create files under remote dir failed $i"
22185         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22186 }
22187 run_test 230l "readdir between MDTs won't crash"
22188
22189 test_230m() {
22190         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22191         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22192                 skip "Need MDS version at least 2.11.56"
22193
22194         local MDTIDX=1
22195         local mig_dir=$DIR/$tdir/migrate_dir
22196         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22197         local shortstr="b"
22198         local val
22199
22200         echo "Creating files and dirs with xattrs"
22201         test_mkdir $DIR/$tdir
22202         test_mkdir -i0 -c1 $mig_dir
22203         mkdir $mig_dir/dir
22204         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22205                 error "cannot set xattr attr1 on dir"
22206         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22207                 error "cannot set xattr attr2 on dir"
22208         touch $mig_dir/dir/f0
22209         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22210                 error "cannot set xattr attr1 on file"
22211         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22212                 error "cannot set xattr attr2 on file"
22213         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22214         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22215         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22216         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22217         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22218         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22219         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22220         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22221         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22222
22223         echo "Migrating to MDT1"
22224         $LFS migrate -m $MDTIDX $mig_dir ||
22225                 error "fails on migrating dir to MDT1"
22226
22227         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22228         echo "Checking xattrs"
22229         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22230         [ "$val" = $longstr ] ||
22231                 error "expecting xattr1 $longstr on dir, found $val"
22232         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22233         [ "$val" = $shortstr ] ||
22234                 error "expecting xattr2 $shortstr on dir, found $val"
22235         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22236         [ "$val" = $longstr ] ||
22237                 error "expecting xattr1 $longstr on file, found $val"
22238         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22239         [ "$val" = $shortstr ] ||
22240                 error "expecting xattr2 $shortstr on file, found $val"
22241 }
22242 run_test 230m "xattrs not changed after dir migration"
22243
22244 test_230n() {
22245         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22246         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22247                 skip "Need MDS version at least 2.13.53"
22248
22249         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22250         cat /etc/hosts > $DIR/$tdir/$tfile
22251         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22252         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22253
22254         cmp /etc/hosts $DIR/$tdir/$tfile ||
22255                 error "File data mismatch after migration"
22256 }
22257 run_test 230n "Dir migration with mirrored file"
22258
22259 test_230o() {
22260         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22261         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22262                 skip "Need MDS version at least 2.13.52"
22263
22264         local mdts=$(comma_list $(mdts_nodes))
22265         local timeout=100
22266         local restripe_status
22267         local delta
22268         local i
22269
22270         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22271
22272         # in case "crush" hash type is not set
22273         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22274
22275         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22276                            mdt.*MDT0000.enable_dir_restripe)
22277         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22278         stack_trap "do_nodes $mdts $LCTL set_param \
22279                     mdt.*.enable_dir_restripe=$restripe_status"
22280
22281         mkdir $DIR/$tdir
22282         createmany -m $DIR/$tdir/f 100 ||
22283                 error "create files under remote dir failed $i"
22284         createmany -d $DIR/$tdir/d 100 ||
22285                 error "create dirs under remote dir failed $i"
22286
22287         for i in $(seq 2 $MDSCOUNT); do
22288                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22289                 $LFS setdirstripe -c $i $DIR/$tdir ||
22290                         error "split -c $i $tdir failed"
22291                 wait_update $HOSTNAME \
22292                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22293                         error "dir split not finished"
22294                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22295                         awk '/migrate/ {sum += $2} END { print sum }')
22296                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22297                 # delta is around total_files/stripe_count
22298                 (( $delta < 200 / (i - 1) + 4 )) ||
22299                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22300         done
22301 }
22302 run_test 230o "dir split"
22303
22304 test_230p() {
22305         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22306         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22307                 skip "Need MDS version at least 2.13.52"
22308
22309         local mdts=$(comma_list $(mdts_nodes))
22310         local timeout=100
22311         local restripe_status
22312         local delta
22313         local c
22314
22315         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22316
22317         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22318
22319         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22320                            mdt.*MDT0000.enable_dir_restripe)
22321         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22322         stack_trap "do_nodes $mdts $LCTL set_param \
22323                     mdt.*.enable_dir_restripe=$restripe_status"
22324
22325         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22326         createmany -m $DIR/$tdir/f 100 ||
22327                 error "create files under remote dir failed"
22328         createmany -d $DIR/$tdir/d 100 ||
22329                 error "create dirs under remote dir failed"
22330
22331         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22332                 local mdt_hash="crush"
22333
22334                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22335                 $LFS setdirstripe -c $c $DIR/$tdir ||
22336                         error "split -c $c $tdir failed"
22337                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22338                         mdt_hash="$mdt_hash,fixed"
22339                 elif [ $c -eq 1 ]; then
22340                         mdt_hash="none"
22341                 fi
22342                 wait_update $HOSTNAME \
22343                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22344                         error "dir merge not finished"
22345                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22346                         awk '/migrate/ {sum += $2} END { print sum }')
22347                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22348                 # delta is around total_files/stripe_count
22349                 (( delta < 200 / c + 4 )) ||
22350                         error "$delta files migrated >= $((200 / c + 4))"
22351         done
22352 }
22353 run_test 230p "dir merge"
22354
22355 test_230q() {
22356         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22357         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22358                 skip "Need MDS version at least 2.13.52"
22359
22360         local mdts=$(comma_list $(mdts_nodes))
22361         local saved_threshold=$(do_facet mds1 \
22362                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22363         local saved_delta=$(do_facet mds1 \
22364                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22365         local threshold=100
22366         local delta=2
22367         local total=0
22368         local stripe_count=0
22369         local stripe_index
22370         local nr_files
22371         local create
22372
22373         # test with fewer files on ZFS
22374         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22375
22376         stack_trap "do_nodes $mdts $LCTL set_param \
22377                     mdt.*.dir_split_count=$saved_threshold"
22378         stack_trap "do_nodes $mdts $LCTL set_param \
22379                     mdt.*.dir_split_delta=$saved_delta"
22380         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22381         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22382         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22383         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22384         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22385         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22386
22387         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22388         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22389
22390         create=$((threshold * 3 / 2))
22391         while [ $stripe_count -lt $MDSCOUNT ]; do
22392                 createmany -m $DIR/$tdir/f $total $create ||
22393                         error "create sub files failed"
22394                 stat $DIR/$tdir > /dev/null
22395                 total=$((total + create))
22396                 stripe_count=$((stripe_count + delta))
22397                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22398
22399                 wait_update $HOSTNAME \
22400                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22401                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22402
22403                 wait_update $HOSTNAME \
22404                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22405                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22406
22407                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22408                 echo "$nr_files/$total files on MDT$stripe_index after split"
22409                 # allow 10% margin of imbalance with crush hash
22410                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22411                         error "$nr_files files on MDT$stripe_index after split"
22412
22413                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22414                 [ $nr_files -eq $total ] ||
22415                         error "total sub files $nr_files != $total"
22416         done
22417
22418         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22419
22420         echo "fixed layout directory won't auto split"
22421         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22422         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22423                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22424         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22425                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22426 }
22427 run_test 230q "dir auto split"
22428
22429 test_230r() {
22430         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22431         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22432         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22433                 skip "Need MDS version at least 2.13.54"
22434
22435         # maximum amount of local locks:
22436         # parent striped dir - 2 locks
22437         # new stripe in parent to migrate to - 1 lock
22438         # source and target - 2 locks
22439         # Total 5 locks for regular file
22440         mkdir -p $DIR/$tdir
22441         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22442         touch $DIR/$tdir/dir1/eee
22443
22444         # create 4 hardlink for 4 more locks
22445         # Total: 9 locks > RS_MAX_LOCKS (8)
22446         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22447         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22448         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22449         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22450         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22451         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22452         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22453         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22454
22455         cancel_lru_locks mdc
22456
22457         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22458                 error "migrate dir fails"
22459
22460         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22461 }
22462 run_test 230r "migrate with too many local locks"
22463
22464 test_230s() {
22465         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22466                 skip "Need MDS version at least 2.14.52"
22467
22468         local mdts=$(comma_list $(mdts_nodes))
22469         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22470                                 mdt.*MDT0000.enable_dir_restripe)
22471
22472         stack_trap "do_nodes $mdts $LCTL set_param \
22473                     mdt.*.enable_dir_restripe=$restripe_status"
22474
22475         local st
22476         for st in 0 1; do
22477                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22478                 test_mkdir $DIR/$tdir
22479                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22480                         error "$LFS mkdir should return EEXIST if target exists"
22481                 rmdir $DIR/$tdir
22482         done
22483 }
22484 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22485
22486 test_230t()
22487 {
22488         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22489         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22490                 skip "Need MDS version at least 2.14.50"
22491
22492         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22493         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22494         $LFS project -p 1 -s $DIR/$tdir ||
22495                 error "set $tdir project id failed"
22496         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22497                 error "set subdir project id failed"
22498         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22499 }
22500 run_test 230t "migrate directory with project ID set"
22501
22502 test_230u()
22503 {
22504         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22505         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22506                 skip "Need MDS version at least 2.14.53"
22507
22508         local count
22509
22510         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22511         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22512         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22513         for i in $(seq 0 $((MDSCOUNT - 1))); do
22514                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22515                 echo "$count dirs migrated to MDT$i"
22516         done
22517         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22518         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22519 }
22520 run_test 230u "migrate directory by QOS"
22521
22522 test_230v()
22523 {
22524         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22525         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22526                 skip "Need MDS version at least 2.14.53"
22527
22528         local count
22529
22530         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22531         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22532         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22533         for i in $(seq 0 $((MDSCOUNT - 1))); do
22534                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22535                 echo "$count subdirs migrated to MDT$i"
22536                 (( i == 3 )) && (( count > 0 )) &&
22537                         error "subdir shouldn't be migrated to MDT3"
22538         done
22539         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22540         (( count == 3 )) || error "dirs migrated to $count MDTs"
22541 }
22542 run_test 230v "subdir migrated to the MDT where its parent is located"
22543
22544 test_230w() {
22545         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22546         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22547                 skip "Need MDS version at least 2.15.0"
22548
22549         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22550         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22551         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22552
22553         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22554                 error "migrate failed"
22555
22556         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22557                 error "$tdir stripe count mismatch"
22558
22559         for i in $(seq 0 9); do
22560                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22561                         error "d$i is striped"
22562         done
22563 }
22564 run_test 230w "non-recursive mode dir migration"
22565
22566 test_230x() {
22567         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22568         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22569                 skip "Need MDS version at least 2.15.0"
22570
22571         mkdir -p $DIR/$tdir || error "mkdir failed"
22572         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22573
22574         local mdt_name=$(mdtname_from_index 0)
22575         local low=$(do_facet mds2 $LCTL get_param -n \
22576                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22577         local high=$(do_facet mds2 $LCTL get_param -n \
22578                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22579         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22580         local maxage=$(do_facet mds2 $LCTL get_param -n \
22581                 osp.*$mdt_name-osp-MDT0001.maxage)
22582
22583         stack_trap "do_facet mds2 $LCTL set_param -n \
22584                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22585                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22586         stack_trap "do_facet mds2 $LCTL set_param -n \
22587                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22588
22589         do_facet mds2 $LCTL set_param -n \
22590                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22591         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22592         sleep 4
22593         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22594                 error "migrate $tdir should fail"
22595
22596         do_facet mds2 $LCTL set_param -n \
22597                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22598         do_facet mds2 $LCTL set_param -n \
22599                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22600         sleep 4
22601         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22602                 error "migrate failed"
22603         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22604                 error "$tdir stripe count mismatch"
22605 }
22606 run_test 230x "dir migration check space"
22607
22608 test_230y() {
22609         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22610         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22611                 skip "Need MDS version at least 2.15.55.45"
22612
22613         local pid
22614
22615         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22616         $LFS getdirstripe $DIR/$tdir
22617         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22618         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22619         pid=$!
22620         sleep 1
22621
22622         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22623         do_facet mds2 lctl set_param fail_loc=0x1802
22624
22625         wait $pid
22626         do_facet mds2 lctl set_param fail_loc=0
22627         $LFS getdirstripe $DIR/$tdir
22628         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22629         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22630 }
22631 run_test 230y "unlink dir with bad hash type"
22632
22633 test_230z() {
22634         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22635         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22636                 skip "Need MDS version at least 2.15.55.45"
22637
22638         local pid
22639
22640         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22641         $LFS getdirstripe $DIR/$tdir
22642         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22643         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22644         pid=$!
22645         sleep 1
22646
22647         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22648         do_facet mds2 lctl set_param fail_loc=0x1802
22649
22650         wait $pid
22651         do_facet mds2 lctl set_param fail_loc=0
22652         $LFS getdirstripe $DIR/$tdir
22653
22654         # resume migration
22655         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22656                 error "resume migration failed"
22657         $LFS getdirstripe $DIR/$tdir
22658         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22659                 error "migration is not finished"
22660 }
22661 run_test 230z "resume dir migration with bad hash type"
22662
22663 test_231a()
22664 {
22665         # For simplicity this test assumes that max_pages_per_rpc
22666         # is the same across all OSCs
22667         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22668         local bulk_size=$((max_pages * PAGE_SIZE))
22669         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22670                                        head -n 1)
22671
22672         mkdir -p $DIR/$tdir
22673         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22674                 error "failed to set stripe with -S ${brw_size}M option"
22675         stack_trap "rm -rf $DIR/$tdir"
22676
22677         # clear the OSC stats
22678         $LCTL set_param osc.*.stats=0 &>/dev/null
22679         stop_writeback
22680
22681         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22682         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22683                 oflag=direct &>/dev/null || error "dd failed"
22684
22685         sync; sleep 1; sync # just to be safe
22686         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22687         if [ x$nrpcs != "x1" ]; then
22688                 $LCTL get_param osc.*.stats
22689                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22690         fi
22691
22692         start_writeback
22693         # Drop the OSC cache, otherwise we will read from it
22694         cancel_lru_locks osc
22695
22696         # clear the OSC stats
22697         $LCTL set_param osc.*.stats=0 &>/dev/null
22698
22699         # Client reads $bulk_size.
22700         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22701                 iflag=direct &>/dev/null || error "dd failed"
22702
22703         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22704         if [ x$nrpcs != "x1" ]; then
22705                 $LCTL get_param osc.*.stats
22706                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22707         fi
22708 }
22709 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22710
22711 test_231b() {
22712         mkdir -p $DIR/$tdir
22713         stack_trap "rm -rf $DIR/$tdir"
22714         local i
22715         for i in {0..1023}; do
22716                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22717                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22718                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22719         done
22720         sync
22721 }
22722 run_test 231b "must not assert on fully utilized OST request buffer"
22723
22724 test_232a() {
22725         mkdir -p $DIR/$tdir
22726         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22727
22728         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22729         do_facet ost1 $LCTL set_param fail_loc=0x31c
22730
22731         # ignore dd failure
22732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22733         stack_trap "rm -f $DIR/$tdir/$tfile"
22734
22735         do_facet ost1 $LCTL set_param fail_loc=0
22736         umount_client $MOUNT || error "umount failed"
22737         mount_client $MOUNT || error "mount failed"
22738         stop ost1 || error "cannot stop ost1"
22739         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22740 }
22741 run_test 232a "failed lock should not block umount"
22742
22743 test_232b() {
22744         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22745                 skip "Need MDS version at least 2.10.58"
22746
22747         mkdir -p $DIR/$tdir
22748         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22749         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22750         stack_trap "rm -f $DIR/$tdir/$tfile"
22751         sync
22752         cancel_lru_locks osc
22753
22754         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22755         do_facet ost1 $LCTL set_param fail_loc=0x31c
22756
22757         # ignore failure
22758         $LFS data_version $DIR/$tdir/$tfile || true
22759
22760         do_facet ost1 $LCTL set_param fail_loc=0
22761         umount_client $MOUNT || error "umount failed"
22762         mount_client $MOUNT || error "mount failed"
22763         stop ost1 || error "cannot stop ost1"
22764         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22765 }
22766 run_test 232b "failed data version lock should not block umount"
22767
22768 test_233a() {
22769         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22770                 skip "Need MDS version at least 2.3.64"
22771         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22772
22773         local fid=$($LFS path2fid $MOUNT)
22774
22775         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22776                 error "cannot access $MOUNT using its FID '$fid'"
22777 }
22778 run_test 233a "checking that OBF of the FS root succeeds"
22779
22780 test_233b() {
22781         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22782                 skip "Need MDS version at least 2.5.90"
22783         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22784
22785         local fid=$($LFS path2fid $MOUNT/.lustre)
22786
22787         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22788                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22789
22790         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22791         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22792                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22793 }
22794 run_test 233b "checking that OBF of the FS .lustre succeeds"
22795
22796 test_234() {
22797         local p="$TMP/sanityN-$TESTNAME.parameters"
22798         save_lustre_params client "llite.*.xattr_cache" > $p
22799         lctl set_param llite.*.xattr_cache 1 ||
22800                 skip_env "xattr cache is not supported"
22801
22802         mkdir -p $DIR/$tdir || error "mkdir failed"
22803         touch $DIR/$tdir/$tfile || error "touch failed"
22804         # OBD_FAIL_LLITE_XATTR_ENOMEM
22805         $LCTL set_param fail_loc=0x1405
22806         getfattr -n user.attr $DIR/$tdir/$tfile &&
22807                 error "getfattr should have failed with ENOMEM"
22808         $LCTL set_param fail_loc=0x0
22809         rm -rf $DIR/$tdir
22810
22811         restore_lustre_params < $p
22812         rm -f $p
22813 }
22814 run_test 234 "xattr cache should not crash on ENOMEM"
22815
22816 test_235() {
22817         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22818                 skip "Need MDS version at least 2.4.52"
22819
22820         flock_deadlock $DIR/$tfile
22821         local RC=$?
22822         case $RC in
22823                 0)
22824                 ;;
22825                 124) error "process hangs on a deadlock"
22826                 ;;
22827                 *) error "error executing flock_deadlock $DIR/$tfile"
22828                 ;;
22829         esac
22830 }
22831 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22832
22833 #LU-2935
22834 test_236() {
22835         check_swap_layouts_support
22836
22837         local ref1=/etc/passwd
22838         local ref2=/etc/group
22839         local file1=$DIR/$tdir/f1
22840         local file2=$DIR/$tdir/f2
22841
22842         test_mkdir -c1 $DIR/$tdir
22843         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22844         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22845         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22846         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22847         local fd=$(free_fd)
22848         local cmd="exec $fd<>$file2"
22849         eval $cmd
22850         rm $file2
22851         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22852                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22853         cmd="exec $fd>&-"
22854         eval $cmd
22855         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22856
22857         #cleanup
22858         rm -rf $DIR/$tdir
22859 }
22860 run_test 236 "Layout swap on open unlinked file"
22861
22862 # LU-4659 linkea consistency
22863 test_238() {
22864         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22865                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22866                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22867                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22868
22869         touch $DIR/$tfile
22870         ln $DIR/$tfile $DIR/$tfile.lnk
22871         touch $DIR/$tfile.new
22872         mv $DIR/$tfile.new $DIR/$tfile
22873         local fid1=$($LFS path2fid $DIR/$tfile)
22874         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22875         local path1=$($LFS fid2path $FSNAME "$fid1")
22876         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22877         local path2=$($LFS fid2path $FSNAME "$fid2")
22878         [ $tfile.lnk == $path2 ] ||
22879                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22880         rm -f $DIR/$tfile*
22881 }
22882 run_test 238 "Verify linkea consistency"
22883
22884 test_239A() { # was test_239
22885         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22886                 skip "Need MDS version at least 2.5.60"
22887
22888         local list=$(comma_list $(mdts_nodes))
22889
22890         mkdir -p $DIR/$tdir
22891         createmany -o $DIR/$tdir/f- 5000
22892         unlinkmany $DIR/$tdir/f- 5000
22893         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22894                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22895         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22896                         osp.*MDT*.sync_in_flight" | calc_sum)
22897         [ "$changes" -eq 0 ] || error "$changes not synced"
22898 }
22899 run_test 239A "osp_sync test"
22900
22901 test_239a() { #LU-5297
22902         remote_mds_nodsh && skip "remote MDS with nodsh"
22903
22904         touch $DIR/$tfile
22905         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22906         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22907         chgrp $RUNAS_GID $DIR/$tfile
22908         wait_delete_completed
22909 }
22910 run_test 239a "process invalid osp sync record correctly"
22911
22912 test_239b() { #LU-5297
22913         remote_mds_nodsh && skip "remote MDS with nodsh"
22914
22915         touch $DIR/$tfile1
22916         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22917         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22918         chgrp $RUNAS_GID $DIR/$tfile1
22919         wait_delete_completed
22920         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22921         touch $DIR/$tfile2
22922         chgrp $RUNAS_GID $DIR/$tfile2
22923         wait_delete_completed
22924 }
22925 run_test 239b "process osp sync record with ENOMEM error correctly"
22926
22927 test_240() {
22928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22929         remote_mds_nodsh && skip "remote MDS with nodsh"
22930
22931         mkdir -p $DIR/$tdir
22932
22933         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22934                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22935         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22936                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22937
22938         umount_client $MOUNT || error "umount failed"
22939         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22940         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22941         mount_client $MOUNT || error "failed to mount client"
22942
22943         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22944         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22945 }
22946 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22947
22948 test_241_bio() {
22949         local count=$1
22950         local bsize=$2
22951
22952         for LOOP in $(seq $count); do
22953                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22954                 cancel_lru_locks $OSC || true
22955         done
22956 }
22957
22958 test_241_dio() {
22959         local count=$1
22960         local bsize=$2
22961
22962         for LOOP in $(seq $1); do
22963                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22964                         2>/dev/null
22965         done
22966 }
22967
22968 test_241a() { # was test_241
22969         local bsize=$PAGE_SIZE
22970
22971         (( bsize < 40960 )) && bsize=40960
22972         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22973         ls -la $DIR/$tfile
22974         cancel_lru_locks $OSC
22975         test_241_bio 1000 $bsize &
22976         PID=$!
22977         test_241_dio 1000 $bsize
22978         wait $PID
22979 }
22980 run_test 241a "bio vs dio"
22981
22982 test_241b() {
22983         local bsize=$PAGE_SIZE
22984
22985         (( bsize < 40960 )) && bsize=40960
22986         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22987         ls -la $DIR/$tfile
22988         test_241_dio 1000 $bsize &
22989         PID=$!
22990         test_241_dio 1000 $bsize
22991         wait $PID
22992 }
22993 run_test 241b "dio vs dio"
22994
22995 test_242() {
22996         remote_mds_nodsh && skip "remote MDS with nodsh"
22997
22998         mkdir_on_mdt0 $DIR/$tdir
22999         touch $DIR/$tdir/$tfile
23000
23001         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23002         do_facet mds1 lctl set_param fail_loc=0x105
23003         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23004
23005         do_facet mds1 lctl set_param fail_loc=0
23006         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23007 }
23008 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23009
23010 test_243()
23011 {
23012         test_mkdir $DIR/$tdir
23013         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23014 }
23015 run_test 243 "various group lock tests"
23016
23017 test_244a()
23018 {
23019         test_mkdir $DIR/$tdir
23020         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23021         sendfile_grouplock $DIR/$tdir/$tfile || \
23022                 error "sendfile+grouplock failed"
23023         rm -rf $DIR/$tdir
23024 }
23025 run_test 244a "sendfile with group lock tests"
23026
23027 test_244b()
23028 {
23029         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23030
23031         local threads=50
23032         local size=$((1024*1024))
23033
23034         test_mkdir $DIR/$tdir
23035         for i in $(seq 1 $threads); do
23036                 local file=$DIR/$tdir/file_$((i / 10))
23037                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23038                 local pids[$i]=$!
23039         done
23040         for i in $(seq 1 $threads); do
23041                 wait ${pids[$i]}
23042         done
23043 }
23044 run_test 244b "multi-threaded write with group lock"
23045
23046 test_245a() {
23047         local flagname="multi_mod_rpcs"
23048         local connect_data_name="max_mod_rpcs"
23049         local out
23050
23051         # check if multiple modify RPCs flag is set
23052         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23053                 grep "connect_flags:")
23054         echo "$out"
23055
23056         echo "$out" | grep -qw $flagname
23057         if [ $? -ne 0 ]; then
23058                 echo "connect flag $flagname is not set"
23059                 return
23060         fi
23061
23062         # check if multiple modify RPCs data is set
23063         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23064         echo "$out"
23065
23066         echo "$out" | grep -qw $connect_data_name ||
23067                 error "import should have connect data $connect_data_name"
23068 }
23069 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23070
23071 test_245b() {
23072         local flagname="multi_mod_rpcs"
23073         local connect_data_name="max_mod_rpcs"
23074         local out
23075
23076         remote_mds_nodsh && skip "remote MDS with nodsh"
23077         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23078
23079         # check if multiple modify RPCs flag is set
23080         out=$(do_facet mds1 \
23081               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23082               grep "connect_flags:")
23083         echo "$out"
23084
23085         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23086
23087         # check if multiple modify RPCs data is set
23088         out=$(do_facet mds1 \
23089               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23090
23091         [[ "$out" =~ $connect_data_name ]] ||
23092                 {
23093                         echo "$out"
23094                         error "missing connect data $connect_data_name"
23095                 }
23096 }
23097 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23098
23099 cleanup_247() {
23100         local submount=$1
23101
23102         trap 0
23103         umount_client $submount
23104         rmdir $submount
23105 }
23106
23107 test_247a() {
23108         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23109                 grep -q subtree ||
23110                 skip_env "Fileset feature is not supported"
23111
23112         local submount=${MOUNT}_$tdir
23113
23114         mkdir $MOUNT/$tdir
23115         mkdir -p $submount || error "mkdir $submount failed"
23116         FILESET="$FILESET/$tdir" mount_client $submount ||
23117                 error "mount $submount failed"
23118         trap "cleanup_247 $submount" EXIT
23119         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23120         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23121                 error "read $MOUNT/$tdir/$tfile failed"
23122         cleanup_247 $submount
23123 }
23124 run_test 247a "mount subdir as fileset"
23125
23126 test_247b() {
23127         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23128                 skip_env "Fileset feature is not supported"
23129
23130         local submount=${MOUNT}_$tdir
23131
23132         rm -rf $MOUNT/$tdir
23133         mkdir -p $submount || error "mkdir $submount failed"
23134         SKIP_FILESET=1
23135         FILESET="$FILESET/$tdir" mount_client $submount &&
23136                 error "mount $submount should fail"
23137         rmdir $submount
23138 }
23139 run_test 247b "mount subdir that dose not exist"
23140
23141 test_247c() {
23142         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23143                 skip_env "Fileset feature is not supported"
23144
23145         local submount=${MOUNT}_$tdir
23146
23147         mkdir -p $MOUNT/$tdir/dir1
23148         mkdir -p $submount || error "mkdir $submount failed"
23149         trap "cleanup_247 $submount" EXIT
23150         FILESET="$FILESET/$tdir" mount_client $submount ||
23151                 error "mount $submount failed"
23152         local fid=$($LFS path2fid $MOUNT/)
23153         $LFS fid2path $submount $fid && error "fid2path should fail"
23154         cleanup_247 $submount
23155 }
23156 run_test 247c "running fid2path outside subdirectory root"
23157
23158 test_247d() {
23159         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23160                 skip "Fileset feature is not supported"
23161
23162         local submount=${MOUNT}_$tdir
23163
23164         mkdir -p $MOUNT/$tdir/dir1
23165         mkdir -p $submount || error "mkdir $submount failed"
23166         FILESET="$FILESET/$tdir" mount_client $submount ||
23167                 error "mount $submount failed"
23168         trap "cleanup_247 $submount" EXIT
23169
23170         local td=$submount/dir1
23171         local fid=$($LFS path2fid $td)
23172         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23173
23174         # check that we get the same pathname back
23175         local rootpath
23176         local found
23177         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23178                 echo "$rootpath $fid"
23179                 found=$($LFS fid2path $rootpath "$fid")
23180                 [ -n "$found" ] || error "fid2path should succeed"
23181                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23182         done
23183         # check wrong root path format
23184         rootpath=$submount"_wrong"
23185         found=$($LFS fid2path $rootpath "$fid")
23186         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23187
23188         cleanup_247 $submount
23189 }
23190 run_test 247d "running fid2path inside subdirectory root"
23191
23192 # LU-8037
23193 test_247e() {
23194         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23195                 grep -q subtree ||
23196                 skip "Fileset feature is not supported"
23197
23198         local submount=${MOUNT}_$tdir
23199
23200         mkdir $MOUNT/$tdir
23201         mkdir -p $submount || error "mkdir $submount failed"
23202         FILESET="$FILESET/.." mount_client $submount &&
23203                 error "mount $submount should fail"
23204         rmdir $submount
23205 }
23206 run_test 247e "mount .. as fileset"
23207
23208 test_247f() {
23209         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23210         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23211                 skip "Need at least version 2.14.50.162"
23212         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23213                 skip "Fileset feature is not supported"
23214
23215         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23216         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23217                 error "mkdir remote failed"
23218         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23219                 error "mkdir remote/subdir failed"
23220         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23221                 error "mkdir striped failed"
23222         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23223
23224         local submount=${MOUNT}_$tdir
23225
23226         mkdir -p $submount || error "mkdir $submount failed"
23227         stack_trap "rmdir $submount"
23228
23229         local dir
23230         local fileset=$FILESET
23231         local mdts=$(comma_list $(mdts_nodes))
23232
23233         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23234         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23235                 $tdir/striped/subdir $tdir/striped/.; do
23236                 FILESET="$fileset/$dir" mount_client $submount ||
23237                         error "mount $dir failed"
23238                 umount_client $submount
23239         done
23240 }
23241 run_test 247f "mount striped or remote directory as fileset"
23242
23243 test_subdir_mount_lock()
23244 {
23245         local testdir=$1
23246         local submount=${MOUNT}_$(basename $testdir)
23247
23248         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23249
23250         mkdir -p $submount || error "mkdir $submount failed"
23251         stack_trap "rmdir $submount"
23252
23253         FILESET="$fileset/$testdir" mount_client $submount ||
23254                 error "mount $FILESET failed"
23255         stack_trap "umount $submount"
23256
23257         local mdts=$(comma_list $(mdts_nodes))
23258
23259         local nrpcs
23260
23261         stat $submount > /dev/null || error "stat $submount failed"
23262         cancel_lru_locks $MDC
23263         stat $submount > /dev/null || error "stat $submount failed"
23264         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23265         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23266         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23267         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23268                 awk '/getattr/ {sum += $2} END {print sum}')
23269
23270         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23271 }
23272
23273 test_247g() {
23274         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23275
23276         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23277                 error "mkdir $tdir failed"
23278         test_subdir_mount_lock $tdir
23279 }
23280 run_test 247g "striped directory submount revalidate ROOT from cache"
23281
23282 test_247h() {
23283         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23284         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23285                 skip "Need MDS version at least 2.15.51"
23286
23287         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23288         test_subdir_mount_lock $tdir
23289         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23290         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23291                 error "mkdir $tdir.1 failed"
23292         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23293 }
23294 run_test 247h "remote directory submount revalidate ROOT from cache"
23295
23296 test_248a() {
23297         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23298         [ -z "$fast_read_sav" ] && skip "no fast read support"
23299
23300         # create a large file for fast read verification
23301         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23302
23303         # make sure the file is created correctly
23304         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23305                 { rm -f $DIR/$tfile; skip "file creation error"; }
23306
23307         echo "Test 1: verify that fast read is 4 times faster on cache read"
23308
23309         # small read with fast read enabled
23310         $LCTL set_param -n llite.*.fast_read=1
23311         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23312                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23313                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23314         # small read with fast read disabled
23315         $LCTL set_param -n llite.*.fast_read=0
23316         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23317                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23318                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23319
23320         # verify that fast read is 4 times faster for cache read
23321         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23322                 error_not_in_vm "fast read was not 4 times faster: " \
23323                            "$t_fast vs $t_slow"
23324
23325         echo "Test 2: verify the performance between big and small read"
23326         $LCTL set_param -n llite.*.fast_read=1
23327
23328         # 1k non-cache read
23329         cancel_lru_locks osc
23330         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23331                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23332                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23333
23334         # 1M non-cache read
23335         cancel_lru_locks osc
23336         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23337                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23338                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23339
23340         # verify that big IO is not 4 times faster than small IO
23341         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23342                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23343
23344         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23345         rm -f $DIR/$tfile
23346 }
23347 run_test 248a "fast read verification"
23348
23349 test_248b() {
23350         # Default short_io_bytes=16384, try both smaller and larger sizes.
23351         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23352         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23353         echo "bs=53248 count=113 normal buffered write"
23354         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23355                 error "dd of initial data file failed"
23356         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23357
23358         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23359         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23360                 error "dd with sync normal writes failed"
23361         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23362
23363         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23364         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23365                 error "dd with sync small writes failed"
23366         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23367
23368         cancel_lru_locks osc
23369
23370         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23371         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23372         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23373         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23374                 iflag=direct || error "dd with O_DIRECT small read failed"
23375         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23376         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23377                 error "compare $TMP/$tfile.1 failed"
23378
23379         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23380         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23381
23382         # just to see what the maximum tunable value is, and test parsing
23383         echo "test invalid parameter 2MB"
23384         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23385                 error "too-large short_io_bytes allowed"
23386         echo "test maximum parameter 512KB"
23387         # if we can set a larger short_io_bytes, run test regardless of version
23388         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23389                 # older clients may not allow setting it this large, that's OK
23390                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23391                         skip "Need at least client version 2.13.50"
23392                 error "medium short_io_bytes failed"
23393         fi
23394         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23395         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23396
23397         echo "test large parameter 64KB"
23398         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23399         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23400
23401         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23402         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23403                 error "dd with sync large writes failed"
23404         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23405
23406         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23407         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23408         num=$((113 * 4096 / PAGE_SIZE))
23409         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23410         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23411                 error "dd with O_DIRECT large writes failed"
23412         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23413                 error "compare $DIR/$tfile.3 failed"
23414
23415         cancel_lru_locks osc
23416
23417         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23418         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23419                 error "dd with O_DIRECT large read failed"
23420         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23421                 error "compare $TMP/$tfile.2 failed"
23422
23423         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23424         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23425                 error "dd with O_DIRECT large read failed"
23426         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23427                 error "compare $TMP/$tfile.3 failed"
23428 }
23429 run_test 248b "test short_io read and write for both small and large sizes"
23430
23431 test_249() { # LU-7890
23432         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23433                 skip "Need at least version 2.8.54"
23434
23435         rm -f $DIR/$tfile
23436         $LFS setstripe -c 1 $DIR/$tfile
23437         # Offset 2T == 4k * 512M
23438         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23439                 error "dd to 2T offset failed"
23440 }
23441 run_test 249 "Write above 2T file size"
23442
23443 test_250() {
23444         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23445          && skip "no 16TB file size limit on ZFS"
23446
23447         $LFS setstripe -c 1 $DIR/$tfile
23448         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23449         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23450         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23451         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23452                 conv=notrunc,fsync && error "append succeeded"
23453         return 0
23454 }
23455 run_test 250 "Write above 16T limit"
23456
23457 test_251() {
23458         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23459
23460         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23461         #Skip once - writing the first stripe will succeed
23462         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23463         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23464                 error "short write happened"
23465
23466         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23467         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23468                 error "short read happened"
23469
23470         rm -f $DIR/$tfile
23471 }
23472 run_test 251 "Handling short read and write correctly"
23473
23474 test_252() {
23475         remote_mds_nodsh && skip "remote MDS with nodsh"
23476         remote_ost_nodsh && skip "remote OST with nodsh"
23477         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23478                 skip_env "ldiskfs only test"
23479         fi
23480
23481         local tgt
23482         local dev
23483         local out
23484         local uuid
23485         local num
23486         local gen
23487
23488         # check lr_reader on OST0000
23489         tgt=ost1
23490         dev=$(facet_device $tgt)
23491         out=$(do_facet $tgt $LR_READER $dev)
23492         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23493         echo "$out"
23494         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23495         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23496                 error "Invalid uuid returned by $LR_READER on target $tgt"
23497         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23498
23499         # check lr_reader -c on MDT0000
23500         tgt=mds1
23501         dev=$(facet_device $tgt)
23502         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23503                 skip "$LR_READER does not support additional options"
23504         fi
23505         out=$(do_facet $tgt $LR_READER -c $dev)
23506         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23507         echo "$out"
23508         num=$(echo "$out" | grep -c "mdtlov")
23509         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23510                 error "Invalid number of mdtlov clients returned by $LR_READER"
23511         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23512
23513         # check lr_reader -cr on MDT0000
23514         out=$(do_facet $tgt $LR_READER -cr $dev)
23515         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23516         echo "$out"
23517         echo "$out" | grep -q "^reply_data:$" ||
23518                 error "$LR_READER should have returned 'reply_data' section"
23519         num=$(echo "$out" | grep -c "client_generation")
23520         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23521 }
23522 run_test 252 "check lr_reader tool"
23523
23524 test_253() {
23525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23526         remote_mds_nodsh && skip "remote MDS with nodsh"
23527         remote_mgs_nodsh && skip "remote MGS with nodsh"
23528
23529         local ostidx=0
23530         local rc=0
23531         local ost_name=$(ostname_from_index $ostidx)
23532
23533         # on the mdt's osc
23534         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23535         do_facet $SINGLEMDS $LCTL get_param -n \
23536                 osp.$mdtosc_proc1.reserved_mb_high ||
23537                 skip  "remote MDS does not support reserved_mb_high"
23538
23539         rm -rf $DIR/$tdir
23540         wait_mds_ost_sync
23541         wait_delete_completed
23542         mkdir $DIR/$tdir
23543         stack_trap "rm -rf $DIR/$tdir"
23544
23545         pool_add $TESTNAME || error "Pool creation failed"
23546         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23547
23548         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23549                 error "Setstripe failed"
23550
23551         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23552
23553         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23554                     grep "watermarks")
23555         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23556
23557         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23558                         osp.$mdtosc_proc1.prealloc_status)
23559         echo "prealloc_status $oa_status"
23560
23561         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23562                 error "File creation should fail"
23563
23564         #object allocation was stopped, but we still able to append files
23565         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23566                 oflag=append || error "Append failed"
23567
23568         rm -f $DIR/$tdir/$tfile.0
23569
23570         # For this test, we want to delete the files we created to go out of
23571         # space but leave the watermark, so we remain nearly out of space
23572         ost_watermarks_enospc_delete_files $tfile $ostidx
23573
23574         wait_delete_completed
23575
23576         sleep_maxage
23577
23578         for i in $(seq 10 12); do
23579                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23580                         2>/dev/null || error "File creation failed after rm"
23581         done
23582
23583         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23584                         osp.$mdtosc_proc1.prealloc_status)
23585         echo "prealloc_status $oa_status"
23586
23587         if (( oa_status != 0 )); then
23588                 error "Object allocation still disable after rm"
23589         fi
23590 }
23591 run_test 253 "Check object allocation limit"
23592
23593 test_254() {
23594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23595         remote_mds_nodsh && skip "remote MDS with nodsh"
23596
23597         local mdt=$(facet_svc $SINGLEMDS)
23598
23599         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23600                 skip "MDS does not support changelog_size"
23601
23602         local cl_user
23603
23604         changelog_register || error "changelog_register failed"
23605
23606         changelog_clear 0 || error "changelog_clear failed"
23607
23608         local size1=$(do_facet $SINGLEMDS \
23609                       $LCTL get_param -n mdd.$mdt.changelog_size)
23610         echo "Changelog size $size1"
23611
23612         rm -rf $DIR/$tdir
23613         $LFS mkdir -i 0 $DIR/$tdir
23614         # change something
23615         mkdir -p $DIR/$tdir/pics/2008/zachy
23616         touch $DIR/$tdir/pics/2008/zachy/timestamp
23617         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23618         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23619         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23620         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23621         rm $DIR/$tdir/pics/desktop.jpg
23622
23623         local size2=$(do_facet $SINGLEMDS \
23624                       $LCTL get_param -n mdd.$mdt.changelog_size)
23625         echo "Changelog size after work $size2"
23626
23627         (( $size2 > $size1 )) ||
23628                 error "new Changelog size=$size2 less than old size=$size1"
23629 }
23630 run_test 254 "Check changelog size"
23631
23632 ladvise_no_type()
23633 {
23634         local type=$1
23635         local file=$2
23636
23637         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23638                 awk -F: '{print $2}' | grep $type > /dev/null
23639         if [ $? -ne 0 ]; then
23640                 return 0
23641         fi
23642         return 1
23643 }
23644
23645 ladvise_no_ioctl()
23646 {
23647         local file=$1
23648
23649         lfs ladvise -a willread $file > /dev/null 2>&1
23650         if [ $? -eq 0 ]; then
23651                 return 1
23652         fi
23653
23654         lfs ladvise -a willread $file 2>&1 |
23655                 grep "Inappropriate ioctl for device" > /dev/null
23656         if [ $? -eq 0 ]; then
23657                 return 0
23658         fi
23659         return 1
23660 }
23661
23662 percent() {
23663         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23664 }
23665
23666 # run a random read IO workload
23667 # usage: random_read_iops <filename> <filesize> <iosize>
23668 random_read_iops() {
23669         local file=$1
23670         local fsize=$2
23671         local iosize=${3:-4096}
23672
23673         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23674                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23675 }
23676
23677 drop_file_oss_cache() {
23678         local file="$1"
23679         local nodes="$2"
23680
23681         $LFS ladvise -a dontneed $file 2>/dev/null ||
23682                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23683 }
23684
23685 ladvise_willread_performance()
23686 {
23687         local repeat=10
23688         local average_origin=0
23689         local average_cache=0
23690         local average_ladvise=0
23691
23692         for ((i = 1; i <= $repeat; i++)); do
23693                 echo "Iter $i/$repeat: reading without willread hint"
23694                 cancel_lru_locks osc
23695                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23696                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23697                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23698                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23699
23700                 cancel_lru_locks osc
23701                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23702                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23703                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23704
23705                 cancel_lru_locks osc
23706                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23707                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23708                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23709                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23710                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23711         done
23712         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23713         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23714         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23715
23716         speedup_cache=$(percent $average_cache $average_origin)
23717         speedup_ladvise=$(percent $average_ladvise $average_origin)
23718
23719         echo "Average uncached read: $average_origin"
23720         echo "Average speedup with OSS cached read: " \
23721                 "$average_cache = +$speedup_cache%"
23722         echo "Average speedup with ladvise willread: " \
23723                 "$average_ladvise = +$speedup_ladvise%"
23724
23725         local lowest_speedup=20
23726         if (( ${average_cache%.*} < $lowest_speedup )); then
23727                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23728                      " got $average_cache%. Skipping ladvise willread check."
23729                 return 0
23730         fi
23731
23732         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23733         # it is still good to run until then to exercise 'ladvise willread'
23734         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23735                 [ "$ost1_FSTYPE" = "zfs" ] &&
23736                 echo "osd-zfs does not support dontneed or drop_caches" &&
23737                 return 0
23738
23739         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23740         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23741                 error_not_in_vm "Speedup with willread is less than " \
23742                         "$lowest_speedup%, got $average_ladvise%"
23743 }
23744
23745 test_255a() {
23746         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23747                 skip "lustre < 2.8.54 does not support ladvise "
23748         remote_ost_nodsh && skip "remote OST with nodsh"
23749
23750         stack_trap "rm -f $DIR/$tfile"
23751         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23752
23753         ladvise_no_type willread $DIR/$tfile &&
23754                 skip "willread ladvise is not supported"
23755
23756         ladvise_no_ioctl $DIR/$tfile &&
23757                 skip "ladvise ioctl is not supported"
23758
23759         local size_mb=100
23760         local size=$((size_mb * 1048576))
23761         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23762                 error "dd to $DIR/$tfile failed"
23763
23764         lfs ladvise -a willread $DIR/$tfile ||
23765                 error "Ladvise failed with no range argument"
23766
23767         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23768                 error "Ladvise failed with no -l or -e argument"
23769
23770         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23771                 error "Ladvise failed with only -e argument"
23772
23773         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23774                 error "Ladvise failed with only -l argument"
23775
23776         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23777                 error "End offset should not be smaller than start offset"
23778
23779         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23780                 error "End offset should not be equal to start offset"
23781
23782         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23783                 error "Ladvise failed with overflowing -s argument"
23784
23785         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23786                 error "Ladvise failed with overflowing -e argument"
23787
23788         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23789                 error "Ladvise failed with overflowing -l argument"
23790
23791         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23792                 error "Ladvise succeeded with conflicting -l and -e arguments"
23793
23794         echo "Synchronous ladvise should wait"
23795         local delay=8
23796 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23797         do_nodes $(comma_list $(osts_nodes)) \
23798                 $LCTL set_param fail_val=$delay fail_loc=0x237
23799         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23800                 $LCTL set_param fail_loc=0"
23801
23802         local start_ts=$SECONDS
23803         lfs ladvise -a willread $DIR/$tfile ||
23804                 error "Ladvise failed with no range argument"
23805         local end_ts=$SECONDS
23806         local inteval_ts=$((end_ts - start_ts))
23807
23808         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23809                 error "Synchronous advice didn't wait reply"
23810         fi
23811
23812         echo "Asynchronous ladvise shouldn't wait"
23813         local start_ts=$SECONDS
23814         lfs ladvise -a willread -b $DIR/$tfile ||
23815                 error "Ladvise failed with no range argument"
23816         local end_ts=$SECONDS
23817         local inteval_ts=$((end_ts - start_ts))
23818
23819         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23820                 error "Asynchronous advice blocked"
23821         fi
23822
23823         ladvise_willread_performance
23824 }
23825 run_test 255a "check 'lfs ladvise -a willread'"
23826
23827 facet_meminfo() {
23828         local facet=$1
23829         local info=$2
23830
23831         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23832 }
23833
23834 test_255b() {
23835         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23836                 skip "lustre < 2.8.54 does not support ladvise "
23837         remote_ost_nodsh && skip "remote OST with nodsh"
23838
23839         stack_trap "rm -f $DIR/$tfile"
23840         lfs setstripe -c 1 -i 0 $DIR/$tfile
23841
23842         ladvise_no_type dontneed $DIR/$tfile &&
23843                 skip "dontneed ladvise is not supported"
23844
23845         ladvise_no_ioctl $DIR/$tfile &&
23846                 skip "ladvise ioctl is not supported"
23847
23848         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23849                 [ "$ost1_FSTYPE" = "zfs" ] &&
23850                 skip "zfs-osd does not support 'ladvise dontneed'"
23851
23852         local size_mb=100
23853         local size=$((size_mb * 1048576))
23854         # In order to prevent disturbance of other processes, only check 3/4
23855         # of the memory usage
23856         local kibibytes=$((size_mb * 1024 * 3 / 4))
23857
23858         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23859                 error "dd to $DIR/$tfile failed"
23860
23861         #force write to complete before dropping OST cache & checking memory
23862         sync
23863
23864         local total=$(facet_meminfo ost1 MemTotal)
23865         echo "Total memory: $total KiB"
23866
23867         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23868         local before_read=$(facet_meminfo ost1 Cached)
23869         echo "Cache used before read: $before_read KiB"
23870
23871         lfs ladvise -a willread $DIR/$tfile ||
23872                 error "Ladvise willread failed"
23873         local after_read=$(facet_meminfo ost1 Cached)
23874         echo "Cache used after read: $after_read KiB"
23875
23876         lfs ladvise -a dontneed $DIR/$tfile ||
23877                 error "Ladvise dontneed again failed"
23878         local no_read=$(facet_meminfo ost1 Cached)
23879         echo "Cache used after dontneed ladvise: $no_read KiB"
23880
23881         if [ $total -lt $((before_read + kibibytes)) ]; then
23882                 echo "Memory is too small, abort checking"
23883                 return 0
23884         fi
23885
23886         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23887                 error "Ladvise willread should use more memory" \
23888                         "than $kibibytes KiB"
23889         fi
23890
23891         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23892                 error "Ladvise dontneed should release more memory" \
23893                         "than $kibibytes KiB"
23894         fi
23895 }
23896 run_test 255b "check 'lfs ladvise -a dontneed'"
23897
23898 test_255c() {
23899         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23900                 skip "lustre < 2.10.50 does not support lockahead"
23901
23902         local ost1_imp=$(get_osc_import_name client ost1)
23903         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23904                          cut -d'.' -f2)
23905         local count
23906         local new_count
23907         local difference
23908         local i
23909         local rc
23910
23911         test_mkdir -p $DIR/$tdir
23912         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23913
23914         #test 10 returns only success/failure
23915         i=10
23916         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23917         rc=$?
23918         if [ $rc -eq 255 ]; then
23919                 error "Ladvise test${i} failed, ${rc}"
23920         fi
23921
23922         #test 11 counts lock enqueue requests, all others count new locks
23923         i=11
23924         count=$(do_facet ost1 \
23925                 $LCTL get_param -n ost.OSS.ost.stats)
23926         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23927
23928         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23929         rc=$?
23930         if [ $rc -eq 255 ]; then
23931                 error "Ladvise test${i} failed, ${rc}"
23932         fi
23933
23934         new_count=$(do_facet ost1 \
23935                 $LCTL get_param -n ost.OSS.ost.stats)
23936         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23937                    awk '{ print $2 }')
23938
23939         difference="$((new_count - count))"
23940         if [ $difference -ne $rc ]; then
23941                 error "Ladvise test${i}, bad enqueue count, returned " \
23942                       "${rc}, actual ${difference}"
23943         fi
23944
23945         for i in $(seq 12 21); do
23946                 # If we do not do this, we run the risk of having too many
23947                 # locks and starting lock cancellation while we are checking
23948                 # lock counts.
23949                 cancel_lru_locks osc
23950
23951                 count=$($LCTL get_param -n \
23952                        ldlm.namespaces.$imp_name.lock_unused_count)
23953
23954                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23955                 rc=$?
23956                 if [ $rc -eq 255 ]; then
23957                         error "Ladvise test ${i} failed, ${rc}"
23958                 fi
23959
23960                 new_count=$($LCTL get_param -n \
23961                        ldlm.namespaces.$imp_name.lock_unused_count)
23962                 difference="$((new_count - count))"
23963
23964                 # Test 15 output is divided by 100 to map down to valid return
23965                 if [ $i -eq 15 ]; then
23966                         rc="$((rc * 100))"
23967                 fi
23968
23969                 if [ $difference -ne $rc ]; then
23970                         error "Ladvise test ${i}, bad lock count, returned " \
23971                               "${rc}, actual ${difference}"
23972                 fi
23973         done
23974
23975         #test 22 returns only success/failure
23976         i=22
23977         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23978         rc=$?
23979         if [ $rc -eq 255 ]; then
23980                 error "Ladvise test${i} failed, ${rc}"
23981         fi
23982 }
23983 run_test 255c "suite of ladvise lockahead tests"
23984
23985 test_256() {
23986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23987         remote_mds_nodsh && skip "remote MDS with nodsh"
23988         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23989         changelog_users $SINGLEMDS | grep "^cl" &&
23990                 skip "active changelog user"
23991
23992         local cl_user
23993         local cat_sl
23994         local mdt_dev
23995
23996         mdt_dev=$(facet_device $SINGLEMDS)
23997         echo $mdt_dev
23998
23999         changelog_register || error "changelog_register failed"
24000
24001         rm -rf $DIR/$tdir
24002         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24003
24004         changelog_clear 0 || error "changelog_clear failed"
24005
24006         # change something
24007         touch $DIR/$tdir/{1..10}
24008
24009         # stop the MDT
24010         stop $SINGLEMDS || error "Fail to stop MDT"
24011
24012         # remount the MDT
24013         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24014                 error "Fail to start MDT"
24015
24016         #after mount new plainllog is used
24017         touch $DIR/$tdir/{11..19}
24018         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24019         stack_trap "rm -f $tmpfile"
24020         cat_sl=$(do_facet $SINGLEMDS "sync; \
24021                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24022                  llog_reader $tmpfile | grep -c type=1064553b")
24023         do_facet $SINGLEMDS llog_reader $tmpfile
24024
24025         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24026
24027         changelog_clear 0 || error "changelog_clear failed"
24028
24029         cat_sl=$(do_facet $SINGLEMDS "sync; \
24030                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24031                  llog_reader $tmpfile | grep -c type=1064553b")
24032
24033         if (( cat_sl == 2 )); then
24034                 error "Empty plain llog was not deleted from changelog catalog"
24035         elif (( cat_sl != 1 )); then
24036                 error "Active plain llog shouldn't be deleted from catalog"
24037         fi
24038 }
24039 run_test 256 "Check llog delete for empty and not full state"
24040
24041 test_257() {
24042         remote_mds_nodsh && skip "remote MDS with nodsh"
24043         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24044                 skip "Need MDS version at least 2.8.55"
24045
24046         test_mkdir $DIR/$tdir
24047
24048         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24049                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24050         stat $DIR/$tdir
24051
24052 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24053         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24054         local facet=mds$((mdtidx + 1))
24055         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24056         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24057
24058         stop $facet || error "stop MDS failed"
24059         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24060                 error "start MDS fail"
24061         wait_recovery_complete $facet
24062 }
24063 run_test 257 "xattr locks are not lost"
24064
24065 # Verify we take the i_mutex when security requires it
24066 test_258a() {
24067 #define OBD_FAIL_IMUTEX_SEC 0x141c
24068         $LCTL set_param fail_loc=0x141c
24069         touch $DIR/$tfile
24070         chmod u+s $DIR/$tfile
24071         chmod a+rwx $DIR/$tfile
24072         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24073         RC=$?
24074         if [ $RC -ne 0 ]; then
24075                 error "error, failed to take i_mutex, rc=$?"
24076         fi
24077         rm -f $DIR/$tfile
24078 }
24079 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24080
24081 # Verify we do NOT take the i_mutex in the normal case
24082 test_258b() {
24083 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24084         $LCTL set_param fail_loc=0x141d
24085         touch $DIR/$tfile
24086         chmod a+rwx $DIR
24087         chmod a+rw $DIR/$tfile
24088         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24089         RC=$?
24090         if [ $RC -ne 0 ]; then
24091                 error "error, took i_mutex unnecessarily, rc=$?"
24092         fi
24093         rm -f $DIR/$tfile
24094
24095 }
24096 run_test 258b "verify i_mutex security behavior"
24097
24098 test_259() {
24099         local file=$DIR/$tfile
24100         local before
24101         local after
24102
24103         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24104
24105         stack_trap "rm -f $file" EXIT
24106
24107         wait_delete_completed
24108         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24109         echo "before: $before"
24110
24111         $LFS setstripe -i 0 -c 1 $file
24112         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24113         sync_all_data
24114         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24115         echo "after write: $after"
24116
24117 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24118         do_facet ost1 $LCTL set_param fail_loc=0x2301
24119         $TRUNCATE $file 0
24120         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24121         echo "after truncate: $after"
24122
24123         stop ost1
24124         do_facet ost1 $LCTL set_param fail_loc=0
24125         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24126         sleep 2
24127         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24128         echo "after restart: $after"
24129         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24130                 error "missing truncate?"
24131
24132         return 0
24133 }
24134 run_test 259 "crash at delayed truncate"
24135
24136 test_260() {
24137 #define OBD_FAIL_MDC_CLOSE               0x806
24138         $LCTL set_param fail_loc=0x80000806
24139         touch $DIR/$tfile
24140
24141 }
24142 run_test 260 "Check mdc_close fail"
24143
24144 ### Data-on-MDT sanity tests ###
24145 test_270a() {
24146         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24147                 skip "Need MDS version at least 2.10.55 for DoM"
24148
24149         # create DoM file
24150         local dom=$DIR/$tdir/dom_file
24151         local tmp=$DIR/$tdir/tmp_file
24152
24153         mkdir_on_mdt0 $DIR/$tdir
24154
24155         # basic checks for DoM component creation
24156         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24157                 error "Can set MDT layout to non-first entry"
24158
24159         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24160                 error "Can define multiple entries as MDT layout"
24161
24162         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24163
24164         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24165         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24166         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24167
24168         local mdtidx=$($LFS getstripe -m $dom)
24169         local mdtname=MDT$(printf %04x $mdtidx)
24170         local facet=mds$((mdtidx + 1))
24171         local space_check=1
24172
24173         # Skip free space checks with ZFS
24174         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24175
24176         # write
24177         sync
24178         local size_tmp=$((65536 * 3))
24179         local mdtfree1=$(do_facet $facet \
24180                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24181
24182         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24183         # check also direct IO along write
24184         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24185         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24186         sync
24187         cmp $tmp $dom || error "file data is different"
24188         [ $(stat -c%s $dom) == $size_tmp ] ||
24189                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24190         if [ $space_check == 1 ]; then
24191                 local mdtfree2=$(do_facet $facet \
24192                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24193
24194                 # increase in usage from by $size_tmp
24195                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24196                         error "MDT free space wrong after write: " \
24197                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24198         fi
24199
24200         # truncate
24201         local size_dom=10000
24202
24203         $TRUNCATE $dom $size_dom
24204         [ $(stat -c%s $dom) == $size_dom ] ||
24205                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24206         if [ $space_check == 1 ]; then
24207                 mdtfree1=$(do_facet $facet \
24208                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24209                 # decrease in usage from $size_tmp to new $size_dom
24210                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24211                   $(((size_tmp - size_dom) / 1024)) ] ||
24212                         error "MDT free space is wrong after truncate: " \
24213                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24214         fi
24215
24216         # append
24217         cat $tmp >> $dom
24218         sync
24219         size_dom=$((size_dom + size_tmp))
24220         [ $(stat -c%s $dom) == $size_dom ] ||
24221                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24222         if [ $space_check == 1 ]; then
24223                 mdtfree2=$(do_facet $facet \
24224                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24225                 # increase in usage by $size_tmp from previous
24226                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24227                         error "MDT free space is wrong after append: " \
24228                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24229         fi
24230
24231         # delete
24232         rm $dom
24233         if [ $space_check == 1 ]; then
24234                 mdtfree1=$(do_facet $facet \
24235                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24236                 # decrease in usage by $size_dom from previous
24237                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24238                         error "MDT free space is wrong after removal: " \
24239                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24240         fi
24241
24242         # combined striping
24243         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24244                 error "Can't create DoM + OST striping"
24245
24246         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24247         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24248         # check also direct IO along write
24249         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24250         sync
24251         cmp $tmp $dom || error "file data is different"
24252         [ $(stat -c%s $dom) == $size_tmp ] ||
24253                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24254         rm $dom $tmp
24255
24256         return 0
24257 }
24258 run_test 270a "DoM: basic functionality tests"
24259
24260 test_270b() {
24261         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24262                 skip "Need MDS version at least 2.10.55"
24263
24264         local dom=$DIR/$tdir/dom_file
24265         local max_size=1048576
24266
24267         mkdir -p $DIR/$tdir
24268         $LFS setstripe -E $max_size -L mdt $dom
24269
24270         # truncate over the limit
24271         $TRUNCATE $dom $(($max_size + 1)) &&
24272                 error "successful truncate over the maximum size"
24273         # write over the limit
24274         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24275                 error "successful write over the maximum size"
24276         # append over the limit
24277         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24278         echo "12345" >> $dom && error "successful append over the maximum size"
24279         rm $dom
24280
24281         return 0
24282 }
24283 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24284
24285 test_270c() {
24286         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24287                 skip "Need MDS version at least 2.10.55"
24288
24289         mkdir -p $DIR/$tdir
24290         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24291
24292         # check files inherit DoM EA
24293         touch $DIR/$tdir/first
24294         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24295                 error "bad pattern"
24296         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24297                 error "bad stripe count"
24298         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24299                 error "bad stripe size"
24300
24301         # check directory inherits DoM EA and uses it as default
24302         mkdir $DIR/$tdir/subdir
24303         touch $DIR/$tdir/subdir/second
24304         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24305                 error "bad pattern in sub-directory"
24306         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24307                 error "bad stripe count in sub-directory"
24308         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24309                 error "bad stripe size in sub-directory"
24310         return 0
24311 }
24312 run_test 270c "DoM: DoM EA inheritance tests"
24313
24314 test_270d() {
24315         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24316                 skip "Need MDS version at least 2.10.55"
24317
24318         mkdir -p $DIR/$tdir
24319         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24320
24321         # inherit default DoM striping
24322         mkdir $DIR/$tdir/subdir
24323         touch $DIR/$tdir/subdir/f1
24324
24325         # change default directory striping
24326         $LFS setstripe -c 1 $DIR/$tdir/subdir
24327         touch $DIR/$tdir/subdir/f2
24328         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24329                 error "wrong default striping in file 2"
24330         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24331                 error "bad pattern in file 2"
24332         return 0
24333 }
24334 run_test 270d "DoM: change striping from DoM to RAID0"
24335
24336 test_270e() {
24337         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24338                 skip "Need MDS version at least 2.10.55"
24339
24340         mkdir -p $DIR/$tdir/dom
24341         mkdir -p $DIR/$tdir/norm
24342         DOMFILES=20
24343         NORMFILES=10
24344         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24345         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24346
24347         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24348         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24349
24350         # find DoM files by layout
24351         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24352         [ $NUM -eq  $DOMFILES ] ||
24353                 error "lfs find -L: found $NUM, expected $DOMFILES"
24354         echo "Test 1: lfs find 20 DOM files by layout: OK"
24355
24356         # there should be 1 dir with default DOM striping
24357         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24358         [ $NUM -eq  1 ] ||
24359                 error "lfs find -L: found $NUM, expected 1 dir"
24360         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24361
24362         # find DoM files by stripe size
24363         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24364         [ $NUM -eq  $DOMFILES ] ||
24365                 error "lfs find -S: found $NUM, expected $DOMFILES"
24366         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24367
24368         # find files by stripe offset except DoM files
24369         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24370         [ $NUM -eq  $NORMFILES ] ||
24371                 error "lfs find -i: found $NUM, expected $NORMFILES"
24372         echo "Test 5: lfs find no DOM files by stripe index: OK"
24373         return 0
24374 }
24375 run_test 270e "DoM: lfs find with DoM files test"
24376
24377 test_270f() {
24378         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24379                 skip "Need MDS version at least 2.10.55"
24380
24381         local mdtname=${FSNAME}-MDT0000-mdtlov
24382         local dom=$DIR/$tdir/dom_file
24383         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24384                                                 lod.$mdtname.dom_stripesize)
24385         local dom_limit=131072
24386
24387         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24388         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24389                                                 lod.$mdtname.dom_stripesize)
24390         [ ${dom_limit} -eq ${dom_current} ] ||
24391                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24392
24393         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24394         $LFS setstripe -d $DIR/$tdir
24395         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24396                 error "Can't set directory default striping"
24397
24398         # exceed maximum stripe size
24399         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24400                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24401         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24402                 error "Able to create DoM component size more than LOD limit"
24403
24404         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24405         dom_current=$(do_facet mds1 $LCTL get_param -n \
24406                                                 lod.$mdtname.dom_stripesize)
24407         [ 0 -eq ${dom_current} ] ||
24408                 error "Can't set zero DoM stripe limit"
24409         rm $dom
24410
24411         # attempt to create DoM file on server with disabled DoM should
24412         # remove DoM entry from layout and be succeed
24413         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24414                 error "Can't create DoM file (DoM is disabled)"
24415         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24416                 error "File has DoM component while DoM is disabled"
24417         rm $dom
24418
24419         # attempt to create DoM file with only DoM stripe should return error
24420         $LFS setstripe -E $dom_limit -L mdt $dom &&
24421                 error "Able to create DoM-only file while DoM is disabled"
24422
24423         # too low values to be aligned with smallest stripe size 64K
24424         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24425         dom_current=$(do_facet mds1 $LCTL get_param -n \
24426                                                 lod.$mdtname.dom_stripesize)
24427         [ 30000 -eq ${dom_current} ] &&
24428                 error "Can set too small DoM stripe limit"
24429
24430         # 64K is a minimal stripe size in Lustre, expect limit of that size
24431         [ 65536 -eq ${dom_current} ] ||
24432                 error "Limit is not set to 64K but ${dom_current}"
24433
24434         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24435         dom_current=$(do_facet mds1 $LCTL get_param -n \
24436                                                 lod.$mdtname.dom_stripesize)
24437         echo $dom_current
24438         [ 2147483648 -eq ${dom_current} ] &&
24439                 error "Can set too large DoM stripe limit"
24440
24441         do_facet mds1 $LCTL set_param -n \
24442                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24443         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24444                 error "Can't create DoM component size after limit change"
24445         do_facet mds1 $LCTL set_param -n \
24446                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24447         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24448                 error "Can't create DoM file after limit decrease"
24449         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24450                 error "Can create big DoM component after limit decrease"
24451         touch ${dom}_def ||
24452                 error "Can't create file with old default layout"
24453
24454         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24455         return 0
24456 }
24457 run_test 270f "DoM: maximum DoM stripe size checks"
24458
24459 test_270g() {
24460         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24461                 skip "Need MDS version at least 2.13.52"
24462         local dom=$DIR/$tdir/$tfile
24463
24464         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24465         local lodname=${FSNAME}-MDT0000-mdtlov
24466
24467         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24468         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24469         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24470         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24471
24472         local dom_limit=1024
24473         local dom_threshold="50%"
24474
24475         $LFS setstripe -d $DIR/$tdir
24476         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24477                 error "Can't set directory default striping"
24478
24479         do_facet mds1 $LCTL set_param -n \
24480                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24481         # set 0 threshold and create DOM file to change tunable stripesize
24482         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24483         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24484                 error "Failed to create $dom file"
24485         # now tunable dom_cur_stripesize should reach maximum
24486         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24487                                         lod.${lodname}.dom_stripesize_cur_kb)
24488         [[ $dom_current == $dom_limit ]] ||
24489                 error "Current DOM stripesize is not maximum"
24490         rm $dom
24491
24492         # set threshold for further tests
24493         do_facet mds1 $LCTL set_param -n \
24494                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24495         echo "DOM threshold is $dom_threshold free space"
24496         local dom_def
24497         local dom_set
24498         # Spoof bfree to exceed threshold
24499         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24500         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24501         for spfree in 40 20 0 15 30 55; do
24502                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24503                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24504                         error "Failed to create $dom file"
24505                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24506                                         lod.${lodname}.dom_stripesize_cur_kb)
24507                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24508                 [[ $dom_def != $dom_current ]] ||
24509                         error "Default stripe size was not changed"
24510                 if (( spfree > 0 )) ; then
24511                         dom_set=$($LFS getstripe -S $dom)
24512                         (( dom_set == dom_def * 1024 )) ||
24513                                 error "DOM component size is still old"
24514                 else
24515                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24516                                 error "DoM component is set with no free space"
24517                 fi
24518                 rm $dom
24519                 dom_current=$dom_def
24520         done
24521 }
24522 run_test 270g "DoM: default DoM stripe size depends on free space"
24523
24524 test_270h() {
24525         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24526                 skip "Need MDS version at least 2.13.53"
24527
24528         local mdtname=${FSNAME}-MDT0000-mdtlov
24529         local dom=$DIR/$tdir/$tfile
24530         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24531
24532         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24533         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24534
24535         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24536         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24537                 error "can't create OST file"
24538         # mirrored file with DOM entry in the second mirror
24539         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24540                 error "can't create mirror with DoM component"
24541
24542         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24543
24544         # DOM component in the middle and has other enries in the same mirror,
24545         # should succeed but lost DoM component
24546         $LFS setstripe --copy=${dom}_1 $dom ||
24547                 error "Can't create file from OST|DOM mirror layout"
24548         # check new file has no DoM layout after all
24549         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24550                 error "File has DoM component while DoM is disabled"
24551 }
24552 run_test 270h "DoM: DoM stripe removal when disabled on server"
24553
24554 test_270i() {
24555         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24556                 skip "Need MDS version at least 2.14.54"
24557
24558         mkdir $DIR/$tdir
24559         # DoM with plain layout
24560         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24561                 error "default plain layout with DoM must fail"
24562         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24563                 error "setstripe plain file layout with DoM must fail"
24564         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24565                 error "default DoM layout with bad striping must fail"
24566         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24567                 error "setstripe to DoM layout with bad striping must fail"
24568         return 0
24569 }
24570 run_test 270i "DoM: setting invalid DoM striping should fail"
24571
24572 test_270j() {
24573         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24574                 skip "Need MDS version at least 2.15.55.203"
24575
24576         local dom=$DIR/$tdir/$tfile
24577         local odv
24578         local ndv
24579
24580         mkdir -p $DIR/$tdir
24581
24582         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24583
24584         odv=$($LFS data_version $dom)
24585         chmod 666 $dom
24586         mv $dom ${dom}_moved
24587         link ${dom}_moved $dom
24588         setfattr -n user.attrx -v "some_attr" $dom
24589         ndv=$($LFS data_version $dom)
24590         (( $ndv == $odv )) ||
24591                 error "data version was changed by metadata operations"
24592
24593         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24594                 error "failed to write data into $dom"
24595         cancel_lru_locks mdc
24596         ndv=$($LFS data_version $dom)
24597         (( $ndv != $odv )) ||
24598                 error "data version wasn't changed on write"
24599
24600         odv=$ndv
24601         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24602         ndv=$($LFS data_version $dom)
24603         (( $ndv != $odv )) ||
24604                 error "data version wasn't changed on truncate down"
24605
24606         odv=$ndv
24607         $TRUNCATE $dom 25000
24608         ndv=$($LFS data_version $dom)
24609         (( $ndv != $odv )) ||
24610                 error "data version wasn't changed on truncate up"
24611
24612         # check also fallocate for ldiskfs
24613         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24614                 odv=$ndv
24615                 fallocate -l 1048576 $dom
24616                 ndv=$($LFS data_version $dom)
24617                 (( $ndv != $odv )) ||
24618                         error "data version wasn't changed on fallocate"
24619
24620                 odv=$ndv
24621                 fallocate -p --offset 4096 -l 4096 $dom
24622                 ndv=$($LFS data_version $dom)
24623                 (( $ndv != $odv )) ||
24624                         error "data version wasn't changed on fallocate punch"
24625         fi
24626 }
24627 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24628
24629 test_271a() {
24630         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24631                 skip "Need MDS version at least 2.10.55"
24632
24633         local dom=$DIR/$tdir/dom
24634
24635         mkdir -p $DIR/$tdir
24636
24637         $LFS setstripe -E 1024K -L mdt $dom
24638
24639         lctl set_param -n mdc.*.stats=clear
24640         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24641         cat $dom > /dev/null
24642         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24643         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24644         ls $dom
24645         rm -f $dom
24646 }
24647 run_test 271a "DoM: data is cached for read after write"
24648
24649 test_271b() {
24650         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24651                 skip "Need MDS version at least 2.10.55"
24652
24653         local dom=$DIR/$tdir/dom
24654
24655         mkdir -p $DIR/$tdir
24656
24657         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24658
24659         lctl set_param -n mdc.*.stats=clear
24660         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24661         cancel_lru_locks mdc
24662         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24663         # second stat to check size is cached on client
24664         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24665         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24666         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24667         rm -f $dom
24668 }
24669 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24670
24671 test_271ba() {
24672         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24673                 skip "Need MDS version at least 2.10.55"
24674
24675         local dom=$DIR/$tdir/dom
24676
24677         mkdir -p $DIR/$tdir
24678
24679         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24680
24681         lctl set_param -n mdc.*.stats=clear
24682         lctl set_param -n osc.*.stats=clear
24683         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24684         cancel_lru_locks mdc
24685         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24686         # second stat to check size is cached on client
24687         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24688         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24689         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24690         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24691         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24692         rm -f $dom
24693 }
24694 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24695
24696
24697 get_mdc_stats() {
24698         local mdtidx=$1
24699         local param=$2
24700         local mdt=MDT$(printf %04x $mdtidx)
24701
24702         if [ -z $param ]; then
24703                 lctl get_param -n mdc.*$mdt*.stats
24704         else
24705                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24706         fi
24707 }
24708
24709 test_271c() {
24710         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24711                 skip "Need MDS version at least 2.10.55"
24712
24713         local dom=$DIR/$tdir/dom
24714
24715         mkdir -p $DIR/$tdir
24716
24717         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24718
24719         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24720         local facet=mds$((mdtidx + 1))
24721
24722         cancel_lru_locks mdc
24723         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24724         createmany -o $dom 1000
24725         lctl set_param -n mdc.*.stats=clear
24726         smalliomany -w $dom 1000 200
24727         get_mdc_stats $mdtidx
24728         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24729         # Each file has 1 open, 1 IO enqueues, total 2000
24730         # but now we have also +1 getxattr for security.capability, total 3000
24731         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24732         unlinkmany $dom 1000
24733
24734         cancel_lru_locks mdc
24735         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24736         createmany -o $dom 1000
24737         lctl set_param -n mdc.*.stats=clear
24738         smalliomany -w $dom 1000 200
24739         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24740         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24741         # for OPEN and IO lock.
24742         [ $((enq - enq_2)) -ge 1000 ] ||
24743                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24744         unlinkmany $dom 1000
24745         return 0
24746 }
24747 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24748
24749 cleanup_271def_tests() {
24750         trap 0
24751         rm -f $1
24752 }
24753
24754 test_271d() {
24755         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24756                 skip "Need MDS version at least 2.10.57"
24757
24758         local dom=$DIR/$tdir/dom
24759         local tmp=$TMP/$tfile
24760         trap "cleanup_271def_tests $tmp" EXIT
24761
24762         mkdir -p $DIR/$tdir
24763
24764         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24765
24766         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24767
24768         cancel_lru_locks mdc
24769         dd if=/dev/urandom of=$tmp bs=1000 count=1
24770         dd if=$tmp of=$dom bs=1000 count=1
24771         cancel_lru_locks mdc
24772
24773         cat /etc/hosts >> $tmp
24774         lctl set_param -n mdc.*.stats=clear
24775
24776         # append data to the same file it should update local page
24777         echo "Append to the same page"
24778         cat /etc/hosts >> $dom
24779         local num=$(get_mdc_stats $mdtidx ost_read)
24780         local ra=$(get_mdc_stats $mdtidx req_active)
24781         local rw=$(get_mdc_stats $mdtidx req_waittime)
24782
24783         [ -z $num ] || error "$num READ RPC occured"
24784         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24785         echo "... DONE"
24786
24787         # compare content
24788         cmp $tmp $dom || error "file miscompare"
24789
24790         cancel_lru_locks mdc
24791         lctl set_param -n mdc.*.stats=clear
24792
24793         echo "Open and read file"
24794         cat $dom > /dev/null
24795         local num=$(get_mdc_stats $mdtidx ost_read)
24796         local ra=$(get_mdc_stats $mdtidx req_active)
24797         local rw=$(get_mdc_stats $mdtidx req_waittime)
24798
24799         [ -z $num ] || error "$num READ RPC occured"
24800         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24801         echo "... DONE"
24802
24803         # compare content
24804         cmp $tmp $dom || error "file miscompare"
24805
24806         return 0
24807 }
24808 run_test 271d "DoM: read on open (1K file in reply buffer)"
24809
24810 test_271f() {
24811         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24812                 skip "Need MDS version at least 2.10.57"
24813
24814         local dom=$DIR/$tdir/dom
24815         local tmp=$TMP/$tfile
24816         trap "cleanup_271def_tests $tmp" EXIT
24817
24818         mkdir -p $DIR/$tdir
24819
24820         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24821
24822         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24823
24824         cancel_lru_locks mdc
24825         dd if=/dev/urandom of=$tmp bs=265000 count=1
24826         dd if=$tmp of=$dom bs=265000 count=1
24827         cancel_lru_locks mdc
24828         cat /etc/hosts >> $tmp
24829         lctl set_param -n mdc.*.stats=clear
24830
24831         echo "Append to the same page"
24832         cat /etc/hosts >> $dom
24833         local num=$(get_mdc_stats $mdtidx ost_read)
24834         local ra=$(get_mdc_stats $mdtidx req_active)
24835         local rw=$(get_mdc_stats $mdtidx req_waittime)
24836
24837         [ -z $num ] || error "$num READ RPC occured"
24838         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24839         echo "... DONE"
24840
24841         # compare content
24842         cmp $tmp $dom || error "file miscompare"
24843
24844         cancel_lru_locks mdc
24845         lctl set_param -n mdc.*.stats=clear
24846
24847         echo "Open and read file"
24848         cat $dom > /dev/null
24849         local num=$(get_mdc_stats $mdtidx ost_read)
24850         local ra=$(get_mdc_stats $mdtidx req_active)
24851         local rw=$(get_mdc_stats $mdtidx req_waittime)
24852
24853         [ -z $num ] && num=0
24854         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24855         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24856         echo "... DONE"
24857
24858         # compare content
24859         cmp $tmp $dom || error "file miscompare"
24860
24861         return 0
24862 }
24863 run_test 271f "DoM: read on open (200K file and read tail)"
24864
24865 test_271g() {
24866         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24867                 skip "Skipping due to old client or server version"
24868
24869         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24870         # to get layout
24871         $CHECKSTAT -t file $DIR1/$tfile
24872
24873         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24874         MULTIOP_PID=$!
24875         sleep 1
24876         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24877         $LCTL set_param fail_loc=0x80000314
24878         rm $DIR1/$tfile || error "Unlink fails"
24879         RC=$?
24880         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24881         [ $RC -eq 0 ] || error "Failed write to stale object"
24882 }
24883 run_test 271g "Discard DoM data vs client flush race"
24884
24885 test_272a() {
24886         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24887                 skip "Need MDS version at least 2.11.50"
24888
24889         local dom=$DIR/$tdir/dom
24890         mkdir -p $DIR/$tdir
24891
24892         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24893         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24894                 error "failed to write data into $dom"
24895         local old_md5=$(md5sum $dom)
24896
24897         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24898                 error "failed to migrate to the same DoM component"
24899
24900         local new_md5=$(md5sum $dom)
24901
24902         [ "$old_md5" == "$new_md5" ] ||
24903                 error "md5sum differ: $old_md5, $new_md5"
24904
24905         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24906                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24907 }
24908 run_test 272a "DoM migration: new layout with the same DOM component"
24909
24910 test_272b() {
24911         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24912                 skip "Need MDS version at least 2.11.50"
24913
24914         local dom=$DIR/$tdir/dom
24915         mkdir -p $DIR/$tdir
24916         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24917         stack_trap "rm -rf $DIR/$tdir"
24918
24919         local mdtidx=$($LFS getstripe -m $dom)
24920         local mdtname=MDT$(printf %04x $mdtidx)
24921         local facet=mds$((mdtidx + 1))
24922
24923         local mdtfree1=$(do_facet $facet \
24924                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24925         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24926                 error "failed to write data into $dom"
24927         local old_md5=$(md5sum $dom)
24928         cancel_lru_locks mdc
24929         local mdtfree1=$(do_facet $facet \
24930                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24931
24932         $LFS migrate -c2 $dom ||
24933                 error "failed to migrate to the new composite layout"
24934         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24935                 error "MDT stripe was not removed"
24936         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24937                 error "$dir1 shouldn't have DATAVER EA"
24938
24939         cancel_lru_locks mdc
24940         local new_md5=$(md5sum $dom)
24941         [ "$old_md5" == "$new_md5" ] ||
24942                 error "$old_md5 != $new_md5"
24943
24944         # Skip free space checks with ZFS
24945         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24946                 local mdtfree2=$(do_facet $facet \
24947                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24948                 [ $mdtfree2 -gt $mdtfree1 ] ||
24949                         error "MDT space is not freed after migration"
24950         fi
24951         return 0
24952 }
24953 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24954
24955 test_272c() {
24956         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24957                 skip "Need MDS version at least 2.11.50"
24958
24959         local dom=$DIR/$tdir/$tfile
24960         mkdir -p $DIR/$tdir
24961         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24962         stack_trap "rm -rf $DIR/$tdir"
24963
24964         local mdtidx=$($LFS getstripe -m $dom)
24965         local mdtname=MDT$(printf %04x $mdtidx)
24966         local facet=mds$((mdtidx + 1))
24967
24968         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24969                 error "failed to write data into $dom"
24970         local old_md5=$(md5sum $dom)
24971         cancel_lru_locks mdc
24972         local mdtfree1=$(do_facet $facet \
24973                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24974
24975         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24976                 error "failed to migrate to the new composite layout"
24977         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24978                 error "MDT stripe was not removed"
24979
24980         cancel_lru_locks mdc
24981         local new_md5=$(md5sum $dom)
24982         [ "$old_md5" == "$new_md5" ] ||
24983                 error "$old_md5 != $new_md5"
24984
24985         # Skip free space checks with ZFS
24986         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24987                 local mdtfree2=$(do_facet $facet \
24988                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24989                 [ $mdtfree2 -gt $mdtfree1 ] ||
24990                         error "MDS space is not freed after migration"
24991         fi
24992         return 0
24993 }
24994 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24995
24996 test_272d() {
24997         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24998                 skip "Need MDS version at least 2.12.55"
24999
25000         local dom=$DIR/$tdir/$tfile
25001         mkdir -p $DIR/$tdir
25002         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25003
25004         local mdtidx=$($LFS getstripe -m $dom)
25005         local mdtname=MDT$(printf %04x $mdtidx)
25006         local facet=mds$((mdtidx + 1))
25007
25008         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25009                 error "failed to write data into $dom"
25010         local old_md5=$(md5sum $dom)
25011         cancel_lru_locks mdc
25012         local mdtfree1=$(do_facet $facet \
25013                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25014
25015         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25016                 error "failed mirroring to the new composite layout"
25017         $LFS mirror resync $dom ||
25018                 error "failed mirror resync"
25019         $LFS mirror split --mirror-id 1 -d $dom ||
25020                 error "failed mirror split"
25021
25022         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25023                 error "MDT stripe was not removed"
25024
25025         cancel_lru_locks mdc
25026         local new_md5=$(md5sum $dom)
25027         [ "$old_md5" == "$new_md5" ] ||
25028                 error "$old_md5 != $new_md5"
25029
25030         # Skip free space checks with ZFS
25031         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25032                 local mdtfree2=$(do_facet $facet \
25033                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25034                 [ $mdtfree2 -gt $mdtfree1 ] ||
25035                         error "MDS space is not freed after DOM mirror deletion"
25036         fi
25037         return 0
25038 }
25039 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25040
25041 test_272e() {
25042         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25043                 skip "Need MDS version at least 2.12.55"
25044
25045         local dom=$DIR/$tdir/$tfile
25046         mkdir -p $DIR/$tdir
25047         $LFS setstripe -c 2 $dom
25048
25049         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25050                 error "failed to write data into $dom"
25051         local old_md5=$(md5sum $dom)
25052         cancel_lru_locks
25053
25054         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25055                 error "failed mirroring to the DOM layout"
25056         $LFS mirror resync $dom ||
25057                 error "failed mirror resync"
25058         $LFS mirror split --mirror-id 1 -d $dom ||
25059                 error "failed mirror split"
25060
25061         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25062                 error "MDT stripe wasn't set"
25063
25064         cancel_lru_locks
25065         local new_md5=$(md5sum $dom)
25066         [ "$old_md5" == "$new_md5" ] ||
25067                 error "$old_md5 != $new_md5"
25068
25069         return 0
25070 }
25071 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25072
25073 test_272f() {
25074         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25075                 skip "Need MDS version at least 2.12.55"
25076
25077         local dom=$DIR/$tdir/$tfile
25078         mkdir -p $DIR/$tdir
25079         $LFS setstripe -c 2 $dom
25080
25081         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25082                 error "failed to write data into $dom"
25083         local old_md5=$(md5sum $dom)
25084         cancel_lru_locks
25085
25086         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25087                 error "failed migrating to the DOM file"
25088
25089         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25090                 error "MDT stripe wasn't set"
25091
25092         cancel_lru_locks
25093         local new_md5=$(md5sum $dom)
25094         [ "$old_md5" != "$new_md5" ] &&
25095                 error "$old_md5 != $new_md5"
25096
25097         return 0
25098 }
25099 run_test 272f "DoM migration: OST-striped file to DOM file"
25100
25101 test_273a() {
25102         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25103                 skip "Need MDS version at least 2.11.50"
25104
25105         # Layout swap cannot be done if either file has DOM component,
25106         # this will never be supported, migration should be used instead
25107
25108         local dom=$DIR/$tdir/$tfile
25109         mkdir -p $DIR/$tdir
25110
25111         $LFS setstripe -c2 ${dom}_plain
25112         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25113         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25114                 error "can swap layout with DoM component"
25115         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25116                 error "can swap layout with DoM component"
25117
25118         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25119         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25120                 error "can swap layout with DoM component"
25121         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25122                 error "can swap layout with DoM component"
25123         return 0
25124 }
25125 run_test 273a "DoM: layout swapping should fail with DOM"
25126
25127 test_273b() {
25128         mkdir -p $DIR/$tdir
25129         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25130
25131 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25132         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25133
25134         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25135 }
25136 run_test 273b "DoM: race writeback and object destroy"
25137
25138 test_273c() {
25139         mkdir -p $DIR/$tdir
25140         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25141
25142         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25143         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25144
25145         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25146 }
25147 run_test 273c "race writeback and object destroy"
25148
25149 test_275() {
25150         remote_ost_nodsh && skip "remote OST with nodsh"
25151         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25152                 skip "Need OST version >= 2.10.57"
25153
25154         local file=$DIR/$tfile
25155         local oss
25156
25157         oss=$(comma_list $(osts_nodes))
25158
25159         dd if=/dev/urandom of=$file bs=1M count=2 ||
25160                 error "failed to create a file"
25161         stack_trap "rm -f $file"
25162         cancel_lru_locks osc
25163
25164         #lock 1
25165         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25166                 error "failed to read a file"
25167
25168 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25169         $LCTL set_param fail_loc=0x8000031f
25170
25171         cancel_lru_locks osc &
25172         sleep 1
25173
25174 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25175         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25176         #IO takes another lock, but matches the PENDING one
25177         #and places it to the IO RPC
25178         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25179                 error "failed to read a file with PENDING lock"
25180 }
25181 run_test 275 "Read on a canceled duplicate lock"
25182
25183 test_276() {
25184         remote_ost_nodsh && skip "remote OST with nodsh"
25185         local pid
25186
25187         do_facet ost1 "(while true; do \
25188                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25189                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25190         pid=$!
25191
25192         for LOOP in $(seq 20); do
25193                 stop ost1
25194                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25195         done
25196         kill -9 $pid
25197         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25198                 rm $TMP/sanity_276_pid"
25199 }
25200 run_test 276 "Race between mount and obd_statfs"
25201
25202 test_277() {
25203         $LCTL set_param ldlm.namespaces.*.lru_size=0
25204         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25205         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25206                           awk '/^used_mb/ { print $2 }')
25207         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25208         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25209                 oflag=direct conv=notrunc
25210         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25211                     awk '/^used_mb/ { print $2 }')
25212         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25213 }
25214 run_test 277 "Direct IO shall drop page cache"
25215
25216 test_278() {
25217         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25218         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25219         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25220                 skip "needs the same host for mdt1 mdt2" && return
25221
25222         local pid1
25223         local pid2
25224
25225 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25226         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25227         stop mds2 &
25228         pid2=$!
25229
25230         stop mds1
25231
25232         echo "Starting MDTs"
25233         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25234         wait $pid2
25235 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25236 #will return NULL
25237         do_facet mds2 $LCTL set_param fail_loc=0
25238
25239         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25240         wait_recovery_complete mds2
25241 }
25242 run_test 278 "Race starting MDS between MDTs stop/start"
25243
25244 test_280() {
25245         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25246                 skip "Need MGS version at least 2.13.52"
25247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25248         combined_mgs_mds || skip "needs combined MGS/MDT"
25249
25250         umount_client $MOUNT
25251 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25252         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25253
25254         mount_client $MOUNT &
25255         sleep 1
25256         stop mgs || error "stop mgs failed"
25257         #for a race mgs would crash
25258         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25259         # make sure we unmount client before remounting
25260         wait
25261         umount_client $MOUNT
25262         mount_client $MOUNT || error "mount client failed"
25263 }
25264 run_test 280 "Race between MGS umount and client llog processing"
25265
25266 cleanup_test_300() {
25267         trap 0
25268         umask $SAVE_UMASK
25269 }
25270 test_striped_dir() {
25271         local mdt_index=$1
25272         local stripe_count
25273         local stripe_index
25274
25275         mkdir -p $DIR/$tdir
25276
25277         SAVE_UMASK=$(umask)
25278         trap cleanup_test_300 RETURN EXIT
25279
25280         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25281                                                 $DIR/$tdir/striped_dir ||
25282                 error "set striped dir error"
25283
25284         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25285         [ "$mode" = "755" ] || error "expect 755 got $mode"
25286
25287         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25288                 error "getdirstripe failed"
25289         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25290         if [ "$stripe_count" != "2" ]; then
25291                 error "1:stripe_count is $stripe_count, expect 2"
25292         fi
25293         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25294         if [ "$stripe_count" != "2" ]; then
25295                 error "2:stripe_count is $stripe_count, expect 2"
25296         fi
25297
25298         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25299         if [ "$stripe_index" != "$mdt_index" ]; then
25300                 error "stripe_index is $stripe_index, expect $mdt_index"
25301         fi
25302
25303         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25304                 error "nlink error after create striped dir"
25305
25306         mkdir $DIR/$tdir/striped_dir/a
25307         mkdir $DIR/$tdir/striped_dir/b
25308
25309         stat $DIR/$tdir/striped_dir/a ||
25310                 error "create dir under striped dir failed"
25311         stat $DIR/$tdir/striped_dir/b ||
25312                 error "create dir under striped dir failed"
25313
25314         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25315                 error "nlink error after mkdir"
25316
25317         rmdir $DIR/$tdir/striped_dir/a
25318         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25319                 error "nlink error after rmdir"
25320
25321         rmdir $DIR/$tdir/striped_dir/b
25322         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25323                 error "nlink error after rmdir"
25324
25325         chattr +i $DIR/$tdir/striped_dir
25326         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25327                 error "immutable flags not working under striped dir!"
25328         chattr -i $DIR/$tdir/striped_dir
25329
25330         rmdir $DIR/$tdir/striped_dir ||
25331                 error "rmdir striped dir error"
25332
25333         cleanup_test_300
25334
25335         true
25336 }
25337
25338 test_300a() {
25339         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25340                 skip "skipped for lustre < 2.7.0"
25341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25343
25344         test_striped_dir 0 || error "failed on striped dir on MDT0"
25345         test_striped_dir 1 || error "failed on striped dir on MDT0"
25346 }
25347 run_test 300a "basic striped dir sanity test"
25348
25349 test_300b() {
25350         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25351                 skip "skipped for lustre < 2.7.0"
25352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25354
25355         local i
25356         local mtime1
25357         local mtime2
25358         local mtime3
25359
25360         test_mkdir $DIR/$tdir || error "mkdir fail"
25361         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25362                 error "set striped dir error"
25363         for i in {0..9}; do
25364                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25365                 sleep 1
25366                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25367                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25368                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25369                 sleep 1
25370                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25371                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25372                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25373         done
25374         true
25375 }
25376 run_test 300b "check ctime/mtime for striped dir"
25377
25378 test_300c() {
25379         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25380                 skip "skipped for lustre < 2.7.0"
25381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25383
25384         local file_count
25385
25386         mkdir_on_mdt0 $DIR/$tdir
25387         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25388                 error "set striped dir error"
25389
25390         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25391                 error "chown striped dir failed"
25392
25393         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25394                 error "create 5k files failed"
25395
25396         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25397
25398         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25399
25400         rm -rf $DIR/$tdir
25401 }
25402 run_test 300c "chown && check ls under striped directory"
25403
25404 test_300d() {
25405         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25406                 skip "skipped for lustre < 2.7.0"
25407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25408         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25409
25410         local stripe_count
25411         local file
25412
25413         mkdir -p $DIR/$tdir
25414         $LFS setstripe -c 2 $DIR/$tdir
25415
25416         #local striped directory
25417         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25418                 error "set striped dir error"
25419         #look at the directories for debug purposes
25420         ls -l $DIR/$tdir
25421         $LFS getdirstripe $DIR/$tdir
25422         ls -l $DIR/$tdir/striped_dir
25423         $LFS getdirstripe $DIR/$tdir/striped_dir
25424         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25425                 error "create 10 files failed"
25426
25427         #remote striped directory
25428         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25429                 error "set striped dir error"
25430         #look at the directories for debug purposes
25431         ls -l $DIR/$tdir
25432         $LFS getdirstripe $DIR/$tdir
25433         ls -l $DIR/$tdir/remote_striped_dir
25434         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25435         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25436                 error "create 10 files failed"
25437
25438         for file in $(find $DIR/$tdir); do
25439                 stripe_count=$($LFS getstripe -c $file)
25440                 [ $stripe_count -eq 2 ] ||
25441                         error "wrong stripe $stripe_count for $file"
25442         done
25443
25444         rm -rf $DIR/$tdir
25445 }
25446 run_test 300d "check default stripe under striped directory"
25447
25448 test_300e() {
25449         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25450                 skip "Need MDS version at least 2.7.55"
25451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25453
25454         local stripe_count
25455         local file
25456
25457         mkdir -p $DIR/$tdir
25458
25459         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25460                 error "set striped dir error"
25461
25462         touch $DIR/$tdir/striped_dir/a
25463         touch $DIR/$tdir/striped_dir/b
25464         touch $DIR/$tdir/striped_dir/c
25465
25466         mkdir $DIR/$tdir/striped_dir/dir_a
25467         mkdir $DIR/$tdir/striped_dir/dir_b
25468         mkdir $DIR/$tdir/striped_dir/dir_c
25469
25470         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25471                 error "set striped adir under striped dir error"
25472
25473         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25474                 error "set striped bdir under striped dir error"
25475
25476         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25477                 error "set striped cdir under striped dir error"
25478
25479         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25480                 error "rename dir under striped dir fails"
25481
25482         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25483                 error "rename dir under different stripes fails"
25484
25485         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25486                 error "rename file under striped dir should succeed"
25487
25488         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25489                 error "rename dir under striped dir should succeed"
25490
25491         rm -rf $DIR/$tdir
25492 }
25493 run_test 300e "check rename under striped directory"
25494
25495 test_300f() {
25496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25497         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25498         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25499                 skip "Need MDS version at least 2.7.55"
25500
25501         local stripe_count
25502         local file
25503
25504         rm -rf $DIR/$tdir
25505         mkdir -p $DIR/$tdir
25506
25507         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25508                 error "set striped dir error"
25509
25510         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25511                 error "set striped dir error"
25512
25513         touch $DIR/$tdir/striped_dir/a
25514         mkdir $DIR/$tdir/striped_dir/dir_a
25515         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25516                 error "create striped dir under striped dir fails"
25517
25518         touch $DIR/$tdir/striped_dir1/b
25519         mkdir $DIR/$tdir/striped_dir1/dir_b
25520         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25521                 error "create striped dir under striped dir fails"
25522
25523         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25524                 error "rename dir under different striped dir should fail"
25525
25526         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25527                 error "rename striped dir under diff striped dir should fail"
25528
25529         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25530                 error "rename file under diff striped dirs fails"
25531
25532         rm -rf $DIR/$tdir
25533 }
25534 run_test 300f "check rename cross striped directory"
25535
25536 test_300_check_default_striped_dir()
25537 {
25538         local dirname=$1
25539         local default_count=$2
25540         local default_index=$3
25541         local stripe_count
25542         local stripe_index
25543         local dir_stripe_index
25544         local dir
25545
25546         echo "checking $dirname $default_count $default_index"
25547         $LFS setdirstripe -D -c $default_count -i $default_index \
25548                                 -H all_char $DIR/$tdir/$dirname ||
25549                 error "set default stripe on striped dir error"
25550         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25551         [ $stripe_count -eq $default_count ] ||
25552                 error "expect $default_count get $stripe_count for $dirname"
25553
25554         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25555         [ $stripe_index -eq $default_index ] ||
25556                 error "expect $default_index get $stripe_index for $dirname"
25557
25558         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25559                                                 error "create dirs failed"
25560
25561         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25562         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25563         for dir in $(find $DIR/$tdir/$dirname/*); do
25564                 stripe_count=$($LFS getdirstripe -c $dir)
25565                 (( $stripe_count == $default_count )) ||
25566                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25567                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25568                 error "stripe count $default_count != $stripe_count for $dir"
25569
25570                 stripe_index=$($LFS getdirstripe -i $dir)
25571                 [ $default_index -eq -1 ] ||
25572                         [ $stripe_index -eq $default_index ] ||
25573                         error "$stripe_index != $default_index for $dir"
25574
25575                 #check default stripe
25576                 stripe_count=$($LFS getdirstripe -D -c $dir)
25577                 [ $stripe_count -eq $default_count ] ||
25578                 error "default count $default_count != $stripe_count for $dir"
25579
25580                 stripe_index=$($LFS getdirstripe -D -i $dir)
25581                 [ $stripe_index -eq $default_index ] ||
25582                 error "default index $default_index != $stripe_index for $dir"
25583         done
25584         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25585 }
25586
25587 test_300g() {
25588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25589         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25590                 skip "Need MDS version at least 2.7.55"
25591
25592         local dir
25593         local stripe_count
25594         local stripe_index
25595
25596         mkdir_on_mdt0 $DIR/$tdir
25597         mkdir $DIR/$tdir/normal_dir
25598
25599         #Checking when client cache stripe index
25600         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25601         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25602                 error "create striped_dir failed"
25603
25604         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25605                 error "create dir0 fails"
25606         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25607         [ $stripe_index -eq 0 ] ||
25608                 error "dir0 expect index 0 got $stripe_index"
25609
25610         mkdir $DIR/$tdir/striped_dir/dir1 ||
25611                 error "create dir1 fails"
25612         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25613         [ $stripe_index -eq 1 ] ||
25614                 error "dir1 expect index 1 got $stripe_index"
25615
25616         #check default stripe count/stripe index
25617         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25618         test_300_check_default_striped_dir normal_dir 1 0
25619         test_300_check_default_striped_dir normal_dir -1 1
25620         test_300_check_default_striped_dir normal_dir 2 -1
25621
25622         #delete default stripe information
25623         echo "delete default stripeEA"
25624         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25625                 error "set default stripe on striped dir error"
25626
25627         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25628         for dir in $(find $DIR/$tdir/normal_dir/*); do
25629                 stripe_count=$($LFS getdirstripe -c $dir)
25630                 [ $stripe_count -eq 0 ] ||
25631                         error "expect 1 get $stripe_count for $dir"
25632         done
25633 }
25634 run_test 300g "check default striped directory for normal directory"
25635
25636 test_300h() {
25637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25638         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25639                 skip "Need MDS version at least 2.7.55"
25640
25641         local dir
25642         local stripe_count
25643
25644         mkdir $DIR/$tdir
25645         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25646                 error "set striped dir error"
25647
25648         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25649         test_300_check_default_striped_dir striped_dir 1 0
25650         test_300_check_default_striped_dir striped_dir -1 1
25651         test_300_check_default_striped_dir striped_dir 2 -1
25652
25653         #delete default stripe information
25654         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25655                 error "set default stripe on striped dir error"
25656
25657         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25658         for dir in $(find $DIR/$tdir/striped_dir/*); do
25659                 stripe_count=$($LFS getdirstripe -c $dir)
25660                 [ $stripe_count -eq 0 ] ||
25661                         error "expect 1 get $stripe_count for $dir"
25662         done
25663 }
25664 run_test 300h "check default striped directory for striped directory"
25665
25666 test_300i() {
25667         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25668         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25669         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25670                 skip "Need MDS version at least 2.7.55"
25671
25672         local stripe_count
25673         local file
25674
25675         mkdir $DIR/$tdir
25676
25677         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25678                 error "set striped dir error"
25679
25680         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25681                 error "create files under striped dir failed"
25682
25683         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25684                 error "set striped hashdir error"
25685
25686         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25687                 error "create dir0 under hash dir failed"
25688         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25689                 error "create dir1 under hash dir failed"
25690         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25691                 error "create dir2 under hash dir failed"
25692
25693         # unfortunately, we need to umount to clear dir layout cache for now
25694         # once we fully implement dir layout, we can drop this
25695         umount_client $MOUNT || error "umount failed"
25696         mount_client $MOUNT || error "mount failed"
25697
25698         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25699         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25700         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25701
25702         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25703                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25704                         error "create crush2 dir $tdir/hashdir/d3 failed"
25705                 $LFS find -H crush2 $DIR/$tdir/hashdir
25706                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25707                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25708
25709                 # mkdir with an invalid hash type (hash=fail_val) from client
25710                 # should be replaced on MDS with a valid (default) hash type
25711                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25712                 $LCTL set_param fail_loc=0x1901 fail_val=99
25713                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25714
25715                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25716                 local expect=$(do_facet mds1 \
25717                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25718                 [[ $hash == $expect ]] ||
25719                         error "d99 hash '$hash' != expected hash '$expect'"
25720         fi
25721
25722         #set the stripe to be unknown hash type on read
25723         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25724         $LCTL set_param fail_loc=0x1901 fail_val=99
25725         for ((i = 0; i < 10; i++)); do
25726                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25727                         error "stat f-$i failed"
25728                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25729         done
25730
25731         touch $DIR/$tdir/striped_dir/f0 &&
25732                 error "create under striped dir with unknown hash should fail"
25733
25734         $LCTL set_param fail_loc=0
25735
25736         umount_client $MOUNT || error "umount failed"
25737         mount_client $MOUNT || error "mount failed"
25738
25739         return 0
25740 }
25741 run_test 300i "client handle unknown hash type striped directory"
25742
25743 test_300j() {
25744         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25746         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25747                 skip "Need MDS version at least 2.7.55"
25748
25749         local stripe_count
25750         local file
25751
25752         mkdir $DIR/$tdir
25753
25754         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25755         $LCTL set_param fail_loc=0x1702
25756         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25757                 error "set striped dir error"
25758
25759         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25760                 error "create files under striped dir failed"
25761
25762         $LCTL set_param fail_loc=0
25763
25764         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25765
25766         return 0
25767 }
25768 run_test 300j "test large update record"
25769
25770 test_300k() {
25771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25772         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25773         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25774                 skip "Need MDS version at least 2.7.55"
25775
25776         # this test needs a huge transaction
25777         local kb
25778         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25779              osd*.$FSNAME-MDT0000.kbytestotal")
25780         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25781
25782         local stripe_count
25783         local file
25784
25785         mkdir $DIR/$tdir
25786
25787         #define OBD_FAIL_LARGE_STRIPE   0x1703
25788         $LCTL set_param fail_loc=0x1703
25789         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25790                 error "set striped dir error"
25791         $LCTL set_param fail_loc=0
25792
25793         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25794                 error "getstripeddir fails"
25795         rm -rf $DIR/$tdir/striped_dir ||
25796                 error "unlink striped dir fails"
25797
25798         return 0
25799 }
25800 run_test 300k "test large striped directory"
25801
25802 test_300l() {
25803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25804         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25805         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25806                 skip "Need MDS version at least 2.7.55"
25807
25808         local stripe_index
25809
25810         test_mkdir -p $DIR/$tdir/striped_dir
25811         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25812                         error "chown $RUNAS_ID failed"
25813         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25814                 error "set default striped dir failed"
25815
25816         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25817         $LCTL set_param fail_loc=0x80000158
25818         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25819
25820         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25821         [ $stripe_index -eq 1 ] ||
25822                 error "expect 1 get $stripe_index for $dir"
25823 }
25824 run_test 300l "non-root user to create dir under striped dir with stale layout"
25825
25826 test_300m() {
25827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25828         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25829         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25830                 skip "Need MDS version at least 2.7.55"
25831
25832         mkdir -p $DIR/$tdir/striped_dir
25833         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25834                 error "set default stripes dir error"
25835
25836         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25837
25838         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25839         [ $stripe_count -eq 0 ] ||
25840                         error "expect 0 get $stripe_count for a"
25841
25842         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25843                 error "set default stripes dir error"
25844
25845         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25846
25847         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25848         [ $stripe_count -eq 0 ] ||
25849                         error "expect 0 get $stripe_count for b"
25850
25851         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25852                 error "set default stripes dir error"
25853
25854         mkdir $DIR/$tdir/striped_dir/c &&
25855                 error "default stripe_index is invalid, mkdir c should fails"
25856
25857         rm -rf $DIR/$tdir || error "rmdir fails"
25858 }
25859 run_test 300m "setstriped directory on single MDT FS"
25860
25861 cleanup_300n() {
25862         local list=$(comma_list $(mdts_nodes))
25863
25864         trap 0
25865         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25866 }
25867
25868 test_300n() {
25869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25871         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25872                 skip "Need MDS version at least 2.7.55"
25873         remote_mds_nodsh && skip "remote MDS with nodsh"
25874
25875         local stripe_index
25876         local list=$(comma_list $(mdts_nodes))
25877
25878         trap cleanup_300n RETURN EXIT
25879         mkdir -p $DIR/$tdir
25880         chmod 777 $DIR/$tdir
25881         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25882                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25883                 error "create striped dir succeeds with gid=0"
25884
25885         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25886         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25887                 error "create striped dir fails with gid=-1"
25888
25889         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25890         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25891                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25892                 error "set default striped dir succeeds with gid=0"
25893
25894
25895         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25896         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25897                 error "set default striped dir fails with gid=-1"
25898
25899
25900         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25901         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25902                                         error "create test_dir fails"
25903         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25904                                         error "create test_dir1 fails"
25905         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25906                                         error "create test_dir2 fails"
25907         cleanup_300n
25908 }
25909 run_test 300n "non-root user to create dir under striped dir with default EA"
25910
25911 test_300o() {
25912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25913         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25914         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25915                 skip "Need MDS version at least 2.7.55"
25916
25917         local numfree1
25918         local numfree2
25919
25920         mkdir -p $DIR/$tdir
25921
25922         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25923         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25924         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25925                 skip "not enough free inodes $numfree1 $numfree2"
25926         fi
25927
25928         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25929         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25930         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25931                 skip "not enough free space $numfree1 $numfree2"
25932         fi
25933
25934         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25935                 error "setdirstripe fails"
25936
25937         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25938                 error "create dirs fails"
25939
25940         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25941         ls $DIR/$tdir/striped_dir > /dev/null ||
25942                 error "ls striped dir fails"
25943         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25944                 error "unlink big striped dir fails"
25945 }
25946 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25947
25948 test_300p() {
25949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25951         remote_mds_nodsh && skip "remote MDS with nodsh"
25952
25953         mkdir_on_mdt0 $DIR/$tdir
25954
25955         #define OBD_FAIL_OUT_ENOSPC     0x1704
25956         do_facet mds2 lctl set_param fail_loc=0x80001704
25957         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25958                  && error "create striped directory should fail"
25959
25960         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25961
25962         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25963         true
25964 }
25965 run_test 300p "create striped directory without space"
25966
25967 test_300q() {
25968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25970
25971         local fd=$(free_fd)
25972         local cmd="exec $fd<$tdir"
25973         cd $DIR
25974         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25975         eval $cmd
25976         cmd="exec $fd<&-"
25977         trap "eval $cmd" EXIT
25978         cd $tdir || error "cd $tdir fails"
25979         rmdir  ../$tdir || error "rmdir $tdir fails"
25980         mkdir local_dir && error "create dir succeeds"
25981         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25982         eval $cmd
25983         return 0
25984 }
25985 run_test 300q "create remote directory under orphan directory"
25986
25987 test_300r() {
25988         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25989                 skip "Need MDS version at least 2.7.55" && return
25990         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25991
25992         mkdir $DIR/$tdir
25993
25994         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25995                 error "set striped dir error"
25996
25997         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25998                 error "getstripeddir fails"
25999
26000         local stripe_count
26001         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26002                       awk '/lmv_stripe_count:/ { print $2 }')
26003
26004         [ $MDSCOUNT -ne $stripe_count ] &&
26005                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26006
26007         rm -rf $DIR/$tdir/striped_dir ||
26008                 error "unlink striped dir fails"
26009 }
26010 run_test 300r "test -1 striped directory"
26011
26012 test_300s_helper() {
26013         local count=$1
26014
26015         local stripe_dir=$DIR/$tdir/striped_dir.$count
26016
26017         $LFS mkdir -c $count $stripe_dir ||
26018                 error "lfs mkdir -c error"
26019
26020         $LFS getdirstripe $stripe_dir ||
26021                 error "lfs getdirstripe fails"
26022
26023         local stripe_count
26024         stripe_count=$($LFS getdirstripe $stripe_dir |
26025                       awk '/lmv_stripe_count:/ { print $2 }')
26026
26027         [ $count -ne $stripe_count ] &&
26028                 error_noexit "bad stripe count $stripe_count expected $count"
26029
26030         local dupe_stripes
26031         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26032                 awk '/0x/ {count[$1] += 1}; END {
26033                         for (idx in count) {
26034                                 if (count[idx]>1) {
26035                                         print "index " idx " count " count[idx]
26036                                 }
26037                         }
26038                 }')
26039
26040         if [[ -n "$dupe_stripes" ]] ; then
26041                 lfs getdirstripe $stripe_dir
26042                 error_noexit "Dupe MDT above: $dupe_stripes "
26043         fi
26044
26045         rm -rf $stripe_dir ||
26046                 error_noexit "unlink $stripe_dir fails"
26047 }
26048
26049 test_300s() {
26050         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26051                 skip "Need MDS version at least 2.7.55" && return
26052         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26053
26054         mkdir $DIR/$tdir
26055         for count in $(seq 2 $MDSCOUNT); do
26056                 test_300s_helper $count
26057         done
26058 }
26059 run_test 300s "test lfs mkdir -c without -i"
26060
26061 test_300t() {
26062         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26063                 skip "need MDS 2.14.55 or later"
26064         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26065
26066         local testdir="$DIR/$tdir/striped_dir"
26067         local dir1=$testdir/dir1
26068         local dir2=$testdir/dir2
26069
26070         mkdir -p $testdir
26071
26072         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26073                 error "failed to set default stripe count for $testdir"
26074
26075         mkdir $dir1
26076         local stripe_count=$($LFS getdirstripe -c $dir1)
26077
26078         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26079
26080         local max_count=$((MDSCOUNT - 1))
26081         local mdts=$(comma_list $(mdts_nodes))
26082
26083         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26084         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26085
26086         mkdir $dir2
26087         stripe_count=$($LFS getdirstripe -c $dir2)
26088
26089         (( $stripe_count == $max_count )) || error "wrong stripe count"
26090 }
26091 run_test 300t "test max_mdt_stripecount"
26092
26093 prepare_remote_file() {
26094         mkdir $DIR/$tdir/src_dir ||
26095                 error "create remote source failed"
26096
26097         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26098                  error "cp to remote source failed"
26099         touch $DIR/$tdir/src_dir/a
26100
26101         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26102                 error "create remote target dir failed"
26103
26104         touch $DIR/$tdir/tgt_dir/b
26105
26106         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26107                 error "rename dir cross MDT failed!"
26108
26109         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26110                 error "src_child still exists after rename"
26111
26112         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26113                 error "missing file(a) after rename"
26114
26115         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26116                 error "diff after rename"
26117 }
26118
26119 test_310a() {
26120         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26122
26123         local remote_file=$DIR/$tdir/tgt_dir/b
26124
26125         mkdir -p $DIR/$tdir
26126
26127         prepare_remote_file || error "prepare remote file failed"
26128
26129         #open-unlink file
26130         $OPENUNLINK $remote_file $remote_file ||
26131                 error "openunlink $remote_file failed"
26132         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26133 }
26134 run_test 310a "open unlink remote file"
26135
26136 test_310b() {
26137         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26139
26140         local remote_file=$DIR/$tdir/tgt_dir/b
26141
26142         mkdir -p $DIR/$tdir
26143
26144         prepare_remote_file || error "prepare remote file failed"
26145
26146         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26147         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26148         $CHECKSTAT -t file $remote_file || error "check file failed"
26149 }
26150 run_test 310b "unlink remote file with multiple links while open"
26151
26152 test_310c() {
26153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26154         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26155
26156         local remote_file=$DIR/$tdir/tgt_dir/b
26157
26158         mkdir -p $DIR/$tdir
26159
26160         prepare_remote_file || error "prepare remote file failed"
26161
26162         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26163         multiop_bg_pause $remote_file O_uc ||
26164                         error "mulitop failed for remote file"
26165         MULTIPID=$!
26166         $MULTIOP $DIR/$tfile Ouc
26167         kill -USR1 $MULTIPID
26168         wait $MULTIPID
26169 }
26170 run_test 310c "open-unlink remote file with multiple links"
26171
26172 #LU-4825
26173 test_311() {
26174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26175         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26176         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26177                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26178         remote_mds_nodsh && skip "remote MDS with nodsh"
26179
26180         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26181         local mdts=$(comma_list $(mdts_nodes))
26182
26183         mkdir -p $DIR/$tdir
26184         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26185         createmany -o $DIR/$tdir/$tfile. 1000
26186
26187         # statfs data is not real time, let's just calculate it
26188         old_iused=$((old_iused + 1000))
26189
26190         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26191                         osp.*OST0000*MDT0000.create_count")
26192         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26193                                 osp.*OST0000*MDT0000.max_create_count")
26194         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26195
26196         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26197         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26198         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26199
26200         unlinkmany $DIR/$tdir/$tfile. 1000
26201
26202         do_nodes $mdts "$LCTL set_param -n \
26203                         osp.*OST0000*.max_create_count=$max_count"
26204         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26205                 do_nodes $mdts "$LCTL set_param -n \
26206                                 osp.*OST0000*.create_count=$count"
26207         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26208                         grep "=0" && error "create_count is zero"
26209
26210         local new_iused
26211         for i in $(seq 120); do
26212                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26213                 # system may be too busy to destroy all objs in time, use
26214                 # a somewhat small value to not fail autotest
26215                 [ $((old_iused - new_iused)) -gt 400 ] && break
26216                 sleep 1
26217         done
26218
26219         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26220         [ $((old_iused - new_iused)) -gt 400 ] ||
26221                 error "objs not destroyed after unlink"
26222 }
26223 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26224
26225 zfs_get_objid()
26226 {
26227         local ost=$1
26228         local tf=$2
26229         local fid=($($LFS getstripe $tf | grep 0x))
26230         local seq=${fid[3]#0x}
26231         local objid=${fid[1]}
26232
26233         local vdevdir=$(dirname $(facet_vdevice $ost))
26234         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26235         local zfs_zapid=$(do_facet $ost $cmd |
26236                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26237                           awk '/Object/{getline; print $1}')
26238         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26239                           awk "/$objid = /"'{printf $3}')
26240
26241         echo $zfs_objid
26242 }
26243
26244 zfs_object_blksz() {
26245         local ost=$1
26246         local objid=$2
26247
26248         local vdevdir=$(dirname $(facet_vdevice $ost))
26249         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26250         local blksz=$(do_facet $ost $cmd $objid |
26251                       awk '/dblk/{getline; printf $4}')
26252
26253         case "${blksz: -1}" in
26254                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26255                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26256                 *) ;;
26257         esac
26258
26259         echo $blksz
26260 }
26261
26262 test_312() { # LU-4856
26263         remote_ost_nodsh && skip "remote OST with nodsh"
26264         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26265
26266         local max_blksz=$(do_facet ost1 \
26267                           $ZFS get -p recordsize $(facet_device ost1) |
26268                           awk '!/VALUE/{print $3}')
26269         local tf=$DIR/$tfile
26270
26271         $LFS setstripe -c1 $tf
26272         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26273
26274         # Get ZFS object id
26275         local zfs_objid=$(zfs_get_objid $facet $tf)
26276         # block size change by sequential overwrite
26277         local bs
26278
26279         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26280                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26281
26282                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26283                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26284         done
26285         rm -f $tf
26286
26287         $LFS setstripe -c1 $tf
26288         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26289
26290         # block size change by sequential append write
26291         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26292         zfs_objid=$(zfs_get_objid $facet $tf)
26293         local count
26294
26295         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26296                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26297                         oflag=sync conv=notrunc
26298
26299                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26300                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26301                         error "blksz error, actual $blksz, " \
26302                                 "expected: 2 * $count * $PAGE_SIZE"
26303         done
26304         rm -f $tf
26305
26306         # random write
26307         $LFS setstripe -c1 $tf
26308         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26309         zfs_objid=$(zfs_get_objid $facet $tf)
26310
26311         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26312         blksz=$(zfs_object_blksz $facet $zfs_objid)
26313         (( blksz == PAGE_SIZE )) ||
26314                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26315
26316         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26317         blksz=$(zfs_object_blksz $facet $zfs_objid)
26318         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26319
26320         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26321         blksz=$(zfs_object_blksz $facet $zfs_objid)
26322         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26323 }
26324 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26325
26326 test_313() {
26327         remote_ost_nodsh && skip "remote OST with nodsh"
26328
26329         local file=$DIR/$tfile
26330
26331         rm -f $file
26332         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26333
26334         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26335         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26336         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26337                 error "write should failed"
26338         do_facet ost1 "$LCTL set_param fail_loc=0"
26339         rm -f $file
26340 }
26341 run_test 313 "io should fail after last_rcvd update fail"
26342
26343 test_314() {
26344         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26345
26346         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26347         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26348         rm -f $DIR/$tfile
26349         wait_delete_completed
26350         do_facet ost1 "$LCTL set_param fail_loc=0"
26351 }
26352 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26353
26354 test_315() { # LU-618
26355         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26356
26357         local file=$DIR/$tfile
26358         rm -f $file
26359
26360         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26361                 error "multiop file write failed"
26362         $MULTIOP $file oO_RDONLY:r4063232_c &
26363         PID=$!
26364
26365         sleep 2
26366
26367         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26368         kill -USR1 $PID
26369
26370         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26371         rm -f $file
26372 }
26373 run_test 315 "read should be accounted"
26374
26375 test_316() {
26376         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26377         large_xattr_enabled || skip "ea_inode feature disabled"
26378
26379         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26380         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26381         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26382         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26383
26384         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26385 }
26386 run_test 316 "lfs migrate of file with large_xattr enabled"
26387
26388 test_317() {
26389         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26390                 skip "Need MDS version at least 2.11.53"
26391         if [ "$ost1_FSTYPE" == "zfs" ]; then
26392                 skip "LU-10370: no implementation for ZFS"
26393         fi
26394
26395         local trunc_sz
26396         local grant_blk_size
26397
26398         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26399                         awk '/grant_block_size:/ { print $2; exit; }')
26400         #
26401         # Create File of size 5M. Truncate it to below size's and verify
26402         # blocks count.
26403         #
26404         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26405                 error "Create file $DIR/$tfile failed"
26406         stack_trap "rm -f $DIR/$tfile" EXIT
26407
26408         for trunc_sz in 2097152 4097 4000 509 0; do
26409                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26410                         error "truncate $tfile to $trunc_sz failed"
26411                 local sz=$(stat --format=%s $DIR/$tfile)
26412                 local blk=$(stat --format=%b $DIR/$tfile)
26413                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26414                                      grant_blk_size) * 8))
26415
26416                 if [[ $blk -ne $trunc_blk ]]; then
26417                         $(which stat) $DIR/$tfile
26418                         error "Expected Block $trunc_blk got $blk for $tfile"
26419                 fi
26420
26421                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26422                         error "Expected Size $trunc_sz got $sz for $tfile"
26423         done
26424
26425         #
26426         # sparse file test
26427         # Create file with a hole and write actual 65536 bytes which aligned
26428         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26429         #
26430         local bs=65536
26431         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26432                 error "Create file : $DIR/$tfile"
26433
26434         #
26435         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26436         # blocks. The block count must drop to 8.
26437         #
26438         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26439                 ((bs - grant_blk_size) + 1)))
26440         $TRUNCATE $DIR/$tfile $trunc_sz ||
26441                 error "truncate $tfile to $trunc_sz failed"
26442
26443         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26444         sz=$(stat --format=%s $DIR/$tfile)
26445         blk=$(stat --format=%b $DIR/$tfile)
26446
26447         if [[ $blk -ne $trunc_bsz ]]; then
26448                 $(which stat) $DIR/$tfile
26449                 error "Expected Block $trunc_bsz got $blk for $tfile"
26450         fi
26451
26452         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26453                 error "Expected Size $trunc_sz got $sz for $tfile"
26454 }
26455 run_test 317 "Verify blocks get correctly update after truncate"
26456
26457 test_318() {
26458         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26459         local old_max_active=$($LCTL get_param -n \
26460                             ${llite_name}.max_read_ahead_async_active \
26461                             2>/dev/null)
26462
26463         $LCTL set_param llite.*.max_read_ahead_async_active=256
26464         local max_active=$($LCTL get_param -n \
26465                            ${llite_name}.max_read_ahead_async_active \
26466                            2>/dev/null)
26467         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26468
26469         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26470                 error "set max_read_ahead_async_active should succeed"
26471
26472         $LCTL set_param llite.*.max_read_ahead_async_active=512
26473         max_active=$($LCTL get_param -n \
26474                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26475         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26476
26477         # restore @max_active
26478         [ $old_max_active -ne 0 ] && $LCTL set_param \
26479                 llite.*.max_read_ahead_async_active=$old_max_active
26480
26481         local old_threshold=$($LCTL get_param -n \
26482                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26483         local max_per_file_mb=$($LCTL get_param -n \
26484                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26485
26486         local invalid=$(($max_per_file_mb + 1))
26487         $LCTL set_param \
26488                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26489                         && error "set $invalid should fail"
26490
26491         local valid=$(($invalid - 1))
26492         $LCTL set_param \
26493                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26494                         error "set $valid should succeed"
26495         local threshold=$($LCTL get_param -n \
26496                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26497         [ $threshold -eq $valid ] || error \
26498                 "expect threshold $valid got $threshold"
26499         $LCTL set_param \
26500                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26501 }
26502 run_test 318 "Verify async readahead tunables"
26503
26504 test_319() {
26505         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26506
26507         local before=$(date +%s)
26508         local evict
26509         local mdir=$DIR/$tdir
26510         local file=$mdir/xxx
26511
26512         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26513         touch $file
26514
26515 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26516         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26517         $LFS migrate -m1 $mdir &
26518
26519         sleep 1
26520         dd if=$file of=/dev/null
26521         wait
26522         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26523           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26524
26525         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26526 }
26527 run_test 319 "lost lease lock on migrate error"
26528
26529 test_398a() { # LU-4198
26530         local ost1_imp=$(get_osc_import_name client ost1)
26531         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26532                          cut -d'.' -f2)
26533
26534         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26535         stack_trap "rm -f $DIR/$tfile"
26536         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26537
26538         # request a new lock on client
26539         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26540
26541         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26542         local lock_count=$($LCTL get_param -n \
26543                            ldlm.namespaces.$imp_name.lru_size)
26544         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26545
26546         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26547
26548         # no lock cached, should use lockless DIO and not enqueue new lock
26549         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26550         lock_count=$($LCTL get_param -n \
26551                      ldlm.namespaces.$imp_name.lru_size)
26552         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26553
26554         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26555
26556         # no lock cached, should use locked DIO append
26557         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26558                 conv=notrunc || error "DIO append failed"
26559         lock_count=$($LCTL get_param -n \
26560                      ldlm.namespaces.$imp_name.lru_size)
26561         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26562 }
26563 run_test 398a "direct IO should cancel lock otherwise lockless"
26564
26565 test_398b() { # LU-4198
26566         local before=$(date +%s)
26567         local njobs=4
26568         local size=48
26569
26570         which fio || skip_env "no fio installed"
26571         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26572         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26573
26574         # Single page, multiple pages, stripe size, 4*stripe size
26575         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26576                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26577                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26578                         --numjobs=$njobs --fallocate=none \
26579                         --iodepth=16 --allow_file_create=0 \
26580                         --size=$((size/njobs))M \
26581                         --filename=$DIR/$tfile &
26582                 bg_pid=$!
26583
26584                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26585                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26586                         --numjobs=$njobs --fallocate=none \
26587                         --iodepth=16 --allow_file_create=0 \
26588                         --size=$((size/njobs))M \
26589                         --filename=$DIR/$tfile || true
26590                 wait $bg_pid
26591         done
26592
26593         evict=$(do_facet client $LCTL get_param \
26594                 osc.$FSNAME-OST*-osc-*/state |
26595             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26596
26597         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26598                 (do_facet client $LCTL get_param \
26599                         osc.$FSNAME-OST*-osc-*/state;
26600                     error "eviction happened: $evict before:$before")
26601
26602         rm -f $DIR/$tfile
26603 }
26604 run_test 398b "DIO and buffer IO race"
26605
26606 test_398c() { # LU-4198
26607         local ost1_imp=$(get_osc_import_name client ost1)
26608         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26609                          cut -d'.' -f2)
26610
26611         which fio || skip_env "no fio installed"
26612
26613         saved_debug=$($LCTL get_param -n debug)
26614         $LCTL set_param debug=0
26615
26616         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26617         ((size /= 1024)) # by megabytes
26618         ((size /= 2)) # write half of the OST at most
26619         [ $size -gt 40 ] && size=40 #reduce test time anyway
26620
26621         $LFS setstripe -c 1 $DIR/$tfile
26622
26623         # it seems like ldiskfs reserves more space than necessary if the
26624         # writing blocks are not mapped, so it extends the file firstly
26625         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26626         cancel_lru_locks osc
26627
26628         # clear and verify rpc_stats later
26629         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26630
26631         local njobs=4
26632         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26633         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26634                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26635                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26636                 --filename=$DIR/$tfile
26637         [ $? -eq 0 ] || error "fio write error"
26638
26639         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26640                 error "Locks were requested while doing AIO"
26641
26642         # get the percentage of 1-page I/O
26643         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26644                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26645                 awk '{print $7}')
26646         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26647
26648         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26649         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26650                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26651                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26652                 --filename=$DIR/$tfile
26653         [ $? -eq 0 ] || error "fio mixed read write error"
26654
26655         echo "AIO with large block size ${size}M"
26656         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26657                 --numjobs=1 --fallocate=none --ioengine=libaio \
26658                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26659                 --filename=$DIR/$tfile
26660         [ $? -eq 0 ] || error "fio large block size failed"
26661
26662         rm -f $DIR/$tfile
26663         $LCTL set_param debug="$saved_debug"
26664 }
26665 run_test 398c "run fio to test AIO"
26666
26667 test_398d() { #  LU-13846
26668         which aiocp || skip_env "no aiocp installed"
26669         local aio_file=$DIR/$tfile.aio
26670
26671         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26672
26673         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26674         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26675         stack_trap "rm -f $DIR/$tfile $aio_file"
26676
26677         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26678
26679         # test memory unaligned aio
26680         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26681                 error "unaligned aio failed"
26682         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26683
26684         rm -f $DIR/$tfile $aio_file
26685 }
26686 run_test 398d "run aiocp to verify block size > stripe size"
26687
26688 test_398e() {
26689         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26690         touch $DIR/$tfile.new
26691         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26692 }
26693 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26694
26695 test_398f() { #  LU-14687
26696         which aiocp || skip_env "no aiocp installed"
26697         local aio_file=$DIR/$tfile.aio
26698
26699         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26700
26701         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26702         stack_trap "rm -f $DIR/$tfile $aio_file"
26703
26704         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26705         $LCTL set_param fail_loc=0x1418
26706         # make sure we don't crash and fail properly
26707         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26708                 error "aio with page allocation failure succeeded"
26709         $LCTL set_param fail_loc=0
26710         diff $DIR/$tfile $aio_file
26711         [[ $? != 0 ]] || error "no diff after failed aiocp"
26712 }
26713 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26714
26715 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26716 # stripe and i/o size must be > stripe size
26717 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26718 # single RPC in flight.  This test shows async DIO submission is working by
26719 # showing multiple RPCs in flight.
26720 test_398g() { #  LU-13798
26721         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26722
26723         # We need to do some i/o first to acquire enough grant to put our RPCs
26724         # in flight; otherwise a new connection may not have enough grant
26725         # available
26726         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26727                 error "parallel dio failed"
26728         stack_trap "rm -f $DIR/$tfile"
26729
26730         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26731         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26732         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26733         stack_trap "$LCTL set_param -n $pages_per_rpc"
26734
26735         # Recreate file so it's empty
26736         rm -f $DIR/$tfile
26737         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26738         #Pause rpc completion to guarantee we see multiple rpcs in flight
26739         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26740         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26741         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26742
26743         # Clear rpc stats
26744         $LCTL set_param osc.*.rpc_stats=c
26745
26746         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26747                 error "parallel dio failed"
26748         stack_trap "rm -f $DIR/$tfile"
26749
26750         $LCTL get_param osc.*-OST0000-*.rpc_stats
26751         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26752                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26753                 grep "8:" | awk '{print $8}')
26754         # We look at the "8 rpcs in flight" field, and verify A) it is present
26755         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26756         # as expected for an 8M DIO to a file with 1M stripes.
26757         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26758
26759         # Verify turning off parallel dio works as expected
26760         # Clear rpc stats
26761         $LCTL set_param osc.*.rpc_stats=c
26762         $LCTL set_param llite.*.parallel_dio=0
26763         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26764
26765         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26766                 error "dio with parallel dio disabled failed"
26767
26768         # Ideally, we would see only one RPC in flight here, but there is an
26769         # unavoidable race between i/o completion and RPC in flight counting,
26770         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26771         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26772         # So instead we just verify it's always < 8.
26773         $LCTL get_param osc.*-OST0000-*.rpc_stats
26774         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26775                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26776                 grep '^$' -B1 | grep . | awk '{print $1}')
26777         [ $ret != "8:" ] ||
26778                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26779 }
26780 run_test 398g "verify parallel dio async RPC submission"
26781
26782 test_398h() { #  LU-13798
26783         local dio_file=$DIR/$tfile.dio
26784
26785         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26786
26787         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26788         stack_trap "rm -f $DIR/$tfile $dio_file"
26789
26790         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26791                 error "parallel dio failed"
26792         diff $DIR/$tfile $dio_file
26793         [[ $? == 0 ]] || error "file diff after aiocp"
26794 }
26795 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26796
26797 test_398i() { #  LU-13798
26798         local dio_file=$DIR/$tfile.dio
26799
26800         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26801
26802         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26803         stack_trap "rm -f $DIR/$tfile $dio_file"
26804
26805         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26806         $LCTL set_param fail_loc=0x1418
26807         # make sure we don't crash and fail properly
26808         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26809                 error "parallel dio page allocation failure succeeded"
26810         diff $DIR/$tfile $dio_file
26811         [[ $? != 0 ]] || error "no diff after failed aiocp"
26812 }
26813 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26814
26815 test_398j() { #  LU-13798
26816         # Stripe size > RPC size but less than i/o size tests split across
26817         # stripes and RPCs for individual i/o op
26818         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26819
26820         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26821         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26822         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26823         stack_trap "$LCTL set_param -n $pages_per_rpc"
26824
26825         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26826                 error "parallel dio write failed"
26827         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26828
26829         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26830                 error "parallel dio read failed"
26831         diff $DIR/$tfile $DIR/$tfile.2
26832         [[ $? == 0 ]] || error "file diff after parallel dio read"
26833 }
26834 run_test 398j "test parallel dio where stripe size > rpc_size"
26835
26836 test_398k() { #  LU-13798
26837         wait_delete_completed
26838         wait_mds_ost_sync
26839
26840         # 4 stripe file; we will cause out of space on OST0
26841         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26842
26843         # Fill OST0 (if it's not too large)
26844         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26845                    head -n1)
26846         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26847                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26848         fi
26849         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26850         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26851                 error "dd should fill OST0"
26852         stack_trap "rm -f $DIR/$tfile.1"
26853
26854         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26855         err=$?
26856
26857         ls -la $DIR/$tfile
26858         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26859                 error "file is not 0 bytes in size"
26860
26861         # dd above should not succeed, but don't error until here so we can
26862         # get debug info above
26863         [[ $err != 0 ]] ||
26864                 error "parallel dio write with enospc succeeded"
26865         stack_trap "rm -f $DIR/$tfile"
26866 }
26867 run_test 398k "test enospc on first stripe"
26868
26869 test_398l() { #  LU-13798
26870         wait_delete_completed
26871         wait_mds_ost_sync
26872
26873         # 4 stripe file; we will cause out of space on OST0
26874         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26875         # happens on the second i/o chunk we issue
26876         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26877
26878         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26879         stack_trap "rm -f $DIR/$tfile"
26880
26881         # Fill OST0 (if it's not too large)
26882         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26883                    head -n1)
26884         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26885                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26886         fi
26887         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26888         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26889                 error "dd should fill OST0"
26890         stack_trap "rm -f $DIR/$tfile.1"
26891
26892         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26893         err=$?
26894         stack_trap "rm -f $DIR/$tfile.2"
26895
26896         # Check that short write completed as expected
26897         ls -la $DIR/$tfile.2
26898         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26899                 error "file is not 1M in size"
26900
26901         # dd above should not succeed, but don't error until here so we can
26902         # get debug info above
26903         [[ $err != 0 ]] ||
26904                 error "parallel dio write with enospc succeeded"
26905
26906         # Truncate source file to same length as output file and diff them
26907         $TRUNCATE $DIR/$tfile 1048576
26908         diff $DIR/$tfile $DIR/$tfile.2
26909         [[ $? == 0 ]] || error "data incorrect after short write"
26910 }
26911 run_test 398l "test enospc on intermediate stripe/RPC"
26912
26913 test_398m() { #  LU-13798
26914         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26915
26916         # Set up failure on OST0, the first stripe:
26917         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26918         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26919         # OST0 is on ost1, OST1 is on ost2.
26920         # So this fail_val specifies OST0
26921         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26922         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26923
26924         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26925                 error "parallel dio write with failure on first stripe succeeded"
26926         stack_trap "rm -f $DIR/$tfile"
26927         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26928
26929         # Place data in file for read
26930         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26931                 error "parallel dio write failed"
26932
26933         # Fail read on OST0, first stripe
26934         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26935         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26936         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26937                 error "parallel dio read with error on first stripe succeeded"
26938         rm -f $DIR/$tfile.2
26939         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26940
26941         # Switch to testing on OST1, second stripe
26942         # Clear file contents, maintain striping
26943         echo > $DIR/$tfile
26944         # Set up failure on OST1, second stripe:
26945         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26946         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26947
26948         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26949                 error "parallel dio write with failure on second stripe succeeded"
26950         stack_trap "rm -f $DIR/$tfile"
26951         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26952
26953         # Place data in file for read
26954         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26955                 error "parallel dio write failed"
26956
26957         # Fail read on OST1, second stripe
26958         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26959         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26960         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26961                 error "parallel dio read with error on second stripe succeeded"
26962         rm -f $DIR/$tfile.2
26963         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26964 }
26965 run_test 398m "test RPC failures with parallel dio"
26966
26967 # Parallel submission of DIO should not cause problems for append, but it's
26968 # important to verify.
26969 test_398n() { #  LU-13798
26970         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26971
26972         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26973                 error "dd to create source file failed"
26974         stack_trap "rm -f $DIR/$tfile"
26975
26976         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26977                 error "parallel dio write with failure on second stripe succeeded"
26978         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26979         diff $DIR/$tfile $DIR/$tfile.1
26980         [[ $? == 0 ]] || error "data incorrect after append"
26981
26982 }
26983 run_test 398n "test append with parallel DIO"
26984
26985 test_398o() {
26986         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26987 }
26988 run_test 398o "right kms with DIO"
26989
26990 test_398p()
26991 {
26992         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26993         which aiocp || skip_env "no aiocp installed"
26994
26995         local stripe_size=$((1024 * 1024)) #1 MiB
26996         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26997         local file_size=$((25 * stripe_size))
26998
26999         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27000         stack_trap "rm -f $DIR/$tfile*"
27001         # Just a bit bigger than the largest size in the test set below
27002         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27003                 error "buffered i/o to create file failed"
27004
27005         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27006                 $((stripe_size * 4)); do
27007
27008                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27009
27010                 echo "bs: $bs, file_size $file_size"
27011                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27012                         $DIR/$tfile.1 $DIR/$tfile.2 &
27013                 pid_dio1=$!
27014                 # Buffered I/O with similar but not the same block size
27015                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27016                         conv=notrunc &
27017                 pid_bio2=$!
27018                 wait $pid_dio1
27019                 rc1=$?
27020                 wait $pid_bio2
27021                 rc2=$?
27022                 if (( rc1 != 0 )); then
27023                         error "aio copy 1 w/bsize $bs failed: $rc1"
27024                 fi
27025                 if (( rc2 != 0 )); then
27026                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27027                 fi
27028
27029                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27030                         error "size incorrect"
27031                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27032                         error "files differ, bsize $bs"
27033                 rm -f $DIR/$tfile.2
27034         done
27035 }
27036 run_test 398p "race aio with buffered i/o"
27037
27038 test_398q()
27039 {
27040         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27041
27042         local stripe_size=$((1024 * 1024)) #1 MiB
27043         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27044         local file_size=$((25 * stripe_size))
27045
27046         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27047         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27048
27049         # Just a bit bigger than the largest size in the test set below
27050         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27051                 error "buffered i/o to create file failed"
27052
27053         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27054                 $((stripe_size * 4)); do
27055
27056                 echo "bs: $bs, file_size $file_size"
27057                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
27058                         conv=notrunc oflag=direct iflag=direct &
27059                 pid_dio1=$!
27060                 # Buffered I/O with similar but not the same block size
27061                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27062                         conv=notrunc &
27063                 pid_bio2=$!
27064                 wait $pid_dio1
27065                 rc1=$?
27066                 wait $pid_bio2
27067                 rc2=$?
27068                 if (( rc1 != 0 )); then
27069                         error "dio copy 1 w/bsize $bs failed: $rc1"
27070                 fi
27071                 if (( rc2 != 0 )); then
27072                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27073                 fi
27074
27075                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27076                         error "size incorrect"
27077                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27078                         error "files differ, bsize $bs"
27079         done
27080
27081         rm -f $DIR/$tfile*
27082 }
27083 run_test 398q "race dio with buffered i/o"
27084
27085 test_fake_rw() {
27086         local read_write=$1
27087         if [ "$read_write" = "write" ]; then
27088                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27089         elif [ "$read_write" = "read" ]; then
27090                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27091         else
27092                 error "argument error"
27093         fi
27094
27095         # turn off debug for performance testing
27096         local saved_debug=$($LCTL get_param -n debug)
27097         $LCTL set_param debug=0
27098
27099         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27100
27101         # get ost1 size - $FSNAME-OST0000
27102         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27103         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27104         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27105
27106         if [ "$read_write" = "read" ]; then
27107                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27108         fi
27109
27110         local start_time=$(date +%s.%N)
27111         $dd_cmd bs=1M count=$blocks oflag=sync ||
27112                 error "real dd $read_write error"
27113         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27114
27115         if [ "$read_write" = "write" ]; then
27116                 rm -f $DIR/$tfile
27117         fi
27118
27119         # define OBD_FAIL_OST_FAKE_RW           0x238
27120         do_facet ost1 $LCTL set_param fail_loc=0x238
27121
27122         local start_time=$(date +%s.%N)
27123         $dd_cmd bs=1M count=$blocks oflag=sync ||
27124                 error "fake dd $read_write error"
27125         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27126
27127         if [ "$read_write" = "write" ]; then
27128                 # verify file size
27129                 cancel_lru_locks osc
27130                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27131                         error "$tfile size not $blocks MB"
27132         fi
27133         do_facet ost1 $LCTL set_param fail_loc=0
27134
27135         echo "fake $read_write $duration_fake vs. normal $read_write" \
27136                 "$duration in seconds"
27137         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27138                 error_not_in_vm "fake write is slower"
27139
27140         $LCTL set_param -n debug="$saved_debug"
27141         rm -f $DIR/$tfile
27142 }
27143 test_399a() { # LU-7655 for OST fake write
27144         remote_ost_nodsh && skip "remote OST with nodsh"
27145
27146         test_fake_rw write
27147 }
27148 run_test 399a "fake write should not be slower than normal write"
27149
27150 test_399b() { # LU-8726 for OST fake read
27151         remote_ost_nodsh && skip "remote OST with nodsh"
27152         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27153                 skip_env "ldiskfs only test"
27154         fi
27155
27156         test_fake_rw read
27157 }
27158 run_test 399b "fake read should not be slower than normal read"
27159
27160 test_400a() { # LU-1606, was conf-sanity test_74
27161         if ! which $CC > /dev/null 2>&1; then
27162                 skip_env "$CC is not installed"
27163         fi
27164
27165         local extra_flags=''
27166         local out=$TMP/$tfile
27167         local prefix=/usr/include/lustre
27168         local prog
27169
27170         # Oleg removes .c files in his test rig so test if any c files exist
27171         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27172                 skip_env "Needed .c test files are missing"
27173
27174         if ! [[ -d $prefix ]]; then
27175                 # Assume we're running in tree and fixup the include path.
27176                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27177                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27178                 extra_flags+=" -L$LUSTRE/utils/.libs"
27179         fi
27180
27181         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27182                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27183                         error "client api broken"
27184         done
27185         rm -f $out
27186 }
27187 run_test 400a "Lustre client api program can compile and link"
27188
27189 test_400b() { # LU-1606, LU-5011
27190         local header
27191         local out=$TMP/$tfile
27192         local prefix=/usr/include/linux/lustre
27193
27194         # We use a hard coded prefix so that this test will not fail
27195         # when run in tree. There are headers in lustre/include/lustre/
27196         # that are not packaged (like lustre_idl.h) and have more
27197         # complicated include dependencies (like config.h and lnet/types.h).
27198         # Since this test about correct packaging we just skip them when
27199         # they don't exist (see below) rather than try to fixup cppflags.
27200
27201         if ! which $CC > /dev/null 2>&1; then
27202                 skip_env "$CC is not installed"
27203         fi
27204
27205         for header in $prefix/*.h; do
27206                 if ! [[ -f "$header" ]]; then
27207                         continue
27208                 fi
27209
27210                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27211                         continue # lustre_ioctl.h is internal header
27212                 fi
27213
27214                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27215                         error "cannot compile '$header'"
27216         done
27217         rm -f $out
27218 }
27219 run_test 400b "packaged headers can be compiled"
27220
27221 test_401a() { #LU-7437
27222         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27223         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27224
27225         #count the number of parameters by "list_param -R"
27226         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27227         #count the number of parameters by listing proc files
27228         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27229         echo "proc_dirs='$proc_dirs'"
27230         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27231         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27232                       sort -u | wc -l)
27233
27234         [ $params -eq $procs ] ||
27235                 error "found $params parameters vs. $procs proc files"
27236
27237         # test the list_param -D option only returns directories
27238         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27239         #count the number of parameters by listing proc directories
27240         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27241                 sort -u | wc -l)
27242
27243         [ $params -eq $procs ] ||
27244                 error "found $params parameters vs. $procs proc files"
27245 }
27246 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27247
27248 test_401b() {
27249         # jobid_var may not allow arbitrary values, so use jobid_name
27250         # if available
27251         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27252                 local testname=jobid_name tmp='testing%p'
27253         else
27254                 local testname=jobid_var tmp=testing
27255         fi
27256
27257         local save=$($LCTL get_param -n $testname)
27258
27259         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27260                 error "no error returned when setting bad parameters"
27261
27262         local jobid_new=$($LCTL get_param -n foe $testname baz)
27263         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27264
27265         $LCTL set_param -n fog=bam $testname=$save bat=fog
27266         local jobid_old=$($LCTL get_param -n foe $testname bag)
27267         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27268 }
27269 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27270
27271 test_401c() {
27272         # jobid_var may not allow arbitrary values, so use jobid_name
27273         # if available
27274         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27275                 local testname=jobid_name
27276         else
27277                 local testname=jobid_var
27278         fi
27279
27280         local jobid_var_old=$($LCTL get_param -n $testname)
27281         local jobid_var_new
27282
27283         $LCTL set_param $testname= &&
27284                 error "no error returned for 'set_param a='"
27285
27286         jobid_var_new=$($LCTL get_param -n $testname)
27287         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27288                 error "$testname was changed by setting without value"
27289
27290         $LCTL set_param $testname &&
27291                 error "no error returned for 'set_param a'"
27292
27293         jobid_var_new=$($LCTL get_param -n $testname)
27294         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27295                 error "$testname was changed by setting without value"
27296 }
27297 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27298
27299 test_401d() {
27300         # jobid_var may not allow arbitrary values, so use jobid_name
27301         # if available
27302         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27303                 local testname=jobid_name new_value='foo=bar%p'
27304         else
27305                 local testname=jobid_var new_valuie=foo=bar
27306         fi
27307
27308         local jobid_var_old=$($LCTL get_param -n $testname)
27309         local jobid_var_new
27310
27311         $LCTL set_param $testname=$new_value ||
27312                 error "'set_param a=b' did not accept a value containing '='"
27313
27314         jobid_var_new=$($LCTL get_param -n $testname)
27315         [[ "$jobid_var_new" == "$new_value" ]] ||
27316                 error "'set_param a=b' failed on a value containing '='"
27317
27318         # Reset the $testname to test the other format
27319         $LCTL set_param $testname=$jobid_var_old
27320         jobid_var_new=$($LCTL get_param -n $testname)
27321         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27322                 error "failed to reset $testname"
27323
27324         $LCTL set_param $testname $new_value ||
27325                 error "'set_param a b' did not accept a value containing '='"
27326
27327         jobid_var_new=$($LCTL get_param -n $testname)
27328         [[ "$jobid_var_new" == "$new_value" ]] ||
27329                 error "'set_param a b' failed on a value containing '='"
27330
27331         $LCTL set_param $testname $jobid_var_old
27332         jobid_var_new=$($LCTL get_param -n $testname)
27333         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27334                 error "failed to reset $testname"
27335 }
27336 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27337
27338 test_401e() { # LU-14779
27339         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27340                 error "lctl list_param MGC* failed"
27341         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27342         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27343                 error "lctl get_param lru_size failed"
27344 }
27345 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27346
27347 test_402() {
27348         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27349         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27350                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27351         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27352                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27353                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27354         remote_mds_nodsh && skip "remote MDS with nodsh"
27355
27356         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27357 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27358         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27359         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27360                 echo "Touch failed - OK"
27361 }
27362 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27363
27364 test_403() {
27365         local file1=$DIR/$tfile.1
27366         local file2=$DIR/$tfile.2
27367         local tfile=$TMP/$tfile
27368
27369         rm -f $file1 $file2 $tfile
27370
27371         touch $file1
27372         ln $file1 $file2
27373
27374         # 30 sec OBD_TIMEOUT in ll_getattr()
27375         # right before populating st_nlink
27376         $LCTL set_param fail_loc=0x80001409
27377         stat -c %h $file1 > $tfile &
27378
27379         # create an alias, drop all locks and reclaim the dentry
27380         < $file2
27381         cancel_lru_locks mdc
27382         cancel_lru_locks osc
27383         sysctl -w vm.drop_caches=2
27384
27385         wait
27386
27387         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27388
27389         rm -f $tfile $file1 $file2
27390 }
27391 run_test 403 "i_nlink should not drop to zero due to aliasing"
27392
27393 test_404() { # LU-6601
27394         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27395                 skip "Need server version newer than 2.8.52"
27396         remote_mds_nodsh && skip "remote MDS with nodsh"
27397
27398         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27399                 awk '/osp .*-osc-MDT/ { print $4}')
27400
27401         local osp
27402         for osp in $mosps; do
27403                 echo "Deactivate: " $osp
27404                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27405                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27406                         awk -vp=$osp '$4 == p { print $2 }')
27407                 [ $stat = IN ] || {
27408                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27409                         error "deactivate error"
27410                 }
27411                 echo "Activate: " $osp
27412                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27413                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27414                         awk -vp=$osp '$4 == p { print $2 }')
27415                 [ $stat = UP ] || {
27416                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27417                         error "activate error"
27418                 }
27419         done
27420 }
27421 run_test 404 "validate manual {de}activated works properly for OSPs"
27422
27423 test_405() {
27424         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27425         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27426                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27427                         skip "Layout swap lock is not supported"
27428
27429         check_swap_layouts_support
27430         check_swap_layout_no_dom $DIR
27431
27432         test_mkdir $DIR/$tdir
27433         swap_lock_test -d $DIR/$tdir ||
27434                 error "One layout swap locked test failed"
27435 }
27436 run_test 405 "Various layout swap lock tests"
27437
27438 test_406() {
27439         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27440         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27441         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27443         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27444                 skip "Need MDS version at least 2.8.50"
27445
27446         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27447         local test_pool=$TESTNAME
27448
27449         pool_add $test_pool || error "pool_add failed"
27450         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27451                 error "pool_add_targets failed"
27452
27453         save_layout_restore_at_exit $MOUNT
27454
27455         # parent set default stripe count only, child will stripe from both
27456         # parent and fs default
27457         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27458                 error "setstripe $MOUNT failed"
27459         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27460         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27461         for i in $(seq 10); do
27462                 local f=$DIR/$tdir/$tfile.$i
27463                 touch $f || error "touch failed"
27464                 local count=$($LFS getstripe -c $f)
27465                 [ $count -eq $OSTCOUNT ] ||
27466                         error "$f stripe count $count != $OSTCOUNT"
27467                 local offset=$($LFS getstripe -i $f)
27468                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27469                 local size=$($LFS getstripe -S $f)
27470                 [ $size -eq $((def_stripe_size * 2)) ] ||
27471                         error "$f stripe size $size != $((def_stripe_size * 2))"
27472                 local pool=$($LFS getstripe -p $f)
27473                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27474         done
27475
27476         # change fs default striping, delete parent default striping, now child
27477         # will stripe from new fs default striping only
27478         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27479                 error "change $MOUNT default stripe failed"
27480         $LFS setstripe -c 0 $DIR/$tdir ||
27481                 error "delete $tdir default stripe failed"
27482         for i in $(seq 11 20); do
27483                 local f=$DIR/$tdir/$tfile.$i
27484                 touch $f || error "touch $f failed"
27485                 local count=$($LFS getstripe -c $f)
27486                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27487                 local offset=$($LFS getstripe -i $f)
27488                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27489                 local size=$($LFS getstripe -S $f)
27490                 [ $size -eq $def_stripe_size ] ||
27491                         error "$f stripe size $size != $def_stripe_size"
27492                 local pool=$($LFS getstripe -p $f)
27493                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27494         done
27495
27496         unlinkmany $DIR/$tdir/$tfile. 1 20
27497
27498         local f=$DIR/$tdir/$tfile
27499         pool_remove_all_targets $test_pool $f
27500         pool_remove $test_pool $f
27501 }
27502 run_test 406 "DNE support fs default striping"
27503
27504 test_407() {
27505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27506         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27507                 skip "Need MDS version at least 2.8.55"
27508         remote_mds_nodsh && skip "remote MDS with nodsh"
27509
27510         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27511                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27512         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27513                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27514         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27515
27516         #define OBD_FAIL_DT_TXN_STOP    0x2019
27517         for idx in $(seq $MDSCOUNT); do
27518                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27519         done
27520         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27521         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27522                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27523         true
27524 }
27525 run_test 407 "transaction fail should cause operation fail"
27526
27527 test_408() {
27528         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27529
27530         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27531         lctl set_param fail_loc=0x8000040a
27532         # let ll_prepare_partial_page() fail
27533         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27534
27535         rm -f $DIR/$tfile
27536
27537         # create at least 100 unused inodes so that
27538         # shrink_icache_memory(0) should not return 0
27539         touch $DIR/$tfile-{0..100}
27540         rm -f $DIR/$tfile-{0..100}
27541         sync
27542
27543         echo 2 > /proc/sys/vm/drop_caches
27544 }
27545 run_test 408 "drop_caches should not hang due to page leaks"
27546
27547 test_409()
27548 {
27549         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27550
27551         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27552         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27553         touch $DIR/$tdir/guard || error "(2) Fail to create"
27554
27555         local PREFIX=$(str_repeat 'A' 128)
27556         echo "Create 1K hard links start at $(date)"
27557         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27558                 error "(3) Fail to hard link"
27559
27560         echo "Links count should be right although linkEA overflow"
27561         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27562         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27563         [ $linkcount -eq 1001 ] ||
27564                 error "(5) Unexpected hard links count: $linkcount"
27565
27566         echo "List all links start at $(date)"
27567         ls -l $DIR/$tdir/foo > /dev/null ||
27568                 error "(6) Fail to list $DIR/$tdir/foo"
27569
27570         echo "Unlink hard links start at $(date)"
27571         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27572                 error "(7) Fail to unlink"
27573         echo "Unlink hard links finished at $(date)"
27574 }
27575 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27576
27577 test_410()
27578 {
27579         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27580                 skip "Need client version at least 2.9.59"
27581         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27582                 skip "Need MODULES build"
27583
27584         # Create a file, and stat it from the kernel
27585         local testfile=$DIR/$tfile
27586         touch $testfile
27587
27588         local run_id=$RANDOM
27589         local my_ino=$(stat --format "%i" $testfile)
27590
27591         # Try to insert the module. This will always fail as the
27592         # module is designed to not be inserted.
27593         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27594             &> /dev/null
27595
27596         # Anything but success is a test failure
27597         dmesg | grep -q \
27598             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27599             error "no inode match"
27600 }
27601 run_test 410 "Test inode number returned from kernel thread"
27602
27603 cleanup_test411_cgroup() {
27604         trap 0
27605         cat $1/memory.stat
27606         rmdir "$1"
27607 }
27608
27609 test_411a() {
27610         local cg_basedir=/sys/fs/cgroup/memory
27611         # LU-9966
27612         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27613                 skip "no setup for cgroup"
27614
27615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27616                 error "test file creation failed"
27617         cancel_lru_locks osc
27618
27619         # Create a very small memory cgroup to force a slab allocation error
27620         local cgdir=$cg_basedir/osc_slab_alloc
27621         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27622         trap "cleanup_test411_cgroup $cgdir" EXIT
27623         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27624         echo 1M > $cgdir/memory.limit_in_bytes
27625
27626         # Should not LBUG, just be killed by oom-killer
27627         # dd will return 0 even allocation failure in some environment.
27628         # So don't check return value
27629         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27630         cleanup_test411_cgroup $cgdir
27631
27632         return 0
27633 }
27634 run_test 411a "Slab allocation error with cgroup does not LBUG"
27635
27636 test_411b() {
27637         local cg_basedir=/sys/fs/cgroup/memory
27638         # LU-9966
27639         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27640                 skip "no setup for cgroup"
27641         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27642         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27643         # limit, so we have 384M in cgroup
27644         # (arm) this seems to hit OOM more often than x86, so 1024M
27645         if [[ $(uname -m) = aarch64 ]]; then
27646                 local memlimit_mb=1024
27647         else
27648                 local memlimit_mb=384
27649         fi
27650
27651         # Create a cgroup and set memory limit
27652         # (tfile is used as an easy way to get a recognizable cgroup name)
27653         local cgdir=$cg_basedir/$tfile
27654         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27655         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27656         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27657
27658         echo "writing first file"
27659         # Write a file 4x the memory limit in size
27660         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27661                 error "(1) failed to write successfully"
27662
27663         sync
27664         cancel_lru_locks osc
27665
27666         rm -f $DIR/$tfile
27667         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27668
27669         # Try writing at a larger block size
27670         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27671         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27672         # need *some* memory to do IO in)
27673         echo "writing at larger block size"
27674         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27675                 error "(3) failed to write successfully"
27676
27677         sync
27678         cancel_lru_locks osc
27679         rm -f $DIR/$tfile
27680         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27681
27682         # Try writing multiple files at once
27683         echo "writing multiple files"
27684         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27685         local pid1=$!
27686         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27687         local pid2=$!
27688         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27689         local pid3=$!
27690         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27691         local pid4=$!
27692
27693         wait $pid1
27694         local rc1=$?
27695         wait $pid2
27696         local rc2=$?
27697         wait $pid3
27698         local rc3=$?
27699         wait $pid4
27700         local rc4=$?
27701         if (( rc1 != 0)); then
27702                 error "error $rc1 writing to file from $pid1"
27703         fi
27704         if (( rc2 != 0)); then
27705                 error "error $rc2 writing to file from $pid2"
27706         fi
27707         if (( rc3 != 0)); then
27708                 error "error $rc3 writing to file from $pid3"
27709         fi
27710         if (( rc4 != 0)); then
27711                 error "error $rc4 writing to file from $pid4"
27712         fi
27713
27714         sync
27715         cancel_lru_locks osc
27716
27717         # These files can be large-ish (~1 GiB total), so delete them rather
27718         # than leave for later cleanup
27719         rm -f $DIR/$tfile.*
27720         return 0
27721 }
27722 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27723
27724 test_412() {
27725         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27726         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27727                 skip "Need server version at least 2.10.55"
27728
27729         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27730                 error "mkdir failed"
27731         $LFS getdirstripe $DIR/$tdir
27732         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27733         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27734                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27735         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27736         [ $stripe_count -eq 2 ] ||
27737                 error "expect 2 get $stripe_count"
27738
27739         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27740
27741         local index
27742         local index2
27743
27744         # subdirs should be on the same MDT as parent
27745         for i in $(seq 0 $((MDSCOUNT - 1))); do
27746                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27747                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27748                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27749                 (( index == i )) || error "mdt$i/sub on MDT$index"
27750         done
27751
27752         # stripe offset -1, ditto
27753         for i in {1..10}; do
27754                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27755                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27756                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27757                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27758                 (( index == index2 )) ||
27759                         error "qos$i on MDT$index, sub on MDT$index2"
27760         done
27761
27762         local testdir=$DIR/$tdir/inherit
27763
27764         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27765         # inherit 2 levels
27766         for i in 1 2; do
27767                 testdir=$testdir/s$i
27768                 mkdir $testdir || error "mkdir $testdir failed"
27769                 index=$($LFS getstripe -m $testdir)
27770                 (( index == 1 )) ||
27771                         error "$testdir on MDT$index"
27772         done
27773
27774         # not inherit any more
27775         testdir=$testdir/s3
27776         mkdir $testdir || error "mkdir $testdir failed"
27777         getfattr -d -m dmv $testdir | grep dmv &&
27778                 error "default LMV set on $testdir" || true
27779 }
27780 run_test 412 "mkdir on specific MDTs"
27781
27782 TEST413_COUNT=${TEST413_COUNT:-200}
27783
27784 #
27785 # set_maxage() is used by test_413 only.
27786 # This is a helper function to set maxage. Does not return any value.
27787 # Input: maxage to set
27788 #
27789 set_maxage() {
27790         local lmv_qos_maxage
27791         local lod_qos_maxage
27792         local new_maxage=$1
27793
27794         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27795         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27796         stack_trap "$LCTL set_param \
27797                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27798         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27799                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27800         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27801                 lod.*.mdt_qos_maxage=$new_maxage
27802         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27803                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27804 }
27805
27806 generate_uneven_mdts() {
27807         local threshold=$1
27808         local ffree
27809         local bavail
27810         local max
27811         local min
27812         local max_index
27813         local min_index
27814         local tmp
27815         local i
27816
27817         echo
27818         echo "Check for uneven MDTs: "
27819
27820         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27821         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27822         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27823
27824         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27825         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27826         max_index=0
27827         min_index=0
27828         for ((i = 1; i < ${#ffree[@]}; i++)); do
27829                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27830                 if [ $tmp -gt $max ]; then
27831                         max=$tmp
27832                         max_index=$i
27833                 fi
27834                 if [ $tmp -lt $min ]; then
27835                         min=$tmp
27836                         min_index=$i
27837                 fi
27838         done
27839
27840         (( min > 0 )) || skip "low space on MDT$min_index"
27841         (( ${ffree[min_index]} > 0 )) ||
27842                 skip "no free files on MDT$min_index"
27843         (( ${ffree[min_index]} < 10000000 )) ||
27844                 skip "too many free files on MDT$min_index"
27845
27846         # Check if we need to generate uneven MDTs
27847         local diff=$(((max - min) * 100 / min))
27848         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27849         local testdir # individual folder within $testdirp
27850         local start
27851         local cmd
27852
27853         # fallocate is faster to consume space on MDT, if available
27854         if check_fallocate_supported mds$((min_index + 1)); then
27855                 cmd="fallocate -l 128K "
27856         else
27857                 cmd="dd if=/dev/zero bs=128K count=1 of="
27858         fi
27859
27860         echo "using cmd $cmd"
27861         for (( i = 0; diff < threshold; i++ )); do
27862                 testdir=${testdirp}/$i
27863                 [ -d $testdir ] && continue
27864
27865                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27866
27867                 mkdir -p $testdirp
27868                 # generate uneven MDTs, create till $threshold% diff
27869                 echo -n "weight diff=$diff% must be > $threshold% ..."
27870                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27871                 $LFS mkdir -i $min_index $testdir ||
27872                         error "mkdir $testdir failed"
27873                 $LFS setstripe -E 1M -L mdt $testdir ||
27874                         error "setstripe $testdir failed"
27875                 start=$SECONDS
27876                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27877                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27878                 done
27879                 sync; sleep 1; sync
27880
27881                 # wait for QOS to update
27882                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27883
27884                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27885                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27886                 max=$(((${ffree[max_index]} >> 8) *
27887                         (${bavail[max_index]} * bsize >> 16)))
27888                 min=$(((${ffree[min_index]} >> 8) *
27889                         (${bavail[min_index]} * bsize >> 16)))
27890                 (( min > 0 )) || skip "low space on MDT$min_index"
27891                 diff=$(((max - min) * 100 / min))
27892         done
27893
27894         echo "MDT filesfree available: ${ffree[*]}"
27895         echo "MDT blocks available: ${bavail[*]}"
27896         echo "weight diff=$diff%"
27897 }
27898
27899 test_qos_mkdir() {
27900         local mkdir_cmd=$1
27901         local stripe_count=$2
27902         local mdts=$(comma_list $(mdts_nodes))
27903
27904         local testdir
27905         local lmv_qos_prio_free
27906         local lmv_qos_threshold_rr
27907         local lod_qos_prio_free
27908         local lod_qos_threshold_rr
27909         local total
27910         local count
27911         local i
27912
27913         # @total is total directories created if it's testing plain
27914         # directories, otherwise it's total stripe object count for
27915         # striped directories test.
27916         # remote/striped directory unlinking is slow on zfs and may
27917         # timeout, test with fewer directories
27918         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27919
27920         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27921         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27922         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27923                 head -n1)
27924         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27925         stack_trap "$LCTL set_param \
27926                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27927         stack_trap "$LCTL set_param \
27928                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27929
27930         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27931                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27932         lod_qos_prio_free=${lod_qos_prio_free%%%}
27933         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27934                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27935         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27936         stack_trap "do_nodes $mdts $LCTL set_param \
27937                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27938         stack_trap "do_nodes $mdts $LCTL set_param \
27939                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27940
27941         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27942         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27943
27944         testdir=$DIR/$tdir-s$stripe_count/rr
27945
27946         local stripe_index=$($LFS getstripe -m $testdir)
27947         local test_mkdir_rr=true
27948
27949         getfattr -d -m dmv -e hex $testdir | grep dmv
27950         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27951                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27952                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27953                         test_mkdir_rr=false
27954         fi
27955
27956         echo
27957         $test_mkdir_rr &&
27958                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27959                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27960
27961         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27962         for (( i = 0; i < total / stripe_count; i++ )); do
27963                 eval $mkdir_cmd $testdir/subdir$i ||
27964                         error "$mkdir_cmd subdir$i failed"
27965         done
27966
27967         for (( i = 0; i < $MDSCOUNT; i++ )); do
27968                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27969                 echo "$count directories created on MDT$i"
27970                 if $test_mkdir_rr; then
27971                         (( count == total / stripe_count / MDSCOUNT )) ||
27972                                 error "subdirs are not evenly distributed"
27973                 elif (( i == stripe_index )); then
27974                         (( count == total / stripe_count )) ||
27975                                 error "$count subdirs created on MDT$i"
27976                 else
27977                         (( count == 0 )) ||
27978                                 error "$count subdirs created on MDT$i"
27979                 fi
27980
27981                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27982                         count=$($LFS getdirstripe $testdir/* |
27983                                 grep -c -P "^\s+$i\t")
27984                         echo "$count stripes created on MDT$i"
27985                         # deviation should < 5% of average
27986                         delta=$((count - total / MDSCOUNT))
27987                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27988                                 error "stripes are not evenly distributed"
27989                 fi
27990         done
27991
27992         echo
27993         echo "Check for uneven MDTs: "
27994
27995         local ffree
27996         local bavail
27997         local max
27998         local min
27999         local max_index
28000         local min_index
28001         local tmp
28002
28003         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28004         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28005         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28006
28007         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28008         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28009         max_index=0
28010         min_index=0
28011         for ((i = 1; i < ${#ffree[@]}; i++)); do
28012                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28013                 if [ $tmp -gt $max ]; then
28014                         max=$tmp
28015                         max_index=$i
28016                 fi
28017                 if [ $tmp -lt $min ]; then
28018                         min=$tmp
28019                         min_index=$i
28020                 fi
28021         done
28022         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28023
28024         (( min > 0 )) || skip "low space on MDT$min_index"
28025         (( ${ffree[min_index]} < 10000000 )) ||
28026                 skip "too many free files on MDT$min_index"
28027
28028         generate_uneven_mdts 120
28029
28030         echo "MDT filesfree available: ${ffree[*]}"
28031         echo "MDT blocks available: ${bavail[*]}"
28032         echo "weight diff=$(((max - min) * 100 / min))%"
28033         echo
28034         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28035
28036         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28037         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28038         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28039         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28040         # decrease statfs age, so that it can be updated in time
28041         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28042         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28043
28044         sleep 1
28045
28046         testdir=$DIR/$tdir-s$stripe_count/qos
28047
28048         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28049         for (( i = 0; i < total / stripe_count; i++ )); do
28050                 eval $mkdir_cmd $testdir/subdir$i ||
28051                         error "$mkdir_cmd subdir$i failed"
28052         done
28053
28054         max=0
28055         for (( i = 0; i < $MDSCOUNT; i++ )); do
28056                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28057                 (( count > max )) && max=$count
28058                 echo "$count directories created on MDT$i : curmax=$max"
28059         done
28060
28061         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28062
28063         # D-value should > 10% of average
28064         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28065                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28066
28067         # ditto for stripes
28068         if (( stripe_count > 1 )); then
28069                 max=0
28070                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28071                         count=$($LFS getdirstripe $testdir/* |
28072                                 grep -c -P "^\s+$i\t")
28073                         (( count > max )) && max=$count
28074                         echo "$count stripes created on MDT$i"
28075                 done
28076
28077                 min=$($LFS getdirstripe $testdir/* |
28078                         grep -c -P "^\s+$min_index\t")
28079                 (( max - min > total / MDSCOUNT / 10 )) ||
28080                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28081         fi
28082 }
28083
28084 most_full_mdt() {
28085         local ffree
28086         local bavail
28087         local bsize
28088         local min
28089         local min_index
28090         local tmp
28091
28092         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28093         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28094         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28095
28096         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28097         min_index=0
28098         for ((i = 1; i < ${#ffree[@]}; i++)); do
28099                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28100                 (( tmp < min )) && min=$tmp && min_index=$i
28101         done
28102
28103         echo -n $min_index
28104 }
28105
28106 test_413a() {
28107         [ $MDSCOUNT -lt 2 ] &&
28108                 skip "We need at least 2 MDTs for this test"
28109
28110         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28111                 skip "Need server version at least 2.12.52"
28112
28113         local stripe_max=$((MDSCOUNT - 1))
28114         local stripe_count
28115
28116         # let caller set maxage for latest result
28117         set_maxage 1
28118
28119         # fill MDT unevenly
28120         generate_uneven_mdts 120
28121
28122         # test 4-stripe directory at most, otherwise it's too slow
28123         # We are being very defensive. Although Autotest uses 4 MDTs.
28124         # We make sure stripe_max does not go over 4.
28125         (( stripe_max > 4 )) && stripe_max=4
28126         # unlinking striped directory is slow on zfs, and may timeout, only test
28127         # plain directory
28128         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28129         for stripe_count in $(seq 1 $stripe_max); do
28130                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28131                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28132                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28133                         error "mkdir failed"
28134                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28135         done
28136 }
28137 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28138
28139 test_413b() {
28140         [ $MDSCOUNT -lt 2 ] &&
28141                 skip "We need at least 2 MDTs for this test"
28142
28143         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28144                 skip "Need server version at least 2.12.52"
28145
28146         local stripe_max=$((MDSCOUNT - 1))
28147         local testdir
28148         local stripe_count
28149
28150         # let caller set maxage for latest result
28151         set_maxage 1
28152
28153         # fill MDT unevenly
28154         generate_uneven_mdts 120
28155
28156         # test 4-stripe directory at most, otherwise it's too slow
28157         # We are being very defensive. Although Autotest uses 4 MDTs.
28158         # We make sure stripe_max does not go over 4.
28159         (( stripe_max > 4 )) && stripe_max=4
28160         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28161         for stripe_count in $(seq 1 $stripe_max); do
28162                 testdir=$DIR/$tdir-s$stripe_count
28163                 mkdir $testdir || error "mkdir $testdir failed"
28164                 mkdir $testdir/rr || error "mkdir rr failed"
28165                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28166                         error "mkdir qos failed"
28167                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28168                         $testdir/rr || error "setdirstripe rr failed"
28169                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28170                         error "setdirstripe failed"
28171                 test_qos_mkdir "mkdir" $stripe_count
28172         done
28173 }
28174 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28175
28176 test_413c() {
28177         (( $MDSCOUNT >= 2 )) ||
28178                 skip "We need at least 2 MDTs for this test"
28179
28180         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28181                 skip "Need server version at least 2.14.51"
28182
28183         local testdir
28184         local inherit
28185         local inherit_rr
28186         local lmv_qos_maxage
28187         local lod_qos_maxage
28188
28189         # let caller set maxage for latest result
28190         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28191         $LCTL set_param lmv.*.qos_maxage=1
28192         stack_trap "$LCTL set_param \
28193                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28194         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28195                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28196         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28197                 lod.*.mdt_qos_maxage=1
28198         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28199                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28200
28201         # fill MDT unevenly
28202         generate_uneven_mdts 120
28203
28204         testdir=$DIR/${tdir}-s1
28205         mkdir $testdir || error "mkdir $testdir failed"
28206         mkdir $testdir/rr || error "mkdir rr failed"
28207         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28208         # default max_inherit is -1, default max_inherit_rr is 0
28209         $LFS setdirstripe -D -c 1 $testdir/rr ||
28210                 error "setdirstripe rr failed"
28211         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28212                 error "setdirstripe qos failed"
28213         test_qos_mkdir "mkdir" 1
28214
28215         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28216         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28217         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28218         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28219         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28220
28221         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28222         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28223         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28224         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28225         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28226         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28227         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28228                 error "level2 shouldn't have default LMV" || true
28229 }
28230 run_test 413c "mkdir with default LMV max inherit rr"
28231
28232 test_413d() {
28233         (( MDSCOUNT >= 2 )) ||
28234                 skip "We need at least 2 MDTs for this test"
28235
28236         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28237                 skip "Need server version at least 2.14.51"
28238
28239         local lmv_qos_threshold_rr
28240
28241         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28242                 head -n1)
28243         stack_trap "$LCTL set_param \
28244                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28245
28246         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28247         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28248         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28249                 error "$tdir shouldn't have default LMV"
28250         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28251                 error "mkdir sub failed"
28252
28253         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28254
28255         (( count == 100 )) || error "$count subdirs on MDT0"
28256 }
28257 run_test 413d "inherit ROOT default LMV"
28258
28259 test_413e() {
28260         (( MDSCOUNT >= 2 )) ||
28261                 skip "We need at least 2 MDTs for this test"
28262         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28263                 skip "Need server version at least 2.14.55"
28264
28265         local testdir=$DIR/$tdir
28266         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28267         local max_inherit
28268         local sub_max_inherit
28269
28270         mkdir -p $testdir || error "failed to create $testdir"
28271
28272         # set default max-inherit to -1 if stripe count is 0 or 1
28273         $LFS setdirstripe -D -c 1 $testdir ||
28274                 error "failed to set default LMV"
28275         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28276         (( max_inherit == -1 )) ||
28277                 error "wrong max_inherit value $max_inherit"
28278
28279         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28280         $LFS setdirstripe -D -c -1 $testdir ||
28281                 error "failed to set default LMV"
28282         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28283         (( max_inherit > 0 )) ||
28284                 error "wrong max_inherit value $max_inherit"
28285
28286         # and the subdir will decrease the max_inherit by 1
28287         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28288         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28289         (( sub_max_inherit == max_inherit - 1)) ||
28290                 error "wrong max-inherit of subdir $sub_max_inherit"
28291
28292         # check specified --max-inherit and warning message
28293         stack_trap "rm -f $tmpfile"
28294         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28295                 error "failed to set default LMV"
28296         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28297         (( max_inherit == -1 )) ||
28298                 error "wrong max_inherit value $max_inherit"
28299
28300         # check the warning messages
28301         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28302                 error "failed to detect warning string"
28303         fi
28304 }
28305 run_test 413e "check default max-inherit value"
28306
28307 test_fs_dmv_inherit()
28308 {
28309         local testdir=$DIR/$tdir
28310
28311         local count
28312         local inherit
28313         local inherit_rr
28314
28315         for i in 1 2; do
28316                 mkdir $testdir || error "mkdir $testdir failed"
28317                 count=$($LFS getdirstripe -D -c $testdir)
28318                 (( count == 1 )) ||
28319                         error "$testdir default LMV count mismatch $count != 1"
28320                 inherit=$($LFS getdirstripe -D -X $testdir)
28321                 (( inherit == 3 - i )) ||
28322                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28323                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28324                 (( inherit_rr == 3 - i )) ||
28325                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28326                 testdir=$testdir/sub
28327         done
28328
28329         mkdir $testdir || error "mkdir $testdir failed"
28330         count=$($LFS getdirstripe -D -c $testdir)
28331         (( count == 0 )) ||
28332                 error "$testdir default LMV count not zero: $count"
28333 }
28334
28335 test_413f() {
28336         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28337
28338         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28339                 skip "Need server version at least 2.14.55"
28340
28341         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28342                 error "dump $DIR default LMV failed"
28343         stack_trap "setfattr --restore=$TMP/dmv.ea"
28344
28345         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28346                 error "set $DIR default LMV failed"
28347
28348         test_fs_dmv_inherit
28349 }
28350 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28351
28352 test_413g() {
28353         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28354
28355         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28356         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28357                 error "dump $DIR default LMV failed"
28358         stack_trap "setfattr --restore=$TMP/dmv.ea"
28359
28360         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28361                 error "set $DIR default LMV failed"
28362
28363         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28364                 error "mount $MOUNT2 failed"
28365         stack_trap "umount_client $MOUNT2"
28366
28367         local saved_DIR=$DIR
28368
28369         export DIR=$MOUNT2
28370
28371         stack_trap "export DIR=$saved_DIR"
28372
28373         # first check filesystem-wide default LMV inheritance
28374         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28375
28376         # then check subdirs are spread to all MDTs
28377         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28378
28379         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28380
28381         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28382 }
28383 run_test 413g "enforce ROOT default LMV on subdir mount"
28384
28385 test_413h() {
28386         (( MDSCOUNT >= 2 )) ||
28387                 skip "We need at least 2 MDTs for this test"
28388
28389         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28390                 skip "Need server version at least 2.15.50.6"
28391
28392         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28393
28394         stack_trap "$LCTL set_param \
28395                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28396         $LCTL set_param lmv.*.qos_maxage=1
28397
28398         local depth=5
28399         local rr_depth=4
28400         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28401         local count=$((MDSCOUNT * 20))
28402
28403         generate_uneven_mdts 50
28404
28405         mkdir -p $dir || error "mkdir $dir failed"
28406         stack_trap "rm -rf $dir"
28407         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28408                 --max-inherit-rr=$rr_depth $dir
28409
28410         for ((d=0; d < depth + 2; d++)); do
28411                 log "dir=$dir:"
28412                 for ((sub=0; sub < count; sub++)); do
28413                         mkdir $dir/d$sub
28414                 done
28415                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28416                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28417                 # subdirs within $rr_depth should be created round-robin
28418                 if (( d < rr_depth )); then
28419                         (( ${num[0]} != count )) ||
28420                                 error "all objects created on MDT ${num[1]}"
28421                 fi
28422
28423                 dir=$dir/d0
28424         done
28425 }
28426 run_test 413h "don't stick to parent for round-robin dirs"
28427
28428 test_413i() {
28429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28430
28431         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28432                 skip "Need server version at least 2.14.55"
28433
28434         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28435                 error "dump $DIR default LMV failed"
28436         stack_trap "setfattr --restore=$TMP/dmv.ea"
28437
28438         local testdir=$DIR/$tdir
28439         local def_max_rr=1
28440         local def_max=3
28441         local count
28442
28443         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28444                 --max-inherit-rr=$def_max_rr $DIR ||
28445                 error "set $DIR default LMV failed"
28446
28447         for i in $(seq 2 3); do
28448                 def_max=$((def_max - 1))
28449                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28450
28451                 mkdir $testdir
28452                 # RR is decremented and keeps zeroed once exhausted
28453                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28454                 (( count == def_max_rr )) ||
28455                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28456
28457                 # max-inherit is decremented
28458                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28459                 (( count == def_max )) ||
28460                         error_noexit "$testdir: max-inherit $count != $def_max"
28461
28462                 testdir=$testdir/d$i
28463         done
28464
28465         # d3 is the last inherited from ROOT, no inheritance anymore
28466         # i.e. no the default layout anymore
28467         mkdir -p $testdir/d4/d5
28468         count=$($LFS getdirstripe -D --max-inherit $testdir)
28469         (( count == -1 )) ||
28470                 error_noexit "$testdir: max-inherit $count != -1"
28471
28472         local p_count=$($LFS getdirstripe -i $testdir)
28473
28474         for i in $(seq 4 5); do
28475                 testdir=$testdir/d$i
28476
28477                 # the root default layout is not applied once exhausted
28478                 count=$($LFS getdirstripe -i $testdir)
28479                 (( count == p_count )) ||
28480                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28481         done
28482
28483         $LFS setdirstripe -i 0 $DIR/d2
28484         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28485         (( count == -1 )) ||
28486                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28487 }
28488 run_test 413i "check default layout inheritance"
28489
28490 test_413z() {
28491         local pids=""
28492         local subdir
28493         local pid
28494
28495         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28496                 unlinkmany $subdir/f. $TEST413_COUNT &
28497                 pids="$pids $!"
28498         done
28499
28500         for pid in $pids; do
28501                 wait $pid
28502         done
28503
28504         true
28505 }
28506 run_test 413z "413 test cleanup"
28507
28508 test_414() {
28509 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28510         $LCTL set_param fail_loc=0x80000521
28511         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28512         rm -f $DIR/$tfile
28513 }
28514 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28515
28516 test_415() {
28517         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28518         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28519                 skip "Need server version at least 2.11.52"
28520
28521         # LU-11102
28522         local total=500
28523         local max=120
28524
28525         # this test may be slow on ZFS
28526         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28527
28528         # though this test is designed for striped directory, let's test normal
28529         # directory too since lock is always saved as CoS lock.
28530         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28531         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28532         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28533         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28534         wait_delete_completed_mds
28535
28536         # run a loop without concurrent touch to measure rename duration.
28537         # only for test debug/robustness, NOT part of COS functional test.
28538         local start_time=$SECONDS
28539         for ((i = 0; i < total; i++)); do
28540                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28541                         > /dev/null
28542         done
28543         local baseline=$((SECONDS - start_time))
28544         echo "rename $total files without 'touch' took $baseline sec"
28545
28546         (
28547                 while true; do
28548                         touch $DIR/$tdir
28549                 done
28550         ) &
28551         local setattr_pid=$!
28552
28553         # rename files back to original name so unlinkmany works
28554         start_time=$SECONDS
28555         for ((i = 0; i < total; i++)); do
28556                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28557                         > /dev/null
28558         done
28559         local duration=$((SECONDS - start_time))
28560
28561         kill -9 $setattr_pid
28562
28563         echo "rename $total files with 'touch' took $duration sec"
28564         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28565         (( duration <= max )) ||
28566                 error_not_in_vm "rename took $duration > $max sec"
28567 }
28568 run_test 415 "lock revoke is not missing"
28569
28570 test_416() {
28571         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28572                 skip "Need server version at least 2.11.55"
28573
28574         # define OBD_FAIL_OSD_TXN_START    0x19a
28575         do_facet mds1 lctl set_param fail_loc=0x19a
28576
28577         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28578
28579         true
28580 }
28581 run_test 416 "transaction start failure won't cause system hung"
28582
28583 cleanup_417() {
28584         trap 0
28585         do_nodes $(comma_list $(mdts_nodes)) \
28586                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28587         do_nodes $(comma_list $(mdts_nodes)) \
28588                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28589         do_nodes $(comma_list $(mdts_nodes)) \
28590                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28591 }
28592
28593 test_417() {
28594         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28595         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28596                 skip "Need MDS version at least 2.11.56"
28597
28598         trap cleanup_417 RETURN EXIT
28599
28600         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28601         do_nodes $(comma_list $(mdts_nodes)) \
28602                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28603         $LFS migrate -m 0 $DIR/$tdir.1 &&
28604                 error "migrate dir $tdir.1 should fail"
28605
28606         do_nodes $(comma_list $(mdts_nodes)) \
28607                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28608         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28609                 error "create remote dir $tdir.2 should fail"
28610
28611         do_nodes $(comma_list $(mdts_nodes)) \
28612                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28613         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28614                 error "create striped dir $tdir.3 should fail"
28615         true
28616 }
28617 run_test 417 "disable remote dir, striped dir and dir migration"
28618
28619 # Checks that the outputs of df [-i] and lfs df [-i] match
28620 #
28621 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28622 check_lfs_df() {
28623         local dir=$2
28624         local inodes
28625         local df_out
28626         local lfs_df_out
28627         local count
28628         local passed=false
28629
28630         # blocks or inodes
28631         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28632
28633         for count in {1..100}; do
28634                 do_nodes "$CLIENTS" \
28635                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28636                 sync; sleep 0.2
28637
28638                 # read the lines of interest
28639                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28640                         error "df $inodes $dir | tail -n +2 failed"
28641                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28642                         error "lfs df $inodes $dir | grep summary: failed"
28643
28644                 # skip first substrings of each output as they are different
28645                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28646                 # compare the two outputs
28647                 passed=true
28648                 #  skip "available" on MDT until LU-13997 is fixed.
28649                 #for i in {1..5}; do
28650                 for i in 1 2 4 5; do
28651                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28652                 done
28653                 $passed && break
28654         done
28655
28656         if ! $passed; then
28657                 df -P $inodes $dir
28658                 echo
28659                 lfs df $inodes $dir
28660                 error "df and lfs df $1 output mismatch: "      \
28661                       "df ${inodes}: ${df_out[*]}, "            \
28662                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28663         fi
28664 }
28665
28666 test_418() {
28667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28668
28669         local dir=$DIR/$tdir
28670         local numfiles=$((RANDOM % 4096 + 2))
28671         local numblocks=$((RANDOM % 256 + 1))
28672
28673         wait_delete_completed
28674         test_mkdir $dir
28675
28676         # check block output
28677         check_lfs_df blocks $dir
28678         # check inode output
28679         check_lfs_df inodes $dir
28680
28681         # create a single file and retest
28682         echo "Creating a single file and testing"
28683         createmany -o $dir/$tfile- 1 &>/dev/null ||
28684                 error "creating 1 file in $dir failed"
28685         check_lfs_df blocks $dir
28686         check_lfs_df inodes $dir
28687
28688         # create a random number of files
28689         echo "Creating $((numfiles - 1)) files and testing"
28690         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28691                 error "creating $((numfiles - 1)) files in $dir failed"
28692
28693         # write a random number of blocks to the first test file
28694         echo "Writing $numblocks 4K blocks and testing"
28695         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28696                 count=$numblocks &>/dev/null ||
28697                 error "dd to $dir/${tfile}-0 failed"
28698
28699         # retest
28700         check_lfs_df blocks $dir
28701         check_lfs_df inodes $dir
28702
28703         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28704                 error "unlinking $numfiles files in $dir failed"
28705 }
28706 run_test 418 "df and lfs df outputs match"
28707
28708 test_419()
28709 {
28710         local dir=$DIR/$tdir
28711
28712         mkdir -p $dir
28713         touch $dir/file
28714
28715         cancel_lru_locks mdc
28716
28717         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28718         $LCTL set_param fail_loc=0x1410
28719         cat $dir/file
28720         $LCTL set_param fail_loc=0
28721         rm -rf $dir
28722 }
28723 run_test 419 "Verify open file by name doesn't crash kernel"
28724
28725 test_420()
28726 {
28727         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28728                 skip "Need MDS version at least 2.12.53"
28729
28730         local SAVE_UMASK=$(umask)
28731         local dir=$DIR/$tdir
28732         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28733
28734         mkdir -p $dir
28735         umask 0000
28736         mkdir -m03777 $dir/testdir
28737         ls -dn $dir/testdir
28738         # Need to remove trailing '.' when SELinux is enabled
28739         local dirperms=$(ls -dn $dir/testdir |
28740                          awk '{ sub(/\.$/, "", $1); print $1}')
28741         [ $dirperms == "drwxrwsrwt" ] ||
28742                 error "incorrect perms on $dir/testdir"
28743
28744         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28745                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28746         ls -n $dir/testdir/testfile
28747         local fileperms=$(ls -n $dir/testdir/testfile |
28748                           awk '{ sub(/\.$/, "", $1); print $1}')
28749         [ $fileperms == "-rwxr-xr-x" ] ||
28750                 error "incorrect perms on $dir/testdir/testfile"
28751
28752         umask $SAVE_UMASK
28753 }
28754 run_test 420 "clear SGID bit on non-directories for non-members"
28755
28756 test_421a() {
28757         local cnt
28758         local fid1
28759         local fid2
28760
28761         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28762                 skip "Need MDS version at least 2.12.54"
28763
28764         test_mkdir $DIR/$tdir
28765         createmany -o $DIR/$tdir/f 3
28766         cnt=$(ls -1 $DIR/$tdir | wc -l)
28767         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28768
28769         fid1=$(lfs path2fid $DIR/$tdir/f1)
28770         fid2=$(lfs path2fid $DIR/$tdir/f2)
28771         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28772
28773         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28774         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28775
28776         cnt=$(ls -1 $DIR/$tdir | wc -l)
28777         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28778
28779         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28780         createmany -o $DIR/$tdir/f 3
28781         cnt=$(ls -1 $DIR/$tdir | wc -l)
28782         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28783
28784         fid1=$(lfs path2fid $DIR/$tdir/f1)
28785         fid2=$(lfs path2fid $DIR/$tdir/f2)
28786         echo "remove using fsname $FSNAME"
28787         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28788
28789         cnt=$(ls -1 $DIR/$tdir | wc -l)
28790         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28791 }
28792 run_test 421a "simple rm by fid"
28793
28794 test_421b() {
28795         local cnt
28796         local FID1
28797         local FID2
28798
28799         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28800                 skip "Need MDS version at least 2.12.54"
28801
28802         test_mkdir $DIR/$tdir
28803         createmany -o $DIR/$tdir/f 3
28804         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28805         MULTIPID=$!
28806
28807         FID1=$(lfs path2fid $DIR/$tdir/f1)
28808         FID2=$(lfs path2fid $DIR/$tdir/f2)
28809         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28810
28811         kill -USR1 $MULTIPID
28812         wait
28813
28814         cnt=$(ls $DIR/$tdir | wc -l)
28815         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28816 }
28817 run_test 421b "rm by fid on open file"
28818
28819 test_421c() {
28820         local cnt
28821         local FIDS
28822
28823         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28824                 skip "Need MDS version at least 2.12.54"
28825
28826         test_mkdir $DIR/$tdir
28827         createmany -o $DIR/$tdir/f 3
28828         touch $DIR/$tdir/$tfile
28829         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28830         cnt=$(ls -1 $DIR/$tdir | wc -l)
28831         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28832
28833         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28834         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28835
28836         cnt=$(ls $DIR/$tdir | wc -l)
28837         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28838 }
28839 run_test 421c "rm by fid against hardlinked files"
28840
28841 test_421d() {
28842         local cnt
28843         local FIDS
28844
28845         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28846                 skip "Need MDS version at least 2.12.54"
28847
28848         test_mkdir $DIR/$tdir
28849         createmany -o $DIR/$tdir/f 4097
28850         cnt=$(ls -1 $DIR/$tdir | wc -l)
28851         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28852
28853         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28854         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28855
28856         cnt=$(ls $DIR/$tdir | wc -l)
28857         rm -rf $DIR/$tdir
28858         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28859 }
28860 run_test 421d "rmfid en masse"
28861
28862 test_421e() {
28863         local cnt
28864         local FID
28865
28866         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28867         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28868                 skip "Need MDS version at least 2.12.54"
28869
28870         mkdir -p $DIR/$tdir
28871         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28872         createmany -o $DIR/$tdir/striped_dir/f 512
28873         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28874         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28875
28876         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28877                 sed "s/[/][^:]*://g")
28878         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28879
28880         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28881         rm -rf $DIR/$tdir
28882         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28883 }
28884 run_test 421e "rmfid in DNE"
28885
28886 test_421f() {
28887         local cnt
28888         local FID
28889
28890         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28891                 skip "Need MDS version at least 2.12.54"
28892
28893         test_mkdir $DIR/$tdir
28894         touch $DIR/$tdir/f
28895         cnt=$(ls -1 $DIR/$tdir | wc -l)
28896         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28897
28898         FID=$(lfs path2fid $DIR/$tdir/f)
28899         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28900         # rmfid should fail
28901         cnt=$(ls -1 $DIR/$tdir | wc -l)
28902         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28903
28904         chmod a+rw $DIR/$tdir
28905         ls -la $DIR/$tdir
28906         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28907         # rmfid should fail
28908         cnt=$(ls -1 $DIR/$tdir | wc -l)
28909         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28910
28911         rm -f $DIR/$tdir/f
28912         $RUNAS touch $DIR/$tdir/f
28913         FID=$(lfs path2fid $DIR/$tdir/f)
28914         echo "rmfid as root"
28915         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28916         cnt=$(ls -1 $DIR/$tdir | wc -l)
28917         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28918
28919         rm -f $DIR/$tdir/f
28920         $RUNAS touch $DIR/$tdir/f
28921         cnt=$(ls -1 $DIR/$tdir | wc -l)
28922         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28923         FID=$(lfs path2fid $DIR/$tdir/f)
28924         # rmfid w/o user_fid2path mount option should fail
28925         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28926         cnt=$(ls -1 $DIR/$tdir | wc -l)
28927         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28928
28929         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28930         stack_trap "rmdir $tmpdir"
28931         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28932                 error "failed to mount client'"
28933         stack_trap "umount_client $tmpdir"
28934
28935         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28936         # rmfid should succeed
28937         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28938         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28939
28940         # rmfid shouldn't allow to remove files due to dir's permission
28941         chmod a+rwx $tmpdir/$tdir
28942         touch $tmpdir/$tdir/f
28943         ls -la $tmpdir/$tdir
28944         FID=$(lfs path2fid $tmpdir/$tdir/f)
28945         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28946         return 0
28947 }
28948 run_test 421f "rmfid checks permissions"
28949
28950 test_421g() {
28951         local cnt
28952         local FIDS
28953
28954         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28955         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28956                 skip "Need MDS version at least 2.12.54"
28957
28958         mkdir -p $DIR/$tdir
28959         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28960         createmany -o $DIR/$tdir/striped_dir/f 512
28961         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28962         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28963
28964         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28965                 sed "s/[/][^:]*://g")
28966
28967         rm -f $DIR/$tdir/striped_dir/f1*
28968         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28969         removed=$((512 - cnt))
28970
28971         # few files have been just removed, so we expect
28972         # rmfid to fail on their fids
28973         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28974         [ $removed != $errors ] && error "$errors != $removed"
28975
28976         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28977         rm -rf $DIR/$tdir
28978         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28979 }
28980 run_test 421g "rmfid to return errors properly"
28981
28982 test_421h() {
28983         local mount_other
28984         local mount_ret
28985         local rmfid_ret
28986         local old_fid
28987         local fidA
28988         local fidB
28989         local fidC
28990         local fidD
28991
28992         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28993                 skip "Need MDS version at least 2.15.53"
28994
28995         test_mkdir $DIR/$tdir
28996         test_mkdir $DIR/$tdir/subdir
28997         touch $DIR/$tdir/subdir/file0
28998         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28999         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29000         rm -f $DIR/$tdir/subdir/file0
29001         touch $DIR/$tdir/subdir/fileA
29002         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29003         echo File $DIR/$tdir/subdir/fileA FID $fidA
29004         touch $DIR/$tdir/subdir/fileB
29005         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29006         echo File $DIR/$tdir/subdir/fileB FID $fidB
29007         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29008         touch $DIR/$tdir/subdir/fileC
29009         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29010         echo File $DIR/$tdir/subdir/fileC FID $fidC
29011         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29012         touch $DIR/$tdir/fileD
29013         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29014         echo File $DIR/$tdir/fileD FID $fidD
29015
29016         # mount another client mount point with subdirectory mount
29017         export FILESET=/$tdir/subdir
29018         mount_other=${MOUNT}_other
29019         mount_client $mount_other ${MOUNT_OPTS}
29020         mount_ret=$?
29021         export FILESET=""
29022         (( mount_ret == 0 )) || error "mount $mount_other failed"
29023
29024         echo Removing FIDs:
29025         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29026         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29027         rmfid_ret=$?
29028
29029         umount_client $mount_other || error "umount $mount_other failed"
29030
29031         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29032
29033         # fileA should have been deleted
29034         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29035
29036         # fileB should have been deleted
29037         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29038
29039         # fileC should not have been deleted, fid also exists outside of fileset
29040         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29041
29042         # fileD should not have been deleted, it exists outside of fileset
29043         stat $DIR/$tdir/fileD || error "fileD deleted"
29044 }
29045 run_test 421h "rmfid with fileset mount"
29046
29047 test_422() {
29048         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29049         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29050         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29051         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29052         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29053
29054         local amc=$(at_max_get client)
29055         local amo=$(at_max_get mds1)
29056         local timeout=`lctl get_param -n timeout`
29057
29058         at_max_set 0 client
29059         at_max_set 0 mds1
29060
29061 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29062         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29063                         fail_val=$(((2*timeout + 10)*1000))
29064         touch $DIR/$tdir/d3/file &
29065         sleep 2
29066 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29067         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29068                         fail_val=$((2*timeout + 5))
29069         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29070         local pid=$!
29071         sleep 1
29072         kill -9 $pid
29073         sleep $((2 * timeout))
29074         echo kill $pid
29075         kill -9 $pid
29076         lctl mark touch
29077         touch $DIR/$tdir/d2/file3
29078         touch $DIR/$tdir/d2/file4
29079         touch $DIR/$tdir/d2/file5
29080
29081         wait
29082         at_max_set $amc client
29083         at_max_set $amo mds1
29084
29085         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29086         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29087                 error "Watchdog is always throttled"
29088 }
29089 run_test 422 "kill a process with RPC in progress"
29090
29091 stat_test() {
29092     df -h $MOUNT &
29093     df -h $MOUNT &
29094     df -h $MOUNT &
29095     df -h $MOUNT &
29096     df -h $MOUNT &
29097     df -h $MOUNT &
29098 }
29099
29100 test_423() {
29101     local _stats
29102     # ensure statfs cache is expired
29103     sleep 2;
29104
29105     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29106     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29107
29108     return 0
29109 }
29110 run_test 423 "statfs should return a right data"
29111
29112 test_424() {
29113 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29114         $LCTL set_param fail_loc=0x80000522
29115         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29116         rm -f $DIR/$tfile
29117 }
29118 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29119
29120 test_425() {
29121         test_mkdir -c -1 $DIR/$tdir
29122         $LFS setstripe -c -1 $DIR/$tdir
29123
29124         lru_resize_disable "" 100
29125         stack_trap "lru_resize_enable" EXIT
29126
29127         sleep 5
29128
29129         for i in $(seq $((MDSCOUNT * 125))); do
29130                 local t=$DIR/$tdir/$tfile_$i
29131
29132                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29133                         error_noexit "Create file $t"
29134         done
29135         stack_trap "rm -rf $DIR/$tdir" EXIT
29136
29137         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29138                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29139                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29140
29141                 [ $lock_count -le $lru_size ] ||
29142                         error "osc lock count $lock_count > lru size $lru_size"
29143         done
29144
29145         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29146                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29147                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29148
29149                 [ $lock_count -le $lru_size ] ||
29150                         error "mdc lock count $lock_count > lru size $lru_size"
29151         done
29152 }
29153 run_test 425 "lock count should not exceed lru size"
29154
29155 test_426() {
29156         splice-test -r $DIR/$tfile
29157         splice-test -rd $DIR/$tfile
29158         splice-test $DIR/$tfile
29159         splice-test -d $DIR/$tfile
29160 }
29161 run_test 426 "splice test on Lustre"
29162
29163 test_427() {
29164         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29165         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29166                 skip "Need MDS version at least 2.12.4"
29167         local log
29168
29169         mkdir $DIR/$tdir
29170         mkdir $DIR/$tdir/1
29171         mkdir $DIR/$tdir/2
29172         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29173         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29174
29175         $LFS getdirstripe $DIR/$tdir/1/dir
29176
29177         #first setfattr for creating updatelog
29178         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29179
29180 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29181         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29182         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29183         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29184
29185         sleep 2
29186         fail mds2
29187         wait_recovery_complete mds2 $((2*TIMEOUT))
29188
29189         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29190         echo $log | grep "get update log failed" &&
29191                 error "update log corruption is detected" || true
29192 }
29193 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29194
29195 test_428() {
29196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29197         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29198                               awk '/^max_cached_mb/ { print $2 }')
29199         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29200
29201         $LCTL set_param -n llite.*.max_cached_mb=64
29202
29203         mkdir $DIR/$tdir
29204         $LFS setstripe -c 1 $DIR/$tdir
29205         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29206         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29207         #test write
29208         for f in $(seq 4); do
29209                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29210         done
29211         wait
29212
29213         cancel_lru_locks osc
29214         # Test read
29215         for f in $(seq 4); do
29216                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29217         done
29218         wait
29219 }
29220 run_test 428 "large block size IO should not hang"
29221
29222 test_429() { # LU-7915 / LU-10948
29223         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29224         local testfile=$DIR/$tfile
29225         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29226         local new_flag=1
29227         local first_rpc
29228         local second_rpc
29229         local third_rpc
29230
29231         $LCTL get_param $ll_opencache_threshold_count ||
29232                 skip "client does not have opencache parameter"
29233
29234         set_opencache $new_flag
29235         stack_trap "restore_opencache"
29236         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29237                 error "enable opencache failed"
29238         touch $testfile
29239         # drop MDC DLM locks
29240         cancel_lru_locks mdc
29241         # clear MDC RPC stats counters
29242         $LCTL set_param $mdc_rpcstats=clear
29243
29244         # According to the current implementation, we need to run 3 times
29245         # open & close file to verify if opencache is enabled correctly.
29246         # 1st, RPCs are sent for lookup/open and open handle is released on
29247         #      close finally.
29248         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29249         #      so open handle won't be released thereafter.
29250         # 3rd, No RPC is sent out.
29251         $MULTIOP $testfile oc || error "multiop failed"
29252         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29253         echo "1st: $first_rpc RPCs in flight"
29254
29255         $MULTIOP $testfile oc || error "multiop failed"
29256         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29257         echo "2nd: $second_rpc RPCs in flight"
29258
29259         $MULTIOP $testfile oc || error "multiop failed"
29260         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29261         echo "3rd: $third_rpc RPCs in flight"
29262
29263         #verify no MDC RPC is sent
29264         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29265 }
29266 run_test 429 "verify if opencache flag on client side does work"
29267
29268 lseek_test_430() {
29269         local offset
29270         local file=$1
29271
29272         # data at [200K, 400K)
29273         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29274                 error "256K->512K dd fails"
29275         # data at [2M, 3M)
29276         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29277                 error "2M->3M dd fails"
29278         # data at [4M, 5M)
29279         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29280                 error "4M->5M dd fails"
29281         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29282         # start at first component hole #1
29283         printf "Seeking hole from 1000 ... "
29284         offset=$(lseek_test -l 1000 $file)
29285         echo $offset
29286         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29287         printf "Seeking data from 1000 ... "
29288         offset=$(lseek_test -d 1000 $file)
29289         echo $offset
29290         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29291
29292         # start at first component data block
29293         printf "Seeking hole from 300000 ... "
29294         offset=$(lseek_test -l 300000 $file)
29295         echo $offset
29296         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29297         printf "Seeking data from 300000 ... "
29298         offset=$(lseek_test -d 300000 $file)
29299         echo $offset
29300         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29301
29302         # start at the first component but beyond end of object size
29303         printf "Seeking hole from 1000000 ... "
29304         offset=$(lseek_test -l 1000000 $file)
29305         echo $offset
29306         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29307         printf "Seeking data from 1000000 ... "
29308         offset=$(lseek_test -d 1000000 $file)
29309         echo $offset
29310         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29311
29312         # start at second component stripe 2 (empty file)
29313         printf "Seeking hole from 1500000 ... "
29314         offset=$(lseek_test -l 1500000 $file)
29315         echo $offset
29316         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29317         printf "Seeking data from 1500000 ... "
29318         offset=$(lseek_test -d 1500000 $file)
29319         echo $offset
29320         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29321
29322         # start at second component stripe 1 (all data)
29323         printf "Seeking hole from 3000000 ... "
29324         offset=$(lseek_test -l 3000000 $file)
29325         echo $offset
29326         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29327         printf "Seeking data from 3000000 ... "
29328         offset=$(lseek_test -d 3000000 $file)
29329         echo $offset
29330         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29331
29332         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29333                 error "2nd dd fails"
29334         echo "Add data block at 640K...1280K"
29335
29336         # start at before new data block, in hole
29337         printf "Seeking hole from 600000 ... "
29338         offset=$(lseek_test -l 600000 $file)
29339         echo $offset
29340         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29341         printf "Seeking data from 600000 ... "
29342         offset=$(lseek_test -d 600000 $file)
29343         echo $offset
29344         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29345
29346         # start at the first component new data block
29347         printf "Seeking hole from 1000000 ... "
29348         offset=$(lseek_test -l 1000000 $file)
29349         echo $offset
29350         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29351         printf "Seeking data from 1000000 ... "
29352         offset=$(lseek_test -d 1000000 $file)
29353         echo $offset
29354         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29355
29356         # start at second component stripe 2, new data
29357         printf "Seeking hole from 1200000 ... "
29358         offset=$(lseek_test -l 1200000 $file)
29359         echo $offset
29360         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29361         printf "Seeking data from 1200000 ... "
29362         offset=$(lseek_test -d 1200000 $file)
29363         echo $offset
29364         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29365
29366         # start beyond file end
29367         printf "Using offset > filesize ... "
29368         lseek_test -l 4000000 $file && error "lseek should fail"
29369         printf "Using offset > filesize ... "
29370         lseek_test -d 4000000 $file && error "lseek should fail"
29371
29372         printf "Done\n\n"
29373 }
29374
29375 test_430a() {
29376         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29377                 skip "MDT does not support SEEK_HOLE"
29378
29379         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29380                 skip "OST does not support SEEK_HOLE"
29381
29382         local file=$DIR/$tdir/$tfile
29383
29384         mkdir -p $DIR/$tdir
29385
29386         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29387         # OST stripe #1 will have continuous data at [1M, 3M)
29388         # OST stripe #2 is empty
29389         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29390         lseek_test_430 $file
29391         rm $file
29392         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29393         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29394         lseek_test_430 $file
29395         rm $file
29396         $LFS setstripe -c2 -S 512K $file
29397         echo "Two stripes, stripe size 512K"
29398         lseek_test_430 $file
29399         rm $file
29400         # FLR with stale mirror
29401         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29402                        -N -c2 -S 1M $file
29403         echo "Mirrored file:"
29404         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29405         echo "Plain 2 stripes 1M"
29406         lseek_test_430 $file
29407         rm $file
29408 }
29409 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29410
29411 test_430b() {
29412         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29413                 skip "OST does not support SEEK_HOLE"
29414
29415         local offset
29416         local file=$DIR/$tdir/$tfile
29417
29418         mkdir -p $DIR/$tdir
29419         # Empty layout lseek should fail
29420         $MCREATE $file
29421         # seek from 0
29422         printf "Seeking hole from 0 ... "
29423         lseek_test -l 0 $file && error "lseek should fail"
29424         printf "Seeking data from 0 ... "
29425         lseek_test -d 0 $file && error "lseek should fail"
29426         rm $file
29427
29428         # 1M-hole file
29429         $LFS setstripe -E 1M -c2 -E eof $file
29430         $TRUNCATE $file 1048576
29431         printf "Seeking hole from 1000000 ... "
29432         offset=$(lseek_test -l 1000000 $file)
29433         echo $offset
29434         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29435         printf "Seeking data from 1000000 ... "
29436         lseek_test -d 1000000 $file && error "lseek should fail"
29437         rm $file
29438
29439         # full component followed by non-inited one
29440         $LFS setstripe -E 1M -c2 -E eof $file
29441         dd if=/dev/urandom of=$file bs=1M count=1
29442         printf "Seeking hole from 1000000 ... "
29443         offset=$(lseek_test -l 1000000 $file)
29444         echo $offset
29445         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29446         printf "Seeking hole from 1048576 ... "
29447         lseek_test -l 1048576 $file && error "lseek should fail"
29448         # init second component and truncate back
29449         echo "123" >> $file
29450         $TRUNCATE $file 1048576
29451         printf "Seeking hole from 1000000 ... "
29452         offset=$(lseek_test -l 1000000 $file)
29453         echo $offset
29454         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29455         printf "Seeking hole from 1048576 ... "
29456         lseek_test -l 1048576 $file && error "lseek should fail"
29457         # boundary checks for big values
29458         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29459         offset=$(lseek_test -d 0 $file.10g)
29460         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29461         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29462         offset=$(lseek_test -d 0 $file.100g)
29463         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29464         return 0
29465 }
29466 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29467
29468 test_430c() {
29469         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29470                 skip "OST does not support SEEK_HOLE"
29471
29472         local file=$DIR/$tdir/$tfile
29473         local start
29474
29475         mkdir -p $DIR/$tdir
29476         stack_trap "rm -f $file $file.tmp"
29477         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29478
29479         # cp version 8.33+ prefers lseek over fiemap
29480         local ver=$(cp --version | awk '{ print $4; exit; }')
29481
29482         echo "cp $ver installed"
29483         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29484                 start=$SECONDS
29485                 time cp -v $file $file.tmp || error "cp $file failed"
29486                 (( SECONDS - start < 5 )) || {
29487                         strace cp $file $file.tmp |&
29488                                 grep -E "open|read|seek|FIEMAP" |
29489                                 grep -A 100 $file
29490                         error "cp: too long runtime $((SECONDS - start))"
29491                 }
29492         else
29493                 echo "cp test skipped due to $ver < 8.33"
29494         fi
29495
29496         # tar version 1.29+ supports SEEK_HOLE/DATA
29497         ver=$(tar --version | awk '{ print $4; exit; }')
29498         echo "tar $ver installed"
29499         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29500                 start=$SECONDS
29501                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29502                 (( SECONDS - start < 5 )) || {
29503                         strace tar cf $file.tmp --sparse $file |&
29504                                 grep -E "open|read|seek|FIEMAP" |
29505                                 grep -A 100 $file
29506                         error "tar: too long runtime $((SECONDS - start))"
29507                 }
29508         else
29509                 echo "tar test skipped due to $ver < 1.29"
29510         fi
29511 }
29512 run_test 430c "lseek: external tools check"
29513
29514 test_431() { # LU-14187
29515         local file=$DIR/$tdir/$tfile
29516
29517         mkdir -p $DIR/$tdir
29518         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29519         dd if=/dev/urandom of=$file bs=4k count=1
29520         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29521         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29522         #define OBD_FAIL_OST_RESTART_IO 0x251
29523         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29524         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29525         cp $file $file.0
29526         cancel_lru_locks
29527         sync_all_data
29528         echo 3 > /proc/sys/vm/drop_caches
29529         diff  $file $file.0 || error "data diff"
29530 }
29531 run_test 431 "Restart transaction for IO"
29532
29533 cleanup_test_432() {
29534         do_facet mgs $LCTL nodemap_activate 0
29535         wait_nm_sync active
29536 }
29537
29538 test_432() {
29539         local tmpdir=$TMP/dir432
29540
29541         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29542                 skip "Need MDS version at least 2.14.52"
29543
29544         stack_trap cleanup_test_432 EXIT
29545         mkdir $DIR/$tdir
29546         mkdir $tmpdir
29547
29548         do_facet mgs $LCTL nodemap_activate 1
29549         wait_nm_sync active
29550         do_facet mgs $LCTL nodemap_modify --name default \
29551                 --property admin --value 1
29552         do_facet mgs $LCTL nodemap_modify --name default \
29553                 --property trusted --value 1
29554         cancel_lru_locks mdc
29555         wait_nm_sync default admin_nodemap
29556         wait_nm_sync default trusted_nodemap
29557
29558         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29559                grep -ci "Operation not permitted") -ne 0 ]; then
29560                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29561         fi
29562 }
29563 run_test 432 "mv dir from outside Lustre"
29564
29565 test_433() {
29566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29567
29568         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29569                 skip "inode cache not supported"
29570
29571         $LCTL set_param llite.*.inode_cache=0
29572         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29573
29574         local count=256
29575         local before
29576         local after
29577
29578         cancel_lru_locks mdc
29579         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29580         createmany -m $DIR/$tdir/f $count
29581         createmany -d $DIR/$tdir/d $count
29582         ls -l $DIR/$tdir > /dev/null
29583         stack_trap "rm -rf $DIR/$tdir"
29584
29585         before=$(num_objects)
29586         cancel_lru_locks mdc
29587         after=$(num_objects)
29588
29589         # sometimes even @before is less than 2 * count
29590         while (( before - after < count )); do
29591                 sleep 1
29592                 after=$(num_objects)
29593                 wait=$((wait + 1))
29594                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29595                 if (( wait > 60 )); then
29596                         error "inode slab grew from $before to $after"
29597                 fi
29598         done
29599
29600         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29601 }
29602 run_test 433 "ldlm lock cancel releases dentries and inodes"
29603
29604 test_434() {
29605         local file
29606         local getxattr_count
29607         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29608         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29609
29610         [[ $(getenforce) == "Disabled" ]] ||
29611                 skip "lsm selinux module have to be disabled for this test"
29612
29613         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29614                 error "fail to create $DIR/$tdir/ on MDT0000"
29615
29616         touch $DIR/$tdir/$tfile-{001..100}
29617
29618         # disable the xattr cache
29619         save_lustre_params client "llite.*.xattr_cache" > $p
29620         lctl set_param llite.*.xattr_cache=0
29621         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29622
29623         # clear clients mdc stats
29624         clear_stats $mdc_stat_param ||
29625                 error "fail to clear stats on mdc MDT0000"
29626
29627         for file in $DIR/$tdir/$tfile-{001..100}; do
29628                 getfattr -n security.selinux $file |&
29629                         grep -q "Operation not supported" ||
29630                         error "getxattr on security.selinux should return EOPNOTSUPP"
29631         done
29632
29633         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29634         (( getxattr_count < 100 )) ||
29635                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29636 }
29637 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29638
29639 test_440() {
29640         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29641                 source $LUSTRE/scripts/bash-completion/lustre
29642         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29643                 source /usr/share/bash-completion/completions/lustre
29644         else
29645                 skip "bash completion scripts not found"
29646         fi
29647
29648         local lctl_completions
29649         local lfs_completions
29650
29651         lctl_completions=$(_lustre_cmds lctl)
29652         if [[ ! $lctl_completions =~ "get_param" ]]; then
29653                 error "lctl bash completion failed"
29654         fi
29655
29656         lfs_completions=$(_lustre_cmds lfs)
29657         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29658                 error "lfs bash completion failed"
29659         fi
29660 }
29661 run_test 440 "bash completion for lfs, lctl"
29662
29663 prep_801() {
29664         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29665         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29666                 skip "Need server version at least 2.9.55"
29667
29668         start_full_debug_logging
29669 }
29670
29671 post_801() {
29672         stop_full_debug_logging
29673 }
29674
29675 barrier_stat() {
29676         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29677                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29678                            awk '/The barrier for/ { print $7 }')
29679                 echo $st
29680         else
29681                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29682                 echo \'$st\'
29683         fi
29684 }
29685
29686 barrier_expired() {
29687         local expired
29688
29689         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29690                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29691                           awk '/will be expired/ { print $7 }')
29692         else
29693                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29694         fi
29695
29696         echo $expired
29697 }
29698
29699 test_801a() {
29700         prep_801
29701
29702         echo "Start barrier_freeze at: $(date)"
29703         #define OBD_FAIL_BARRIER_DELAY          0x2202
29704         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29705         # Do not reduce barrier time - See LU-11873
29706         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29707
29708         sleep 2
29709         local b_status=$(barrier_stat)
29710         echo "Got barrier status at: $(date)"
29711         [ "$b_status" = "'freezing_p1'" ] ||
29712                 error "(1) unexpected barrier status $b_status"
29713
29714         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29715         wait
29716         b_status=$(barrier_stat)
29717         [ "$b_status" = "'frozen'" ] ||
29718                 error "(2) unexpected barrier status $b_status"
29719
29720         local expired=$(barrier_expired)
29721         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29722         sleep $((expired + 3))
29723
29724         b_status=$(barrier_stat)
29725         [ "$b_status" = "'expired'" ] ||
29726                 error "(3) unexpected barrier status $b_status"
29727
29728         # Do not reduce barrier time - See LU-11873
29729         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29730                 error "(4) fail to freeze barrier"
29731
29732         b_status=$(barrier_stat)
29733         [ "$b_status" = "'frozen'" ] ||
29734                 error "(5) unexpected barrier status $b_status"
29735
29736         echo "Start barrier_thaw at: $(date)"
29737         #define OBD_FAIL_BARRIER_DELAY          0x2202
29738         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29739         do_facet mgs $LCTL barrier_thaw $FSNAME &
29740
29741         sleep 2
29742         b_status=$(barrier_stat)
29743         echo "Got barrier status at: $(date)"
29744         [ "$b_status" = "'thawing'" ] ||
29745                 error "(6) unexpected barrier status $b_status"
29746
29747         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29748         wait
29749         b_status=$(barrier_stat)
29750         [ "$b_status" = "'thawed'" ] ||
29751                 error "(7) unexpected barrier status $b_status"
29752
29753         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29754         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29755         do_facet mgs $LCTL barrier_freeze $FSNAME
29756
29757         b_status=$(barrier_stat)
29758         [ "$b_status" = "'failed'" ] ||
29759                 error "(8) unexpected barrier status $b_status"
29760
29761         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29762         do_facet mgs $LCTL barrier_thaw $FSNAME
29763
29764         post_801
29765 }
29766 run_test 801a "write barrier user interfaces and stat machine"
29767
29768 test_801b() {
29769         prep_801
29770
29771         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29772         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29773         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29774         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29775         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29776
29777         cancel_lru_locks mdc
29778
29779         # 180 seconds should be long enough
29780         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29781
29782         local b_status=$(barrier_stat)
29783         [ "$b_status" = "'frozen'" ] ||
29784                 error "(6) unexpected barrier status $b_status"
29785
29786         mkdir $DIR/$tdir/d0/d10 &
29787         mkdir_pid=$!
29788
29789         touch $DIR/$tdir/d1/f13 &
29790         touch_pid=$!
29791
29792         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29793         ln_pid=$!
29794
29795         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29796         mv_pid=$!
29797
29798         rm -f $DIR/$tdir/d4/f12 &
29799         rm_pid=$!
29800
29801         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29802
29803         # To guarantee taht the 'stat' is not blocked
29804         b_status=$(barrier_stat)
29805         [ "$b_status" = "'frozen'" ] ||
29806                 error "(8) unexpected barrier status $b_status"
29807
29808         # let above commands to run at background
29809         sleep 5
29810
29811         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29812         ps -p $touch_pid || error "(10) touch should be blocked"
29813         ps -p $ln_pid || error "(11) link should be blocked"
29814         ps -p $mv_pid || error "(12) rename should be blocked"
29815         ps -p $rm_pid || error "(13) unlink should be blocked"
29816
29817         b_status=$(barrier_stat)
29818         [ "$b_status" = "'frozen'" ] ||
29819                 error "(14) unexpected barrier status $b_status"
29820
29821         do_facet mgs $LCTL barrier_thaw $FSNAME
29822         b_status=$(barrier_stat)
29823         [ "$b_status" = "'thawed'" ] ||
29824                 error "(15) unexpected barrier status $b_status"
29825
29826         wait $mkdir_pid || error "(16) mkdir should succeed"
29827         wait $touch_pid || error "(17) touch should succeed"
29828         wait $ln_pid || error "(18) link should succeed"
29829         wait $mv_pid || error "(19) rename should succeed"
29830         wait $rm_pid || error "(20) unlink should succeed"
29831
29832         post_801
29833 }
29834 run_test 801b "modification will be blocked by write barrier"
29835
29836 test_801c() {
29837         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29838
29839         prep_801
29840
29841         stop mds2 || error "(1) Fail to stop mds2"
29842
29843         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29844
29845         local b_status=$(barrier_stat)
29846         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29847                 do_facet mgs $LCTL barrier_thaw $FSNAME
29848                 error "(2) unexpected barrier status $b_status"
29849         }
29850
29851         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29852                 error "(3) Fail to rescan barrier bitmap"
29853
29854         # Do not reduce barrier time - See LU-11873
29855         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29856
29857         b_status=$(barrier_stat)
29858         [ "$b_status" = "'frozen'" ] ||
29859                 error "(4) unexpected barrier status $b_status"
29860
29861         do_facet mgs $LCTL barrier_thaw $FSNAME
29862         b_status=$(barrier_stat)
29863         [ "$b_status" = "'thawed'" ] ||
29864                 error "(5) unexpected barrier status $b_status"
29865
29866         local devname=$(mdsdevname 2)
29867
29868         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29869
29870         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29871                 error "(7) Fail to rescan barrier bitmap"
29872
29873         post_801
29874 }
29875 run_test 801c "rescan barrier bitmap"
29876
29877 test_802b() {
29878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29879         remote_mds_nodsh && skip "remote MDS with nodsh"
29880
29881         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29882                 skip "readonly option not available"
29883
29884         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29885
29886         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29887                 error "(2) Fail to copy"
29888
29889         # write back all cached data before setting MDT to readonly
29890         cancel_lru_locks
29891         sync_all_data
29892
29893         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29894         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29895
29896         echo "Modify should be refused"
29897         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29898
29899         echo "Read should be allowed"
29900         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29901                 error "(7) Read should succeed under ro mode"
29902
29903         # disable readonly
29904         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29905 }
29906 run_test 802b "be able to set MDTs to readonly"
29907
29908 test_803a() {
29909         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29910         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29911                 skip "MDS needs to be newer than 2.10.54"
29912
29913         mkdir_on_mdt0 $DIR/$tdir
29914         # Create some objects on all MDTs to trigger related logs objects
29915         for idx in $(seq $MDSCOUNT); do
29916                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29917                         $DIR/$tdir/dir${idx} ||
29918                         error "Fail to create $DIR/$tdir/dir${idx}"
29919         done
29920
29921         wait_delete_completed # ensure old test cleanups are finished
29922         sleep 3
29923         echo "before create:"
29924         $LFS df -i $MOUNT
29925         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29926
29927         for i in {1..10}; do
29928                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29929                         error "Fail to create $DIR/$tdir/foo$i"
29930         done
29931
29932         # sync ZFS-on-MDS to refresh statfs data
29933         wait_zfs_commit mds1
29934         sleep 3
29935         echo "after create:"
29936         $LFS df -i $MOUNT
29937         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29938
29939         # allow for an llog to be cleaned up during the test
29940         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29941                 error "before ($before_used) + 10 > after ($after_used)"
29942
29943         for i in {1..10}; do
29944                 rm -rf $DIR/$tdir/foo$i ||
29945                         error "Fail to remove $DIR/$tdir/foo$i"
29946         done
29947
29948         # sync ZFS-on-MDS to refresh statfs data
29949         wait_zfs_commit mds1
29950         wait_delete_completed
29951         sleep 3 # avoid MDT return cached statfs
29952         echo "after unlink:"
29953         $LFS df -i $MOUNT
29954         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29955
29956         # allow for an llog to be created during the test
29957         [ $after_used -le $((before_used + 1)) ] ||
29958                 error "after ($after_used) > before ($before_used) + 1"
29959 }
29960 run_test 803a "verify agent object for remote object"
29961
29962 test_803b() {
29963         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29964         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29965                 skip "MDS needs to be newer than 2.13.56"
29966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29967
29968         for i in $(seq 0 $((MDSCOUNT - 1))); do
29969                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29970         done
29971
29972         local before=0
29973         local after=0
29974
29975         local tmp
29976
29977         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29978         for i in $(seq 0 $((MDSCOUNT - 1))); do
29979                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29980                         awk '/getattr/ { print $2 }')
29981                 before=$((before + tmp))
29982         done
29983         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29984         for i in $(seq 0 $((MDSCOUNT - 1))); do
29985                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29986                         awk '/getattr/ { print $2 }')
29987                 after=$((after + tmp))
29988         done
29989
29990         [ $before -eq $after ] || error "getattr count $before != $after"
29991 }
29992 run_test 803b "remote object can getattr from cache"
29993
29994 test_804() {
29995         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29996         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29997                 skip "MDS needs to be newer than 2.10.54"
29998         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29999
30000         mkdir -p $DIR/$tdir
30001         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30002                 error "Fail to create $DIR/$tdir/dir0"
30003
30004         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30005         local dev=$(mdsdevname 2)
30006
30007         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30008                 grep ${fid} || error "NOT found agent entry for dir0"
30009
30010         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30011                 error "Fail to create $DIR/$tdir/dir1"
30012
30013         touch $DIR/$tdir/dir1/foo0 ||
30014                 error "Fail to create $DIR/$tdir/dir1/foo0"
30015         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30016         local rc=0
30017
30018         for idx in $(seq $MDSCOUNT); do
30019                 dev=$(mdsdevname $idx)
30020                 do_facet mds${idx} \
30021                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30022                         grep ${fid} && rc=$idx
30023         done
30024
30025         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30026                 error "Fail to rename foo0 to foo1"
30027         if [ $rc -eq 0 ]; then
30028                 for idx in $(seq $MDSCOUNT); do
30029                         dev=$(mdsdevname $idx)
30030                         do_facet mds${idx} \
30031                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30032                         grep ${fid} && rc=$idx
30033                 done
30034         fi
30035
30036         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30037                 error "Fail to rename foo1 to foo2"
30038         if [ $rc -eq 0 ]; then
30039                 for idx in $(seq $MDSCOUNT); do
30040                         dev=$(mdsdevname $idx)
30041                         do_facet mds${idx} \
30042                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30043                         grep ${fid} && rc=$idx
30044                 done
30045         fi
30046
30047         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30048
30049         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30050                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30051         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30052                 error "Fail to rename foo2 to foo0"
30053         unlink $DIR/$tdir/dir1/foo0 ||
30054                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30055         rm -rf $DIR/$tdir/dir0 ||
30056                 error "Fail to rm $DIR/$tdir/dir0"
30057
30058         for idx in $(seq $MDSCOUNT); do
30059                 rc=0
30060
30061                 stop mds${idx}
30062                 dev=$(mdsdevname $idx)
30063                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30064                         rc=$?
30065                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30066                         error "mount mds$idx failed"
30067                 df $MOUNT > /dev/null 2>&1
30068
30069                 # e2fsck should not return error
30070                 [ $rc -eq 0 ] ||
30071                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30072         done
30073 }
30074 run_test 804 "verify agent entry for remote entry"
30075
30076 cleanup_805() {
30077         do_facet $SINGLEMDS zfs set quota=$old $fsset
30078         unlinkmany $DIR/$tdir/f- 1000000
30079         trap 0
30080 }
30081
30082 test_805() {
30083         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30084         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30085         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30086                 skip "netfree not implemented before 0.7"
30087         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30088                 skip "Need MDS version at least 2.10.57"
30089
30090         local fsset
30091         local freekb
30092         local usedkb
30093         local old
30094         local quota
30095         local pref="osd-zfs.$FSNAME-MDT0000."
30096
30097         # limit available space on MDS dataset to meet nospace issue
30098         # quickly. then ZFS 0.7.2 can use reserved space if asked
30099         # properly (using netfree flag in osd_declare_destroy()
30100         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30101         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30102                 gawk '{print $3}')
30103         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30104         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30105         let "usedkb=usedkb-freekb"
30106         let "freekb=freekb/2"
30107         if let "freekb > 5000"; then
30108                 let "freekb=5000"
30109         fi
30110         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30111         trap cleanup_805 EXIT
30112         mkdir_on_mdt0 $DIR/$tdir
30113         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30114                 error "Can't set PFL layout"
30115         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30116         rm -rf $DIR/$tdir || error "not able to remove"
30117         do_facet $SINGLEMDS zfs set quota=$old $fsset
30118         trap 0
30119 }
30120 run_test 805 "ZFS can remove from full fs"
30121
30122 # Size-on-MDS test
30123 check_lsom_data()
30124 {
30125         local file=$1
30126         local expect=$(stat -c %s $file)
30127
30128         check_lsom_size $1 $expect
30129
30130         local blocks=$($LFS getsom -b $file)
30131         expect=$(stat -c %b $file)
30132         [[ $blocks == $expect ]] ||
30133                 error "$file expected blocks: $expect, got: $blocks"
30134 }
30135
30136 check_lsom_size()
30137 {
30138         local size
30139         local expect=$2
30140
30141         cancel_lru_locks mdc
30142
30143         size=$($LFS getsom -s $1)
30144         [[ $size == $expect ]] ||
30145                 error "$file expected size: $expect, got: $size"
30146 }
30147
30148 test_806() {
30149         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30150                 skip "Need MDS version at least 2.11.52"
30151
30152         local bs=1048576
30153
30154         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30155
30156         disable_opencache
30157         stack_trap "restore_opencache"
30158
30159         # single-threaded write
30160         echo "Test SOM for single-threaded write"
30161         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30162                 error "write $tfile failed"
30163         check_lsom_size $DIR/$tfile $bs
30164
30165         local num=32
30166         local size=$(($num * $bs))
30167         local offset=0
30168         local i
30169
30170         echo "Test SOM for single client multi-threaded($num) write"
30171         $TRUNCATE $DIR/$tfile 0
30172         for ((i = 0; i < $num; i++)); do
30173                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30174                 local pids[$i]=$!
30175                 offset=$((offset + $bs))
30176         done
30177         for (( i=0; i < $num; i++ )); do
30178                 wait ${pids[$i]}
30179         done
30180         check_lsom_size $DIR/$tfile $size
30181
30182         $TRUNCATE $DIR/$tfile 0
30183         for ((i = 0; i < $num; i++)); do
30184                 offset=$((offset - $bs))
30185                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30186                 local pids[$i]=$!
30187         done
30188         for (( i=0; i < $num; i++ )); do
30189                 wait ${pids[$i]}
30190         done
30191         check_lsom_size $DIR/$tfile $size
30192
30193         # multi-client writes
30194         num=$(get_node_count ${CLIENTS//,/ })
30195         size=$(($num * $bs))
30196         offset=0
30197         i=0
30198
30199         echo "Test SOM for multi-client ($num) writes"
30200         $TRUNCATE $DIR/$tfile 0
30201         for client in ${CLIENTS//,/ }; do
30202                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30203                 local pids[$i]=$!
30204                 i=$((i + 1))
30205                 offset=$((offset + $bs))
30206         done
30207         for (( i=0; i < $num; i++ )); do
30208                 wait ${pids[$i]}
30209         done
30210         check_lsom_size $DIR/$tfile $offset
30211
30212         i=0
30213         $TRUNCATE $DIR/$tfile 0
30214         for client in ${CLIENTS//,/ }; do
30215                 offset=$((offset - $bs))
30216                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30217                 local pids[$i]=$!
30218                 i=$((i + 1))
30219         done
30220         for (( i=0; i < $num; i++ )); do
30221                 wait ${pids[$i]}
30222         done
30223         check_lsom_size $DIR/$tfile $size
30224
30225         # verify SOM blocks count
30226         echo "Verify SOM block count"
30227         $TRUNCATE $DIR/$tfile 0
30228         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30229                 error "failed to write file $tfile with fdatasync and fstat"
30230         check_lsom_data $DIR/$tfile
30231
30232         $TRUNCATE $DIR/$tfile 0
30233         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30234                 error "failed to write file $tfile with fdatasync"
30235         check_lsom_data $DIR/$tfile
30236
30237         $TRUNCATE $DIR/$tfile 0
30238         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30239                 error "failed to write file $tfile with sync IO"
30240         check_lsom_data $DIR/$tfile
30241
30242         # verify truncate
30243         echo "Test SOM for truncate"
30244         # use ftruncate to sync blocks on close request
30245         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30246         check_lsom_size $DIR/$tfile 16384
30247         check_lsom_data $DIR/$tfile
30248
30249         $TRUNCATE $DIR/$tfile 1234
30250         check_lsom_size $DIR/$tfile 1234
30251         # sync blocks on the MDT
30252         $MULTIOP $DIR/$tfile oc
30253         check_lsom_data $DIR/$tfile
30254 }
30255 run_test 806 "Verify Lazy Size on MDS"
30256
30257 test_807() {
30258         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30259         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30260                 skip "Need MDS version at least 2.11.52"
30261
30262         # Registration step
30263         changelog_register || error "changelog_register failed"
30264         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30265         changelog_users $SINGLEMDS | grep -q $cl_user ||
30266                 error "User $cl_user not found in changelog_users"
30267
30268         rm -rf $DIR/$tdir || error "rm $tdir failed"
30269         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30270         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30271         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30272         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30273                 error "truncate $tdir/trunc failed"
30274
30275         local bs=1048576
30276         echo "Test SOM for single-threaded write with fsync"
30277         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30278                 error "write $tfile failed"
30279         sync;sync;sync
30280
30281         # multi-client wirtes
30282         local num=$(get_node_count ${CLIENTS//,/ })
30283         local offset=0
30284         local i=0
30285
30286         echo "Test SOM for multi-client ($num) writes"
30287         touch $DIR/$tfile || error "touch $tfile failed"
30288         $TRUNCATE $DIR/$tfile 0
30289         for client in ${CLIENTS//,/ }; do
30290                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30291                 local pids[$i]=$!
30292                 i=$((i + 1))
30293                 offset=$((offset + $bs))
30294         done
30295         for (( i=0; i < $num; i++ )); do
30296                 wait ${pids[$i]}
30297         done
30298
30299         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30300         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30301         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30302         check_lsom_data $DIR/$tdir/trunc
30303         check_lsom_data $DIR/$tdir/single_dd
30304         check_lsom_data $DIR/$tfile
30305
30306         rm -rf $DIR/$tdir
30307         # Deregistration step
30308         changelog_deregister || error "changelog_deregister failed"
30309 }
30310 run_test 807 "verify LSOM syncing tool"
30311
30312 check_som_nologged()
30313 {
30314         local lines=$($LFS changelog $FSNAME-MDT0000 |
30315                 grep 'x=trusted.som' | wc -l)
30316         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30317 }
30318
30319 test_808() {
30320         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30321                 skip "Need MDS version at least 2.11.55"
30322
30323         # Registration step
30324         changelog_register || error "changelog_register failed"
30325
30326         touch $DIR/$tfile || error "touch $tfile failed"
30327         check_som_nologged
30328
30329         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30330                 error "write $tfile failed"
30331         check_som_nologged
30332
30333         $TRUNCATE $DIR/$tfile 1234
30334         check_som_nologged
30335
30336         $TRUNCATE $DIR/$tfile 1048576
30337         check_som_nologged
30338
30339         # Deregistration step
30340         changelog_deregister || error "changelog_deregister failed"
30341 }
30342 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30343
30344 check_som_nodata()
30345 {
30346         $LFS getsom $1
30347         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30348 }
30349
30350 test_809() {
30351         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30352                 skip "Need MDS version at least 2.11.56"
30353
30354         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30355                 error "failed to create DoM-only file $DIR/$tfile"
30356         touch $DIR/$tfile || error "touch $tfile failed"
30357         check_som_nodata $DIR/$tfile
30358
30359         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30360                 error "write $tfile failed"
30361         check_som_nodata $DIR/$tfile
30362
30363         $TRUNCATE $DIR/$tfile 1234
30364         check_som_nodata $DIR/$tfile
30365
30366         $TRUNCATE $DIR/$tfile 4097
30367         check_som_nodata $DIR/$file
30368 }
30369 run_test 809 "Verify no SOM xattr store for DoM-only files"
30370
30371 test_810() {
30372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30373         $GSS && skip_env "could not run with gss"
30374         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30375                 skip "OST < 2.12.58 doesn't align checksum"
30376
30377         set_checksums 1
30378         stack_trap "set_checksums $ORIG_CSUM" EXIT
30379         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30380
30381         local csum
30382         local before
30383         local after
30384         for csum in $CKSUM_TYPES; do
30385                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30386                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30387                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30388                         eval set -- $i
30389                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30390                         before=$(md5sum $DIR/$tfile)
30391                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30392                         after=$(md5sum $DIR/$tfile)
30393                         [ "$before" == "$after" ] ||
30394                                 error "$csum: $before != $after bs=$1 seek=$2"
30395                 done
30396         done
30397 }
30398 run_test 810 "partial page writes on ZFS (LU-11663)"
30399
30400 test_812a() {
30401         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30402                 skip "OST < 2.12.51 doesn't support this fail_loc"
30403
30404         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30405         # ensure ost1 is connected
30406         stat $DIR/$tfile >/dev/null || error "can't stat"
30407         wait_osc_import_state client ost1 FULL
30408         # no locks, no reqs to let the connection idle
30409         cancel_lru_locks osc
30410
30411         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30412 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30413         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30414         wait_osc_import_state client ost1 CONNECTING
30415         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30416
30417         stat $DIR/$tfile >/dev/null || error "can't stat file"
30418 }
30419 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30420
30421 test_812b() { # LU-12378
30422         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30423                 skip "OST < 2.12.51 doesn't support this fail_loc"
30424
30425         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30426         # ensure ost1 is connected
30427         stat $DIR/$tfile >/dev/null || error "can't stat"
30428         wait_osc_import_state client ost1 FULL
30429         # no locks, no reqs to let the connection idle
30430         cancel_lru_locks osc
30431
30432         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30433 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30434         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30435         wait_osc_import_state client ost1 CONNECTING
30436         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30437
30438         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30439         wait_osc_import_state client ost1 IDLE
30440 }
30441 run_test 812b "do not drop no resend request for idle connect"
30442
30443 test_812c() {
30444         local old
30445
30446         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30447
30448         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30449         $LFS getstripe $DIR/$tfile
30450         $LCTL set_param osc.*.idle_timeout=10
30451         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30452         # ensure ost1 is connected
30453         stat $DIR/$tfile >/dev/null || error "can't stat"
30454         wait_osc_import_state client ost1 FULL
30455         # no locks, no reqs to let the connection idle
30456         cancel_lru_locks osc
30457
30458 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30459         $LCTL set_param fail_loc=0x80000533
30460         sleep 15
30461         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30462 }
30463 run_test 812c "idle import vs lock enqueue race"
30464
30465 test_813() {
30466         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30467         [ -z "$file_heat_sav" ] && skip "no file heat support"
30468
30469         local readsample
30470         local writesample
30471         local readbyte
30472         local writebyte
30473         local readsample1
30474         local writesample1
30475         local readbyte1
30476         local writebyte1
30477
30478         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30479         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30480
30481         $LCTL set_param -n llite.*.file_heat=1
30482         echo "Turn on file heat"
30483         echo "Period second: $period_second, Decay percentage: $decay_pct"
30484
30485         echo "QQQQ" > $DIR/$tfile
30486         echo "QQQQ" > $DIR/$tfile
30487         echo "QQQQ" > $DIR/$tfile
30488         cat $DIR/$tfile > /dev/null
30489         cat $DIR/$tfile > /dev/null
30490         cat $DIR/$tfile > /dev/null
30491         cat $DIR/$tfile > /dev/null
30492
30493         local out=$($LFS heat_get $DIR/$tfile)
30494
30495         $LFS heat_get $DIR/$tfile
30496         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30497         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30498         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30499         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30500
30501         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30502         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30503         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30504         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30505
30506         sleep $((period_second + 3))
30507         echo "Sleep $((period_second + 3)) seconds..."
30508         # The recursion formula to calculate the heat of the file f is as
30509         # follow:
30510         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30511         # Where Hi is the heat value in the period between time points i*I and
30512         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30513         # to the weight of Ci.
30514         out=$($LFS heat_get $DIR/$tfile)
30515         $LFS heat_get $DIR/$tfile
30516         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30517         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30518         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30519         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30520
30521         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30522                 error "read sample ($readsample) is wrong"
30523         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30524                 error "write sample ($writesample) is wrong"
30525         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30526                 error "read bytes ($readbyte) is wrong"
30527         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30528                 error "write bytes ($writebyte) is wrong"
30529
30530         echo "QQQQ" > $DIR/$tfile
30531         echo "QQQQ" > $DIR/$tfile
30532         echo "QQQQ" > $DIR/$tfile
30533         cat $DIR/$tfile > /dev/null
30534         cat $DIR/$tfile > /dev/null
30535         cat $DIR/$tfile > /dev/null
30536         cat $DIR/$tfile > /dev/null
30537
30538         sleep $((period_second + 3))
30539         echo "Sleep $((period_second + 3)) seconds..."
30540
30541         out=$($LFS heat_get $DIR/$tfile)
30542         $LFS heat_get $DIR/$tfile
30543         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30544         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30545         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30546         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30547
30548         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30549                 4 * $decay_pct) / 100") -eq 1 ] ||
30550                 error "read sample ($readsample1) is wrong"
30551         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30552                 3 * $decay_pct) / 100") -eq 1 ] ||
30553                 error "write sample ($writesample1) is wrong"
30554         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30555                 20 * $decay_pct) / 100") -eq 1 ] ||
30556                 error "read bytes ($readbyte1) is wrong"
30557         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30558                 15 * $decay_pct) / 100") -eq 1 ] ||
30559                 error "write bytes ($writebyte1) is wrong"
30560
30561         echo "Turn off file heat for the file $DIR/$tfile"
30562         $LFS heat_set -o $DIR/$tfile
30563
30564         echo "QQQQ" > $DIR/$tfile
30565         echo "QQQQ" > $DIR/$tfile
30566         echo "QQQQ" > $DIR/$tfile
30567         cat $DIR/$tfile > /dev/null
30568         cat $DIR/$tfile > /dev/null
30569         cat $DIR/$tfile > /dev/null
30570         cat $DIR/$tfile > /dev/null
30571
30572         out=$($LFS heat_get $DIR/$tfile)
30573         $LFS heat_get $DIR/$tfile
30574         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30575         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30576         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30577         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30578
30579         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30580         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30581         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30582         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30583
30584         echo "Trun on file heat for the file $DIR/$tfile"
30585         $LFS heat_set -O $DIR/$tfile
30586
30587         echo "QQQQ" > $DIR/$tfile
30588         echo "QQQQ" > $DIR/$tfile
30589         echo "QQQQ" > $DIR/$tfile
30590         cat $DIR/$tfile > /dev/null
30591         cat $DIR/$tfile > /dev/null
30592         cat $DIR/$tfile > /dev/null
30593         cat $DIR/$tfile > /dev/null
30594
30595         out=$($LFS heat_get $DIR/$tfile)
30596         $LFS heat_get $DIR/$tfile
30597         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30598         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30599         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30600         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30601
30602         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30603         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30604         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30605         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30606
30607         $LFS heat_set -c $DIR/$tfile
30608         $LCTL set_param -n llite.*.file_heat=0
30609         echo "Turn off file heat support for the Lustre filesystem"
30610
30611         echo "QQQQ" > $DIR/$tfile
30612         echo "QQQQ" > $DIR/$tfile
30613         echo "QQQQ" > $DIR/$tfile
30614         cat $DIR/$tfile > /dev/null
30615         cat $DIR/$tfile > /dev/null
30616         cat $DIR/$tfile > /dev/null
30617         cat $DIR/$tfile > /dev/null
30618
30619         out=$($LFS heat_get $DIR/$tfile)
30620         $LFS heat_get $DIR/$tfile
30621         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30622         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30623         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30624         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30625
30626         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30627         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30628         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30629         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30630
30631         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30632         rm -f $DIR/$tfile
30633 }
30634 run_test 813 "File heat verfication"
30635
30636 test_814()
30637 {
30638         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30639         echo -n y >> $DIR/$tfile
30640         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30641         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30642 }
30643 run_test 814 "sparse cp works as expected (LU-12361)"
30644
30645 test_815()
30646 {
30647         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30648         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30649 }
30650 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30651
30652 test_816() {
30653         local ost1_imp=$(get_osc_import_name client ost1)
30654         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30655                          cut -d'.' -f2)
30656
30657         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30658         # ensure ost1 is connected
30659
30660         stat $DIR/$tfile >/dev/null || error "can't stat"
30661         wait_osc_import_state client ost1 FULL
30662         # no locks, no reqs to let the connection idle
30663         cancel_lru_locks osc
30664         lru_resize_disable osc
30665         local before
30666         local now
30667         before=$($LCTL get_param -n \
30668                  ldlm.namespaces.$imp_name.lru_size)
30669
30670         wait_osc_import_state client ost1 IDLE
30671         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30672         now=$($LCTL get_param -n \
30673               ldlm.namespaces.$imp_name.lru_size)
30674         [ $before == $now ] || error "lru_size changed $before != $now"
30675 }
30676 run_test 816 "do not reset lru_resize on idle reconnect"
30677
30678 cleanup_817() {
30679         umount $tmpdir
30680         exportfs -u localhost:$DIR/nfsexp
30681         rm -rf $DIR/nfsexp
30682 }
30683
30684 test_817() {
30685         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30686
30687         mkdir -p $DIR/nfsexp
30688         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30689                 error "failed to export nfs"
30690
30691         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30692         stack_trap cleanup_817 EXIT
30693
30694         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30695                 error "failed to mount nfs to $tmpdir"
30696
30697         cp /bin/true $tmpdir
30698         $DIR/nfsexp/true || error "failed to execute 'true' command"
30699 }
30700 run_test 817 "nfsd won't cache write lock for exec file"
30701
30702 test_818() {
30703         test_mkdir -i0 -c1 $DIR/$tdir
30704         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30705         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30706         stop $SINGLEMDS
30707
30708         # restore osp-syn threads
30709         stack_trap "fail $SINGLEMDS"
30710
30711         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30712         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30713         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30714                 error "start $SINGLEMDS failed"
30715         rm -rf $DIR/$tdir
30716
30717         local testid=$(echo $TESTNAME | tr '_' ' ')
30718
30719         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30720                 grep "run LFSCK" || error "run LFSCK is not suggested"
30721 }
30722 run_test 818 "unlink with failed llog"
30723
30724 test_819a() {
30725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30726         cancel_lru_locks osc
30727         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30728         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30729         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30730         rm -f $TDIR/$tfile
30731 }
30732 run_test 819a "too big niobuf in read"
30733
30734 test_819b() {
30735         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30736         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30737         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30738         cancel_lru_locks osc
30739         sleep 1
30740         rm -f $TDIR/$tfile
30741 }
30742 run_test 819b "too big niobuf in write"
30743
30744
30745 function test_820_start_ost() {
30746         sleep 5
30747
30748         for num in $(seq $OSTCOUNT); do
30749                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30750         done
30751 }
30752
30753 test_820() {
30754         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30755
30756         mkdir $DIR/$tdir
30757         umount_client $MOUNT || error "umount failed"
30758         for num in $(seq $OSTCOUNT); do
30759                 stop ost$num
30760         done
30761
30762         # mount client with no active OSTs
30763         # so that the client can't initialize max LOV EA size
30764         # from OSC notifications
30765         mount_client $MOUNT || error "mount failed"
30766         # delay OST starting to keep this 0 max EA size for a while
30767         test_820_start_ost &
30768
30769         # create a directory on MDS2
30770         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30771                 error "Failed to create directory"
30772         # open intent should update default EA size
30773         # see mdc_update_max_ea_from_body()
30774         # notice this is the very first RPC to MDS2
30775         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30776         ret=$?
30777         echo $out
30778         # With SSK, this situation can lead to -EPERM being returned.
30779         # In that case, simply retry.
30780         if [ $ret -ne 0 ] && $SHARED_KEY; then
30781                 if echo "$out" | grep -q "not permitted"; then
30782                         cp /etc/services $DIR/$tdir/mds2
30783                         ret=$?
30784                 fi
30785         fi
30786         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30787 }
30788 run_test 820 "update max EA from open intent"
30789
30790 test_823() {
30791         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30792         local OST_MAX_PRECREATE=20000
30793
30794         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30795                 skip "Need MDS version at least 2.14.56"
30796
30797         save_lustre_params mds1 \
30798                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30799         do_facet $SINGLEMDS "$LCTL set_param -n \
30800                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30801         do_facet $SINGLEMDS "$LCTL set_param -n \
30802                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30803
30804         stack_trap "restore_lustre_params < $p; rm $p"
30805
30806         do_facet $SINGLEMDS "$LCTL set_param -n \
30807                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30808
30809         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30810                       osp.$FSNAME-OST0000*MDT0000.create_count")
30811         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30812                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30813         local expect_count=$(((($max/2)/256) * 256))
30814
30815         log "setting create_count to 100200:"
30816         log " -result- count: $count with max: $max, expecting: $expect_count"
30817
30818         [[ $count -eq expect_count ]] ||
30819                 error "Create count not set to max precreate."
30820 }
30821 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30822
30823 test_831() {
30824         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30825                 skip "Need MDS version 2.14.56"
30826
30827         local sync_changes=$(do_facet $SINGLEMDS \
30828                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30829
30830         [ "$sync_changes" -gt 100 ] &&
30831                 skip "Sync changes $sync_changes > 100 already"
30832
30833         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30834
30835         $LFS mkdir -i 0 $DIR/$tdir
30836         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30837
30838         save_lustre_params mds1 \
30839                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30840         save_lustre_params mds1 \
30841                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30842
30843         do_facet mds1 "$LCTL set_param -n \
30844                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30845                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30846         stack_trap "restore_lustre_params < $p" EXIT
30847
30848         createmany -o $DIR/$tdir/f- 1000
30849         unlinkmany $DIR/$tdir/f- 1000 &
30850         local UNLINK_PID=$!
30851
30852         while sleep 1; do
30853                 sync_changes=$(do_facet mds1 \
30854                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30855                 # the check in the code is racy, fail the test
30856                 # if the value above the limit by 10.
30857                 [ $sync_changes -gt 110 ] && {
30858                         kill -2 $UNLINK_PID
30859                         wait
30860                         error "osp changes throttling failed, $sync_changes>110"
30861                 }
30862                 kill -0 $UNLINK_PID 2> /dev/null || break
30863         done
30864         wait
30865 }
30866 run_test 831 "throttling unlink/setattr queuing on OSP"
30867
30868 test_832() {
30869         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30870         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30871                 skip "Need MDS version 2.15.52+"
30872         is_rmentry_supported || skip "rm_entry not supported"
30873
30874         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30875         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30876         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30877                 error "mkdir remote_dir failed"
30878         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30879                 error "mkdir striped_dir failed"
30880         touch $DIR/$tdir/file || error "touch file failed"
30881         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30882         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30883 }
30884 run_test 832 "lfs rm_entry"
30885
30886 test_833() {
30887         local file=$DIR/$tfile
30888
30889         stack_trap "rm -f $file" EXIT
30890         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30891
30892         local wpid
30893         local rpid
30894         local rpid2
30895
30896         # Buffered I/O write
30897         (
30898                 while [ ! -e $DIR/sanity.833.lck ]; do
30899                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30900                                 error "failed to write $file"
30901                         sleep 0.$((RANDOM % 4 + 1))
30902                 done
30903         )&
30904         wpid=$!
30905
30906         # Buffered I/O read
30907         (
30908                 while [ ! -e $DIR/sanity.833.lck ]; do
30909                         dd if=$file of=/dev/null bs=1M count=50 ||
30910                                 error "failed to read $file"
30911                         sleep 0.$((RANDOM % 4 + 1))
30912                 done
30913         )&
30914         rpid=$!
30915
30916         # Direct I/O read
30917         (
30918                 while [ ! -e $DIR/sanity.833.lck ]; do
30919                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30920                                 error "failed to read $file in direct I/O mode"
30921                         sleep 0.$((RANDOM % 4 + 1))
30922                 done
30923         )&
30924         rpid2=$!
30925
30926         sleep 30
30927         touch $DIR/sanity.833.lck
30928         wait $wpid || error "$?: buffered write failed"
30929         wait $rpid || error "$?: buffered read failed"
30930         wait $rpid2 || error "$?: direct read failed"
30931 }
30932 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30933
30934 #
30935 # tests that do cleanup/setup should be run at the end
30936 #
30937
30938 test_900() {
30939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30940         local ls
30941
30942         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30943         $LCTL set_param fail_loc=0x903
30944
30945         cancel_lru_locks MGC
30946
30947         FAIL_ON_ERROR=true cleanup
30948         FAIL_ON_ERROR=true setup
30949 }
30950 run_test 900 "umount should not race with any mgc requeue thread"
30951
30952 # LUS-6253/LU-11185
30953 test_901() {
30954         local old
30955         local count
30956         local oldc
30957         local newc
30958         local olds
30959         local news
30960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30961
30962         # some get_param have a bug to handle dot in param name
30963         cancel_lru_locks MGC
30964         old=$(mount -t lustre | wc -l)
30965         # 1 config+sptlrpc
30966         # 2 params
30967         # 3 nodemap
30968         # 4 IR
30969         old=$((old * 4))
30970         oldc=0
30971         count=0
30972         while [ $old -ne $oldc ]; do
30973                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30974                 sleep 1
30975                 ((count++))
30976                 if [ $count -ge $TIMEOUT ]; then
30977                         error "too large timeout"
30978                 fi
30979         done
30980         umount_client $MOUNT || error "umount failed"
30981         mount_client $MOUNT || error "mount failed"
30982         cancel_lru_locks MGC
30983         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30984
30985         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30986
30987         return 0
30988 }
30989 run_test 901 "don't leak a mgc lock on client umount"
30990
30991 # LU-13377
30992 test_902() {
30993         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30994                 skip "client does not have LU-13377 fix"
30995         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30996         $LCTL set_param fail_loc=0x1415
30997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30998         cancel_lru_locks osc
30999         rm -f $DIR/$tfile
31000 }
31001 run_test 902 "test short write doesn't hang lustre"
31002
31003 # LU-14711
31004 test_903() {
31005         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31006         echo "blah" > $DIR/${tfile}-2
31007         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31008         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31009         $LCTL set_param fail_loc=0x417 fail_val=20
31010
31011         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31012         sleep 1 # To start the destroy
31013         wait_destroy_complete 150 || error "Destroy taking too long"
31014         cat $DIR/$tfile > /dev/null || error "Evicted"
31015 }
31016 run_test 903 "Test long page discard does not cause evictions"
31017
31018 test_904() {
31019         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31020         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31021                 grep -q project || skip "skip project quota not supported"
31022
31023         local testfile="$DIR/$tdir/$tfile"
31024         local xattr="trusted.projid"
31025         local projid
31026         local mdts=$(comma_list $(mdts_nodes))
31027         local saved=$(do_facet mds1 $LCTL get_param -n \
31028                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31029
31030         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31031         stack_trap "do_nodes $mdts $LCTL set_param \
31032                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31033
31034         mkdir -p $DIR/$tdir
31035         touch $testfile
31036         #hide projid xattr on server
31037         $LFS project -p 1 $testfile ||
31038                 error "set $testfile project id failed"
31039         getfattr -m - $testfile | grep $xattr &&
31040                 error "do not show trusted.projid when disabled on server"
31041         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31042         #should be hidden when projid is 0
31043         $LFS project -p 0 $testfile ||
31044                 error "set $testfile project id failed"
31045         getfattr -m - $testfile | grep $xattr &&
31046                 error "do not show trusted.projid with project ID 0"
31047
31048         #still can getxattr explicitly
31049         projid=$(getfattr -n $xattr $testfile |
31050                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31051         [ $projid == "0" ] ||
31052                 error "projid expected 0 not $projid"
31053
31054         #set the projid via setxattr
31055         setfattr -n $xattr -v "1000" $testfile ||
31056                 error "setattr failed with $?"
31057         projid=($($LFS project $testfile))
31058         [ ${projid[0]} == "1000" ] ||
31059                 error "projid expected 1000 not $projid"
31060
31061         #check the new projid via getxattr
31062         $LFS project -p 1001 $testfile ||
31063                 error "set $testfile project id failed"
31064         getfattr -m - $testfile | grep $xattr ||
31065                 error "should show trusted.projid when project ID != 0"
31066         projid=$(getfattr -n $xattr $testfile |
31067                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31068         [ $projid == "1001" ] ||
31069                 error "projid expected 1001 not $projid"
31070
31071         #try to set invalid projid
31072         setfattr -n $xattr -v "4294967295" $testfile &&
31073                 error "set invalid projid should fail"
31074
31075         #remove the xattr means setting projid to 0
31076         setfattr -x $xattr $testfile ||
31077                 error "setfattr failed with $?"
31078         projid=($($LFS project $testfile))
31079         [ ${projid[0]} == "0" ] ||
31080                 error "projid expected 0 not $projid"
31081
31082         #should be hidden when parent has inherit flag and same projid
31083         $LFS project -srp 1002 $DIR/$tdir ||
31084                 error "set $tdir project id failed"
31085         getfattr -m - $testfile | grep $xattr &&
31086                 error "do not show trusted.projid with inherit flag"
31087
31088         #still can getxattr explicitly
31089         projid=$(getfattr -n $xattr $testfile |
31090                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31091         [ $projid == "1002" ] ||
31092                 error "projid expected 1002 not $projid"
31093 }
31094 run_test 904 "virtual project ID xattr"
31095
31096 # LU-8582
31097 test_905() {
31098         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31099                 skip "need OST version >= 2.15.50.220 for fail_loc"
31100
31101         remote_ost_nodsh && skip "remote OST with nodsh"
31102         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31103
31104         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31105
31106         #define OBD_FAIL_OST_OPCODE 0x253
31107         # OST_LADVISE = 21
31108         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31109         $LFS ladvise -a willread $DIR/$tfile &&
31110                 error "unexpected success of ladvise with fault injection"
31111         $LFS ladvise -a willread $DIR/$tfile |&
31112                 grep -q "Operation not supported"
31113         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31114 }
31115 run_test 905 "bad or new opcode should not stuck client"
31116
31117 test_906() {
31118         grep -q io_uring_setup /proc/kallsyms ||
31119                 skip "Client OS does not support io_uring I/O engine"
31120         io_uring_probe || skip "kernel does not support io_uring fully"
31121         which fio || skip_env "no fio installed"
31122         fio --enghelp | grep -q io_uring ||
31123                 skip_env "fio does not support io_uring I/O engine"
31124
31125         local file=$DIR/$tfile
31126         local ioengine="io_uring"
31127         local numjobs=2
31128         local size=50M
31129
31130         fio --name=seqwrite --ioengine=$ioengine        \
31131                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31132                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31133                 error "fio seqwrite $file failed"
31134
31135         fio --name=seqread --ioengine=$ioengine \
31136                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31137                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31138                 error "fio seqread $file failed"
31139
31140         rm -f $file || error "rm -f $file failed"
31141 }
31142 run_test 906 "Simple test for io_uring I/O engine via fio"
31143
31144 test_907() {
31145         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31146
31147         # set stripe size to max rpc size
31148         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31149         $LFS getstripe $DIR/$tfile
31150 #define OBD_FAIL_OST_EROFS               0x216
31151         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31152
31153         local bs=$((max_pages * PAGE_SIZE / 16))
31154
31155         # write full one stripe and one block
31156         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31157
31158         rm $DIR/$tfile || error "rm failed"
31159 }
31160 run_test 907 "write rpc error during unlink"
31161
31162 complete_test $SECONDS
31163 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31164 check_and_cleanup_lustre
31165 if [ "$I_MOUNTED" != "yes" ]; then
31166         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31167 fi
31168 exit_status