Whamcloud - gitweb
3f96ca7c0cddfe9506b5ca393e1f4b60034edb1a
[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         local num_dev_to_create="$((8192 - $dev_count))"
6395
6396         load_module obdclass/obd_test || error "load_module failed"
6397
6398         local start=$SECONDS
6399
6400         # This must be run in iteractive mode, since attach and setup
6401         # are stateful
6402         for ((i = 1; i <= num_dev_to_create; i++)); do
6403                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6404                 echo "setup obd_test_$i"
6405         done | $LCTL || error "OBD device creation failed"
6406
6407         echo "Load time: $((SECONDS - start))"
6408         echo "Devices:"
6409         cat "$dev_path" | tail -n 10
6410
6411         for ((i = 1; i <= num_dev_to_create; i++)); do
6412                 echo "--device obd_name_$i cleanup"
6413                 echo "--device obd_name_$i detach"
6414         done | $LCTL || error "OBD device cleanup failed"
6415
6416         echo "Unload time: $((SECONDS - start))"
6417
6418         rmmod -v obd_test ||
6419                 error "rmmod failed (may trigger a failure in a later test)"
6420 }
6421 run_test 55b "Load and unload max OBD devices"
6422
6423 test_56a() {
6424         local numfiles=3
6425         local numdirs=2
6426         local dir=$DIR/$tdir
6427
6428         rm -rf $dir
6429         test_mkdir -p $dir/dir
6430         for i in $(seq $numfiles); do
6431                 touch $dir/file$i
6432                 touch $dir/dir/file$i
6433         done
6434
6435         local numcomp=$($LFS getstripe --component-count $dir)
6436
6437         [[ $numcomp == 0 ]] && numcomp=1
6438
6439         # test lfs getstripe with --recursive
6440         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6441
6442         [[ $filenum -eq $((numfiles * 2)) ]] ||
6443                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6444         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6445         [[ $filenum -eq $numfiles ]] ||
6446                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6447         echo "$LFS getstripe showed obdidx or l_ost_idx"
6448
6449         # test lfs getstripe with file instead of dir
6450         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6451         [[ $filenum -eq 1 ]] ||
6452                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6453         echo "$LFS getstripe file1 passed"
6454
6455         #test lfs getstripe with --verbose
6456         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6457         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6458                 error "$LFS getstripe --verbose $dir: "\
6459                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6460         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6461                 error "$LFS getstripe $dir: showed lmm_magic"
6462
6463         #test lfs getstripe with -v prints lmm_fid
6464         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6465         local countfids=$((numdirs + numfiles * numcomp))
6466         [[ $filenum -eq $countfids ]] ||
6467                 error "$LFS getstripe -v $dir: "\
6468                       "got $filenum want $countfids lmm_fid"
6469         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6470                 error "$LFS getstripe $dir: showed lmm_fid by default"
6471         echo "$LFS getstripe --verbose passed"
6472
6473         #check for FID information
6474         local fid1=$($LFS getstripe --fid $dir/file1)
6475         local fid2=$($LFS getstripe --verbose $dir/file1 |
6476                      awk '/lmm_fid: / { print $2; exit; }')
6477         local fid3=$($LFS path2fid $dir/file1)
6478
6479         [ "$fid1" != "$fid2" ] &&
6480                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6481         [ "$fid1" != "$fid3" ] &&
6482                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6483         echo "$LFS getstripe --fid passed"
6484
6485         #test lfs getstripe with --obd
6486         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6487                 error "$LFS getstripe --obd wrong_uuid: should return error"
6488
6489         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6490
6491         local ostidx=1
6492         local obduuid=$(ostuuid_from_index $ostidx)
6493         local found=$($LFS getstripe -r --obd $obduuid $dir |
6494                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6495
6496         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6497         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6498                 ((filenum--))
6499         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6500                 ((filenum--))
6501
6502         [[ $found -eq $filenum ]] ||
6503                 error "$LFS getstripe --obd: found $found expect $filenum"
6504         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6505                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6506                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6507                 error "$LFS getstripe --obd: should not show file on other obd"
6508         echo "$LFS getstripe --obd passed"
6509 }
6510 run_test 56a "check $LFS getstripe"
6511
6512 test_56b() {
6513         local dir=$DIR/$tdir
6514         local numdirs=3
6515
6516         test_mkdir $dir
6517         for i in $(seq $numdirs); do
6518                 test_mkdir $dir/dir$i
6519         done
6520
6521         # test lfs getdirstripe default mode is non-recursion, which is
6522         # different from lfs getstripe
6523         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6524
6525         [[ $dircnt -eq 1 ]] ||
6526                 error "$LFS getdirstripe: found $dircnt, not 1"
6527         dircnt=$($LFS getdirstripe --recursive $dir |
6528                 grep -c lmv_stripe_count)
6529         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6530                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6531 }
6532 run_test 56b "check $LFS getdirstripe"
6533
6534 test_56bb() {
6535         verify_yaml_available || skip_env "YAML verification not installed"
6536         local output_file=$DIR/$tfile.out
6537
6538         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6539
6540         cat $output_file
6541         cat $output_file | verify_yaml || error "layout is not valid YAML"
6542 }
6543 run_test 56bb "check $LFS getdirstripe layout is YAML"
6544
6545 test_56c() {
6546         remote_ost_nodsh && skip "remote OST with nodsh"
6547
6548         local ost_idx=0
6549         local ost_name=$(ostname_from_index $ost_idx)
6550         local old_status=$(ost_dev_status $ost_idx)
6551         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6552
6553         [[ -z "$old_status" ]] ||
6554                 skip_env "OST $ost_name is in $old_status status"
6555
6556         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6557         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6558                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6559         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6560                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6561                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6562         fi
6563
6564         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6565                 error "$LFS df -v showing inactive devices"
6566         sleep_maxage
6567
6568         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6569
6570         [[ "$new_status" =~ "D" ]] ||
6571                 error "$ost_name status is '$new_status', missing 'D'"
6572         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6573                 [[ "$new_status" =~ "N" ]] ||
6574                         error "$ost_name status is '$new_status', missing 'N'"
6575         fi
6576         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6577                 [[ "$new_status" =~ "f" ]] ||
6578                         error "$ost_name status is '$new_status', missing 'f'"
6579         fi
6580
6581         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6582         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6583                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6584         [[ -z "$p" ]] && restore_lustre_params < $p || true
6585         sleep_maxage
6586
6587         new_status=$(ost_dev_status $ost_idx)
6588         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6589                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6590         # can't check 'f' as devices may actually be on flash
6591 }
6592 run_test 56c "check 'lfs df' showing device status"
6593
6594 test_56d() {
6595         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6596         local osts=$($LFS df -v $MOUNT | grep -c OST)
6597
6598         $LFS df $MOUNT
6599
6600         (( mdts == MDSCOUNT )) ||
6601                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6602         (( osts == OSTCOUNT )) ||
6603                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6604 }
6605 run_test 56d "'lfs df -v' prints only configured devices"
6606
6607 test_56e() {
6608         err_enoent=2 # No such file or directory
6609         err_eopnotsupp=95 # Operation not supported
6610
6611         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6612         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6613
6614         # Check for handling of path not exists
6615         output=$($LFS df $enoent_mnt 2>&1)
6616         ret=$?
6617
6618         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6619         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6620                 error "expect failure $err_enoent, not $ret"
6621
6622         # Check for handling of non-Lustre FS
6623         output=$($LFS df $notsup_mnt)
6624         ret=$?
6625
6626         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6627         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6628                 error "expect success $err_eopnotsupp, not $ret"
6629
6630         # Check for multiple LustreFS argument
6631         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6632         ret=$?
6633
6634         [[ $output -eq 3 && $ret -eq 0 ]] ||
6635                 error "expect success 3, not $output, rc = $ret"
6636
6637         # Check for correct non-Lustre FS handling among multiple
6638         # LustreFS argument
6639         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6640                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6641         ret=$?
6642
6643         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6644                 error "expect success 2, not $output, rc = $ret"
6645 }
6646 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6647
6648 NUMFILES=3
6649 NUMDIRS=3
6650 setup_56() {
6651         local local_tdir="$1"
6652         local local_numfiles="$2"
6653         local local_numdirs="$3"
6654         local dir_params="$4"
6655         local dir_stripe_params="$5"
6656
6657         if [ ! -d "$local_tdir" ] ; then
6658                 test_mkdir -p $dir_stripe_params $local_tdir
6659                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6660                 for i in $(seq $local_numfiles) ; do
6661                         touch $local_tdir/file$i
6662                 done
6663                 for i in $(seq $local_numdirs) ; do
6664                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6665                         for j in $(seq $local_numfiles) ; do
6666                                 touch $local_tdir/dir$i/file$j
6667                         done
6668                 done
6669         fi
6670 }
6671
6672 setup_56_special() {
6673         local local_tdir=$1
6674         local local_numfiles=$2
6675         local local_numdirs=$3
6676
6677         setup_56 $local_tdir $local_numfiles $local_numdirs
6678
6679         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6680                 for i in $(seq $local_numfiles) ; do
6681                         mknod $local_tdir/loop${i}b b 7 $i
6682                         mknod $local_tdir/null${i}c c 1 3
6683                         ln -s $local_tdir/file1 $local_tdir/link${i}
6684                 done
6685                 for i in $(seq $local_numdirs) ; do
6686                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6687                         mknod $local_tdir/dir$i/null${i}c c 1 3
6688                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6689                 done
6690         fi
6691 }
6692
6693 test_56g() {
6694         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6695         local expected=$(($NUMDIRS + 2))
6696
6697         setup_56 $dir $NUMFILES $NUMDIRS
6698
6699         # test lfs find with -name
6700         for i in $(seq $NUMFILES) ; do
6701                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6702
6703                 [ $nums -eq $expected ] ||
6704                         error "lfs find -name '*$i' $dir wrong: "\
6705                               "found $nums, expected $expected"
6706         done
6707 }
6708 run_test 56g "check lfs find -name"
6709
6710 test_56h() {
6711         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6712         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6713
6714         setup_56 $dir $NUMFILES $NUMDIRS
6715
6716         # test lfs find with ! -name
6717         for i in $(seq $NUMFILES) ; do
6718                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6719
6720                 [ $nums -eq $expected ] ||
6721                         error "lfs find ! -name '*$i' $dir wrong: "\
6722                               "found $nums, expected $expected"
6723         done
6724 }
6725 run_test 56h "check lfs find ! -name"
6726
6727 test_56i() {
6728         local dir=$DIR/$tdir
6729
6730         test_mkdir $dir
6731
6732         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6733         local out=$($cmd)
6734
6735         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6736 }
6737 run_test 56i "check 'lfs find -ost UUID' skips directories"
6738
6739 test_56j() {
6740         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6741
6742         setup_56_special $dir $NUMFILES $NUMDIRS
6743
6744         local expected=$((NUMDIRS + 1))
6745         local cmd="$LFS find -type d $dir"
6746         local nums=$($cmd | wc -l)
6747
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750 }
6751 run_test 56j "check lfs find -type d"
6752
6753 test_56k() {
6754         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6755
6756         setup_56_special $dir $NUMFILES $NUMDIRS
6757
6758         local expected=$(((NUMDIRS + 1) * NUMFILES))
6759         local cmd="$LFS find -type f $dir"
6760         local nums=$($cmd | wc -l)
6761
6762         [ $nums -eq $expected ] ||
6763                 error "'$cmd' wrong: found $nums, expected $expected"
6764 }
6765 run_test 56k "check lfs find -type f"
6766
6767 test_56l() {
6768         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6769
6770         setup_56_special $dir $NUMFILES $NUMDIRS
6771
6772         local expected=$((NUMDIRS + NUMFILES))
6773         local cmd="$LFS find -type b $dir"
6774         local nums=$($cmd | wc -l)
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778 }
6779 run_test 56l "check lfs find -type b"
6780
6781 test_56m() {
6782         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6783
6784         setup_56_special $dir $NUMFILES $NUMDIRS
6785
6786         local expected=$((NUMDIRS + NUMFILES))
6787         local cmd="$LFS find -type c $dir"
6788         local nums=$($cmd | wc -l)
6789         [ $nums -eq $expected ] ||
6790                 error "'$cmd' wrong: found $nums, expected $expected"
6791 }
6792 run_test 56m "check lfs find -type c"
6793
6794 test_56n() {
6795         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6796         setup_56_special $dir $NUMFILES $NUMDIRS
6797
6798         local expected=$((NUMDIRS + NUMFILES))
6799         local cmd="$LFS find -type l $dir"
6800         local nums=$($cmd | wc -l)
6801
6802         [ $nums -eq $expected ] ||
6803                 error "'$cmd' wrong: found $nums, expected $expected"
6804 }
6805 run_test 56n "check lfs find -type l"
6806
6807 test_56o() {
6808         local dir=$DIR/$tdir
6809
6810         setup_56 $dir $NUMFILES $NUMDIRS
6811         utime $dir/file1 > /dev/null || error "utime (1)"
6812         utime $dir/file2 > /dev/null || error "utime (2)"
6813         utime $dir/dir1 > /dev/null || error "utime (3)"
6814         utime $dir/dir2 > /dev/null || error "utime (4)"
6815         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6816         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6817
6818         local expected=4
6819         local nums=$($LFS find -mtime +0 $dir | wc -l)
6820
6821         [ $nums -eq $expected ] ||
6822                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6823
6824         expected=12
6825         cmd="$LFS find -mtime 0 $dir"
6826         nums=$($cmd | wc -l)
6827         [ $nums -eq $expected ] ||
6828                 error "'$cmd' wrong: found $nums, expected $expected"
6829 }
6830 run_test 56o "check lfs find -mtime for old files"
6831
6832 test_56ob() {
6833         local dir=$DIR/$tdir
6834         local expected=1
6835         local count=0
6836
6837         # just to make sure there is something that won't be found
6838         test_mkdir $dir
6839         touch $dir/$tfile.now
6840
6841         for age in year week day hour min; do
6842                 count=$((count + 1))
6843
6844                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6845                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6846                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6847
6848                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6849                 local nums=$($cmd | wc -l)
6850                 [ $nums -eq $expected ] ||
6851                         error "'$cmd' wrong: found $nums, expected $expected"
6852
6853                 cmd="$LFS find $dir -atime $count${age:0:1}"
6854                 nums=$($cmd | wc -l)
6855                 [ $nums -eq $expected ] ||
6856                         error "'$cmd' wrong: found $nums, expected $expected"
6857         done
6858
6859         sleep 2
6860         cmd="$LFS find $dir -ctime +1s -type f"
6861         nums=$($cmd | wc -l)
6862         (( $nums == $count * 2 + 1)) ||
6863                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6864 }
6865 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6866
6867 test_newerXY_base() {
6868         local x=$1
6869         local y=$2
6870         local dir=$DIR/$tdir
6871         local ref
6872         local negref
6873
6874         if [ $y == "t" ]; then
6875                 if [ $x == "b" ]; then
6876                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6877                 else
6878                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6879                 fi
6880         else
6881                 ref=$DIR/$tfile.newer.$x$y
6882                 touch $ref || error "touch $ref failed"
6883         fi
6884
6885         echo "before = $ref"
6886         sleep 2
6887         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6888         sleep 2
6889         if [ $y == "t" ]; then
6890                 if [ $x == "b" ]; then
6891                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6892                 else
6893                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6894                 fi
6895         else
6896                 negref=$DIR/$tfile.negnewer.$x$y
6897                 touch $negref || error "touch $negref failed"
6898         fi
6899
6900         echo "after = $negref"
6901         local cmd="$LFS find $dir -newer$x$y $ref"
6902         local nums=$(eval $cmd | wc -l)
6903         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6904
6905         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6906                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6907
6908         cmd="$LFS find $dir ! -newer$x$y $negref"
6909         nums=$(eval $cmd | wc -l)
6910         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6911                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6912
6913         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6914         nums=$(eval $cmd | wc -l)
6915         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6916                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6917
6918         rm -rf $DIR/*
6919 }
6920
6921 test_56oc() {
6922         test_newerXY_base "a" "a"
6923         test_newerXY_base "a" "m"
6924         test_newerXY_base "a" "c"
6925         test_newerXY_base "m" "a"
6926         test_newerXY_base "m" "m"
6927         test_newerXY_base "m" "c"
6928         test_newerXY_base "c" "a"
6929         test_newerXY_base "c" "m"
6930         test_newerXY_base "c" "c"
6931
6932         test_newerXY_base "a" "t"
6933         test_newerXY_base "m" "t"
6934         test_newerXY_base "c" "t"
6935
6936         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6937            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6938                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6939
6940         test_newerXY_base "b" "b"
6941         test_newerXY_base "b" "t"
6942 }
6943 run_test 56oc "check lfs find -newerXY work"
6944
6945 test_56od() {
6946         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6947                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6948
6949         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6950                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6951
6952         local dir=$DIR/$tdir
6953         local ref=$DIR/$tfile.ref
6954         local negref=$DIR/$tfile.negref
6955
6956         mkdir $dir || error "mkdir $dir failed"
6957         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6958         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6959         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6960         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6961         touch $ref || error "touch $ref failed"
6962         # sleep 3 seconds at least
6963         sleep 3
6964
6965         local before=$(do_facet mds1 date +%s)
6966         local skew=$(($(date +%s) - before + 1))
6967
6968         if (( skew < 0 && skew > -5 )); then
6969                 sleep $((0 - skew + 1))
6970                 skew=0
6971         fi
6972
6973         # Set the dir stripe params to limit files all on MDT0,
6974         # otherwise we need to calc the max clock skew between
6975         # the client and MDTs.
6976         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6977         sleep 2
6978         touch $negref || error "touch $negref failed"
6979
6980         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6981         local nums=$($cmd | wc -l)
6982         local expected=$(((NUMFILES + 1) * NUMDIRS))
6983
6984         [ $nums -eq $expected ] ||
6985                 error "'$cmd' wrong: found $nums, expected $expected"
6986
6987         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6988         nums=$($cmd | wc -l)
6989         expected=$((NUMFILES + 1))
6990         [ $nums -eq $expected ] ||
6991                 error "'$cmd' wrong: found $nums, expected $expected"
6992
6993         [ $skew -lt 0 ] && return
6994
6995         local after=$(do_facet mds1 date +%s)
6996         local age=$((after - before + 1 + skew))
6997
6998         cmd="$LFS find $dir -btime -${age}s -type f"
6999         nums=$($cmd | wc -l)
7000         expected=$(((NUMFILES + 1) * NUMDIRS))
7001
7002         echo "Clock skew between client and server: $skew, age:$age"
7003         [ $nums -eq $expected ] ||
7004                 error "'$cmd' wrong: found $nums, expected $expected"
7005
7006         expected=$(($NUMDIRS + 1))
7007         cmd="$LFS find $dir -btime -${age}s -type d"
7008         nums=$($cmd | wc -l)
7009         [ $nums -eq $expected ] ||
7010                 error "'$cmd' wrong: found $nums, expected $expected"
7011         rm -f $ref $negref || error "Failed to remove $ref $negref"
7012 }
7013 run_test 56od "check lfs find -btime with units"
7014
7015 test_56p() {
7016         [ $RUNAS_ID -eq $UID ] &&
7017                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7018
7019         local dir=$DIR/$tdir
7020
7021         setup_56 $dir $NUMFILES $NUMDIRS
7022         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7023
7024         local expected=$NUMFILES
7025         local cmd="$LFS find -uid $RUNAS_ID $dir"
7026         local nums=$($cmd | wc -l)
7027
7028         [ $nums -eq $expected ] ||
7029                 error "'$cmd' wrong: found $nums, expected $expected"
7030
7031         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7032         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7033         nums=$($cmd | wc -l)
7034         [ $nums -eq $expected ] ||
7035                 error "'$cmd' wrong: found $nums, expected $expected"
7036 }
7037 run_test 56p "check lfs find -uid and ! -uid"
7038
7039 test_56q() {
7040         [ $RUNAS_ID -eq $UID ] &&
7041                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7042
7043         local dir=$DIR/$tdir
7044
7045         setup_56 $dir $NUMFILES $NUMDIRS
7046         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7047
7048         local expected=$NUMFILES
7049         local cmd="$LFS find -gid $RUNAS_GID $dir"
7050         local nums=$($cmd | wc -l)
7051
7052         [ $nums -eq $expected ] ||
7053                 error "'$cmd' wrong: found $nums, expected $expected"
7054
7055         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7056         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7057         nums=$($cmd | wc -l)
7058         [ $nums -eq $expected ] ||
7059                 error "'$cmd' wrong: found $nums, expected $expected"
7060 }
7061 run_test 56q "check lfs find -gid and ! -gid"
7062
7063 test_56r() {
7064         local dir=$DIR/$tdir
7065
7066         setup_56 $dir $NUMFILES $NUMDIRS
7067
7068         local expected=12
7069         local cmd="$LFS find -size 0 -type f -lazy $dir"
7070         local nums=$($cmd | wc -l)
7071
7072         [ $nums -eq $expected ] ||
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074         cmd="$LFS find -size 0 -type f $dir"
7075         nums=$($cmd | wc -l)
7076         [ $nums -eq $expected ] ||
7077                 error "'$cmd' wrong: found $nums, expected $expected"
7078
7079         expected=0
7080         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] ||
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084         cmd="$LFS find ! -size 0 -type f $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] ||
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088
7089         echo "test" > $dir/$tfile
7090         echo "test2" > $dir/$tfile.2 && sync
7091         expected=1
7092         cmd="$LFS find -size 5 -type f -lazy $dir"
7093         nums=$($cmd | wc -l)
7094         [ $nums -eq $expected ] ||
7095                 error "'$cmd' wrong: found $nums, expected $expected"
7096         cmd="$LFS find -size 5 -type f $dir"
7097         nums=$($cmd | wc -l)
7098         [ $nums -eq $expected ] ||
7099                 error "'$cmd' wrong: found $nums, expected $expected"
7100
7101         expected=1
7102         cmd="$LFS find -size +5 -type f -lazy $dir"
7103         nums=$($cmd | wc -l)
7104         [ $nums -eq $expected ] ||
7105                 error "'$cmd' wrong: found $nums, expected $expected"
7106         cmd="$LFS find -size +5 -type f $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110
7111         expected=2
7112         cmd="$LFS find -size +0 -type f -lazy $dir"
7113         nums=$($cmd | wc -l)
7114         [ $nums -eq $expected ] ||
7115                 error "'$cmd' wrong: found $nums, expected $expected"
7116         cmd="$LFS find -size +0 -type f $dir"
7117         nums=$($cmd | wc -l)
7118         [ $nums -eq $expected ] ||
7119                 error "'$cmd' wrong: found $nums, expected $expected"
7120
7121         expected=2
7122         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7123         nums=$($cmd | wc -l)
7124         [ $nums -eq $expected ] ||
7125                 error "'$cmd' wrong: found $nums, expected $expected"
7126         cmd="$LFS find ! -size -5 -type f $dir"
7127         nums=$($cmd | wc -l)
7128         [ $nums -eq $expected ] ||
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130
7131         expected=12
7132         cmd="$LFS find -size -5 -type f -lazy $dir"
7133         nums=$($cmd | wc -l)
7134         [ $nums -eq $expected ] ||
7135                 error "'$cmd' wrong: found $nums, expected $expected"
7136         cmd="$LFS find -size -5 -type f $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140 }
7141 run_test 56r "check lfs find -size works"
7142
7143 test_56ra_sub() {
7144         local expected=$1
7145         local glimpses=$2
7146         local cmd="$3"
7147
7148         cancel_lru_locks $OSC
7149
7150         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7151         local nums=$($cmd | wc -l)
7152
7153         [ $nums -eq $expected ] ||
7154                 error "'$cmd' wrong: found $nums, expected $expected"
7155
7156         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7157
7158         if (( rpcs_before + glimpses != rpcs_after )); then
7159                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7160                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7161
7162                 if [[ $glimpses == 0 ]]; then
7163                         error "'$cmd' should not send glimpse RPCs to OST"
7164                 else
7165                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7166                 fi
7167         fi
7168 }
7169
7170 test_56ra() {
7171         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7172                 skip "MDS < 2.12.58 doesn't return LSOM data"
7173         local dir=$DIR/$tdir
7174         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7175
7176         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7177
7178         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7179         $LCTL set_param -n llite.*.statahead_agl=0
7180         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7181
7182         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7183         # open and close all files to ensure LSOM is updated
7184         cancel_lru_locks $OSC
7185         find $dir -type f | xargs cat > /dev/null
7186
7187         #   expect_found  glimpse_rpcs  command_to_run
7188         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7189         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7190         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7191         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7192
7193         echo "test" > $dir/$tfile
7194         echo "test2" > $dir/$tfile.2 && sync
7195         cancel_lru_locks $OSC
7196         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7197
7198         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7199         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7200         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7201         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7202
7203         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7204         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7205         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7206         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7207         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7208         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7209 }
7210 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7211
7212 test_56rb() {
7213         local dir=$DIR/$tdir
7214         local tmp=$TMP/$tfile.log
7215         local mdt_idx;
7216
7217         test_mkdir -p $dir || error "failed to mkdir $dir"
7218         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7219                 error "failed to setstripe $dir/$tfile"
7220         mdt_idx=$($LFS getdirstripe -i $dir)
7221         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7222
7223         stack_trap "rm -f $tmp" EXIT
7224         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7225         ! grep -q obd_uuid $tmp ||
7226                 error "failed to find --size +100K --ost 0 $dir"
7227         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7228         ! grep -q obd_uuid $tmp ||
7229                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7230 }
7231 run_test 56rb "check lfs find --size --ost/--mdt works"
7232
7233 test_56rc() {
7234         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7235         local dir=$DIR/$tdir
7236         local found
7237
7238         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7239         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7240         (( $MDSCOUNT > 2 )) &&
7241                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7242         mkdir $dir/$tdir-{1..10}
7243         touch $dir/$tfile-{1..10}
7244
7245         found=$($LFS find $dir --mdt-count 2 | wc -l)
7246         expect=11
7247         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7248
7249         found=$($LFS find $dir -T +1 | wc -l)
7250         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7251         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7252
7253         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7254         expect=11
7255         (( $found == $expect )) || error "found $found all_char, expect $expect"
7256
7257         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7258         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7259         (( $found == $expect )) || error "found $found all_char, expect $expect"
7260 }
7261 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7262
7263 test_56rd() {
7264         local dir=$DIR/$tdir
7265
7266         test_mkdir $dir
7267         rm -f $dir/*
7268
7269         mkfifo $dir/fifo || error "failed to create fifo file"
7270         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7271                 error "should not fail even cannot get projid from pipe file"
7272         found=$($LFS find $dir -t p --printf "%y")
7273         [[ "p" == $found ]] || error "found $found, expect p"
7274
7275         mknod $dir/chardev c 1 5 ||
7276                 error "failed to create character device file"
7277         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7278                 error "should not fail even cannot get projid from chardev file"
7279         found=$($LFS find $dir -t c --printf "%y")
7280         [[ "c" == $found ]] || error "found $found, expect c"
7281
7282         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7283         (( found == 2 )) || error "unable to list all files"
7284 }
7285 run_test 56rd "check lfs find --printf special files"
7286
7287 test_56s() { # LU-611 #LU-9369
7288         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7289
7290         local dir=$DIR/$tdir
7291         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7292
7293         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7294         for i in $(seq $NUMDIRS); do
7295                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7296         done
7297
7298         local expected=$NUMDIRS
7299         local cmd="$LFS find -c $OSTCOUNT $dir"
7300         local nums=$($cmd | wc -l)
7301
7302         [ $nums -eq $expected ] || {
7303                 $LFS getstripe -R $dir
7304                 error "'$cmd' wrong: found $nums, expected $expected"
7305         }
7306
7307         expected=$((NUMDIRS + onestripe))
7308         cmd="$LFS find -stripe-count +0 -type f $dir"
7309         nums=$($cmd | wc -l)
7310         [ $nums -eq $expected ] || {
7311                 $LFS getstripe -R $dir
7312                 error "'$cmd' wrong: found $nums, expected $expected"
7313         }
7314
7315         expected=$onestripe
7316         cmd="$LFS find -stripe-count 1 -type f $dir"
7317         nums=$($cmd | wc -l)
7318         [ $nums -eq $expected ] || {
7319                 $LFS getstripe -R $dir
7320                 error "'$cmd' wrong: found $nums, expected $expected"
7321         }
7322
7323         cmd="$LFS find -stripe-count -2 -type f $dir"
7324         nums=$($cmd | wc -l)
7325         [ $nums -eq $expected ] || {
7326                 $LFS getstripe -R $dir
7327                 error "'$cmd' wrong: found $nums, expected $expected"
7328         }
7329
7330         expected=0
7331         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7332         nums=$($cmd | wc -l)
7333         [ $nums -eq $expected ] || {
7334                 $LFS getstripe -R $dir
7335                 error "'$cmd' wrong: found $nums, expected $expected"
7336         }
7337 }
7338 run_test 56s "check lfs find -stripe-count works"
7339
7340 test_56t() { # LU-611 #LU-9369
7341         local dir=$DIR/$tdir
7342
7343         setup_56 $dir 0 $NUMDIRS
7344         for i in $(seq $NUMDIRS); do
7345                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7346         done
7347
7348         local expected=$NUMDIRS
7349         local cmd="$LFS find -S 8M $dir"
7350         local nums=$($cmd | wc -l)
7351
7352         [ $nums -eq $expected ] || {
7353                 $LFS getstripe -R $dir
7354                 error "'$cmd' wrong: found $nums, expected $expected"
7355         }
7356         rm -rf $dir
7357
7358         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7359
7360         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7361
7362         expected=$(((NUMDIRS + 1) * NUMFILES))
7363         cmd="$LFS find -stripe-size 512k -type f $dir"
7364         nums=$($cmd | wc -l)
7365         [ $nums -eq $expected ] ||
7366                 error "'$cmd' wrong: found $nums, expected $expected"
7367
7368         cmd="$LFS find -stripe-size +320k -type f $dir"
7369         nums=$($cmd | wc -l)
7370         [ $nums -eq $expected ] ||
7371                 error "'$cmd' wrong: found $nums, expected $expected"
7372
7373         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7374         cmd="$LFS find -stripe-size +200k -type f $dir"
7375         nums=$($cmd | wc -l)
7376         [ $nums -eq $expected ] ||
7377                 error "'$cmd' wrong: found $nums, expected $expected"
7378
7379         cmd="$LFS find -stripe-size -640k -type f $dir"
7380         nums=$($cmd | wc -l)
7381         [ $nums -eq $expected ] ||
7382                 error "'$cmd' wrong: found $nums, expected $expected"
7383
7384         expected=4
7385         cmd="$LFS find -stripe-size 256k -type f $dir"
7386         nums=$($cmd | wc -l)
7387         [ $nums -eq $expected ] ||
7388                 error "'$cmd' wrong: found $nums, expected $expected"
7389
7390         cmd="$LFS find -stripe-size -320k -type f $dir"
7391         nums=$($cmd | wc -l)
7392         [ $nums -eq $expected ] ||
7393                 error "'$cmd' wrong: found $nums, expected $expected"
7394
7395         expected=0
7396         cmd="$LFS find -stripe-size 1024k -type f $dir"
7397         nums=$($cmd | wc -l)
7398         [ $nums -eq $expected ] ||
7399                 error "'$cmd' wrong: found $nums, expected $expected"
7400 }
7401 run_test 56t "check lfs find -stripe-size works"
7402
7403 test_56u() { # LU-611
7404         local dir=$DIR/$tdir
7405
7406         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7407
7408         if [[ $OSTCOUNT -gt 1 ]]; then
7409                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7410                 onestripe=4
7411         else
7412                 onestripe=0
7413         fi
7414
7415         local expected=$(((NUMDIRS + 1) * NUMFILES))
7416         local cmd="$LFS find -stripe-index 0 -type f $dir"
7417         local nums=$($cmd | wc -l)
7418
7419         [ $nums -eq $expected ] ||
7420                 error "'$cmd' wrong: found $nums, expected $expected"
7421
7422         expected=$onestripe
7423         cmd="$LFS find -stripe-index 1 -type f $dir"
7424         nums=$($cmd | wc -l)
7425         [ $nums -eq $expected ] ||
7426                 error "'$cmd' wrong: found $nums, expected $expected"
7427
7428         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7429         nums=$($cmd | wc -l)
7430         [ $nums -eq $expected ] ||
7431                 error "'$cmd' wrong: found $nums, expected $expected"
7432
7433         expected=0
7434         # This should produce an error and not return any files
7435         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7436         nums=$($cmd 2>/dev/null | wc -l)
7437         [ $nums -eq $expected ] ||
7438                 error "'$cmd' wrong: found $nums, expected $expected"
7439
7440         if [[ $OSTCOUNT -gt 1 ]]; then
7441                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7442                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7443                 nums=$($cmd | wc -l)
7444                 [ $nums -eq $expected ] ||
7445                         error "'$cmd' wrong: found $nums, expected $expected"
7446         fi
7447 }
7448 run_test 56u "check lfs find -stripe-index works"
7449
7450 test_56v() {
7451         local mdt_idx=0
7452         local dir=$DIR/$tdir
7453
7454         setup_56 $dir $NUMFILES $NUMDIRS
7455
7456         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7457         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7458
7459         for file in $($LFS find -m $UUID $dir); do
7460                 file_midx=$($LFS getstripe -m $file)
7461                 [ $file_midx -eq $mdt_idx ] ||
7462                         error "lfs find -m $UUID != getstripe -m $file_midx"
7463         done
7464 }
7465 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7466
7467 test_56wa() {
7468         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7470
7471         local dir=$DIR/$tdir
7472
7473         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7474         stack_trap "rm -rf $dir"
7475
7476         local stripe_size=$($LFS getstripe -S -d $dir) ||
7477                 error "$LFS getstripe -S -d $dir failed"
7478         stripe_size=${stripe_size%% *}
7479
7480         local file_size=$((stripe_size * OSTCOUNT))
7481         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7482         local required_space=$((file_num * file_size))
7483         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7484                            head -n1)
7485         (( free_space >= required_space / 1024 )) ||
7486                 skip_env "need $required_space, have $free_space kbytes"
7487
7488         local dd_bs=65536
7489         local dd_count=$((file_size / dd_bs))
7490
7491         # write data into the files
7492         local i
7493         local j
7494         local file
7495
7496         for ((i = 1; i <= NUMFILES; i++ )); do
7497                 file=$dir/file$i
7498                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7499                         error "write data into $file failed"
7500         done
7501         for ((i = 1; i <= NUMDIRS; i++ )); do
7502                 for ((j = 1; j <= NUMFILES; j++ )); do
7503                         file=$dir/dir$i/file$j
7504                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7505                                 error "write data into $file failed"
7506                 done
7507         done
7508
7509         # $LFS_MIGRATE will fail if hard link migration is unsupported
7510         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7511                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7512                         error "creating links to $dir/dir1/file1 failed"
7513         fi
7514
7515         local expected=-1
7516
7517         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7518
7519         # lfs_migrate file
7520         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7521
7522         echo "$cmd"
7523         eval $cmd || error "$cmd failed"
7524
7525         check_stripe_count $dir/file1 $expected
7526
7527         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7528                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7529                 # OST 1 if it is on OST 0. This file is small enough to
7530                 # be on only one stripe.
7531                 file=$dir/migr_1_ost
7532                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7533                         error "write data into $file failed"
7534                 local obdidx=$($LFS getstripe -i $file)
7535                 local oldmd5=$(md5sum $file)
7536                 local newobdidx=0
7537
7538                 (( obdidx != 0 )) || newobdidx=1
7539                 cmd="$LFS migrate -i $newobdidx $file"
7540                 echo $cmd
7541                 eval $cmd || error "$cmd failed"
7542
7543                 local realobdix=$($LFS getstripe -i $file)
7544                 local newmd5=$(md5sum $file)
7545
7546                 (( $newobdidx == $realobdix )) ||
7547                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7548                 [[ "$oldmd5" == "$newmd5" ]] ||
7549                         error "md5sum differ: $oldmd5, $newmd5"
7550         fi
7551
7552         # lfs_migrate dir
7553         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7554         echo "$cmd"
7555         eval $cmd || error "$cmd failed"
7556
7557         for (( j = 1; j <= NUMFILES; j++ )); do
7558                 check_stripe_count $dir/dir1/file$j $expected
7559         done
7560
7561         # lfs_migrate works with lfs find
7562         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7563              $LFS_MIGRATE -y -c $expected"
7564         echo "$cmd"
7565         eval $cmd || error "$cmd failed"
7566
7567         for (( i = 2; i <= NUMFILES; i++ )); do
7568                 check_stripe_count $dir/file$i $expected
7569         done
7570         for (( i = 2; i <= NUMDIRS; i++ )); do
7571                 for (( j = 1; j <= NUMFILES; j++ )); do
7572                         check_stripe_count $dir/dir$i/file$j $expected
7573                 done
7574         done
7575 }
7576 run_test 56wa "check lfs_migrate -c stripe_count works"
7577
7578 test_56wb() {
7579         local file1=$DIR/$tdir/file1
7580         local create_pool=false
7581         local initial_pool=$($LFS getstripe -p $DIR)
7582         local pool_list=()
7583         local pool=""
7584
7585         echo -n "Creating test dir..."
7586         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7587         echo "done."
7588
7589         echo -n "Creating test file..."
7590         touch $file1 || error "cannot create file"
7591         echo "done."
7592
7593         echo -n "Detecting existing pools..."
7594         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7595
7596         if [ ${#pool_list[@]} -gt 0 ]; then
7597                 echo "${pool_list[@]}"
7598                 for thispool in "${pool_list[@]}"; do
7599                         if [[ -z "$initial_pool" ||
7600                               "$initial_pool" != "$thispool" ]]; then
7601                                 pool="$thispool"
7602                                 echo "Using existing pool '$pool'"
7603                                 break
7604                         fi
7605                 done
7606         else
7607                 echo "none detected."
7608         fi
7609         if [ -z "$pool" ]; then
7610                 pool=${POOL:-testpool}
7611                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7612                 echo -n "Creating pool '$pool'..."
7613                 create_pool=true
7614                 pool_add $pool &> /dev/null ||
7615                         error "pool_add failed"
7616                 echo "done."
7617
7618                 echo -n "Adding target to pool..."
7619                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7620                         error "pool_add_targets failed"
7621                 echo "done."
7622         fi
7623
7624         echo -n "Setting pool using -p option..."
7625         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7626                 error "migrate failed rc = $?"
7627         echo "done."
7628
7629         echo -n "Verifying test file is in pool after migrating..."
7630         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7631                 error "file was not migrated to pool $pool"
7632         echo "done."
7633
7634         echo -n "Removing test file from pool '$pool'..."
7635         # "lfs migrate $file" won't remove the file from the pool
7636         # until some striping information is changed.
7637         $LFS migrate -c 1 $file1 &> /dev/null ||
7638                 error "cannot remove from pool"
7639         [ "$($LFS getstripe -p $file1)" ] &&
7640                 error "pool still set"
7641         echo "done."
7642
7643         echo -n "Setting pool using --pool option..."
7644         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7645                 error "migrate failed rc = $?"
7646         echo "done."
7647
7648         # Clean up
7649         rm -f $file1
7650         if $create_pool; then
7651                 destroy_test_pools 2> /dev/null ||
7652                         error "destroy test pools failed"
7653         fi
7654 }
7655 run_test 56wb "check lfs_migrate pool support"
7656
7657 test_56wc() {
7658         local file1="$DIR/$tdir/$tfile"
7659         local md5
7660         local parent_ssize
7661         local parent_scount
7662         local cur_ssize
7663         local cur_scount
7664         local orig_ssize
7665         local new_scount
7666         local cur_comp
7667
7668         echo -n "Creating test dir..."
7669         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7670         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7671                 error "cannot set stripe by '-S 1M -c 1'"
7672         echo "done"
7673
7674         echo -n "Setting initial stripe for test file..."
7675         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7676                 error "cannot set stripe"
7677         cur_ssize=$($LFS getstripe -S "$file1")
7678         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7679         echo "done."
7680
7681         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7682         stack_trap "rm -f $file1"
7683         md5="$(md5sum $file1)"
7684
7685         # File currently set to -S 512K -c 1
7686
7687         # Ensure -c and -S options are rejected when -R is set
7688         echo -n "Verifying incompatible options are detected..."
7689         $LFS_MIGRATE -R -c 1 "$file1" &&
7690                 error "incompatible -R and -c options not detected"
7691         $LFS_MIGRATE -R -S 1M "$file1" &&
7692                 error "incompatible -R and -S options not detected"
7693         $LFS_MIGRATE -R -p pool "$file1" &&
7694                 error "incompatible -R and -p options not detected"
7695         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7696                 error "incompatible -R and -E options not detected"
7697         $LFS_MIGRATE -R -A "$file1" &&
7698                 error "incompatible -R and -A options not detected"
7699         $LFS_MIGRATE -A -c 1 "$file1" &&
7700                 error "incompatible -A and -c options not detected"
7701         $LFS_MIGRATE -A -S 1M "$file1" &&
7702                 error "incompatible -A and -S options not detected"
7703         $LFS_MIGRATE -A -p pool "$file1" &&
7704                 error "incompatible -A and -p options not detected"
7705         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7706                 error "incompatible -A and -E options not detected"
7707         echo "done."
7708
7709         # Ensure unrecognized options are passed through to 'lfs migrate'
7710         echo -n "Verifying -S option is passed through to lfs migrate..."
7711         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7712         cur_ssize=$($LFS getstripe -S "$file1")
7713         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7714         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7715         echo "done."
7716
7717         # File currently set to -S 1M -c 1
7718
7719         # Ensure long options are supported
7720         echo -n "Verifying long options supported..."
7721         $LFS_MIGRATE --non-block "$file1" ||
7722                 error "long option without argument not supported"
7723         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7724                 error "long option with argument not supported"
7725         cur_ssize=$($LFS getstripe -S "$file1")
7726         (( cur_ssize == 524288 )) ||
7727                 error "migrate --stripe-size $cur_ssize != 524288"
7728         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7729         echo "done."
7730
7731         # File currently set to -S 512K -c 1
7732
7733         if (( OSTCOUNT > 1 )); then
7734                 echo -n "Verifying explicit stripe count can be set..."
7735                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7736                 cur_scount=$($LFS getstripe -c "$file1")
7737                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7738                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7739                         error "file data has changed (3)"
7740                 echo "done."
7741         fi
7742
7743         # File currently set to -S 512K -c 1 or -S 512K -c 2
7744
7745         # Ensure parent striping is used if -R is set, and no stripe
7746         # count or size is specified
7747         echo -n "Setting stripe for parent directory..."
7748         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7749                 error "cannot set stripe '-S 2M -c 1'"
7750         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7751         echo "done."
7752
7753         echo -n "Verifying restripe option uses parent stripe settings..."
7754         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7755         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7756         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7757         cur_ssize=$($LFS getstripe -S "$file1")
7758         (( cur_ssize == parent_ssize )) ||
7759                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7760         cur_scount=$($LFS getstripe -c "$file1")
7761         (( cur_scount == parent_scount )) ||
7762                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7763         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7764         echo "done."
7765
7766         # File currently set to -S 1M -c 1
7767
7768         # Ensure striping is preserved if -R is not set, and no stripe
7769         # count or size is specified
7770         echo -n "Verifying striping size preserved when not specified..."
7771         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7772         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7773                 error "cannot set stripe on parent directory"
7774         $LFS_MIGRATE "$file1" || error "migrate failed"
7775         cur_ssize=$($LFS getstripe -S "$file1")
7776         (( cur_ssize == orig_ssize )) ||
7777                 error "migrate by default $cur_ssize != $orig_ssize"
7778         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7779         echo "done."
7780
7781         # Ensure file name properly detected when final option has no argument
7782         echo -n "Verifying file name properly detected..."
7783         $LFS_MIGRATE "$file1" ||
7784                 error "file name interpreted as option argument"
7785         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7786         echo "done."
7787
7788         # Ensure PFL arguments are passed through properly
7789         echo -n "Verifying PFL options passed through..."
7790         new_scount=$(((OSTCOUNT + 1) / 2))
7791         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7792                 error "migrate PFL arguments failed"
7793         cur_comp=$($LFS getstripe --comp-count $file1)
7794         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7795         cur_scount=$($LFS getstripe --stripe-count $file1)
7796         (( cur_scount == new_scount)) ||
7797                 error "PFL stripe count $cur_scount != $new_scount"
7798         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7799         echo "done."
7800 }
7801 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7802
7803 test_56wd() {
7804         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7805
7806         local file1=$DIR/$tdir/$tfile
7807
7808         echo -n "Creating test dir..."
7809         test_mkdir $DIR/$tdir || error "cannot create dir"
7810         echo "done."
7811
7812         echo -n "Creating test file..."
7813         echo "$tfile" > $file1
7814         echo "done."
7815
7816         # Ensure 'lfs migrate' will fail by using a non-existent option,
7817         # and make sure rsync is not called to recover
7818         echo -n "Make sure --no-rsync option works..."
7819         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7820                 grep -q 'refusing to fall back to rsync' ||
7821                 error "rsync was called with --no-rsync set"
7822         echo "done."
7823
7824         # Ensure rsync is called without trying 'lfs migrate' first
7825         echo -n "Make sure --rsync option works..."
7826         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7827                 grep -q 'falling back to rsync' &&
7828                 error "lfs migrate was called with --rsync set"
7829         echo "done."
7830 }
7831 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7832
7833 test_56we() {
7834         local td=$DIR/$tdir
7835         local tf=$td/$tfile
7836
7837         test_mkdir $td || error "cannot create $td"
7838         touch $tf || error "cannot touch $tf"
7839
7840         echo -n "Make sure --non-direct|-D works..."
7841         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7842                 grep -q "lfs migrate --non-direct" ||
7843                 error "--non-direct option cannot work correctly"
7844         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7845                 grep -q "lfs migrate -D" ||
7846                 error "-D option cannot work correctly"
7847         echo "done."
7848 }
7849 run_test 56we "check lfs_migrate --non-direct|-D support"
7850
7851 test_56x() {
7852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7853         check_swap_layouts_support
7854
7855         local dir=$DIR/$tdir
7856         local ref1=/etc/passwd
7857         local file1=$dir/file1
7858
7859         test_mkdir $dir || error "creating dir $dir"
7860         $LFS setstripe -c 2 $file1
7861         cp $ref1 $file1
7862         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7863         stripe=$($LFS getstripe -c $file1)
7864         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7865         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7866
7867         # clean up
7868         rm -f $file1
7869 }
7870 run_test 56x "lfs migration support"
7871
7872 test_56xa() {
7873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7874         check_swap_layouts_support
7875
7876         local dir=$DIR/$tdir/$testnum
7877
7878         test_mkdir -p $dir
7879
7880         local ref1=/etc/passwd
7881         local file1=$dir/file1
7882
7883         $LFS setstripe -c 2 $file1
7884         cp $ref1 $file1
7885         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7886
7887         local stripe=$($LFS getstripe -c $file1)
7888
7889         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7890         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7891
7892         # clean up
7893         rm -f $file1
7894 }
7895 run_test 56xa "lfs migration --block support"
7896
7897 check_migrate_links() {
7898         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7899         local dir="$1"
7900         local file1="$dir/file1"
7901         local begin="$2"
7902         local count="$3"
7903         local runas="$4"
7904         local total_count=$(($begin + $count - 1))
7905         local symlink_count=10
7906         local uniq_count=10
7907
7908         if [ ! -f "$file1" ]; then
7909                 echo -n "creating initial file..."
7910                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7911                         error "cannot setstripe initial file"
7912                 echo "done"
7913
7914                 echo -n "creating symlinks..."
7915                 for s in $(seq 1 $symlink_count); do
7916                         ln -s "$file1" "$dir/slink$s" ||
7917                                 error "cannot create symlinks"
7918                 done
7919                 echo "done"
7920
7921                 echo -n "creating nonlinked files..."
7922                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7923                         error "cannot create nonlinked files"
7924                 echo "done"
7925         fi
7926
7927         # create hard links
7928         if [ ! -f "$dir/file$total_count" ]; then
7929                 echo -n "creating hard links $begin:$total_count..."
7930                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7931                         /dev/null || error "cannot create hard links"
7932                 echo "done"
7933         fi
7934
7935         echo -n "checking number of hard links listed in xattrs..."
7936         local fid=$($LFS getstripe -F "$file1")
7937         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7938
7939         echo "${#paths[*]}"
7940         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7941                         skip "hard link list has unexpected size, skipping test"
7942         fi
7943         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7944                         error "link names should exceed xattrs size"
7945         fi
7946
7947         echo -n "migrating files..."
7948         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7949         local rc=$?
7950         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7951         echo "done"
7952
7953         # make sure all links have been properly migrated
7954         echo -n "verifying files..."
7955         fid=$($LFS getstripe -F "$file1") ||
7956                 error "cannot get fid for file $file1"
7957         for i in $(seq 2 $total_count); do
7958                 local fid2=$($LFS getstripe -F $dir/file$i)
7959
7960                 [ "$fid2" == "$fid" ] ||
7961                         error "migrated hard link has mismatched FID"
7962         done
7963
7964         # make sure hard links were properly detected, and migration was
7965         # performed only once for the entire link set; nonlinked files should
7966         # also be migrated
7967         local actual=$(grep -c 'done' <<< "$migrate_out")
7968         local expected=$(($uniq_count + 1))
7969
7970         [ "$actual" -eq  "$expected" ] ||
7971                 error "hard links individually migrated ($actual != $expected)"
7972
7973         # make sure the correct number of hard links are present
7974         local hardlinks=$(stat -c '%h' "$file1")
7975
7976         [ $hardlinks -eq $total_count ] ||
7977                 error "num hard links $hardlinks != $total_count"
7978         echo "done"
7979
7980         return 0
7981 }
7982
7983 test_56xb() {
7984         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7985                 skip "Need MDS version at least 2.10.55"
7986
7987         local dir="$DIR/$tdir"
7988
7989         test_mkdir "$dir" || error "cannot create dir $dir"
7990
7991         echo "testing lfs migrate mode when all links fit within xattrs"
7992         check_migrate_links "$dir" 2 99
7993
7994         echo "testing rsync mode when all links fit within xattrs"
7995         check_migrate_links --rsync "$dir" 2 99
7996
7997         echo "testing lfs migrate mode when all links do not fit within xattrs"
7998         check_migrate_links "$dir" 101 100
7999
8000         echo "testing rsync mode when all links do not fit within xattrs"
8001         check_migrate_links --rsync "$dir" 101 100
8002
8003         chown -R $RUNAS_ID $dir
8004         echo "testing non-root lfs migrate mode when not all links are in xattr"
8005         check_migrate_links "$dir" 101 100 "$RUNAS"
8006
8007         # clean up
8008         rm -rf $dir
8009 }
8010 run_test 56xb "lfs migration hard link support"
8011
8012 test_56xc() {
8013         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8014
8015         local dir="$DIR/$tdir"
8016
8017         test_mkdir "$dir" || error "cannot create dir $dir"
8018
8019         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8020         echo -n "Setting initial stripe for 20MB test file..."
8021         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8022                 error "cannot setstripe 20MB file"
8023         echo "done"
8024         echo -n "Sizing 20MB test file..."
8025         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8026         echo "done"
8027         echo -n "Verifying small file autostripe count is 1..."
8028         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8029                 error "cannot migrate 20MB file"
8030         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8031                 error "cannot get stripe for $dir/20mb"
8032         [ $stripe_count -eq 1 ] ||
8033                 error "unexpected stripe count $stripe_count for 20MB file"
8034         rm -f "$dir/20mb"
8035         echo "done"
8036
8037         # Test 2: File is small enough to fit within the available space on
8038         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8039         # have at least an additional 1KB for each desired stripe for test 3
8040         echo -n "Setting stripe for 1GB test file..."
8041         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8042         echo "done"
8043         echo -n "Sizing 1GB test file..."
8044         # File size is 1GB + 3KB
8045         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8046         echo "done"
8047
8048         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8049         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8050         if (( avail > 524288 * OSTCOUNT )); then
8051                 echo -n "Migrating 1GB file..."
8052                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8053                         error "cannot migrate 1GB file"
8054                 echo "done"
8055                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8056                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8057                         error "cannot getstripe for 1GB file"
8058                 [ $stripe_count -eq 2 ] ||
8059                         error "unexpected stripe count $stripe_count != 2"
8060                 echo "done"
8061         fi
8062
8063         # Test 3: File is too large to fit within the available space on
8064         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8065         if [ $OSTCOUNT -ge 3 ]; then
8066                 # The required available space is calculated as
8067                 # file size (1GB + 3KB) / OST count (3).
8068                 local kb_per_ost=349526
8069
8070                 echo -n "Migrating 1GB file with limit..."
8071                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8072                         error "cannot migrate 1GB file with limit"
8073                 echo "done"
8074
8075                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8076                 echo -n "Verifying 1GB autostripe count with limited space..."
8077                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8078                         error "unexpected stripe count $stripe_count (min 3)"
8079                 echo "done"
8080         fi
8081
8082         # clean up
8083         rm -rf $dir
8084 }
8085 run_test 56xc "lfs migration autostripe"
8086
8087 test_56xd() {
8088         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8089
8090         local dir=$DIR/$tdir
8091         local f_mgrt=$dir/$tfile.mgrt
8092         local f_yaml=$dir/$tfile.yaml
8093         local f_copy=$dir/$tfile.copy
8094         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8095         local layout_copy="-c 2 -S 2M -i 1"
8096         local yamlfile=$dir/yamlfile
8097         local layout_before;
8098         local layout_after;
8099
8100         test_mkdir "$dir" || error "cannot create dir $dir"
8101         stack_trap "rm -rf $dir"
8102         $LFS setstripe $layout_yaml $f_yaml ||
8103                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8104         $LFS getstripe --yaml $f_yaml > $yamlfile
8105         $LFS setstripe $layout_copy $f_copy ||
8106                 error "cannot setstripe $f_copy with layout $layout_copy"
8107         touch $f_mgrt
8108         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8109
8110         # 1. test option --yaml
8111         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8112                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8113         layout_before=$(get_layout_param $f_yaml)
8114         layout_after=$(get_layout_param $f_mgrt)
8115         [ "$layout_after" == "$layout_before" ] ||
8116                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8117
8118         # 2. test option --copy
8119         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8120                 error "cannot migrate $f_mgrt with --copy $f_copy"
8121         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8122         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8123         [ "$layout_after" == "$layout_before" ] ||
8124                 error "lfs_migrate --copy: $layout_after != $layout_before"
8125 }
8126 run_test 56xd "check lfs_migrate --yaml and --copy support"
8127
8128 test_56xe() {
8129         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8130
8131         local dir=$DIR/$tdir
8132         local f_comp=$dir/$tfile
8133         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8134         local layout_before=""
8135         local layout_after=""
8136
8137         test_mkdir "$dir" || error "cannot create dir $dir"
8138         stack_trap "rm -rf $dir"
8139         $LFS setstripe $layout $f_comp ||
8140                 error "cannot setstripe $f_comp with layout $layout"
8141         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8142         dd if=/dev/zero of=$f_comp bs=1M count=4
8143
8144         # 1. migrate a comp layout file by lfs_migrate
8145         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8146         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8147         [ "$layout_before" == "$layout_after" ] ||
8148                 error "lfs_migrate: $layout_before != $layout_after"
8149
8150         # 2. migrate a comp layout file by lfs migrate
8151         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8152         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8153         [ "$layout_before" == "$layout_after" ] ||
8154                 error "lfs migrate: $layout_before != $layout_after"
8155 }
8156 run_test 56xe "migrate a composite layout file"
8157
8158 test_56xf() {
8159         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8160
8161         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8162                 skip "Need server version at least 2.13.53"
8163
8164         local dir=$DIR/$tdir
8165         local f_comp=$dir/$tfile
8166         local layout="-E 1M -c1 -E -1 -c2"
8167         local fid_before=""
8168         local fid_after=""
8169
8170         test_mkdir "$dir" || error "cannot create dir $dir"
8171         stack_trap "rm -rf $dir"
8172         $LFS setstripe $layout $f_comp ||
8173                 error "cannot setstripe $f_comp with layout $layout"
8174         fid_before=$($LFS getstripe --fid $f_comp)
8175         dd if=/dev/zero of=$f_comp bs=1M count=4
8176
8177         # 1. migrate a comp layout file to a comp layout
8178         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8179         fid_after=$($LFS getstripe --fid $f_comp)
8180         [ "$fid_before" == "$fid_after" ] ||
8181                 error "comp-to-comp migrate: $fid_before != $fid_after"
8182
8183         # 2. migrate a comp layout file to a plain layout
8184         $LFS migrate -c2 $f_comp ||
8185                 error "cannot migrate $f_comp by lfs migrate"
8186         fid_after=$($LFS getstripe --fid $f_comp)
8187         [ "$fid_before" == "$fid_after" ] ||
8188                 error "comp-to-plain migrate: $fid_before != $fid_after"
8189
8190         # 3. migrate a plain layout file to a comp layout
8191         $LFS migrate $layout $f_comp ||
8192                 error "cannot migrate $f_comp by lfs migrate"
8193         fid_after=$($LFS getstripe --fid $f_comp)
8194         [ "$fid_before" == "$fid_after" ] ||
8195                 error "plain-to-comp migrate: $fid_before != $fid_after"
8196 }
8197 run_test 56xf "FID is not lost during migration of a composite layout file"
8198
8199 check_file_ost_range() {
8200         local file="$1"
8201         shift
8202         local range="$*"
8203         local -a file_range
8204         local idx
8205
8206         file_range=($($LFS getstripe -y "$file" |
8207                 awk '/l_ost_idx:/ { print $NF }'))
8208
8209         if [[ "${#file_range[@]}" = 0 ]]; then
8210                 echo "No osts found for $file"
8211                 return 1
8212         fi
8213
8214         for idx in "${file_range[@]}"; do
8215                 [[ " $range " =~ " $idx " ]] ||
8216                         return 1
8217         done
8218
8219         return 0
8220 }
8221
8222 sub_test_56xg() {
8223         local stripe_opt="$1"
8224         local pool="$2"
8225         shift 2
8226         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8227
8228         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8229                 error "Fail to migrate $tfile on $pool"
8230         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8231                 error "$tfile is not in pool $pool"
8232         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8233                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8234 }
8235
8236 test_56xg() {
8237         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8238         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8239         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8240                 skip "Need MDS version newer than 2.14.52"
8241
8242         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8243         local -a pool_ranges=("0 0" "1 1" "0 1")
8244
8245         # init pools
8246         for i in "${!pool_names[@]}"; do
8247                 pool_add ${pool_names[$i]} ||
8248                         error "pool_add failed (pool: ${pool_names[$i]})"
8249                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8250                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8251         done
8252
8253         # init the file to migrate
8254         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8255                 error "Unable to create $tfile on OST1"
8256         stack_trap "rm -f $DIR/$tfile"
8257         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8258                 error "Unable to write on $tfile"
8259
8260         echo "1. migrate $tfile on pool ${pool_names[0]}"
8261         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8262
8263         echo "2. migrate $tfile on pool ${pool_names[2]}"
8264         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8265
8266         echo "3. migrate $tfile on pool ${pool_names[1]}"
8267         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8268
8269         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8270         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8271         echo
8272
8273         # Clean pools
8274         destroy_test_pools ||
8275                 error "pool_destroy failed"
8276 }
8277 run_test 56xg "lfs migrate pool support"
8278
8279 test_56xh() {
8280         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8281
8282         local size_mb=25
8283         local file1=$DIR/$tfile
8284         local tmp1=$TMP/$tfile.tmp
8285
8286         $LFS setstripe -c 2 $file1
8287
8288         stack_trap "rm -f $file1 $tmp1"
8289         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8290                         error "error creating $tmp1"
8291         ls -lsh $tmp1
8292         cp $tmp1 $file1
8293
8294         local start=$SECONDS
8295
8296         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8297                 error "migrate failed rc = $?"
8298
8299         local elapsed=$((SECONDS - start))
8300
8301         # with 1MB/s, elapsed should equal size_mb
8302         (( elapsed >= size_mb * 95 / 100 )) ||
8303                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8304
8305         (( elapsed <= size_mb * 120 / 100 )) ||
8306                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8307
8308         (( elapsed <= size_mb * 350 / 100 )) ||
8309                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8310
8311         stripe=$($LFS getstripe -c $file1)
8312         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8313         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8314
8315         # Clean up file (since it is multiple MB)
8316         rm -f $file1 $tmp1
8317 }
8318 run_test 56xh "lfs migrate bandwidth limitation support"
8319
8320 test_56xi() {
8321         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8322         verify_yaml_available || skip_env "YAML verification not installed"
8323
8324         local size_mb=5
8325         local file1=$DIR/$tfile.1
8326         local file2=$DIR/$tfile.2
8327         local file3=$DIR/$tfile.3
8328         local output_file=$DIR/$tfile.out
8329         local tmp1=$TMP/$tfile.tmp
8330
8331         $LFS setstripe -c 2 $file1
8332         $LFS setstripe -c 2 $file2
8333         $LFS setstripe -c 2 $file3
8334
8335         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8336         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8337                         error "error creating $tmp1"
8338         ls -lsh $tmp1
8339         cp $tmp1 $file1
8340         cp $tmp1 $file2
8341         cp $tmp1 $file3
8342
8343         $LFS migrate --stats --stats-interval=1 \
8344                 -c 1 $file1 $file2 $file3 1> $output_file ||
8345                 error "migrate failed rc = $?"
8346
8347         cat $output_file
8348         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8349
8350         # Clean up file (since it is multiple MB)
8351         rm -f $file1 $file2 $file3 $tmp1 $output_file
8352 }
8353 run_test 56xi "lfs migrate stats support"
8354
8355 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8356         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8357
8358         local file=$DIR/$tfile
8359         local linkdir=$DIR/$tdir
8360
8361         test_mkdir $linkdir || error "fail to create $linkdir"
8362         $LFS setstripe -i 0 -c 1 -S1M $file
8363         stack_trap "rm -rf $file $linkdir"
8364         dd if=/dev/urandom of=$file bs=1M count=10 ||
8365                 error "fail to create $file"
8366
8367         # Create file links
8368         local cpts
8369         local threads_max
8370         local nlinks
8371
8372         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8373         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8374         (( nlinks = thread_max * 3 / 2 / cpts))
8375
8376         echo "create $nlinks hard links of $file"
8377         createmany -l $file $linkdir/link $nlinks
8378
8379         # Parallel migrates (should not block)
8380         local i
8381         for ((i = 0; i < nlinks; i++)); do
8382                 echo $linkdir/link$i
8383         done | xargs -n1 -P $nlinks $LFS migrate -c2
8384
8385         local stripe_count
8386         stripe_count=$($LFS getstripe -c $file) ||
8387                 error "fail to get stripe count on $file"
8388
8389         ((stripe_count == 2)) ||
8390                 error "fail to migrate $file (stripe_count = $stripe_count)"
8391 }
8392 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8393
8394 test_56xk() {
8395         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8396
8397         local size_mb=5
8398         local file1=$DIR/$tfile
8399
8400         stack_trap "rm -f $file1"
8401         $LFS setstripe -c 1 $file1
8402         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8403                 error "error creating $file1"
8404         $LFS mirror extend -N $file1 || error "can't mirror"
8405         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8406                 error "can't dd"
8407         $LFS getstripe $file1 | grep stale ||
8408                 error "one component must be stale"
8409
8410         local start=$SECONDS
8411         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8412                 error "migrate failed rc = $?"
8413         local elapsed=$((SECONDS - start))
8414         $LFS getstripe $file1 | grep stale &&
8415                 error "all components must be sync"
8416
8417         # with 1MB/s, elapsed should equal size_mb
8418         (( elapsed >= size_mb * 95 / 100 )) ||
8419                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8420
8421         (( elapsed <= size_mb * 120 / 100 )) ||
8422                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8423
8424         (( elapsed <= size_mb * 350 / 100 )) ||
8425                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8426 }
8427 run_test 56xk "lfs mirror resync bandwidth limitation support"
8428
8429 test_56xl() {
8430         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8431         verify_yaml_available || skip_env "YAML verification not installed"
8432
8433         local size_mb=5
8434         local file1=$DIR/$tfile.1
8435         local output_file=$DIR/$tfile.out
8436
8437         stack_trap "rm -f $file1"
8438         $LFS setstripe -c 1 $file1
8439         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8440                 error "error creating $file1"
8441         $LFS mirror extend -N $file1 || error "can't mirror"
8442         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8443                 error "can't dd"
8444         $LFS getstripe $file1 | grep stale ||
8445                 error "one component must be stale"
8446         $LFS getstripe $file1
8447
8448         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8449                 error "resync failed rc = $?"
8450         $LFS getstripe $file1 | grep stale &&
8451                 error "all components must be sync"
8452
8453         cat $output_file
8454         cat $output_file | verify_yaml || error "stats is not valid YAML"
8455 }
8456 run_test 56xl "lfs mirror resync stats support"
8457
8458 test_56y() {
8459         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8460                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8461
8462         local res=""
8463         local dir=$DIR/$tdir
8464         local f1=$dir/file1
8465         local f2=$dir/file2
8466
8467         test_mkdir -p $dir || error "creating dir $dir"
8468         touch $f1 || error "creating std file $f1"
8469         $MULTIOP $f2 H2c || error "creating released file $f2"
8470
8471         # a directory can be raid0, so ask only for files
8472         res=$($LFS find $dir -L raid0 -type f | wc -l)
8473         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8474
8475         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8476         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8477
8478         # only files can be released, so no need to force file search
8479         res=$($LFS find $dir -L released)
8480         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8481
8482         res=$($LFS find $dir -type f \! -L released)
8483         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8484 }
8485 run_test 56y "lfs find -L raid0|released"
8486
8487 test_56z() { # LU-4824
8488         # This checks to make sure 'lfs find' continues after errors
8489         # There are two classes of errors that should be caught:
8490         # - If multiple paths are provided, all should be searched even if one
8491         #   errors out
8492         # - If errors are encountered during the search, it should not terminate
8493         #   early
8494         local dir=$DIR/$tdir
8495         local i
8496
8497         test_mkdir $dir
8498         for i in d{0..9}; do
8499                 test_mkdir $dir/$i
8500                 touch $dir/$i/$tfile
8501         done
8502         $LFS find $DIR/non_existent_dir $dir &&
8503                 error "$LFS find did not return an error"
8504         # Make a directory unsearchable. This should NOT be the last entry in
8505         # directory order.  Arbitrarily pick the 6th entry
8506         chmod 700 $($LFS find $dir -type d | sed '6!d')
8507
8508         $RUNAS $LFS find $DIR/non_existent $dir
8509         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8510
8511         # The user should be able to see 10 directories and 9 files
8512         (( count == 19 )) ||
8513                 error "$LFS find found $count != 19 entries after error"
8514 }
8515 run_test 56z "lfs find should continue after an error"
8516
8517 test_56aa() { # LU-5937
8518         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8519
8520         local dir=$DIR/$tdir
8521
8522         mkdir $dir
8523         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8524
8525         createmany -o $dir/striped_dir/${tfile}- 1024
8526         local dirs=$($LFS find --size +8k $dir/)
8527
8528         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8529 }
8530 run_test 56aa "lfs find --size under striped dir"
8531
8532 test_56ab() { # LU-10705
8533         test_mkdir $DIR/$tdir
8534         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8535         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8536         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8537         # Flush writes to ensure valid blocks.  Need to be more thorough for
8538         # ZFS, since blocks are not allocated/returned to client immediately.
8539         sync_all_data
8540         wait_zfs_commit ost1 2
8541         cancel_lru_locks osc
8542         ls -ls $DIR/$tdir
8543
8544         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8545
8546         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8547
8548         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8549         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8550
8551         rm -f $DIR/$tdir/$tfile.[123]
8552 }
8553 run_test 56ab "lfs find --blocks"
8554
8555 # LU-11188
8556 test_56aca() {
8557         local dir="$DIR/$tdir"
8558         local perms=(001 002 003 004 005 006 007
8559                      010 020 030 040 050 060 070
8560                      100 200 300 400 500 600 700
8561                      111 222 333 444 555 666 777)
8562         local perm_minus=(8 8 4 8 4 4 2
8563                           8 8 4 8 4 4 2
8564                           8 8 4 8 4 4 2
8565                           4 4 2 4 2 2 1)
8566         local perm_slash=(8  8 12  8 12 12 14
8567                           8  8 12  8 12 12 14
8568                           8  8 12  8 12 12 14
8569                          16 16 24 16 24 24 28)
8570
8571         test_mkdir "$dir"
8572         for perm in ${perms[*]}; do
8573                 touch "$dir/$tfile.$perm"
8574                 chmod $perm "$dir/$tfile.$perm"
8575         done
8576
8577         for ((i = 0; i < ${#perms[*]}; i++)); do
8578                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8579                 (( $num == 1 )) ||
8580                         error "lfs find -perm ${perms[i]}:"\
8581                               "$num != 1"
8582
8583                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8584                 (( $num == ${perm_minus[i]} )) ||
8585                         error "lfs find -perm -${perms[i]}:"\
8586                               "$num != ${perm_minus[i]}"
8587
8588                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8589                 (( $num == ${perm_slash[i]} )) ||
8590                         error "lfs find -perm /${perms[i]}:"\
8591                               "$num != ${perm_slash[i]}"
8592         done
8593 }
8594 run_test 56aca "check lfs find -perm with octal representation"
8595
8596 test_56acb() {
8597         local dir=$DIR/$tdir
8598         # p is the permission of write and execute for user, group and other
8599         # without the umask. It is used to test +wx.
8600         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8601         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8602         local symbolic=(+t  a+t u+t g+t o+t
8603                         g+s u+s o+s +s o+sr
8604                         o=r,ug+o,u+w
8605                         u+ g+ o+ a+ ugo+
8606                         u- g- o- a- ugo-
8607                         u= g= o= a= ugo=
8608                         o=r,ug+o,u+w u=r,a+u,u+w
8609                         g=r,ugo=g,u+w u+x,+X +X
8610                         u+x,u+X u+X u+x,g+X o+r,+X
8611                         u+x,go+X +wx +rwx)
8612
8613         test_mkdir $dir
8614         for perm in ${perms[*]}; do
8615                 touch "$dir/$tfile.$perm"
8616                 chmod $perm "$dir/$tfile.$perm"
8617         done
8618
8619         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8620                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8621
8622                 (( $num == 1 )) ||
8623                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8624         done
8625 }
8626 run_test 56acb "check lfs find -perm with symbolic representation"
8627
8628 test_56acc() {
8629         local dir=$DIR/$tdir
8630         local tests="17777 787 789 abcd
8631                 ug=uu ug=a ug=gu uo=ou urw
8632                 u+xg+x a=r,u+x,"
8633
8634         test_mkdir $dir
8635         for err in $tests; do
8636                 if $LFS find $dir -perm $err 2>/dev/null; then
8637                         error "lfs find -perm $err: parsing should have failed"
8638                 fi
8639         done
8640 }
8641 run_test 56acc "check parsing error for lfs find -perm"
8642
8643 test_56ba() {
8644         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8645                 skip "Need MDS version at least 2.10.50"
8646
8647         # Create composite files with one component
8648         local dir=$DIR/$tdir
8649
8650         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8651         # Create composite files with three components
8652         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8653         # LU-16904 Create plain layout files
8654         lfs setstripe -c 1 $dir/$tfile-{1..10}
8655
8656         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8657
8658         [[ $nfiles == 10 ]] ||
8659                 error "lfs find -E 1M found $nfiles != 10 files"
8660
8661         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8662         [[ $nfiles == 25 ]] ||
8663                 error "lfs find ! -E 1M found $nfiles != 25 files"
8664
8665         # All files have a component that starts at 0
8666         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8667         [[ $nfiles == 35 ]] ||
8668                 error "lfs find --component-start 0 - $nfiles != 35 files"
8669
8670         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8671         [[ $nfiles == 15 ]] ||
8672                 error "lfs find --component-start 2M - $nfiles != 15 files"
8673
8674         # All files created here have a componenet that does not starts at 2M
8675         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8676         [[ $nfiles == 35 ]] ||
8677                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8678
8679         # Find files with a specified number of components
8680         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8681         [[ $nfiles == 15 ]] ||
8682                 error "lfs find --component-count 3 - $nfiles != 15 files"
8683
8684         # Remember non-composite files have a component count of zero
8685         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8686         [[ $nfiles == 10 ]] ||
8687                 error "lfs find --component-count 0 - $nfiles != 10 files"
8688
8689         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8690         [[ $nfiles == 20 ]] ||
8691                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8692
8693         # All files have a flag called "init"
8694         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8695         [[ $nfiles == 35 ]] ||
8696                 error "lfs find --component-flags init - $nfiles != 35 files"
8697
8698         # Multi-component files will have a component not initialized
8699         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8700         [[ $nfiles == 15 ]] ||
8701                 error "lfs find !--component-flags init - $nfiles != 15 files"
8702
8703         rm -rf $dir
8704
8705 }
8706 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8707
8708 test_56ca() {
8709         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8710                 skip "Need MDS version at least 2.10.57"
8711
8712         local td=$DIR/$tdir
8713         local tf=$td/$tfile
8714         local dir
8715         local nfiles
8716         local cmd
8717         local i
8718         local j
8719
8720         # create mirrored directories and mirrored files
8721         mkdir $td || error "mkdir $td failed"
8722         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8723         createmany -o $tf- 10 || error "create $tf- failed"
8724
8725         for i in $(seq 2); do
8726                 dir=$td/dir$i
8727                 mkdir $dir || error "mkdir $dir failed"
8728                 $LFS mirror create -N$((3 + i)) $dir ||
8729                         error "create mirrored dir $dir failed"
8730                 createmany -o $dir/$tfile- 10 ||
8731                         error "create $dir/$tfile- failed"
8732         done
8733
8734         # change the states of some mirrored files
8735         echo foo > $tf-6
8736         for i in $(seq 2); do
8737                 dir=$td/dir$i
8738                 for j in $(seq 4 9); do
8739                         echo foo > $dir/$tfile-$j
8740                 done
8741         done
8742
8743         # find mirrored files with specific mirror count
8744         cmd="$LFS find --mirror-count 3 --type f $td"
8745         nfiles=$($cmd | wc -l)
8746         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8747
8748         cmd="$LFS find ! --mirror-count 3 --type f $td"
8749         nfiles=$($cmd | wc -l)
8750         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8751
8752         cmd="$LFS find --mirror-count +2 --type f $td"
8753         nfiles=$($cmd | wc -l)
8754         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8755
8756         cmd="$LFS find --mirror-count -6 --type f $td"
8757         nfiles=$($cmd | wc -l)
8758         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8759
8760         # find mirrored files with specific file state
8761         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8762         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8763
8764         cmd="$LFS find --mirror-state=ro --type f $td"
8765         nfiles=$($cmd | wc -l)
8766         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8767
8768         cmd="$LFS find ! --mirror-state=ro --type f $td"
8769         nfiles=$($cmd | wc -l)
8770         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8771
8772         cmd="$LFS find --mirror-state=wp --type f $td"
8773         nfiles=$($cmd | wc -l)
8774         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8775
8776         cmd="$LFS find ! --mirror-state=sp --type f $td"
8777         nfiles=$($cmd | wc -l)
8778         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8779 }
8780 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8781
8782 test_56da() { # LU-14179
8783         local path=$DIR/$tdir
8784
8785         test_mkdir $path
8786         cd $path
8787
8788         local longdir=$(str_repeat 'a' 255)
8789
8790         for i in {1..15}; do
8791                 path=$path/$longdir
8792                 test_mkdir $longdir
8793                 cd $longdir
8794         done
8795
8796         local len=${#path}
8797         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8798
8799         test_mkdir $lastdir
8800         cd $lastdir
8801         # PATH_MAX-1
8802         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8803
8804         # NAME_MAX
8805         touch $(str_repeat 'f' 255)
8806
8807         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8808                 error "lfs find reported an error"
8809
8810         rm -rf $DIR/$tdir
8811 }
8812 run_test 56da "test lfs find with long paths"
8813
8814 test_56ea() { #LU-10378
8815         local path=$DIR/$tdir
8816         local pool=$TESTNAME
8817
8818         # Create ost pool
8819         pool_add $pool || error "pool_add $pool failed"
8820         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8821                 error "adding targets to $pool failed"
8822
8823         # Set default pool on directory before creating file
8824         mkdir $path || error "mkdir $path failed"
8825         $LFS setstripe -p $pool $path ||
8826                 error "set OST pool on $pool failed"
8827         touch $path/$tfile || error "touch $path/$tfile failed"
8828
8829         # Compare basic file attributes from -printf and stat
8830         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8831         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8832
8833         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8834                 error "Attrs from lfs find and stat don't match"
8835
8836         # Compare Lustre attributes from lfs find and lfs getstripe
8837         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8838         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8839         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8840         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8841         local fpool=$($LFS getstripe --pool $path/$tfile)
8842         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8843
8844         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8845                 error "Attrs from lfs find and lfs getstripe don't match"
8846
8847         # Verify behavior for unknown escape/format sequences
8848         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8849
8850         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8851                 error "Escape/format codes don't match"
8852 }
8853 run_test 56ea "test lfs find -printf option"
8854
8855 test_56eb() {
8856         local dir=$DIR/$tdir
8857         local subdir_1=$dir/subdir_1
8858
8859         test_mkdir -p $subdir_1
8860         ln -s subdir_1 $dir/link_1
8861
8862         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8863                 error "symlink is not followed"
8864
8865         $LFS getstripe --no-follow $dir |
8866                 grep "^$dir/link_1 has no stripe info$" ||
8867                 error "symlink should not have stripe info"
8868
8869         touch $dir/testfile
8870         ln -s testfile $dir/file_link_2
8871
8872         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8873                 error "symlink is not followed"
8874
8875         $LFS getstripe --no-follow $dir |
8876                 grep "^$dir/file_link_2 has no stripe info$" ||
8877                 error "symlink should not have stripe info"
8878 }
8879 run_test 56eb "check lfs getstripe on symlink"
8880
8881 test_56ec() {
8882         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8883         local dir=$DIR/$tdir
8884         local srcfile=$dir/srcfile
8885         local srcyaml=$dir/srcyaml
8886         local destfile=$dir/destfile
8887
8888         test_mkdir -p $dir
8889
8890         $LFS setstripe -i 1 $srcfile
8891         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8892         # if the setstripe yaml parsing fails for any reason, the command can
8893         # randomly assign the correct OST index, leading to an erroneous
8894         # success. but the chance of false success is low enough that a
8895         # regression should still be quickly caught.
8896         $LFS setstripe --yaml=$srcyaml $destfile
8897
8898         local srcindex=$($LFS getstripe -i $srcfile)
8899         local destindex=$($LFS getstripe -i $destfile)
8900
8901         if [[ ! $srcindex -eq $destindex ]]; then
8902                 error "setstripe did not set OST index correctly"
8903         fi
8904 }
8905 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8906
8907 test_56eda() {
8908         local dir=$DIR/$tdir
8909         local subdir=$dir/subdir
8910         local file1=$dir/$tfile
8911         local file2=$dir/$tfile\2
8912         local link=$dir/$tfile-link
8913         local nfiles
8914
8915         test_mkdir -p $dir
8916         $LFS setdirstripe -c1 $subdir
8917         touch $file1
8918         touch $file2
8919         ln $file2 $link
8920
8921         nfiles=$($LFS find --links 1 $dir | wc -l)
8922         (( $nfiles == 1 )) ||
8923                 error "lfs find --links expected 1 file, got $nfiles"
8924
8925         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8926         (( $nfiles == 2 )) ||
8927                 error "lfs find --links expected 2 files, got $nfiles"
8928
8929         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8930         (( $nfiles == 1 )) ||
8931                 error "lfs find --links expected 1 directory, got $nfiles"
8932 }
8933 run_test 56eda "check lfs find --links"
8934
8935 test_56edb() {
8936         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8937
8938         local dir=$DIR/$tdir
8939         local stripedir=$dir/stripedir
8940         local nfiles
8941
8942         test_mkdir -p $dir
8943
8944         $LFS setdirstripe -c2 $stripedir
8945
8946         $LFS getdirstripe $stripedir
8947
8948         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8949         (( $nfiles == 1 )) ||
8950                 error "lfs find --links expected 1 directory, got $nfiles"
8951 }
8952 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8953
8954 test_56ef() {
8955         local dir=$DIR/$tdir
8956         local dir1=$dir/d1
8957         local dir2=$dir/d2
8958         local nfiles
8959
8960         test_mkdir -p $dir
8961
8962         mkdir $dir1
8963         mkdir $dir2
8964
8965         touch $dir1/f
8966         touch $dir2/f
8967
8968         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8969         (( $nfiles == 2 )) ||
8970                 error "(1) lfs find expected 2 files, got $nfiles"
8971
8972         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8973         (( $nfiles == 2 )) ||
8974                 error "(2) lfs find expected 2 files, got $nfiles"
8975
8976         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8977         (( $nfiles == 2 )) ||
8978                 error "(3) lfs find expected 2 files, got $nfiles"
8979 }
8980 run_test 56ef "lfs find with multiple paths"
8981
8982 test_57a() {
8983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8984         # note test will not do anything if MDS is not local
8985         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8986                 skip_env "ldiskfs only test"
8987         fi
8988         remote_mds_nodsh && skip "remote MDS with nodsh"
8989
8990         local MNTDEV="osd*.*MDT*.mntdev"
8991         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8992         [ -z "$DEV" ] && error "can't access $MNTDEV"
8993         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8994                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8995                         error "can't access $DEV"
8996                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8997                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8998                 rm $TMP/t57a.dump
8999         done
9000 }
9001 run_test 57a "verify MDS filesystem created with large inodes =="
9002
9003 test_57b() {
9004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9005         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9006                 skip_env "ldiskfs only test"
9007         fi
9008         remote_mds_nodsh && skip "remote MDS with nodsh"
9009
9010         local dir=$DIR/$tdir
9011         local filecount=100
9012         local file1=$dir/f1
9013         local fileN=$dir/f$filecount
9014
9015         rm -rf $dir || error "removing $dir"
9016         test_mkdir -c1 $dir
9017         local mdtidx=$($LFS getstripe -m $dir)
9018         local mdtname=MDT$(printf %04x $mdtidx)
9019         local facet=mds$((mdtidx + 1))
9020
9021         echo "mcreating $filecount files"
9022         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9023
9024         # verify that files do not have EAs yet
9025         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9026                 error "$file1 has an EA"
9027         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9028                 error "$fileN has an EA"
9029
9030         sync
9031         sleep 1
9032         df $dir  #make sure we get new statfs data
9033         local mdsfree=$(do_facet $facet \
9034                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9035         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9036         local file
9037
9038         echo "opening files to create objects/EAs"
9039         for file in $(seq -f $dir/f%g 1 $filecount); do
9040                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9041                         error "opening $file"
9042         done
9043
9044         # verify that files have EAs now
9045         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9046                 error "$file1 missing EA"
9047         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9048                 error "$fileN missing EA"
9049
9050         sleep 1  #make sure we get new statfs data
9051         df $dir
9052         local mdsfree2=$(do_facet $facet \
9053                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9054         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9055
9056         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9057                 if [ "$mdsfree" != "$mdsfree2" ]; then
9058                         error "MDC before $mdcfree != after $mdcfree2"
9059                 else
9060                         echo "MDC before $mdcfree != after $mdcfree2"
9061                         echo "unable to confirm if MDS has large inodes"
9062                 fi
9063         fi
9064         rm -rf $dir
9065 }
9066 run_test 57b "default LOV EAs are stored inside large inodes ==="
9067
9068 test_58() {
9069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9070         [ -z "$(which wiretest 2>/dev/null)" ] &&
9071                         skip_env "could not find wiretest"
9072
9073         wiretest
9074 }
9075 run_test 58 "verify cross-platform wire constants =============="
9076
9077 test_59() {
9078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9079
9080         echo "touch 130 files"
9081         createmany -o $DIR/f59- 130
9082         echo "rm 130 files"
9083         unlinkmany $DIR/f59- 130
9084         sync
9085         # wait for commitment of removal
9086         wait_delete_completed
9087 }
9088 run_test 59 "verify cancellation of llog records async ========="
9089
9090 TEST60_HEAD="test_60 run $RANDOM"
9091 test_60a() {
9092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9093         remote_mgs_nodsh && skip "remote MGS with nodsh"
9094         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9095                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9096                         skip_env "missing subtest run-llog.sh"
9097
9098         log "$TEST60_HEAD - from kernel mode"
9099         do_facet mgs "$LCTL dk > /dev/null"
9100         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9101         do_facet mgs $LCTL dk > $TMP/$tfile
9102
9103         # LU-6388: test llog_reader
9104         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9105         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9106         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9107                         skip_env "missing llog_reader"
9108         local fstype=$(facet_fstype mgs)
9109         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9110                 skip_env "Only for ldiskfs or zfs type mgs"
9111
9112         local mntpt=$(facet_mntpt mgs)
9113         local mgsdev=$(mgsdevname 1)
9114         local fid_list
9115         local fid
9116         local rec_list
9117         local rec
9118         local rec_type
9119         local obj_file
9120         local path
9121         local seq
9122         local oid
9123         local pass=true
9124
9125         #get fid and record list
9126         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9127                 tail -n 4))
9128         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9129                 tail -n 4))
9130         #remount mgs as ldiskfs or zfs type
9131         stop mgs || error "stop mgs failed"
9132         mount_fstype mgs || error "remount mgs failed"
9133         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9134                 fid=${fid_list[i]}
9135                 rec=${rec_list[i]}
9136                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9137                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9138                 oid=$((16#$oid))
9139
9140                 case $fstype in
9141                         ldiskfs )
9142                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9143                         zfs )
9144                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9145                 esac
9146                 echo "obj_file is $obj_file"
9147                 do_facet mgs $llog_reader $obj_file
9148
9149                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9150                         awk '{ print $3 }' | sed -e "s/^type=//g")
9151                 if [ $rec_type != $rec ]; then
9152                         echo "FAILED test_60a wrong record type $rec_type," \
9153                               "should be $rec"
9154                         pass=false
9155                         break
9156                 fi
9157
9158                 #check obj path if record type is LLOG_LOGID_MAGIC
9159                 if [ "$rec" == "1064553b" ]; then
9160                         path=$(do_facet mgs $llog_reader $obj_file |
9161                                 grep "path=" | awk '{ print $NF }' |
9162                                 sed -e "s/^path=//g")
9163                         if [ $obj_file != $mntpt/$path ]; then
9164                                 echo "FAILED test_60a wrong obj path" \
9165                                       "$montpt/$path, should be $obj_file"
9166                                 pass=false
9167                                 break
9168                         fi
9169                 fi
9170         done
9171         rm -f $TMP/$tfile
9172         #restart mgs before "error", otherwise it will block the next test
9173         stop mgs || error "stop mgs failed"
9174         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9175         $pass || error "test failed, see FAILED test_60a messages for specifics"
9176 }
9177 run_test 60a "llog_test run from kernel module and test llog_reader"
9178
9179 test_60b() { # bug 6411
9180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9181
9182         dmesg > $DIR/$tfile
9183         LLOG_COUNT=$(do_facet mgs dmesg |
9184                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9185                           /llog_[a-z]*.c:[0-9]/ {
9186                                 if (marker)
9187                                         from_marker++
9188                                 from_begin++
9189                           }
9190                           END {
9191                                 if (marker)
9192                                         print from_marker
9193                                 else
9194                                         print from_begin
9195                           }")
9196
9197         [[ $LLOG_COUNT -gt 120 ]] &&
9198                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9199 }
9200 run_test 60b "limit repeated messages from CERROR/CWARN"
9201
9202 test_60c() {
9203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9204
9205         echo "create 5000 files"
9206         createmany -o $DIR/f60c- 5000
9207 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9208         lctl set_param fail_loc=0x80000137
9209         unlinkmany $DIR/f60c- 5000
9210         lctl set_param fail_loc=0
9211 }
9212 run_test 60c "unlink file when mds full"
9213
9214 test_60d() {
9215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9216
9217         SAVEPRINTK=$(lctl get_param -n printk)
9218         # verify "lctl mark" is even working"
9219         MESSAGE="test message ID $RANDOM $$"
9220         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9221         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9222
9223         lctl set_param printk=0 || error "set lnet.printk failed"
9224         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9225         MESSAGE="new test message ID $RANDOM $$"
9226         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9227         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9228         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9229
9230         lctl set_param -n printk="$SAVEPRINTK"
9231 }
9232 run_test 60d "test printk console message masking"
9233
9234 test_60e() {
9235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9236         remote_mds_nodsh && skip "remote MDS with nodsh"
9237
9238         touch $DIR/$tfile
9239 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9240         do_facet mds1 lctl set_param fail_loc=0x15b
9241         rm $DIR/$tfile
9242 }
9243 run_test 60e "no space while new llog is being created"
9244
9245 test_60f() {
9246         local old_path=$($LCTL get_param -n debug_path)
9247
9248         stack_trap "$LCTL set_param debug_path=$old_path"
9249         stack_trap "rm -f $TMP/$tfile*"
9250         rm -f $TMP/$tfile* 2> /dev/null
9251         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9252         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9253         test_mkdir $DIR/$tdir
9254         # retry in case the open is cached and not released
9255         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9256                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9257                 sleep 0.1
9258         done
9259         ls $TMP/$tfile*
9260         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9261 }
9262 run_test 60f "change debug_path works"
9263
9264 test_60g() {
9265         local pid
9266         local i
9267
9268         test_mkdir -c $MDSCOUNT $DIR/$tdir
9269
9270         (
9271                 local index=0
9272                 while true; do
9273                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9274                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9275                                 2>/dev/null
9276                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9277                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9278                         index=$((index + 1))
9279                 done
9280         ) &
9281
9282         pid=$!
9283
9284         for i in {0..100}; do
9285                 # define OBD_FAIL_OSD_TXN_START    0x19a
9286                 local index=$((i % MDSCOUNT + 1))
9287
9288                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9289                         > /dev/null
9290                 sleep 0.01
9291         done
9292
9293         kill -9 $pid
9294
9295         for i in $(seq $MDSCOUNT); do
9296                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9297         done
9298
9299         mkdir $DIR/$tdir/new || error "mkdir failed"
9300         rmdir $DIR/$tdir/new || error "rmdir failed"
9301
9302         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9303                 -t namespace
9304         for i in $(seq $MDSCOUNT); do
9305                 wait_update_facet mds$i "$LCTL get_param -n \
9306                         mdd.$(facet_svc mds$i).lfsck_namespace |
9307                         awk '/^status/ { print \\\$2 }'" "completed"
9308         done
9309
9310         ls -R $DIR/$tdir
9311         rm -rf $DIR/$tdir || error "rmdir failed"
9312 }
9313 run_test 60g "transaction abort won't cause MDT hung"
9314
9315 test_60h() {
9316         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9317                 skip "Need MDS version at least 2.12.52"
9318         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9319
9320         local f
9321
9322         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9323         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9324         for fail_loc in 0x80000188 0x80000189; do
9325                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9326                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9327                         error "mkdir $dir-$fail_loc failed"
9328                 for i in {0..10}; do
9329                         # create may fail on missing stripe
9330                         echo $i > $DIR/$tdir-$fail_loc/$i
9331                 done
9332                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9333                         error "getdirstripe $tdir-$fail_loc failed"
9334                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9335                         error "migrate $tdir-$fail_loc failed"
9336                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9337                         error "getdirstripe $tdir-$fail_loc failed"
9338                 pushd $DIR/$tdir-$fail_loc
9339                 for f in *; do
9340                         echo $f | cmp $f - || error "$f data mismatch"
9341                 done
9342                 popd
9343                 rm -rf $DIR/$tdir-$fail_loc
9344         done
9345 }
9346 run_test 60h "striped directory with missing stripes can be accessed"
9347
9348 function t60i_load() {
9349         mkdir $DIR/$tdir
9350         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9351         $LCTL set_param fail_loc=0x131c fail_val=1
9352         for ((i=0; i<5000; i++)); do
9353                 touch $DIR/$tdir/f$i
9354         done
9355 }
9356
9357 test_60i() {
9358         changelog_register || error "changelog_register failed"
9359         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9360         changelog_users $SINGLEMDS | grep -q $cl_user ||
9361                 error "User $cl_user not found in changelog_users"
9362         changelog_chmask "ALL"
9363         t60i_load &
9364         local PID=$!
9365         for((i=0; i<100; i++)); do
9366                 changelog_dump >/dev/null ||
9367                         error "can't read changelog"
9368         done
9369         kill $PID
9370         wait $PID
9371         changelog_deregister || error "changelog_deregister failed"
9372         $LCTL set_param fail_loc=0
9373 }
9374 run_test 60i "llog: new record vs reader race"
9375
9376 test_60j() {
9377         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9378                 skip "need MDS version at least 2.15.50"
9379         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9380         remote_mds_nodsh && skip "remote MDS with nodsh"
9381         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9382
9383         changelog_users $SINGLEMDS | grep "^cl" &&
9384                 skip "active changelog user"
9385
9386         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9387
9388         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9389                 skip_env "missing llog_reader"
9390
9391         mkdir_on_mdt0 $DIR/$tdir
9392
9393         local f=$DIR/$tdir/$tfile
9394         local mdt_dev
9395         local tmpfile
9396         local plain
9397
9398         changelog_register || error "cannot register changelog user"
9399
9400         # set changelog_mask to ALL
9401         changelog_chmask "ALL"
9402         changelog_clear
9403
9404         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9405         unlinkmany ${f}- 100 || error "unlinkmany failed"
9406
9407         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9408         mdt_dev=$(facet_device $SINGLEMDS)
9409
9410         do_facet $SINGLEMDS sync
9411         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9412                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9413                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9414
9415         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9416
9417         # if $tmpfile is not on EXT3 filesystem for some reason
9418         [[ ${plain:0:1} == 'O' ]] ||
9419                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9420
9421         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9422                 $mdt_dev; stat -c %s $tmpfile")
9423         echo "Truncate llog from $size to $((size - size % 8192))"
9424         size=$((size - size % 8192))
9425         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9426         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9427                 grep -c 'in bitmap only')
9428         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9429
9430         size=$((size - 9000))
9431         echo "Corrupt llog in the middle at $size"
9432         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9433                 count=333 conv=notrunc
9434         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9435                 grep -c 'next chunk')
9436         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9437 }
9438 run_test 60j "llog_reader reports corruptions"
9439
9440 test_61a() {
9441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9442
9443         f="$DIR/f61"
9444         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9445         cancel_lru_locks osc
9446         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9447         sync
9448 }
9449 run_test 61a "mmap() writes don't make sync hang ================"
9450
9451 test_61b() {
9452         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9453 }
9454 run_test 61b "mmap() of unstriped file is successful"
9455
9456 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9457 # Though this test is irrelevant anymore, it helped to reveal some
9458 # other grant bugs (LU-4482), let's keep it.
9459 test_63a() {   # was test_63
9460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9461
9462         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9463
9464         for i in `seq 10` ; do
9465                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9466                 sleep 5
9467                 kill $!
9468                 sleep 1
9469         done
9470
9471         rm -f $DIR/f63 || true
9472 }
9473 run_test 63a "Verify oig_wait interruption does not crash ======="
9474
9475 # bug 2248 - async write errors didn't return to application on sync
9476 # bug 3677 - async write errors left page locked
9477 test_63b() {
9478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9479
9480         debugsave
9481         lctl set_param debug=-1
9482
9483         # ensure we have a grant to do async writes
9484         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9485         rm $DIR/$tfile
9486
9487         sync    # sync lest earlier test intercept the fail_loc
9488
9489         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9490         lctl set_param fail_loc=0x80000406
9491         $MULTIOP $DIR/$tfile Owy && \
9492                 error "sync didn't return ENOMEM"
9493         sync; sleep 2; sync     # do a real sync this time to flush page
9494         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9495                 error "locked page left in cache after async error" || true
9496         debugrestore
9497 }
9498 run_test 63b "async write errors should be returned to fsync ==="
9499
9500 test_64a () {
9501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9502
9503         lfs df $DIR
9504         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9505 }
9506 run_test 64a "verify filter grant calculations (in kernel) ====="
9507
9508 test_64b () {
9509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9510
9511         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9512 }
9513 run_test 64b "check out-of-space detection on client"
9514
9515 test_64c() {
9516         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9517 }
9518 run_test 64c "verify grant shrink"
9519
9520 import_param() {
9521         local tgt=$1
9522         local param=$2
9523
9524         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9525 }
9526
9527 # this does exactly what osc_request.c:osc_announce_cached() does in
9528 # order to calculate max amount of grants to ask from server
9529 want_grant() {
9530         local tgt=$1
9531
9532         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9533         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9534
9535         ((rpc_in_flight++));
9536         nrpages=$((nrpages * rpc_in_flight))
9537
9538         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9539
9540         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9541
9542         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9543         local undirty=$((nrpages * PAGE_SIZE))
9544
9545         local max_extent_pages
9546         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9547         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9548         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9549         local grant_extent_tax
9550         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9551
9552         undirty=$((undirty + nrextents * grant_extent_tax))
9553
9554         echo $undirty
9555 }
9556
9557 # this is size of unit for grant allocation. It should be equal to
9558 # what tgt_grant.c:tgt_grant_chunk() calculates
9559 grant_chunk() {
9560         local tgt=$1
9561         local max_brw_size
9562         local grant_extent_tax
9563
9564         max_brw_size=$(import_param $tgt max_brw_size)
9565
9566         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9567
9568         echo $(((max_brw_size + grant_extent_tax) * 2))
9569 }
9570
9571 test_64d() {
9572         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9573                 skip "OST < 2.10.55 doesn't limit grants enough"
9574
9575         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9576
9577         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9578                 skip "no grant_param connect flag"
9579
9580         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9581
9582         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9583         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9584
9585
9586         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9587         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9588
9589         $LFS setstripe $DIR/$tfile -i 0 -c 1
9590         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9591         ddpid=$!
9592
9593         while kill -0 $ddpid; do
9594                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9595
9596                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9597                         kill $ddpid
9598                         error "cur_grant $cur_grant > $max_cur_granted"
9599                 fi
9600
9601                 sleep 1
9602         done
9603 }
9604 run_test 64d "check grant limit exceed"
9605
9606 check_grants() {
9607         local tgt=$1
9608         local expected=$2
9609         local msg=$3
9610         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9611
9612         ((cur_grants == expected)) ||
9613                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9614 }
9615
9616 round_up_p2() {
9617         echo $((($1 + $2 - 1) & ~($2 - 1)))
9618 }
9619
9620 test_64e() {
9621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9622         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9623                 skip "Need OSS version at least 2.11.56"
9624
9625         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9626         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9627         $LCTL set_param debug=+cache
9628
9629         # Remount client to reset grant
9630         remount_client $MOUNT || error "failed to remount client"
9631         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9632
9633         local init_grants=$(import_param $osc_tgt initial_grant)
9634
9635         check_grants $osc_tgt $init_grants "init grants"
9636
9637         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9638         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9639         local gbs=$(import_param $osc_tgt grant_block_size)
9640
9641         # write random number of bytes from max_brw_size / 4 to max_brw_size
9642         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9643         # align for direct io
9644         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9645         # round to grant consumption unit
9646         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9647
9648         local grants=$((wb_round_up + extent_tax))
9649
9650         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9651         stack_trap "rm -f $DIR/$tfile"
9652
9653         # define OBD_FAIL_TGT_NO_GRANT 0x725
9654         # make the server not grant more back
9655         do_facet ost1 $LCTL set_param fail_loc=0x725
9656         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9657
9658         do_facet ost1 $LCTL set_param fail_loc=0
9659
9660         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9661
9662         rm -f $DIR/$tfile || error "rm failed"
9663
9664         # Remount client to reset grant
9665         remount_client $MOUNT || error "failed to remount client"
9666         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9667
9668         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9669
9670         # define OBD_FAIL_TGT_NO_GRANT 0x725
9671         # make the server not grant more back
9672         do_facet ost1 $LCTL set_param fail_loc=0x725
9673         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9674         do_facet ost1 $LCTL set_param fail_loc=0
9675
9676         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9677 }
9678 run_test 64e "check grant consumption (no grant allocation)"
9679
9680 test_64f() {
9681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9682
9683         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9684         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9685         $LCTL set_param debug=+cache
9686
9687         # Remount client to reset grant
9688         remount_client $MOUNT || error "failed to remount client"
9689         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9690
9691         local init_grants=$(import_param $osc_tgt initial_grant)
9692         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9693         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9694         local gbs=$(import_param $osc_tgt grant_block_size)
9695         local chunk=$(grant_chunk $osc_tgt)
9696
9697         # write random number of bytes from max_brw_size / 4 to max_brw_size
9698         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9699         # align for direct io
9700         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9701         # round to grant consumption unit
9702         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9703
9704         local grants=$((wb_round_up + extent_tax))
9705
9706         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9707         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9708                 error "error writing to $DIR/$tfile"
9709
9710         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9711                 "direct io with grant allocation"
9712
9713         rm -f $DIR/$tfile || error "rm failed"
9714
9715         # Remount client to reset grant
9716         remount_client $MOUNT || error "failed to remount client"
9717         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9718
9719         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9720
9721         # Testing that buffered IO consumes grant on the client
9722
9723         # Delay the RPC on the server so it's guaranteed to not complete even
9724         # if the RPC is sent from the client
9725         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9726         $LCTL set_param fail_loc=0x50a fail_val=3
9727         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9728                 error "error writing to $DIR/$tfile with buffered IO"
9729
9730         check_grants $osc_tgt $((init_grants - grants)) \
9731                 "buffered io, not write rpc"
9732
9733         # Clear the fail loc and do a sync on the client
9734         $LCTL set_param fail_loc=0 fail_val=0
9735         sync
9736
9737         # RPC is now known to have sent
9738         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9739                 "buffered io, one RPC"
9740 }
9741 run_test 64f "check grant consumption (with grant allocation)"
9742
9743 test_64g() {
9744         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9745                 skip "Need MDS version at least 2.14.56"
9746
9747         local mdts=$(comma_list $(mdts_nodes))
9748
9749         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9750                         tr '\n' ' ')
9751         stack_trap "$LCTL set_param $old"
9752
9753         # generate dirty pages and increase dirty granted on MDT
9754         stack_trap "rm -f $DIR/$tfile-*"
9755         for (( i = 0; i < 10; i++)); do
9756                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9757                         error "can't set stripe"
9758                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9759                         error "can't dd"
9760                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9761                         $LFS getstripe $DIR/$tfile-$i
9762                         error "not DoM file"
9763                 }
9764         done
9765
9766         # flush dirty pages
9767         sync
9768
9769         # wait until grant shrink reset grant dirty on MDTs
9770         for ((i = 0; i < 120; i++)); do
9771                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9772                         awk '{sum=sum+$1} END {print sum}')
9773                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9774                 echo "$grant_dirty grants, $vm_dirty pages"
9775                 (( grant_dirty + vm_dirty == 0 )) && break
9776                 (( i == 3 )) && sync &&
9777                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9778                 sleep 1
9779         done
9780
9781         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9782                 awk '{sum=sum+$1} END {print sum}')
9783         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9784 }
9785 run_test 64g "grant shrink on MDT"
9786
9787 test_64h() {
9788         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9789                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9790
9791         local instance=$($LFS getname -i $DIR)
9792         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9793         local num_exps=$(do_facet ost1 \
9794             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9795         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9796         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9797         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9798
9799         # 10MiB is for file to be written, max_brw_size * 16 *
9800         # num_exps is space reserve so that tgt_grant_shrink() decided
9801         # to not shrink
9802         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9803         (( avail * 1024 < expect )) &&
9804                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9805
9806         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9807         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9808         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9809         $LCTL set_param osc.*OST0000*.grant_shrink=1
9810         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9811
9812         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9813         stack_trap "rm -f $DIR/$tfile"
9814         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9815
9816         # drop cache so that coming read would do rpc
9817         cancel_lru_locks osc
9818
9819         # shrink interval is set to 10, pause for 7 seconds so that
9820         # grant thread did not wake up yet but coming read entered
9821         # shrink mode for rpc (osc_should_shrink_grant())
9822         sleep 7
9823
9824         declare -a cur_grant_bytes
9825         declare -a tot_granted
9826         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9827         tot_granted[0]=$(do_facet ost1 \
9828             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9829
9830         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9831
9832         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9833         tot_granted[1]=$(do_facet ost1 \
9834             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9835
9836         # grant change should be equal on both sides
9837         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9838                 tot_granted[0] - tot_granted[1])) ||
9839                 error "grant change mismatch, "                                \
9840                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9841                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9842 }
9843 run_test 64h "grant shrink on read"
9844
9845 test_64i() {
9846         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9847                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9848
9849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9850         remote_ost_nodsh && skip "remote OSTs with nodsh"
9851
9852         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9853         stack_trap "rm -f $DIR/$tfile"
9854
9855         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9856
9857         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9858         local instance=$($LFS getname -i $DIR)
9859
9860         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9861         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9862
9863         # shrink grants and simulate rpc loss
9864         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9865         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9866         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9867
9868         fail ost1
9869
9870         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9871
9872         local testid=$(echo $TESTNAME | tr '_' ' ')
9873
9874         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9875                 grep "GRANT, real grant" &&
9876                 error "client has more grants then it owns" || true
9877 }
9878 run_test 64i "shrink on reconnect"
9879
9880 # bug 1414 - set/get directories' stripe info
9881 test_65a() {
9882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9883
9884         test_mkdir $DIR/$tdir
9885         touch $DIR/$tdir/f1
9886         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9887 }
9888 run_test 65a "directory with no stripe info"
9889
9890 test_65b() {
9891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9892
9893         test_mkdir $DIR/$tdir
9894         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9895
9896         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9897                                                 error "setstripe"
9898         touch $DIR/$tdir/f2
9899         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9900 }
9901 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9902
9903 test_65c() {
9904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9905         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9906
9907         test_mkdir $DIR/$tdir
9908         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9909
9910         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9911                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9912         touch $DIR/$tdir/f3
9913         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9914 }
9915 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9916
9917 test_65d() {
9918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9919
9920         test_mkdir $DIR/$tdir
9921         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9922         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9923
9924         if [[ $STRIPECOUNT -le 0 ]]; then
9925                 sc=1
9926         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9927                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9928                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9929         else
9930                 sc=$(($STRIPECOUNT - 1))
9931         fi
9932         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9933         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9934         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9935                 error "lverify failed"
9936 }
9937 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9938
9939 test_65e() {
9940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9941
9942         # LU-16904 delete layout when root is set as PFL layout
9943         save_layout_restore_at_exit $MOUNT
9944         $LFS setstripe -d $MOUNT || error "setstripe failed"
9945
9946         test_mkdir $DIR/$tdir
9947
9948         $LFS setstripe $DIR/$tdir || error "setstripe"
9949         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9950                                         error "no stripe info failed"
9951         touch $DIR/$tdir/f6
9952         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9953 }
9954 run_test 65e "directory setstripe defaults"
9955
9956 test_65f() {
9957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9958
9959         test_mkdir $DIR/${tdir}f
9960         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9961                 error "setstripe succeeded" || true
9962 }
9963 run_test 65f "dir setstripe permission (should return error) ==="
9964
9965 test_65g() {
9966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9967
9968         # LU-16904 delete layout when root is set as PFL layout
9969         save_layout_restore_at_exit $MOUNT
9970         $LFS setstripe -d $MOUNT || error "setstripe failed"
9971
9972         test_mkdir $DIR/$tdir
9973         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9974
9975         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9976                 error "setstripe -S failed"
9977         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9978         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9979                 error "delete default stripe failed"
9980 }
9981 run_test 65g "directory setstripe -d"
9982
9983 test_65h() {
9984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9985
9986         test_mkdir $DIR/$tdir
9987         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9988
9989         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9990                 error "setstripe -S failed"
9991         test_mkdir $DIR/$tdir/dd1
9992         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9993                 error "stripe info inherit failed"
9994 }
9995 run_test 65h "directory stripe info inherit ===================="
9996
9997 test_65i() {
9998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9999
10000         save_layout_restore_at_exit $MOUNT
10001
10002         # bug6367: set non-default striping on root directory
10003         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10004
10005         # bug12836: getstripe on -1 default directory striping
10006         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10007
10008         # bug12836: getstripe -v on -1 default directory striping
10009         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10010
10011         # bug12836: new find on -1 default directory striping
10012         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10013 }
10014 run_test 65i "various tests to set root directory striping"
10015
10016 test_65j() { # bug6367
10017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10018
10019         sync; sleep 1
10020
10021         # if we aren't already remounting for each test, do so for this test
10022         if [ "$I_MOUNTED" = "yes" ]; then
10023                 cleanup || error "failed to unmount"
10024                 setup
10025         fi
10026
10027         save_layout_restore_at_exit $MOUNT
10028
10029         $LFS setstripe -d $MOUNT || error "setstripe failed"
10030 }
10031 run_test 65j "set default striping on root directory (bug 6367)="
10032
10033 cleanup_65k() {
10034         rm -rf $DIR/$tdir
10035         wait_delete_completed
10036         do_facet $SINGLEMDS "lctl set_param -n \
10037                 osp.$ost*MDT0000.max_create_count=$max_count"
10038         do_facet $SINGLEMDS "lctl set_param -n \
10039                 osp.$ost*MDT0000.create_count=$count"
10040         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10041         echo $INACTIVE_OSC "is Activate"
10042
10043         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10044 }
10045
10046 test_65k() { # bug11679
10047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10048         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10049         remote_mds_nodsh && skip "remote MDS with nodsh"
10050
10051         local disable_precreate=true
10052         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10053                 disable_precreate=false
10054
10055         echo "Check OST status: "
10056         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10057                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10058
10059         for OSC in $MDS_OSCS; do
10060                 echo $OSC "is active"
10061                 do_facet $SINGLEMDS lctl --device %$OSC activate
10062         done
10063
10064         for INACTIVE_OSC in $MDS_OSCS; do
10065                 local ost=$(osc_to_ost $INACTIVE_OSC)
10066                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10067                                lov.*md*.target_obd |
10068                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10069
10070                 mkdir -p $DIR/$tdir
10071                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10072                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10073
10074                 echo "Deactivate: " $INACTIVE_OSC
10075                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10076
10077                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10078                               osp.$ost*MDT0000.create_count")
10079                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10080                                   osp.$ost*MDT0000.max_create_count")
10081                 $disable_precreate &&
10082                         do_facet $SINGLEMDS "lctl set_param -n \
10083                                 osp.$ost*MDT0000.max_create_count=0"
10084
10085                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10086                         [ -f $DIR/$tdir/$idx ] && continue
10087                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10088                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10089                                 { cleanup_65k;
10090                                   error "setstripe $idx should succeed"; }
10091                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10092                 done
10093                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10094                 rmdir $DIR/$tdir
10095
10096                 do_facet $SINGLEMDS "lctl set_param -n \
10097                         osp.$ost*MDT0000.max_create_count=$max_count"
10098                 do_facet $SINGLEMDS "lctl set_param -n \
10099                         osp.$ost*MDT0000.create_count=$count"
10100                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10101                 echo $INACTIVE_OSC "is Activate"
10102
10103                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10104         done
10105 }
10106 run_test 65k "validate manual striping works properly with deactivated OSCs"
10107
10108 test_65l() { # bug 12836
10109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10110
10111         test_mkdir -p $DIR/$tdir/test_dir
10112         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10113         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10114 }
10115 run_test 65l "lfs find on -1 stripe dir ========================"
10116
10117 test_65m() {
10118         local layout=$(save_layout $MOUNT)
10119         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10120                 restore_layout $MOUNT $layout
10121                 error "setstripe should fail by non-root users"
10122         }
10123         true
10124 }
10125 run_test 65m "normal user can't set filesystem default stripe"
10126
10127 test_65n() {
10128         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10129         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10130                 skip "Need MDS version at least 2.12.50"
10131         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10132
10133         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10134         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10135         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10136
10137         save_layout_restore_at_exit $MOUNT
10138
10139         # new subdirectory under root directory should not inherit
10140         # the default layout from root
10141         # LU-16904 check if the root is set as PFL layout
10142         local numcomp=$($LFS getstripe --component-count $MOUNT)
10143
10144         if [[ $numcomp -eq 0 ]]; then
10145                 local dir1=$MOUNT/$tdir-1
10146                 mkdir $dir1 || error "mkdir $dir1 failed"
10147                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10148                         error "$dir1 shouldn't have LOV EA"
10149         fi
10150
10151         # delete the default layout on root directory
10152         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10153
10154         local dir2=$MOUNT/$tdir-2
10155         mkdir $dir2 || error "mkdir $dir2 failed"
10156         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10157                 error "$dir2 shouldn't have LOV EA"
10158
10159         # set a new striping pattern on root directory
10160         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10161         local new_def_stripe_size=$((def_stripe_size * 2))
10162         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10163                 error "set stripe size on $MOUNT failed"
10164
10165         # new file created in $dir2 should inherit the new stripe size from
10166         # the filesystem default
10167         local file2=$dir2/$tfile-2
10168         touch $file2 || error "touch $file2 failed"
10169
10170         local file2_stripe_size=$($LFS getstripe -S $file2)
10171         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10172         {
10173                 echo "file2_stripe_size: '$file2_stripe_size'"
10174                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10175                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10176         }
10177
10178         local dir3=$MOUNT/$tdir-3
10179         mkdir $dir3 || error "mkdir $dir3 failed"
10180         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10181         # the root layout, which is the actual default layout that will be used
10182         # when new files are created in $dir3.
10183         local dir3_layout=$(get_layout_param $dir3)
10184         local root_dir_layout=$(get_layout_param $MOUNT)
10185         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10186         {
10187                 echo "dir3_layout: '$dir3_layout'"
10188                 echo "root_dir_layout: '$root_dir_layout'"
10189                 error "$dir3 should show the default layout from $MOUNT"
10190         }
10191
10192         # set OST pool on root directory
10193         local pool=$TESTNAME
10194         pool_add $pool || error "add $pool failed"
10195         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10196                 error "add targets to $pool failed"
10197
10198         $LFS setstripe -p $pool $MOUNT ||
10199                 error "set OST pool on $MOUNT failed"
10200
10201         # new file created in $dir3 should inherit the pool from
10202         # the filesystem default
10203         local file3=$dir3/$tfile-3
10204         touch $file3 || error "touch $file3 failed"
10205
10206         local file3_pool=$($LFS getstripe -p $file3)
10207         [[ "$file3_pool" = "$pool" ]] ||
10208                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10209
10210         local dir4=$MOUNT/$tdir-4
10211         mkdir $dir4 || error "mkdir $dir4 failed"
10212         local dir4_layout=$(get_layout_param $dir4)
10213         root_dir_layout=$(get_layout_param $MOUNT)
10214         echo "$LFS getstripe -d $dir4"
10215         $LFS getstripe -d $dir4
10216         echo "$LFS getstripe -d $MOUNT"
10217         $LFS getstripe -d $MOUNT
10218         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10219         {
10220                 echo "dir4_layout: '$dir4_layout'"
10221                 echo "root_dir_layout: '$root_dir_layout'"
10222                 error "$dir4 should show the default layout from $MOUNT"
10223         }
10224
10225         # new file created in $dir4 should inherit the pool from
10226         # the filesystem default
10227         local file4=$dir4/$tfile-4
10228         touch $file4 || error "touch $file4 failed"
10229
10230         local file4_pool=$($LFS getstripe -p $file4)
10231         [[ "$file4_pool" = "$pool" ]] ||
10232                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10233
10234         # new subdirectory under non-root directory should inherit
10235         # the default layout from its parent directory
10236         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10237                 error "set directory layout on $dir4 failed"
10238
10239         local dir5=$dir4/$tdir-5
10240         mkdir $dir5 || error "mkdir $dir5 failed"
10241
10242         dir4_layout=$(get_layout_param $dir4)
10243         local dir5_layout=$(get_layout_param $dir5)
10244         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10245         {
10246                 echo "dir4_layout: '$dir4_layout'"
10247                 echo "dir5_layout: '$dir5_layout'"
10248                 error "$dir5 should inherit the default layout from $dir4"
10249         }
10250
10251         # though subdir under ROOT doesn't inherit default layout, but
10252         # its sub dir/file should be created with default layout.
10253         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10254         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10255                 skip "Need MDS version at least 2.12.59"
10256
10257         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10258         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10259         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10260
10261         if [ $default_lmv_hash == "none" ]; then
10262                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10263         else
10264                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10265                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10266         fi
10267
10268         $LFS setdirstripe -D -c 2 $MOUNT ||
10269                 error "setdirstripe -D -c 2 failed"
10270         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10271         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10272         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10273
10274         # $dir4 layout includes pool
10275         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10276         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10277                 error "pool lost on setstripe"
10278         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10279         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10280                 error "pool lost on compound layout setstripe"
10281 }
10282 run_test 65n "don't inherit default layout from root for new subdirectories"
10283
10284 test_65o() {
10285         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10286                 skip "need MDS version at least 2.14.57"
10287
10288         # set OST pool on root directory
10289         local pool=$TESTNAME
10290
10291         pool_add $pool || error "add $pool failed"
10292         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10293                 error "add targets to $pool failed"
10294
10295         local dir1=$MOUNT/$tdir
10296
10297         mkdir $dir1 || error "mkdir $dir1 failed"
10298
10299         # set a new striping pattern on root directory
10300         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10301
10302         $LFS setstripe -p $pool $dir1 ||
10303                 error "set directory layout on $dir1 failed"
10304
10305         # $dir1 layout includes pool
10306         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10307         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10308                 error "pool lost on setstripe"
10309         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10310         $LFS getstripe $dir1
10311         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10312                 error "pool lost on compound layout setstripe"
10313
10314         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10315                 error "setdirstripe failed on sub-dir with inherited pool"
10316         $LFS getstripe $dir1/dir2
10317         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10318                 error "pool lost on compound layout setdirstripe"
10319
10320         $LFS setstripe -E -1 -c 1 $dir1
10321         $LFS getstripe -d $dir1
10322         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10323                 error "pool lost on setstripe"
10324 }
10325 run_test 65o "pool inheritance for mdt component"
10326
10327 test_65p () { # LU-16152
10328         local src_dir=$DIR/$tdir/src_dir
10329         local dst_dir=$DIR/$tdir/dst_dir
10330         local yaml_file=$DIR/$tdir/layout.yaml
10331         local border
10332
10333         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10334                 skip "Need at least version 2.15.51"
10335
10336         test_mkdir -p $src_dir
10337         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10338                 error "failed to setstripe"
10339         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10340                 error "failed to getstripe"
10341
10342         test_mkdir -p $dst_dir
10343         $LFS setstripe --yaml $yaml_file $dst_dir ||
10344                 error "failed to setstripe with yaml file"
10345         border=$($LFS getstripe -d $dst_dir |
10346                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10347                 error "failed to getstripe"
10348
10349         # 2048M is 0x80000000, or 2147483648
10350         (( $border == 2147483648 )) ||
10351                 error "failed to handle huge number in yaml layout"
10352 }
10353 run_test 65p "setstripe with yaml file and huge number"
10354
10355 test_65p () { # LU-16194
10356         local src_dir=$DIR/$tdir/src_dir
10357
10358         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10359                 skip "Need at least version 2.15.51"
10360
10361         test_mkdir -p $src_dir
10362         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10363         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10364                 error "should fail if extent start/end >=8E"
10365
10366         # EOF should work as before
10367         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10368                 error "failed to setstripe normally"
10369 }
10370 run_test 65p "setstripe with >=8E offset should fail"
10371
10372 # bug 2543 - update blocks count on client
10373 test_66() {
10374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10375
10376         local COUNT=${COUNT:-8}
10377         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10378         sync; sync_all_data; sync; sync_all_data
10379         cancel_lru_locks osc
10380         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10381         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10382 }
10383 run_test 66 "update inode blocks count on client ==============="
10384
10385 meminfo() {
10386         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10387 }
10388
10389 swap_used() {
10390         swapon -s | awk '($1 == "'$1'") { print $4 }'
10391 }
10392
10393 # bug5265, obdfilter oa2dentry return -ENOENT
10394 # #define OBD_FAIL_SRV_ENOENT 0x217
10395 test_69() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397         remote_ost_nodsh && skip "remote OST with nodsh"
10398
10399         f="$DIR/$tfile"
10400         $LFS setstripe -c 1 -i 0 $f
10401         stack_trap "rm -f $f ${f}.2"
10402
10403         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10404
10405         do_facet ost1 lctl set_param fail_loc=0x217
10406         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10407         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10408
10409         do_facet ost1 lctl set_param fail_loc=0
10410         $DIRECTIO write $f 0 2 || error "write error"
10411
10412         cancel_lru_locks osc
10413         $DIRECTIO read $f 0 1 || error "read error"
10414
10415         do_facet ost1 lctl set_param fail_loc=0x217
10416         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10417
10418         do_facet ost1 lctl set_param fail_loc=0
10419 }
10420 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10421
10422 test_71() {
10423         test_mkdir $DIR/$tdir
10424         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10425         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10426 }
10427 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10428
10429 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10431         [ "$RUNAS_ID" = "$UID" ] &&
10432                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10433         # Check that testing environment is properly set up. Skip if not
10434         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10435                 skip_env "User $RUNAS_ID does not exist - skipping"
10436
10437         touch $DIR/$tfile
10438         chmod 777 $DIR/$tfile
10439         chmod ug+s $DIR/$tfile
10440         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10441                 error "$RUNAS dd $DIR/$tfile failed"
10442         # See if we are still setuid/sgid
10443         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10444                 error "S/gid is not dropped on write"
10445         # Now test that MDS is updated too
10446         cancel_lru_locks mdc
10447         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10448                 error "S/gid is not dropped on MDS"
10449         rm -f $DIR/$tfile
10450 }
10451 run_test 72a "Test that remove suid works properly (bug5695) ===="
10452
10453 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10454         local perm
10455
10456         [ "$RUNAS_ID" = "$UID" ] &&
10457                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10458         [ "$RUNAS_ID" -eq 0 ] &&
10459                 skip_env "RUNAS_ID = 0 -- skipping"
10460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10461         # Check that testing environment is properly set up. Skip if not
10462         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10463                 skip_env "User $RUNAS_ID does not exist - skipping"
10464
10465         touch $DIR/${tfile}-f{g,u}
10466         test_mkdir $DIR/${tfile}-dg
10467         test_mkdir $DIR/${tfile}-du
10468         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10469         chmod g+s $DIR/${tfile}-{f,d}g
10470         chmod u+s $DIR/${tfile}-{f,d}u
10471         for perm in 777 2777 4777; do
10472                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10473                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10474                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10475                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10476         done
10477         true
10478 }
10479 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10480
10481 # bug 3462 - multiple simultaneous MDC requests
10482 test_73() {
10483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10484
10485         test_mkdir $DIR/d73-1
10486         test_mkdir $DIR/d73-2
10487         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10488         pid1=$!
10489
10490         lctl set_param fail_loc=0x80000129
10491         $MULTIOP $DIR/d73-1/f73-2 Oc &
10492         sleep 1
10493         lctl set_param fail_loc=0
10494
10495         $MULTIOP $DIR/d73-2/f73-3 Oc &
10496         pid3=$!
10497
10498         kill -USR1 $pid1
10499         wait $pid1 || return 1
10500
10501         sleep 25
10502
10503         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10504         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10505         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10506
10507         rm -rf $DIR/d73-*
10508 }
10509 run_test 73 "multiple MDC requests (should not deadlock)"
10510
10511 test_74a() { # bug 6149, 6184
10512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10513
10514         touch $DIR/f74a
10515         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10516         #
10517         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10518         # will spin in a tight reconnection loop
10519         $LCTL set_param fail_loc=0x8000030e
10520         # get any lock that won't be difficult - lookup works.
10521         ls $DIR/f74a
10522         $LCTL set_param fail_loc=0
10523         rm -f $DIR/f74a
10524         true
10525 }
10526 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10527
10528 test_74b() { # bug 13310
10529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10530
10531         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10532         #
10533         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10534         # will spin in a tight reconnection loop
10535         $LCTL set_param fail_loc=0x8000030e
10536         # get a "difficult" lock
10537         touch $DIR/f74b
10538         $LCTL set_param fail_loc=0
10539         rm -f $DIR/f74b
10540         true
10541 }
10542 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10543
10544 test_74c() {
10545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10546
10547         #define OBD_FAIL_LDLM_NEW_LOCK
10548         $LCTL set_param fail_loc=0x319
10549         touch $DIR/$tfile && error "touch successful"
10550         $LCTL set_param fail_loc=0
10551         true
10552 }
10553 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10554
10555 slab_lic=/sys/kernel/slab/lustre_inode_cache
10556 num_objects() {
10557         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10558         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10559                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10560 }
10561
10562 test_76a() { # Now for b=20433, added originally in b=1443
10563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10564
10565         cancel_lru_locks osc
10566         # there may be some slab objects cached per core
10567         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10568         local before=$(num_objects)
10569         local count=$((512 * cpus))
10570         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10571         local margin=$((count / 10))
10572         if [[ -f $slab_lic/aliases ]]; then
10573                 local aliases=$(cat $slab_lic/aliases)
10574                 (( aliases > 0 )) && margin=$((margin * aliases))
10575         fi
10576
10577         echo "before slab objects: $before"
10578         for i in $(seq $count); do
10579                 touch $DIR/$tfile
10580                 rm -f $DIR/$tfile
10581         done
10582         cancel_lru_locks osc
10583         local after=$(num_objects)
10584         echo "created: $count, after slab objects: $after"
10585         # shared slab counts are not very accurate, allow significant margin
10586         # the main goal is that the cache growth is not permanently > $count
10587         while (( after > before + margin )); do
10588                 sleep 1
10589                 after=$(num_objects)
10590                 wait=$((wait + 1))
10591                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10592                 if (( wait > 60 )); then
10593                         error "inode slab grew from $before+$margin to $after"
10594                 fi
10595         done
10596 }
10597 run_test 76a "confirm clients recycle inodes properly ===="
10598
10599 test_76b() {
10600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10601         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10602
10603         local count=512
10604         local before=$(num_objects)
10605
10606         for i in $(seq $count); do
10607                 mkdir $DIR/$tdir
10608                 rmdir $DIR/$tdir
10609         done
10610
10611         local after=$(num_objects)
10612         local wait=0
10613
10614         while (( after > before )); do
10615                 sleep 1
10616                 after=$(num_objects)
10617                 wait=$((wait + 1))
10618                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10619                 if (( wait > 60 )); then
10620                         error "inode slab grew from $before to $after"
10621                 fi
10622         done
10623
10624         echo "slab objects before: $before, after: $after"
10625 }
10626 run_test 76b "confirm clients recycle directory inodes properly ===="
10627
10628 export ORIG_CSUM=""
10629 set_checksums()
10630 {
10631         # Note: in sptlrpc modes which enable its own bulk checksum, the
10632         # original crc32_le bulk checksum will be automatically disabled,
10633         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10634         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10635         # In this case set_checksums() will not be no-op, because sptlrpc
10636         # bulk checksum will be enabled all through the test.
10637
10638         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10639         lctl set_param -n osc.*.checksums $1
10640         return 0
10641 }
10642
10643 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10644                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10645 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10646                              tr -d [] | head -n1)}
10647 set_checksum_type()
10648 {
10649         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10650         rc=$?
10651         log "set checksum type to $1, rc = $rc"
10652         return $rc
10653 }
10654
10655 get_osc_checksum_type()
10656 {
10657         # arugment 1: OST name, like OST0000
10658         ost=$1
10659         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10660                         sed 's/.*\[\(.*\)\].*/\1/g')
10661         rc=$?
10662         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10663         echo $checksum_type
10664 }
10665
10666 F77_TMP=$TMP/f77-temp
10667 F77SZ=8
10668 setup_f77() {
10669         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10670                 error "error writing to $F77_TMP"
10671 }
10672
10673 test_77a() { # bug 10889
10674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10675         $GSS && skip_env "could not run with gss"
10676
10677         [ ! -f $F77_TMP ] && setup_f77
10678         set_checksums 1
10679         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10680         set_checksums 0
10681         rm -f $DIR/$tfile
10682 }
10683 run_test 77a "normal checksum read/write operation"
10684
10685 test_77b() { # bug 10889
10686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10687         $GSS && skip_env "could not run with gss"
10688
10689         [ ! -f $F77_TMP ] && setup_f77
10690         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10691         $LCTL set_param fail_loc=0x80000409
10692         set_checksums 1
10693
10694         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10695                 error "dd error: $?"
10696         $LCTL set_param fail_loc=0
10697
10698         for algo in $CKSUM_TYPES; do
10699                 cancel_lru_locks osc
10700                 set_checksum_type $algo
10701                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10702                 $LCTL set_param fail_loc=0x80000408
10703                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10704                 $LCTL set_param fail_loc=0
10705         done
10706         set_checksums 0
10707         set_checksum_type $ORIG_CSUM_TYPE
10708         rm -f $DIR/$tfile
10709 }
10710 run_test 77b "checksum error on client write, read"
10711
10712 cleanup_77c() {
10713         trap 0
10714         set_checksums 0
10715         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10716         $check_ost &&
10717                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10718         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10719         $check_ost && [ -n "$ost_file_prefix" ] &&
10720                 do_facet ost1 rm -f ${ost_file_prefix}\*
10721 }
10722
10723 test_77c() {
10724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10725         $GSS && skip_env "could not run with gss"
10726         remote_ost_nodsh && skip "remote OST with nodsh"
10727
10728         local bad1
10729         local osc_file_prefix
10730         local osc_file
10731         local check_ost=false
10732         local ost_file_prefix
10733         local ost_file
10734         local orig_cksum
10735         local dump_cksum
10736         local fid
10737
10738         # ensure corruption will occur on first OSS/OST
10739         $LFS setstripe -i 0 $DIR/$tfile
10740
10741         [ ! -f $F77_TMP ] && setup_f77
10742         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10743                 error "dd write error: $?"
10744         fid=$($LFS path2fid $DIR/$tfile)
10745
10746         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10747         then
10748                 check_ost=true
10749                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10750                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10751         else
10752                 echo "OSS do not support bulk pages dump upon error"
10753         fi
10754
10755         osc_file_prefix=$($LCTL get_param -n debug_path)
10756         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10757
10758         trap cleanup_77c EXIT
10759
10760         set_checksums 1
10761         # enable bulk pages dump upon error on Client
10762         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10763         # enable bulk pages dump upon error on OSS
10764         $check_ost &&
10765                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10766
10767         # flush Client cache to allow next read to reach OSS
10768         cancel_lru_locks osc
10769
10770         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10771         $LCTL set_param fail_loc=0x80000408
10772         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10773         $LCTL set_param fail_loc=0
10774
10775         rm -f $DIR/$tfile
10776
10777         # check cksum dump on Client
10778         osc_file=$(ls ${osc_file_prefix}*)
10779         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10780         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10781         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10782         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10783         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10784                      cksum)
10785         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10786         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10787                 error "dump content does not match on Client"
10788
10789         $check_ost || skip "No need to check cksum dump on OSS"
10790
10791         # check cksum dump on OSS
10792         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10793         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10794         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10795         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10796         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10797                 error "dump content does not match on OSS"
10798
10799         cleanup_77c
10800 }
10801 run_test 77c "checksum error on client read with debug"
10802
10803 test_77d() { # bug 10889
10804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10805         $GSS && skip_env "could not run with gss"
10806
10807         stack_trap "rm -f $DIR/$tfile"
10808         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10809         $LCTL set_param fail_loc=0x80000409
10810         set_checksums 1
10811         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10812                 error "direct write: rc=$?"
10813         $LCTL set_param fail_loc=0
10814         set_checksums 0
10815
10816         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10817         $LCTL set_param fail_loc=0x80000408
10818         set_checksums 1
10819         cancel_lru_locks osc
10820         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10821                 error "direct read: rc=$?"
10822         $LCTL set_param fail_loc=0
10823         set_checksums 0
10824 }
10825 run_test 77d "checksum error on OST direct write, read"
10826
10827 test_77f() { # bug 10889
10828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10829         $GSS && skip_env "could not run with gss"
10830
10831         set_checksums 1
10832         stack_trap "rm -f $DIR/$tfile"
10833         for algo in $CKSUM_TYPES; do
10834                 cancel_lru_locks osc
10835                 set_checksum_type $algo
10836                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10837                 $LCTL set_param fail_loc=0x409
10838                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10839                         error "direct write succeeded"
10840                 $LCTL set_param fail_loc=0
10841         done
10842         set_checksum_type $ORIG_CSUM_TYPE
10843         set_checksums 0
10844 }
10845 run_test 77f "repeat checksum error on write (expect error)"
10846
10847 test_77g() { # bug 10889
10848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10849         $GSS && skip_env "could not run with gss"
10850         remote_ost_nodsh && skip "remote OST with nodsh"
10851
10852         [ ! -f $F77_TMP ] && setup_f77
10853
10854         local file=$DIR/$tfile
10855         stack_trap "rm -f $file" EXIT
10856
10857         $LFS setstripe -c 1 -i 0 $file
10858         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10859         do_facet ost1 lctl set_param fail_loc=0x8000021a
10860         set_checksums 1
10861         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10862                 error "write error: rc=$?"
10863         do_facet ost1 lctl set_param fail_loc=0
10864         set_checksums 0
10865
10866         cancel_lru_locks osc
10867         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10868         do_facet ost1 lctl set_param fail_loc=0x8000021b
10869         set_checksums 1
10870         cmp $F77_TMP $file || error "file compare failed"
10871         do_facet ost1 lctl set_param fail_loc=0
10872         set_checksums 0
10873 }
10874 run_test 77g "checksum error on OST write, read"
10875
10876 test_77k() { # LU-10906
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878         $GSS && skip_env "could not run with gss"
10879
10880         local cksum_param="osc.$FSNAME*.checksums"
10881         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10882         local checksum
10883         local i
10884
10885         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10886         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10887         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10888
10889         for i in 0 1; do
10890                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10891                         error "failed to set checksum=$i on MGS"
10892                 wait_update $HOSTNAME "$get_checksum" $i
10893                 #remount
10894                 echo "remount client, checksum should be $i"
10895                 remount_client $MOUNT || error "failed to remount client"
10896                 checksum=$(eval $get_checksum)
10897                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10898         done
10899         # remove persistent param to avoid races with checksum mountopt below
10900         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10901                 error "failed to delete checksum on MGS"
10902
10903         for opt in "checksum" "nochecksum"; do
10904                 #remount with mount option
10905                 echo "remount client with option $opt, checksum should be $i"
10906                 umount_client $MOUNT || error "failed to umount client"
10907                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10908                         error "failed to mount client with option '$opt'"
10909                 checksum=$(eval $get_checksum)
10910                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10911                 i=$((i - 1))
10912         done
10913
10914         remount_client $MOUNT || error "failed to remount client"
10915 }
10916 run_test 77k "enable/disable checksum correctly"
10917
10918 test_77l() {
10919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10920         $GSS && skip_env "could not run with gss"
10921
10922         set_checksums 1
10923         stack_trap "set_checksums $ORIG_CSUM" EXIT
10924         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10925
10926         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10927
10928         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10929         for algo in $CKSUM_TYPES; do
10930                 set_checksum_type $algo || error "fail to set checksum type $algo"
10931                 osc_algo=$(get_osc_checksum_type OST0000)
10932                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10933
10934                 # no locks, no reqs to let the connection idle
10935                 cancel_lru_locks osc
10936                 lru_resize_disable osc
10937                 wait_osc_import_state client ost1 IDLE
10938
10939                 # ensure ost1 is connected
10940                 stat $DIR/$tfile >/dev/null || error "can't stat"
10941                 wait_osc_import_state client ost1 FULL
10942
10943                 osc_algo=$(get_osc_checksum_type OST0000)
10944                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10945         done
10946         return 0
10947 }
10948 run_test 77l "preferred checksum type is remembered after reconnected"
10949
10950 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10951 rm -f $F77_TMP
10952 unset F77_TMP
10953
10954 test_77m() {
10955         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10956                 skip "Need at least version 2.14.52"
10957         local param=checksum_speed
10958
10959         $LCTL get_param $param || error "reading $param failed"
10960
10961         csum_speeds=$($LCTL get_param -n $param)
10962
10963         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10964                 error "known checksum types are missing"
10965 }
10966 run_test 77m "Verify checksum_speed is correctly read"
10967
10968 check_filefrag_77n() {
10969         local nr_ext=0
10970         local starts=()
10971         local ends=()
10972
10973         while read extidx a b start end rest; do
10974                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10975                         nr_ext=$(( $nr_ext + 1 ))
10976                         starts+=( ${start%..} )
10977                         ends+=( ${end%:} )
10978                 fi
10979         done < <( filefrag -sv $1 )
10980
10981         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10982         return 1
10983 }
10984
10985 test_77n() {
10986         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10987
10988         touch $DIR/$tfile
10989         $TRUNCATE $DIR/$tfile 0
10990         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10991         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10992         check_filefrag_77n $DIR/$tfile ||
10993                 skip "$tfile blocks not contiguous around hole"
10994
10995         set_checksums 1
10996         stack_trap "set_checksums $ORIG_CSUM" EXIT
10997         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10998         stack_trap "rm -f $DIR/$tfile"
10999
11000         for algo in $CKSUM_TYPES; do
11001                 if [[ "$algo" =~ ^t10 ]]; then
11002                         set_checksum_type $algo ||
11003                                 error "fail to set checksum type $algo"
11004                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11005                                 error "fail to read $tfile with $algo"
11006                 fi
11007         done
11008         rm -f $DIR/$tfile
11009         return 0
11010 }
11011 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11012
11013 test_77o() {
11014         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11015                 skip "Need MDS version at least 2.14.55"
11016         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11017                 skip "Need OST version at least 2.14.55"
11018         local ofd=obdfilter
11019         local mdt=mdt
11020
11021         # print OST checksum_type
11022         echo "$ofd.$FSNAME-*.checksum_type:"
11023         do_nodes $(comma_list $(osts_nodes)) \
11024                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11025
11026         # print MDT checksum_type
11027         echo "$mdt.$FSNAME-*.checksum_type:"
11028         do_nodes $(comma_list $(mdts_nodes)) \
11029                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11030
11031         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11032                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11033
11034         (( $o_count == $OSTCOUNT )) ||
11035                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11036
11037         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11038                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11039
11040         (( $m_count == $MDSCOUNT )) ||
11041                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11042 }
11043 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11044
11045 cleanup_test_78() {
11046         trap 0
11047         rm -f $DIR/$tfile
11048 }
11049
11050 test_78() { # bug 10901
11051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11052         remote_ost || skip_env "local OST"
11053
11054         NSEQ=5
11055         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11056         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11057         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11058         echo "MemTotal: $MEMTOTAL"
11059
11060         # reserve 256MB of memory for the kernel and other running processes,
11061         # and then take 1/2 of the remaining memory for the read/write buffers.
11062         if [ $MEMTOTAL -gt 512 ] ;then
11063                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11064         else
11065                 # for those poor memory-starved high-end clusters...
11066                 MEMTOTAL=$((MEMTOTAL / 2))
11067         fi
11068         echo "Mem to use for directio: $MEMTOTAL"
11069
11070         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11071         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11072         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11073         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11074                 head -n1)
11075         echo "Smallest OST: $SMALLESTOST"
11076         [[ $SMALLESTOST -lt 10240 ]] &&
11077                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11078
11079         trap cleanup_test_78 EXIT
11080
11081         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11082                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11083
11084         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11085         echo "File size: $F78SIZE"
11086         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11087         for i in $(seq 1 $NSEQ); do
11088                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11089                 echo directIO rdwr round $i of $NSEQ
11090                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11091         done
11092
11093         cleanup_test_78
11094 }
11095 run_test 78 "handle large O_DIRECT writes correctly ============"
11096
11097 test_79() { # bug 12743
11098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11099
11100         wait_delete_completed
11101
11102         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11103         BKFREE=$(calc_osc_kbytes kbytesfree)
11104         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11105
11106         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11107         DFTOTAL=`echo $STRING | cut -d, -f1`
11108         DFUSED=`echo $STRING  | cut -d, -f2`
11109         DFAVAIL=`echo $STRING | cut -d, -f3`
11110         DFFREE=$(($DFTOTAL - $DFUSED))
11111
11112         ALLOWANCE=$((64 * $OSTCOUNT))
11113
11114         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11115            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11116                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11117         fi
11118         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11119            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11120                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11121         fi
11122         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11123            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11124                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11125         fi
11126 }
11127 run_test 79 "df report consistency check ======================="
11128
11129 test_80() { # bug 10718
11130         remote_ost_nodsh && skip "remote OST with nodsh"
11131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11132
11133         # relax strong synchronous semantics for slow backends like ZFS
11134         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11135                 local soc="obdfilter.*.sync_lock_cancel"
11136                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11137
11138                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11139                 if [ -z "$save" ]; then
11140                         soc="obdfilter.*.sync_on_lock_cancel"
11141                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11142                 fi
11143
11144                 if [ "$save" != "never" ]; then
11145                         local hosts=$(comma_list $(osts_nodes))
11146
11147                         do_nodes $hosts $LCTL set_param $soc=never
11148                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11149                 fi
11150         fi
11151
11152         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11153         sync; sleep 1; sync
11154         local before=$(date +%s)
11155         cancel_lru_locks osc
11156         local after=$(date +%s)
11157         local diff=$((after - before))
11158         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11159
11160         rm -f $DIR/$tfile
11161 }
11162 run_test 80 "Page eviction is equally fast at high offsets too"
11163
11164 test_81a() { # LU-456
11165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11166         remote_ost_nodsh && skip "remote OST with nodsh"
11167
11168         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11169         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11170         do_facet ost1 lctl set_param fail_loc=0x80000228
11171
11172         # write should trigger a retry and success
11173         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11174         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11175         RC=$?
11176         if [ $RC -ne 0 ] ; then
11177                 error "write should success, but failed for $RC"
11178         fi
11179 }
11180 run_test 81a "OST should retry write when get -ENOSPC ==============="
11181
11182 test_81b() { # LU-456
11183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11184         remote_ost_nodsh && skip "remote OST with nodsh"
11185
11186         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11187         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11188         do_facet ost1 lctl set_param fail_loc=0x228
11189
11190         # write should retry several times and return -ENOSPC finally
11191         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11192         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11193         RC=$?
11194         ENOSPC=28
11195         if [ $RC -ne $ENOSPC ] ; then
11196                 error "dd should fail for -ENOSPC, but succeed."
11197         fi
11198 }
11199 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11200
11201 test_99() {
11202         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11203
11204         test_mkdir $DIR/$tdir.cvsroot
11205         chown $RUNAS_ID $DIR/$tdir.cvsroot
11206
11207         cd $TMP
11208         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11209
11210         cd /etc/init.d
11211         # some versions of cvs import exit(1) when asked to import links or
11212         # files they can't read.  ignore those files.
11213         local toignore=$(find . -type l -printf '-I %f\n' -o \
11214                          ! -perm /4 -printf '-I %f\n')
11215         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11216                 $tdir.reposname vtag rtag
11217
11218         cd $DIR
11219         test_mkdir $DIR/$tdir.reposname
11220         chown $RUNAS_ID $DIR/$tdir.reposname
11221         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11222
11223         cd $DIR/$tdir.reposname
11224         $RUNAS touch foo99
11225         $RUNAS cvs add -m 'addmsg' foo99
11226         $RUNAS cvs update
11227         $RUNAS cvs commit -m 'nomsg' foo99
11228         rm -fr $DIR/$tdir.cvsroot
11229 }
11230 run_test 99 "cvs strange file/directory operations"
11231
11232 test_100() {
11233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11234         [[ "$NETTYPE" =~ tcp ]] ||
11235                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11236         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11237         remote_ost_nodsh && skip "remote OST with nodsh"
11238         remote_mds_nodsh && skip "remote MDS with nodsh"
11239         remote_servers || skip "useless for local single node setup"
11240
11241         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11242                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11243
11244                 rc=0
11245                 if (( ${LOCAL/*:/} >= 1024 )); then
11246                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11247                         ss -tna
11248                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11249                 fi
11250         done
11251         (( $rc == 0 )) || error "privileged port not found" )
11252 }
11253 run_test 100 "check local port using privileged port"
11254
11255 function get_named_value()
11256 {
11257     local tag=$1
11258
11259     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11260 }
11261
11262 test_101a() {
11263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11264
11265         local s
11266         local discard
11267         local nreads=10000
11268         local cache_limit=32
11269
11270         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11271         $LCTL set_param -n llite.*.read_ahead_stats=0
11272         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11273                               awk '/^max_cached_mb/ { print $2 }')
11274         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11275         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11276
11277         #
11278         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11279         #
11280         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11281         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11282
11283         discard=0
11284         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11285                    get_named_value 'read.but.discarded'); do
11286                         discard=$(($discard + $s))
11287         done
11288
11289         $LCTL get_param osc.*-osc*.rpc_stats
11290         $LCTL get_param llite.*.read_ahead_stats
11291
11292         # Discard is generally zero, but sometimes a few random reads line up
11293         # and trigger larger readahead, which is wasted & leads to discards.
11294         if [[ $(($discard)) -gt $nreads ]]; then
11295                 error "too many ($discard) discarded pages"
11296         fi
11297         rm -f $DIR/$tfile || true
11298 }
11299 run_test 101a "check read-ahead for random reads"
11300
11301 setup_test101bc() {
11302         test_mkdir $DIR/$tdir
11303         local ssize=$1
11304         local FILE_LENGTH=$2
11305         STRIPE_OFFSET=0
11306
11307         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11308
11309         local list=$(comma_list $(osts_nodes))
11310         set_osd_param $list '' read_cache_enable 0
11311         set_osd_param $list '' writethrough_cache_enable 0
11312
11313         trap cleanup_test101bc EXIT
11314         # prepare the read-ahead file
11315         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11316
11317         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11318                                 count=$FILE_SIZE_MB 2> /dev/null
11319
11320 }
11321
11322 cleanup_test101bc() {
11323         trap 0
11324         rm -rf $DIR/$tdir
11325         rm -f $DIR/$tfile
11326
11327         local list=$(comma_list $(osts_nodes))
11328         set_osd_param $list '' read_cache_enable 1
11329         set_osd_param $list '' writethrough_cache_enable 1
11330 }
11331
11332 ra_check_101() {
11333         local read_size=$1
11334         local stripe_size=$2
11335         local stride_length=$((stripe_size / read_size))
11336         local stride_width=$((stride_length * OSTCOUNT))
11337         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11338                                 (stride_width - stride_length) ))
11339         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11340                   get_named_value 'read.but.discarded' | calc_sum)
11341
11342         if [[ $discard -gt $discard_limit ]]; then
11343                 $LCTL get_param llite.*.read_ahead_stats
11344                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11345         else
11346                 echo "Read-ahead success for size ${read_size}"
11347         fi
11348 }
11349
11350 test_101b() {
11351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11352         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11353
11354         local STRIPE_SIZE=1048576
11355         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11356
11357         if [ $SLOW == "yes" ]; then
11358                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11359         else
11360                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11361         fi
11362
11363         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11364
11365         # prepare the read-ahead file
11366         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11367         cancel_lru_locks osc
11368         for BIDX in 2 4 8 16 32 64 128 256
11369         do
11370                 local BSIZE=$((BIDX*4096))
11371                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11372                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11373                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11374                 $LCTL set_param -n llite.*.read_ahead_stats=0
11375                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11376                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11377                 cancel_lru_locks osc
11378                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11379         done
11380         cleanup_test101bc
11381         true
11382 }
11383 run_test 101b "check stride-io mode read-ahead ================="
11384
11385 test_101c() {
11386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11387
11388         local STRIPE_SIZE=1048576
11389         local FILE_LENGTH=$((STRIPE_SIZE*100))
11390         local nreads=10000
11391         local rsize=65536
11392         local osc_rpc_stats
11393
11394         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11395
11396         cancel_lru_locks osc
11397         $LCTL set_param osc.*.rpc_stats=0
11398         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11399         $LCTL get_param osc.*.rpc_stats
11400         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11401                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11402                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11403                 local size
11404
11405                 if [ $lines -le 20 ]; then
11406                         echo "continue debug"
11407                         continue
11408                 fi
11409                 for size in 1 2 4 8; do
11410                         local rpc=$(echo "$stats" |
11411                                     awk '($1 == "'$size':") {print $2; exit; }')
11412                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11413                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11414                 done
11415                 echo "$osc_rpc_stats check passed!"
11416         done
11417         cleanup_test101bc
11418         true
11419 }
11420 run_test 101c "check stripe_size aligned read-ahead"
11421
11422 test_101d() {
11423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11424
11425         local file=$DIR/$tfile
11426         local sz_MB=${FILESIZE_101d:-80}
11427         local ra_MB=${READAHEAD_MB:-40}
11428
11429         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11430         [ $free_MB -lt $sz_MB ] &&
11431                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11432
11433         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11434         $LFS setstripe -c -1 $file || error "setstripe failed"
11435
11436         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11437         echo Cancel LRU locks on lustre client to flush the client cache
11438         cancel_lru_locks osc
11439
11440         echo Disable read-ahead
11441         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11442         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11443         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11444         $LCTL get_param -n llite.*.max_read_ahead_mb
11445
11446         echo "Reading the test file $file with read-ahead disabled"
11447         local sz_KB=$((sz_MB * 1024 / 4))
11448         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11449         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11450         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11451                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11452
11453         echo "Cancel LRU locks on lustre client to flush the client cache"
11454         cancel_lru_locks osc
11455         echo Enable read-ahead with ${ra_MB}MB
11456         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11457
11458         echo "Reading the test file $file with read-ahead enabled"
11459         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11460                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11461
11462         echo "read-ahead disabled time read $raOFF"
11463         echo "read-ahead enabled time read $raON"
11464
11465         rm -f $file
11466         wait_delete_completed
11467
11468         # use awk for this check instead of bash because it handles decimals
11469         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11470                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11471 }
11472 run_test 101d "file read with and without read-ahead enabled"
11473
11474 test_101e() {
11475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11476
11477         local file=$DIR/$tfile
11478         local size_KB=500  #KB
11479         local count=100
11480         local bsize=1024
11481
11482         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11483         local need_KB=$((count * size_KB))
11484         [[ $free_KB -le $need_KB ]] &&
11485                 skip_env "Need free space $need_KB, have $free_KB"
11486
11487         echo "Creating $count ${size_KB}K test files"
11488         for ((i = 0; i < $count; i++)); do
11489                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11490         done
11491
11492         echo "Cancel LRU locks on lustre client to flush the client cache"
11493         cancel_lru_locks $OSC
11494
11495         echo "Reset readahead stats"
11496         $LCTL set_param -n llite.*.read_ahead_stats=0
11497
11498         for ((i = 0; i < $count; i++)); do
11499                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11500         done
11501
11502         $LCTL get_param llite.*.max_cached_mb
11503         $LCTL get_param llite.*.read_ahead_stats
11504         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11505                      get_named_value 'misses' | calc_sum)
11506
11507         for ((i = 0; i < $count; i++)); do
11508                 rm -rf $file.$i 2>/dev/null
11509         done
11510
11511         #10000 means 20% reads are missing in readahead
11512         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11513 }
11514 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11515
11516 test_101f() {
11517         which iozone || skip_env "no iozone installed"
11518
11519         local old_debug=$($LCTL get_param debug)
11520         old_debug=${old_debug#*=}
11521         $LCTL set_param debug="reada mmap"
11522
11523         # create a test file
11524         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11525
11526         echo Cancel LRU locks on lustre client to flush the client cache
11527         cancel_lru_locks osc
11528
11529         echo Reset readahead stats
11530         $LCTL set_param -n llite.*.read_ahead_stats=0
11531
11532         echo mmap read the file with small block size
11533         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11534                 > /dev/null 2>&1
11535
11536         echo checking missing pages
11537         $LCTL get_param llite.*.read_ahead_stats
11538         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11539                         get_named_value 'misses' | calc_sum)
11540
11541         $LCTL set_param debug="$old_debug"
11542         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11543         rm -f $DIR/$tfile
11544 }
11545 run_test 101f "check mmap read performance"
11546
11547 test_101g_brw_size_test() {
11548         local mb=$1
11549         local pages=$((mb * 1048576 / PAGE_SIZE))
11550         local file=$DIR/$tfile
11551
11552         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11553                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11554         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11555                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11556                         return 2
11557         done
11558
11559         stack_trap "rm -f $file" EXIT
11560         $LCTL set_param -n osc.*.rpc_stats=0
11561
11562         # 10 RPCs should be enough for the test
11563         local count=10
11564         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11565                 { error "dd write ${mb} MB blocks failed"; return 3; }
11566         cancel_lru_locks osc
11567         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11568                 { error "dd write ${mb} MB blocks failed"; return 4; }
11569
11570         # calculate number of full-sized read and write RPCs
11571         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11572                 sed -n '/pages per rpc/,/^$/p' |
11573                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11574                 END { print reads,writes }'))
11575         # allow one extra full-sized read RPC for async readahead
11576         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11577                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11578         [[ ${rpcs[1]} == $count ]] ||
11579                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11580 }
11581
11582 test_101g() {
11583         remote_ost_nodsh && skip "remote OST with nodsh"
11584
11585         local rpcs
11586         local osts=$(get_facets OST)
11587         local list=$(comma_list $(osts_nodes))
11588         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11589         local brw_size="obdfilter.*.brw_size"
11590
11591         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11592
11593         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11594
11595         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11596                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11597                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11598            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11599                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11600                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11601
11602                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11603                         suffix="M"
11604
11605                 if [[ $orig_mb -lt 16 ]]; then
11606                         save_lustre_params $osts "$brw_size" > $p
11607                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11608                                 error "set 16MB RPC size failed"
11609
11610                         echo "remount client to enable new RPC size"
11611                         remount_client $MOUNT || error "remount_client failed"
11612                 fi
11613
11614                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11615                 # should be able to set brw_size=12, but no rpc_stats for that
11616                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11617         fi
11618
11619         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11620
11621         if [[ $orig_mb -lt 16 ]]; then
11622                 restore_lustre_params < $p
11623                 remount_client $MOUNT || error "remount_client restore failed"
11624         fi
11625
11626         rm -f $p $DIR/$tfile
11627 }
11628 run_test 101g "Big bulk(4/16 MiB) readahead"
11629
11630 test_101h() {
11631         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11632
11633         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11634                 error "dd 70M file failed"
11635         echo Cancel LRU locks on lustre client to flush the client cache
11636         cancel_lru_locks osc
11637
11638         echo "Reset readahead stats"
11639         $LCTL set_param -n llite.*.read_ahead_stats 0
11640
11641         echo "Read 10M of data but cross 64M bundary"
11642         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11643         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11644                      get_named_value 'misses' | calc_sum)
11645         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11646         rm -f $p $DIR/$tfile
11647 }
11648 run_test 101h "Readahead should cover current read window"
11649
11650 test_101i() {
11651         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11652                 error "dd 10M file failed"
11653
11654         local max_per_file_mb=$($LCTL get_param -n \
11655                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11656         cancel_lru_locks osc
11657         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11658         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11659                 error "set max_read_ahead_per_file_mb to 1 failed"
11660
11661         echo "Reset readahead stats"
11662         $LCTL set_param llite.*.read_ahead_stats=0
11663
11664         dd if=$DIR/$tfile of=/dev/null bs=2M
11665
11666         $LCTL get_param llite.*.read_ahead_stats
11667         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11668                      awk '/misses/ { print $2 }')
11669         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11670         rm -f $DIR/$tfile
11671 }
11672 run_test 101i "allow current readahead to exceed reservation"
11673
11674 test_101j() {
11675         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11676                 error "setstripe $DIR/$tfile failed"
11677         local file_size=$((1048576 * 16))
11678         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11679         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11680
11681         echo Disable read-ahead
11682         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11683
11684         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11685         for blk in $PAGE_SIZE 1048576 $file_size; do
11686                 cancel_lru_locks osc
11687                 echo "Reset readahead stats"
11688                 $LCTL set_param -n llite.*.read_ahead_stats=0
11689                 local count=$(($file_size / $blk))
11690                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11691                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11692                              get_named_value 'failed.to.fast.read' | calc_sum)
11693                 $LCTL get_param -n llite.*.read_ahead_stats
11694                 [ $miss -eq $count ] || error "expected $count got $miss"
11695         done
11696
11697         rm -f $p $DIR/$tfile
11698 }
11699 run_test 101j "A complete read block should be submitted when no RA"
11700
11701 test_readahead_base() {
11702         local file=$DIR/$tfile
11703         local size=$1
11704         local iosz
11705         local ramax
11706         local ranum
11707
11708         $LCTL set_param -n llite.*.read_ahead_stats=0
11709         # The first page is not accounted into readahead
11710         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11711         iosz=$(((size + 1048575) / 1048576 * 1048576))
11712         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11713
11714         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11715         fallocate -l $size $file || error "failed to fallocate $file"
11716         cancel_lru_locks osc
11717         $MULTIOP $file or${iosz}c || error "failed to read $file"
11718         $LCTL get_param -n llite.*.read_ahead_stats
11719         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11720                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11721         (( $ranum <= $ramax )) ||
11722                 error "read-ahead pages is $ranum more than $ramax"
11723         rm -rf $file || error "failed to remove $file"
11724 }
11725
11726 test_101m()
11727 {
11728         local file=$DIR/$tfile
11729         local ramax
11730         local ranum
11731         local size
11732         local iosz
11733
11734         check_set_fallocate_or_skip
11735         stack_trap "rm -f $file" EXIT
11736
11737         test_readahead_base 4096
11738
11739         # file size: 16K = 16384
11740         test_readahead_base 16384
11741         test_readahead_base 16385
11742         test_readahead_base 16383
11743
11744         # file size: 1M + 1 = 1048576 + 1
11745         test_readahead_base 1048577
11746         # file size: 1M + 16K
11747         test_readahead_base $((1048576 + 16384))
11748
11749         # file size: stripe_size * (stripe_count - 1) + 16K
11750         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11751         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11752         # file size: stripe_size * stripe_count + 16K
11753         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11754         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11755         # file size: 2 * stripe_size * stripe_count + 16K
11756         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11757         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11758 }
11759 run_test 101m "read ahead for small file and last stripe of the file"
11760
11761 setup_test102() {
11762         test_mkdir $DIR/$tdir
11763         chown $RUNAS_ID $DIR/$tdir
11764         STRIPE_SIZE=65536
11765         STRIPE_OFFSET=1
11766         STRIPE_COUNT=$OSTCOUNT
11767         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11768
11769         trap cleanup_test102 EXIT
11770         cd $DIR
11771         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11772         cd $DIR/$tdir
11773         for num in 1 2 3 4; do
11774                 for count in $(seq 1 $STRIPE_COUNT); do
11775                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11776                                 local size=`expr $STRIPE_SIZE \* $num`
11777                                 local file=file"$num-$idx-$count"
11778                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11779                         done
11780                 done
11781         done
11782
11783         cd $DIR
11784         $1 tar cf $TMP/f102.tar $tdir --xattrs
11785 }
11786
11787 cleanup_test102() {
11788         trap 0
11789         rm -f $TMP/f102.tar
11790         rm -rf $DIR/d0.sanity/d102
11791 }
11792
11793 test_102a() {
11794         [ "$UID" != 0 ] && skip "must run as root"
11795         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11796                 skip_env "must have user_xattr"
11797
11798         [ -z "$(which setfattr 2>/dev/null)" ] &&
11799                 skip_env "could not find setfattr"
11800
11801         local testfile=$DIR/$tfile
11802
11803         touch $testfile
11804         echo "set/get xattr..."
11805         setfattr -n trusted.name1 -v value1 $testfile ||
11806                 error "setfattr -n trusted.name1=value1 $testfile failed"
11807         getfattr -n trusted.name1 $testfile 2> /dev/null |
11808           grep "trusted.name1=.value1" ||
11809                 error "$testfile missing trusted.name1=value1"
11810
11811         setfattr -n user.author1 -v author1 $testfile ||
11812                 error "setfattr -n user.author1=author1 $testfile failed"
11813         getfattr -n user.author1 $testfile 2> /dev/null |
11814           grep "user.author1=.author1" ||
11815                 error "$testfile missing trusted.author1=author1"
11816
11817         echo "listxattr..."
11818         setfattr -n trusted.name2 -v value2 $testfile ||
11819                 error "$testfile unable to set trusted.name2"
11820         setfattr -n trusted.name3 -v value3 $testfile ||
11821                 error "$testfile unable to set trusted.name3"
11822         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11823             grep "trusted.name" | wc -l) -eq 3 ] ||
11824                 error "$testfile missing 3 trusted.name xattrs"
11825
11826         setfattr -n user.author2 -v author2 $testfile ||
11827                 error "$testfile unable to set user.author2"
11828         setfattr -n user.author3 -v author3 $testfile ||
11829                 error "$testfile unable to set user.author3"
11830         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11831             grep "user.author" | wc -l) -eq 3 ] ||
11832                 error "$testfile missing 3 user.author xattrs"
11833
11834         echo "remove xattr..."
11835         setfattr -x trusted.name1 $testfile ||
11836                 error "$testfile error deleting trusted.name1"
11837         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11838                 error "$testfile did not delete trusted.name1 xattr"
11839
11840         setfattr -x user.author1 $testfile ||
11841                 error "$testfile error deleting user.author1"
11842         echo "set lustre special xattr ..."
11843         $LFS setstripe -c1 $testfile
11844         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11845                 awk -F "=" '/trusted.lov/ { print $2 }' )
11846         setfattr -n "trusted.lov" -v $lovea $testfile ||
11847                 error "$testfile doesn't ignore setting trusted.lov again"
11848         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11849                 error "$testfile allow setting invalid trusted.lov"
11850         rm -f $testfile
11851 }
11852 run_test 102a "user xattr test =================================="
11853
11854 check_102b_layout() {
11855         local layout="$*"
11856         local testfile=$DIR/$tfile
11857
11858         echo "test layout '$layout'"
11859         $LFS setstripe $layout $testfile || error "setstripe failed"
11860         $LFS getstripe -y $testfile
11861
11862         echo "get/set/list trusted.lov xattr ..." # b=10930
11863         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11864         [[ "$value" =~ "trusted.lov" ]] ||
11865                 error "can't get trusted.lov from $testfile"
11866         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11867                 error "getstripe failed"
11868
11869         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11870
11871         value=$(cut -d= -f2 <<<$value)
11872         # LU-13168: truncated xattr should fail if short lov_user_md header
11873         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11874                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11875         for len in $lens; do
11876                 echo "setfattr $len $testfile.2"
11877                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11878                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11879         done
11880         local stripe_size=$($LFS getstripe -S $testfile.2)
11881         local stripe_count=$($LFS getstripe -c $testfile.2)
11882         [[ $stripe_size -eq 65536 ]] ||
11883                 error "stripe size $stripe_size != 65536"
11884         [[ $stripe_count -eq $stripe_count_orig ]] ||
11885                 error "stripe count $stripe_count != $stripe_count_orig"
11886         rm $testfile $testfile.2
11887 }
11888
11889 test_102b() {
11890         [ -z "$(which setfattr 2>/dev/null)" ] &&
11891                 skip_env "could not find setfattr"
11892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11893
11894         # check plain layout
11895         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11896
11897         # and also check composite layout
11898         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11899
11900 }
11901 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11902
11903 test_102c() {
11904         [ -z "$(which setfattr 2>/dev/null)" ] &&
11905                 skip_env "could not find setfattr"
11906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11907
11908         # b10930: get/set/list lustre.lov xattr
11909         echo "get/set/list lustre.lov xattr ..."
11910         test_mkdir $DIR/$tdir
11911         chown $RUNAS_ID $DIR/$tdir
11912         local testfile=$DIR/$tdir/$tfile
11913         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11914                 error "setstripe failed"
11915         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11916                 error "getstripe failed"
11917         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11918         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11919
11920         local testfile2=${testfile}2
11921         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11922                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11923
11924         $RUNAS $MCREATE $testfile2
11925         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11926         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11927         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11928         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11929         [ $stripe_count -eq $STRIPECOUNT ] ||
11930                 error "stripe count $stripe_count != $STRIPECOUNT"
11931 }
11932 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11933
11934 compare_stripe_info1() {
11935         local stripe_index_all_zero=true
11936
11937         for num in 1 2 3 4; do
11938                 for count in $(seq 1 $STRIPE_COUNT); do
11939                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11940                                 local size=$((STRIPE_SIZE * num))
11941                                 local file=file"$num-$offset-$count"
11942                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11943                                 [[ $stripe_size -ne $size ]] &&
11944                                     error "$file: size $stripe_size != $size"
11945                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11946                                 # allow fewer stripes to be created, ORI-601
11947                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11948                                     error "$file: count $stripe_count != $count"
11949                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11950                                 [[ $stripe_index -ne 0 ]] &&
11951                                         stripe_index_all_zero=false
11952                         done
11953                 done
11954         done
11955         $stripe_index_all_zero &&
11956                 error "all files are being extracted starting from OST index 0"
11957         return 0
11958 }
11959
11960 have_xattrs_include() {
11961         tar --help | grep -q xattrs-include &&
11962                 echo --xattrs-include="lustre.*"
11963 }
11964
11965 test_102d() {
11966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11967         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11968
11969         XINC=$(have_xattrs_include)
11970         setup_test102
11971         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11972         cd $DIR/$tdir/$tdir
11973         compare_stripe_info1
11974 }
11975 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11976
11977 test_102f() {
11978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11979         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11980
11981         XINC=$(have_xattrs_include)
11982         setup_test102
11983         test_mkdir $DIR/$tdir.restore
11984         cd $DIR
11985         tar cf - --xattrs $tdir | tar xf - \
11986                 -C $DIR/$tdir.restore --xattrs $XINC
11987         cd $DIR/$tdir.restore/$tdir
11988         compare_stripe_info1
11989 }
11990 run_test 102f "tar copy files, not keep osts"
11991
11992 grow_xattr() {
11993         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11994                 skip "must have user_xattr"
11995         [ -z "$(which setfattr 2>/dev/null)" ] &&
11996                 skip_env "could not find setfattr"
11997         [ -z "$(which getfattr 2>/dev/null)" ] &&
11998                 skip_env "could not find getfattr"
11999
12000         local xsize=${1:-1024}  # in bytes
12001         local file=$DIR/$tfile
12002         local value="$(generate_string $xsize)"
12003         local xbig=trusted.big
12004         local toobig=$2
12005
12006         touch $file
12007         log "save $xbig on $file"
12008         if [ -z "$toobig" ]
12009         then
12010                 setfattr -n $xbig -v $value $file ||
12011                         error "saving $xbig on $file failed"
12012         else
12013                 setfattr -n $xbig -v $value $file &&
12014                         error "saving $xbig on $file succeeded"
12015                 return 0
12016         fi
12017
12018         local orig=$(get_xattr_value $xbig $file)
12019         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12020
12021         local xsml=trusted.sml
12022         log "save $xsml on $file"
12023         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12024
12025         local new=$(get_xattr_value $xbig $file)
12026         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12027
12028         log "grow $xsml on $file"
12029         setfattr -n $xsml -v "$value" $file ||
12030                 error "growing $xsml on $file failed"
12031
12032         new=$(get_xattr_value $xbig $file)
12033         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12034         log "$xbig still valid after growing $xsml"
12035
12036         rm -f $file
12037 }
12038
12039 test_102h() { # bug 15777
12040         grow_xattr 1024
12041 }
12042 run_test 102h "grow xattr from inside inode to external block"
12043
12044 test_102ha() {
12045         large_xattr_enabled || skip_env "ea_inode feature disabled"
12046
12047         echo "setting xattr of max xattr size: $(max_xattr_size)"
12048         grow_xattr $(max_xattr_size)
12049
12050         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12051         echo "This should fail:"
12052         grow_xattr $(($(max_xattr_size) + 10)) 1
12053 }
12054 run_test 102ha "grow xattr from inside inode to external inode"
12055
12056 test_102i() { # bug 17038
12057         [ -z "$(which getfattr 2>/dev/null)" ] &&
12058                 skip "could not find getfattr"
12059
12060         touch $DIR/$tfile
12061         ln -s $DIR/$tfile $DIR/${tfile}link
12062         getfattr -n trusted.lov $DIR/$tfile ||
12063                 error "lgetxattr on $DIR/$tfile failed"
12064         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12065                 grep -i "no such attr" ||
12066                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12067         rm -f $DIR/$tfile $DIR/${tfile}link
12068 }
12069 run_test 102i "lgetxattr test on symbolic link ============"
12070
12071 test_102j() {
12072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12073         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12074
12075         XINC=$(have_xattrs_include)
12076         setup_test102 "$RUNAS"
12077         chown $RUNAS_ID $DIR/$tdir
12078         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12079         cd $DIR/$tdir/$tdir
12080         compare_stripe_info1 "$RUNAS"
12081 }
12082 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12083
12084 test_102k() {
12085         [ -z "$(which setfattr 2>/dev/null)" ] &&
12086                 skip "could not find setfattr"
12087
12088         touch $DIR/$tfile
12089         # b22187 just check that does not crash for regular file.
12090         setfattr -n trusted.lov $DIR/$tfile
12091         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12092         local test_kdir=$DIR/$tdir
12093         test_mkdir $test_kdir
12094         local default_size=$($LFS getstripe -S $test_kdir)
12095         local default_count=$($LFS getstripe -c $test_kdir)
12096         local default_offset=$($LFS getstripe -i $test_kdir)
12097         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12098                 error 'dir setstripe failed'
12099         setfattr -n trusted.lov $test_kdir
12100         local stripe_size=$($LFS getstripe -S $test_kdir)
12101         local stripe_count=$($LFS getstripe -c $test_kdir)
12102         local stripe_offset=$($LFS getstripe -i $test_kdir)
12103         [ $stripe_size -eq $default_size ] ||
12104                 error "stripe size $stripe_size != $default_size"
12105         [ $stripe_count -eq $default_count ] ||
12106                 error "stripe count $stripe_count != $default_count"
12107         [ $stripe_offset -eq $default_offset ] ||
12108                 error "stripe offset $stripe_offset != $default_offset"
12109         rm -rf $DIR/$tfile $test_kdir
12110 }
12111 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12112
12113 test_102l() {
12114         [ -z "$(which getfattr 2>/dev/null)" ] &&
12115                 skip "could not find getfattr"
12116
12117         # LU-532 trusted. xattr is invisible to non-root
12118         local testfile=$DIR/$tfile
12119
12120         touch $testfile
12121
12122         echo "listxattr as user..."
12123         chown $RUNAS_ID $testfile
12124         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12125             grep -q "trusted" &&
12126                 error "$testfile trusted xattrs are user visible"
12127
12128         return 0;
12129 }
12130 run_test 102l "listxattr size test =================================="
12131
12132 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12133         local path=$DIR/$tfile
12134         touch $path
12135
12136         listxattr_size_check $path || error "listattr_size_check $path failed"
12137 }
12138 run_test 102m "Ensure listxattr fails on small bufffer ========"
12139
12140 cleanup_test102
12141
12142 getxattr() { # getxattr path name
12143         # Return the base64 encoding of the value of xattr name on path.
12144         local path=$1
12145         local name=$2
12146
12147         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12148         # file: $path
12149         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12150         #
12151         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12152
12153         getfattr --absolute-names --encoding=base64 --name=$name $path |
12154                 awk -F= -v name=$name '$1 == name {
12155                         print substr($0, index($0, "=") + 1);
12156         }'
12157 }
12158
12159 test_102n() { # LU-4101 mdt: protect internal xattrs
12160         [ -z "$(which setfattr 2>/dev/null)" ] &&
12161                 skip "could not find setfattr"
12162         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12163         then
12164                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12165         fi
12166
12167         local file0=$DIR/$tfile.0
12168         local file1=$DIR/$tfile.1
12169         local xattr0=$TMP/$tfile.0
12170         local xattr1=$TMP/$tfile.1
12171         local namelist="lov lma lmv link fid version som hsm"
12172         local name
12173         local value
12174
12175         rm -rf $file0 $file1 $xattr0 $xattr1
12176         touch $file0 $file1
12177
12178         # Get 'before' xattrs of $file1.
12179         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12180
12181         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12182                 namelist+=" lfsck_namespace"
12183         for name in $namelist; do
12184                 # Try to copy xattr from $file0 to $file1.
12185                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12186
12187                 setfattr --name=trusted.$name --value="$value" $file1 ||
12188                         error "setxattr 'trusted.$name' failed"
12189
12190                 # Try to set a garbage xattr.
12191                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12192
12193                 if [[ x$name == "xlov" ]]; then
12194                         setfattr --name=trusted.lov --value="$value" $file1 &&
12195                         error "setxattr invalid 'trusted.lov' success"
12196                 else
12197                         setfattr --name=trusted.$name --value="$value" $file1 ||
12198                                 error "setxattr invalid 'trusted.$name' failed"
12199                 fi
12200
12201                 # Try to remove the xattr from $file1. We don't care if this
12202                 # appears to succeed or fail, we just don't want there to be
12203                 # any changes or crashes.
12204                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12205         done
12206
12207         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12208         then
12209                 name="lfsck_ns"
12210                 # Try to copy xattr from $file0 to $file1.
12211                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12212
12213                 setfattr --name=trusted.$name --value="$value" $file1 ||
12214                         error "setxattr 'trusted.$name' failed"
12215
12216                 # Try to set a garbage xattr.
12217                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12218
12219                 setfattr --name=trusted.$name --value="$value" $file1 ||
12220                         error "setxattr 'trusted.$name' failed"
12221
12222                 # Try to remove the xattr from $file1. We don't care if this
12223                 # appears to succeed or fail, we just don't want there to be
12224                 # any changes or crashes.
12225                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12226         fi
12227
12228         # Get 'after' xattrs of file1.
12229         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12230
12231         if ! diff $xattr0 $xattr1; then
12232                 error "before and after xattrs of '$file1' differ"
12233         fi
12234
12235         rm -rf $file0 $file1 $xattr0 $xattr1
12236
12237         return 0
12238 }
12239 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12240
12241 test_102p() { # LU-4703 setxattr did not check ownership
12242         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12243                 skip "MDS needs to be at least 2.5.56"
12244
12245         local testfile=$DIR/$tfile
12246
12247         touch $testfile
12248
12249         echo "setfacl as user..."
12250         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12251         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12252
12253         echo "setfattr as user..."
12254         setfacl -m "u:$RUNAS_ID:---" $testfile
12255         $RUNAS setfattr -x system.posix_acl_access $testfile
12256         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12257 }
12258 run_test 102p "check setxattr(2) correctly fails without permission"
12259
12260 test_102q() {
12261         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12262                 skip "MDS needs to be at least 2.6.92"
12263
12264         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12265 }
12266 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12267
12268 test_102r() {
12269         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12270                 skip "MDS needs to be at least 2.6.93"
12271
12272         touch $DIR/$tfile || error "touch"
12273         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12274         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12275         rm $DIR/$tfile || error "rm"
12276
12277         #normal directory
12278         mkdir -p $DIR/$tdir || error "mkdir"
12279         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12280         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12281         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12282                 error "$testfile error deleting user.author1"
12283         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12284                 grep "user.$(basename $tdir)" &&
12285                 error "$tdir did not delete user.$(basename $tdir)"
12286         rmdir $DIR/$tdir || error "rmdir"
12287
12288         #striped directory
12289         test_mkdir $DIR/$tdir
12290         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12291         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12292         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12293                 error "$testfile error deleting user.author1"
12294         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12295                 grep "user.$(basename $tdir)" &&
12296                 error "$tdir did not delete user.$(basename $tdir)"
12297         rmdir $DIR/$tdir || error "rm striped dir"
12298 }
12299 run_test 102r "set EAs with empty values"
12300
12301 test_102s() {
12302         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12303                 skip "MDS needs to be at least 2.11.52"
12304
12305         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12306
12307         save_lustre_params client "llite.*.xattr_cache" > $save
12308
12309         for cache in 0 1; do
12310                 lctl set_param llite.*.xattr_cache=$cache
12311
12312                 rm -f $DIR/$tfile
12313                 touch $DIR/$tfile || error "touch"
12314                 for prefix in lustre security system trusted user; do
12315                         # Note getxattr() may fail with 'Operation not
12316                         # supported' or 'No such attribute' depending
12317                         # on prefix and cache.
12318                         getfattr -n $prefix.n102s $DIR/$tfile &&
12319                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12320                 done
12321         done
12322
12323         restore_lustre_params < $save
12324 }
12325 run_test 102s "getting nonexistent xattrs should fail"
12326
12327 test_102t() {
12328         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12329                 skip "MDS needs to be at least 2.11.52"
12330
12331         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12332
12333         save_lustre_params client "llite.*.xattr_cache" > $save
12334
12335         for cache in 0 1; do
12336                 lctl set_param llite.*.xattr_cache=$cache
12337
12338                 for buf_size in 0 256; do
12339                         rm -f $DIR/$tfile
12340                         touch $DIR/$tfile || error "touch"
12341                         setfattr -n user.multiop $DIR/$tfile
12342                         $MULTIOP $DIR/$tfile oa$buf_size ||
12343                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12344                 done
12345         done
12346
12347         restore_lustre_params < $save
12348 }
12349 run_test 102t "zero length xattr values handled correctly"
12350
12351 run_acl_subtest()
12352 {
12353         local test=$LUSTRE/tests/acl/$1.test
12354         local tmp=$(mktemp -t $1-XXXXXX).test
12355         local bin=$2
12356         local dmn=$3
12357         local grp=$4
12358         local nbd=$5
12359         export LANG=C
12360
12361
12362         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12363         local sedgroups="-e s/:users/:$grp/g"
12364         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12365
12366         sed $sedusers $sedgroups < $test > $tmp
12367         stack_trap "rm -f $tmp"
12368         [[ -s $tmp ]] || error "sed failed to create test script"
12369
12370         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12371         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12372 }
12373
12374 test_103a() {
12375         [ "$UID" != 0 ] && skip "must run as root"
12376         $GSS && skip_env "could not run under gss"
12377         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12378                 skip_env "must have acl enabled"
12379         which setfacl || skip_env "could not find setfacl"
12380         remote_mds_nodsh && skip "remote MDS with nodsh"
12381
12382         local mdts=$(comma_list $(mdts_nodes))
12383         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12384
12385         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12386         stack_trap "[[ -z \"$saved\" ]] || \
12387                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12388
12389         ACLBIN=${ACLBIN:-"bin"}
12390         ACLDMN=${ACLDMN:-"daemon"}
12391         ACLGRP=${ACLGRP:-"users"}
12392         ACLNBD=${ACLNBD:-"nobody"}
12393
12394         if ! id $ACLBIN ||
12395            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12396                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12397                 ACLBIN=$USER0
12398                 if ! id $ACLBIN ; then
12399                         cat /etc/passwd
12400                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12401                 fi
12402         fi
12403         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12404            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12405                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12406                 ACLDMN=$USER1
12407                 if ! id $ACLDMN ; then
12408                         cat /etc/passwd
12409                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12410                 fi
12411         fi
12412         if ! getent group $ACLGRP; then
12413                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12414                 ACLGRP="$TSTUSR"
12415                 if ! getent group $ACLGRP; then
12416                         echo "cannot find group '$ACLGRP', adding it"
12417                         cat /etc/group
12418                         add_group 60000 $ACLGRP
12419                 fi
12420         fi
12421
12422         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12423         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12424         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12425
12426         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12427                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12428                 ACLGRP="$TSTUSR"
12429                 if ! getent group $ACLGRP; then
12430                         echo "cannot find group '$ACLGRP', adding it"
12431                         cat /etc/group
12432                         add_group 60000 $ACLGRP
12433                 fi
12434                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12435                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12436                         cat /etc/group
12437                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12438                 fi
12439         fi
12440
12441         gpasswd -a $ACLDMN $ACLBIN ||
12442                 error "setting client group failed"             # LU-5641
12443         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12444                 error "setting MDS group failed"                # LU-5641
12445
12446         declare -a identity_old
12447
12448         for ((num = 1; num <= $MDSCOUNT; num++)); do
12449                 switch_identity $num true || identity_old[$num]=$?
12450         done
12451
12452         SAVE_UMASK=$(umask)
12453         umask 0022
12454         mkdir -p $DIR/$tdir
12455         cd $DIR/$tdir
12456
12457         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12458         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12459         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12460         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12461         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12462         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12463         if ! id -u $ACLNBD ||
12464            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12465                 ACLNBD="nfsnobody"
12466                 if ! id -u $ACLNBD; then
12467                         ACLNBD=""
12468                 fi
12469         fi
12470         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12471                 add_group $(id -u $ACLNBD) $ACLNBD
12472                 if ! getent group $ACLNBD; then
12473                         ACLNBD=""
12474                 fi
12475         fi
12476         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12477            [[ -n "$ACLNBD" ]] && which setfattr; then
12478                 run_acl_subtest permissions_xattr \
12479                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12480         elif [[ -z "$ACLNBD" ]]; then
12481                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12482         else
12483                 echo "skip 'permission_xattr' test - missing setfattr command"
12484         fi
12485         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12486
12487         # inheritance test got from HP
12488         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12489         chmod +x make-tree || error "chmod +x failed"
12490         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12491         rm -f make-tree
12492
12493         echo "LU-974 ignore umask when acl is enabled..."
12494         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12495         if [ $MDSCOUNT -ge 2 ]; then
12496                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12497         fi
12498
12499         echo "LU-2561 newly created file is same size as directory..."
12500         if [ "$mds1_FSTYPE" != "zfs" ]; then
12501                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12502         else
12503                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12504         fi
12505
12506         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12507
12508         cd $SAVE_PWD
12509         umask $SAVE_UMASK
12510
12511         for ((num = 1; num <= $MDSCOUNT; num++)); do
12512                 if [[ "${identity_old[$num]}" == 1 ]]; then
12513                         switch_identity $num false || identity_old[$num]=$?
12514                 fi
12515         done
12516 }
12517 run_test 103a "acl test"
12518
12519 test_103b() {
12520         declare -a pids
12521         local U
12522
12523         stack_trap "rm -f $DIR/$tfile.*"
12524         for U in {0..511}; do
12525                 {
12526                 local O=$(printf "%04o" $U)
12527
12528                 umask $(printf "%04o" $((511 ^ $O)))
12529                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12530                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12531
12532                 (( $S == ($O & 0666) )) ||
12533                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12534
12535                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12536                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12537                 (( $S == ($O & 0666) )) ||
12538                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12539
12540                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12541                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12542                 (( $S == ($O & 0666) )) ||
12543                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12544                 rm -f $DIR/$tfile.[smp]$0
12545                 } &
12546                 local pid=$!
12547
12548                 # limit the concurrently running threads to 64. LU-11878
12549                 local idx=$((U % 64))
12550                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12551                 pids[idx]=$pid
12552         done
12553         wait
12554 }
12555 run_test 103b "umask lfs setstripe"
12556
12557 test_103c() {
12558         mkdir -p $DIR/$tdir
12559         cp -rp $DIR/$tdir $DIR/$tdir.bak
12560
12561         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12562                 error "$DIR/$tdir shouldn't contain default ACL"
12563         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12564                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12565         true
12566 }
12567 run_test 103c "'cp -rp' won't set empty acl"
12568
12569 test_103e() {
12570         local numacl
12571         local fileacl
12572         local saved_debug=$($LCTL get_param -n debug)
12573
12574         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12575                 skip "MDS needs to be at least 2.14.52"
12576
12577         large_xattr_enabled || skip_env "ea_inode feature disabled"
12578
12579         mkdir -p $DIR/$tdir
12580         # add big LOV EA to cause reply buffer overflow earlier
12581         $LFS setstripe -C 1000 $DIR/$tdir
12582         lctl set_param mdc.*-mdc*.stats=clear
12583
12584         $LCTL set_param debug=0
12585         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12586         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12587
12588         # add a large number of default ACLs (expect 8000+ for 2.13+)
12589         for U in {2..7000}; do
12590                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12591                         error "Able to add just $U default ACLs"
12592         done
12593         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12594         echo "$numacl default ACLs created"
12595
12596         stat $DIR/$tdir || error "Cannot stat directory"
12597         # check file creation
12598         touch $DIR/$tdir/$tfile ||
12599                 error "failed to create $tfile with $numacl default ACLs"
12600         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12601         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12602         echo "$fileacl ACLs were inherited"
12603         (( $fileacl == $numacl )) ||
12604                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12605         # check that new ACLs creation adds new ACLs to inherited ACLs
12606         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12607                 error "Cannot set new ACL"
12608         numacl=$((numacl + 1))
12609         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12610         (( $fileacl == $numacl )) ||
12611                 error "failed to add new ACL: $fileacl != $numacl as expected"
12612         # adds more ACLs to a file to reach their maximum at 8000+
12613         numacl=0
12614         for U in {20000..25000}; do
12615                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12616                 numacl=$((numacl + 1))
12617         done
12618         echo "Added $numacl more ACLs to the file"
12619         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12620         echo "Total $fileacl ACLs in file"
12621         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12622         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12623         rmdir $DIR/$tdir || error "Cannot remove directory"
12624 }
12625 run_test 103e "inheritance of big amount of default ACLs"
12626
12627 test_103f() {
12628         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12629                 skip "MDS needs to be at least 2.14.51"
12630
12631         large_xattr_enabled || skip_env "ea_inode feature disabled"
12632
12633         # enable changelog to consume more internal MDD buffers
12634         changelog_register
12635
12636         mkdir -p $DIR/$tdir
12637         # add big LOV EA
12638         $LFS setstripe -C 1000 $DIR/$tdir
12639         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12640         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12641         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12642         rmdir $DIR/$tdir || error "Cannot remove directory"
12643 }
12644 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12645
12646 test_104a() {
12647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12648
12649         touch $DIR/$tfile
12650         lfs df || error "lfs df failed"
12651         lfs df -ih || error "lfs df -ih failed"
12652         lfs df -h $DIR || error "lfs df -h $DIR failed"
12653         lfs df -i $DIR || error "lfs df -i $DIR failed"
12654         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12655         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12656
12657         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12658         lctl --device %$OSC deactivate
12659         lfs df || error "lfs df with deactivated OSC failed"
12660         lctl --device %$OSC activate
12661         # wait the osc back to normal
12662         wait_osc_import_ready client ost
12663
12664         lfs df || error "lfs df with reactivated OSC failed"
12665         rm -f $DIR/$tfile
12666 }
12667 run_test 104a "lfs df [-ih] [path] test ========================="
12668
12669 test_104b() {
12670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12671         [ $RUNAS_ID -eq $UID ] &&
12672                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12673
12674         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12675                         grep "Permission denied" | wc -l)))
12676         if [ $denied_cnt -ne 0 ]; then
12677                 error "lfs check servers test failed"
12678         fi
12679 }
12680 run_test 104b "$RUNAS lfs check servers test ===================="
12681
12682 #
12683 # Verify $1 is within range of $2.
12684 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12685 # $1 is <= 2% of $2. Else Fail.
12686 #
12687 value_in_range() {
12688         # Strip all units (M, G, T)
12689         actual=$(echo $1 | tr -d A-Z)
12690         expect=$(echo $2 | tr -d A-Z)
12691
12692         expect_lo=$(($expect * 98 / 100)) # 2% below
12693         expect_hi=$(($expect * 102 / 100)) # 2% above
12694
12695         # permit 2% drift above and below
12696         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12697 }
12698
12699 test_104c() {
12700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12701         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12702
12703         local ost_param="osd-zfs.$FSNAME-OST0000."
12704         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12705         local ofacets=$(get_facets OST)
12706         local mfacets=$(get_facets MDS)
12707         local saved_ost_blocks=
12708         local saved_mdt_blocks=
12709
12710         echo "Before recordsize change"
12711         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12712         df=($(df -h | grep "$MOUNT"$))
12713
12714         # For checking.
12715         echo "lfs output : ${lfs_df[*]}"
12716         echo "df  output : ${df[*]}"
12717
12718         for facet in ${ofacets//,/ }; do
12719                 if [ -z $saved_ost_blocks ]; then
12720                         saved_ost_blocks=$(do_facet $facet \
12721                                 lctl get_param -n $ost_param.blocksize)
12722                         echo "OST Blocksize: $saved_ost_blocks"
12723                 fi
12724                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12725                 do_facet $facet zfs set recordsize=32768 $ost
12726         done
12727
12728         # BS too small. Sufficient for functional testing.
12729         for facet in ${mfacets//,/ }; do
12730                 if [ -z $saved_mdt_blocks ]; then
12731                         saved_mdt_blocks=$(do_facet $facet \
12732                                 lctl get_param -n $mdt_param.blocksize)
12733                         echo "MDT Blocksize: $saved_mdt_blocks"
12734                 fi
12735                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12736                 do_facet $facet zfs set recordsize=32768 $mdt
12737         done
12738
12739         # Give new values chance to reflect change
12740         sleep 2
12741
12742         echo "After recordsize change"
12743         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12744         df_after=($(df -h | grep "$MOUNT"$))
12745
12746         # For checking.
12747         echo "lfs output : ${lfs_df_after[*]}"
12748         echo "df  output : ${df_after[*]}"
12749
12750         # Verify lfs df
12751         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12752                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12753         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12754                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12755         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12756                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12757
12758         # Verify df
12759         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12760                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12761         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12762                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12763         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12764                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12765
12766         # Restore MDT recordize back to original
12767         for facet in ${mfacets//,/ }; do
12768                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12769                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12770         done
12771
12772         # Restore OST recordize back to original
12773         for facet in ${ofacets//,/ }; do
12774                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12775                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12776         done
12777
12778         return 0
12779 }
12780 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12781
12782 test_104d() {
12783         (( $RUNAS_ID != $UID )) ||
12784                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12785
12786         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12787                 skip "lustre version doesn't support lctl dl with non-root"
12788
12789         # debugfs only allows root users to access files, so the
12790         # previous move of the "devices" file to debugfs broke
12791         # "lctl dl" for non-root users. The LU-9680 Netlink
12792         # interface again allows non-root users to list devices.
12793         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12794                 error "lctl dl doesn't work for non root"
12795
12796         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12797         [ "$ost_count" -eq $OSTCOUNT ]  ||
12798                 error "lctl dl reports wrong number of OST devices"
12799
12800         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12801         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12802                 error "lctl dl reports wrong number of MDT devices"
12803 }
12804 run_test 104d "$RUNAS lctl dl test"
12805
12806 test_105a() {
12807         # doesn't work on 2.4 kernels
12808         touch $DIR/$tfile
12809         if $(flock_is_enabled); then
12810                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12811         else
12812                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12813         fi
12814         rm -f $DIR/$tfile
12815 }
12816 run_test 105a "flock when mounted without -o flock test ========"
12817
12818 test_105b() {
12819         touch $DIR/$tfile
12820         if $(flock_is_enabled); then
12821                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12822         else
12823                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12824         fi
12825         rm -f $DIR/$tfile
12826 }
12827 run_test 105b "fcntl when mounted without -o flock test ========"
12828
12829 test_105c() {
12830         touch $DIR/$tfile
12831         if $(flock_is_enabled); then
12832                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12833         else
12834                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12835         fi
12836         rm -f $DIR/$tfile
12837 }
12838 run_test 105c "lockf when mounted without -o flock test"
12839
12840 test_105d() { # bug 15924
12841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12842
12843         test_mkdir $DIR/$tdir
12844         flock_is_enabled || skip_env "mount w/o flock enabled"
12845         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12846         $LCTL set_param fail_loc=0x80000315
12847         flocks_test 2 $DIR/$tdir
12848 }
12849 run_test 105d "flock race (should not freeze) ========"
12850
12851 test_105e() { # bug 22660 && 22040
12852         flock_is_enabled || skip_env "mount w/o flock enabled"
12853
12854         touch $DIR/$tfile
12855         flocks_test 3 $DIR/$tfile
12856 }
12857 run_test 105e "Two conflicting flocks from same process"
12858
12859 test_106() { #bug 10921
12860         test_mkdir $DIR/$tdir
12861         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12862         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12863 }
12864 run_test 106 "attempt exec of dir followed by chown of that dir"
12865
12866 test_107() {
12867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12868
12869         CDIR=`pwd`
12870         local file=core
12871
12872         cd $DIR
12873         rm -f $file
12874
12875         local save_pattern=$(sysctl -n kernel.core_pattern)
12876         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12877         sysctl -w kernel.core_pattern=$file
12878         sysctl -w kernel.core_uses_pid=0
12879
12880         ulimit -c unlimited
12881         sleep 60 &
12882         SLEEPPID=$!
12883
12884         sleep 1
12885
12886         kill -s 11 $SLEEPPID
12887         wait $SLEEPPID
12888         if [ -e $file ]; then
12889                 size=`stat -c%s $file`
12890                 [ $size -eq 0 ] && error "Fail to create core file $file"
12891         else
12892                 error "Fail to create core file $file"
12893         fi
12894         rm -f $file
12895         sysctl -w kernel.core_pattern=$save_pattern
12896         sysctl -w kernel.core_uses_pid=$save_uses_pid
12897         cd $CDIR
12898 }
12899 run_test 107 "Coredump on SIG"
12900
12901 test_110() {
12902         test_mkdir $DIR/$tdir
12903         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12904         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12905                 error "mkdir with 256 char should fail, but did not"
12906         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12907                 error "create with 255 char failed"
12908         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12909                 error "create with 256 char should fail, but did not"
12910
12911         ls -l $DIR/$tdir
12912         rm -rf $DIR/$tdir
12913 }
12914 run_test 110 "filename length checking"
12915
12916 test_116a() { # was previously test_116()
12917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12918         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12919         remote_mds_nodsh && skip "remote MDS with nodsh"
12920
12921         echo -n "Free space priority "
12922         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12923                 head -n1
12924         declare -a AVAIL
12925         free_min_max
12926
12927         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12928         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12929         stack_trap simple_cleanup_common
12930
12931         # Check if we need to generate uneven OSTs
12932         test_mkdir -p $DIR/$tdir/OST${MINI}
12933         local FILL=$((MINV / 4))
12934         local DIFF=$((MAXV - MINV))
12935         local DIFF2=$((DIFF * 100 / MINV))
12936
12937         local threshold=$(do_facet $SINGLEMDS \
12938                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12939         threshold=${threshold%%%}
12940         echo -n "Check for uneven OSTs: "
12941         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12942
12943         if [[ $DIFF2 -gt $threshold ]]; then
12944                 echo "ok"
12945                 echo "Don't need to fill OST$MINI"
12946         else
12947                 # generate uneven OSTs. Write 2% over the QOS threshold value
12948                 echo "no"
12949                 DIFF=$((threshold - DIFF2 + 2))
12950                 DIFF2=$((MINV * DIFF / 100))
12951                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12952                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12953                         error "setstripe failed"
12954                 DIFF=$((DIFF2 / 2048))
12955                 i=0
12956                 while [ $i -lt $DIFF ]; do
12957                         i=$((i + 1))
12958                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12959                                 bs=2M count=1 2>/dev/null
12960                         echo -n .
12961                 done
12962                 echo .
12963                 sync
12964                 sleep_maxage
12965                 free_min_max
12966         fi
12967
12968         DIFF=$((MAXV - MINV))
12969         DIFF2=$((DIFF * 100 / MINV))
12970         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12971         if [ $DIFF2 -gt $threshold ]; then
12972                 echo "ok"
12973         else
12974                 skip "QOS imbalance criteria not met"
12975         fi
12976
12977         MINI1=$MINI
12978         MINV1=$MINV
12979         MAXI1=$MAXI
12980         MAXV1=$MAXV
12981
12982         # now fill using QOS
12983         $LFS setstripe -c 1 $DIR/$tdir
12984         FILL=$((FILL / 200))
12985         if [ $FILL -gt 600 ]; then
12986                 FILL=600
12987         fi
12988         echo "writing $FILL files to QOS-assigned OSTs"
12989         i=0
12990         while [ $i -lt $FILL ]; do
12991                 i=$((i + 1))
12992                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12993                         count=1 2>/dev/null
12994                 echo -n .
12995         done
12996         echo "wrote $i 200k files"
12997         sync
12998         sleep_maxage
12999
13000         echo "Note: free space may not be updated, so measurements might be off"
13001         free_min_max
13002         DIFF2=$((MAXV - MINV))
13003         echo "free space delta: orig $DIFF final $DIFF2"
13004         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13005         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13006         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13007         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13008         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13009         if [[ $DIFF -gt 0 ]]; then
13010                 FILL=$((DIFF2 * 100 / DIFF - 100))
13011                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13012         fi
13013
13014         # Figure out which files were written where
13015         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13016                awk '/'$MINI1': / {print $2; exit}')
13017         echo $UUID
13018         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13019         echo "$MINC files created on smaller OST $MINI1"
13020         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13021                awk '/'$MAXI1': / {print $2; exit}')
13022         echo $UUID
13023         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13024         echo "$MAXC files created on larger OST $MAXI1"
13025         if [[ $MINC -gt 0 ]]; then
13026                 FILL=$((MAXC * 100 / MINC - 100))
13027                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13028         fi
13029         [[ $MAXC -gt $MINC ]] ||
13030                 error_ignore LU-9 "stripe QOS didn't balance free space"
13031 }
13032 run_test 116a "stripe QOS: free space balance ==================="
13033
13034 test_116b() { # LU-2093
13035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13036         remote_mds_nodsh && skip "remote MDS with nodsh"
13037
13038 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13039         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13040                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13041         [ -z "$old_rr" ] && skip "no QOS"
13042         do_facet $SINGLEMDS lctl set_param \
13043                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13044         mkdir -p $DIR/$tdir
13045         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13046         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13047         do_facet $SINGLEMDS lctl set_param fail_loc=0
13048         rm -rf $DIR/$tdir
13049         do_facet $SINGLEMDS lctl set_param \
13050                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13051 }
13052 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13053
13054 test_117() # bug 10891
13055 {
13056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13057
13058         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13059         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13060         lctl set_param fail_loc=0x21e
13061         > $DIR/$tfile || error "truncate failed"
13062         lctl set_param fail_loc=0
13063         echo "Truncate succeeded."
13064         rm -f $DIR/$tfile
13065 }
13066 run_test 117 "verify osd extend =========="
13067
13068 NO_SLOW_RESENDCOUNT=4
13069 export OLD_RESENDCOUNT=""
13070 set_resend_count () {
13071         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13072         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13073         lctl set_param -n $PROC_RESENDCOUNT $1
13074         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13075 }
13076
13077 # for reduce test_118* time (b=14842)
13078 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13079
13080 # Reset async IO behavior after error case
13081 reset_async() {
13082         FILE=$DIR/reset_async
13083
13084         # Ensure all OSCs are cleared
13085         $LFS setstripe -c -1 $FILE
13086         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13087         sync
13088         rm $FILE
13089 }
13090
13091 test_118a() #bug 11710
13092 {
13093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13094
13095         reset_async
13096
13097         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13098         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13099         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13100
13101         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13102                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13103                 return 1;
13104         fi
13105         rm -f $DIR/$tfile
13106 }
13107 run_test 118a "verify O_SYNC works =========="
13108
13109 test_118b()
13110 {
13111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13112         remote_ost_nodsh && skip "remote OST with nodsh"
13113
13114         reset_async
13115
13116         #define OBD_FAIL_SRV_ENOENT 0x217
13117         set_nodes_failloc "$(osts_nodes)" 0x217
13118         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13119         RC=$?
13120         set_nodes_failloc "$(osts_nodes)" 0
13121         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13122         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13123                     grep -c writeback)
13124
13125         if [[ $RC -eq 0 ]]; then
13126                 error "Must return error due to dropped pages, rc=$RC"
13127                 return 1;
13128         fi
13129
13130         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13131                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13132                 return 1;
13133         fi
13134
13135         echo "Dirty pages not leaked on ENOENT"
13136
13137         # Due to the above error the OSC will issue all RPCs syncronously
13138         # until a subsequent RPC completes successfully without error.
13139         $MULTIOP $DIR/$tfile Ow4096yc
13140         rm -f $DIR/$tfile
13141
13142         return 0
13143 }
13144 run_test 118b "Reclaim dirty pages on fatal error =========="
13145
13146 test_118c()
13147 {
13148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13149
13150         # for 118c, restore the original resend count, LU-1940
13151         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13152                                 set_resend_count $OLD_RESENDCOUNT
13153         remote_ost_nodsh && skip "remote OST with nodsh"
13154
13155         reset_async
13156
13157         #define OBD_FAIL_OST_EROFS               0x216
13158         set_nodes_failloc "$(osts_nodes)" 0x216
13159
13160         # multiop should block due to fsync until pages are written
13161         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13162         MULTIPID=$!
13163         sleep 1
13164
13165         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13166                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13167         fi
13168
13169         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13170                     grep -c writeback)
13171         if [[ $WRITEBACK -eq 0 ]]; then
13172                 error "No page in writeback, writeback=$WRITEBACK"
13173         fi
13174
13175         set_nodes_failloc "$(osts_nodes)" 0
13176         wait $MULTIPID
13177         RC=$?
13178         if [[ $RC -ne 0 ]]; then
13179                 error "Multiop fsync failed, rc=$RC"
13180         fi
13181
13182         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13183         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13184                     grep -c writeback)
13185         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13186                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13187         fi
13188
13189         rm -f $DIR/$tfile
13190         echo "Dirty pages flushed via fsync on EROFS"
13191         return 0
13192 }
13193 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13194
13195 # continue to use small resend count to reduce test_118* time (b=14842)
13196 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13197
13198 test_118d()
13199 {
13200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13201         remote_ost_nodsh && skip "remote OST with nodsh"
13202
13203         reset_async
13204
13205         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13206         set_nodes_failloc "$(osts_nodes)" 0x214
13207         # multiop should block due to fsync until pages are written
13208         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13209         MULTIPID=$!
13210         sleep 1
13211
13212         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13213                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13214         fi
13215
13216         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13217                     grep -c writeback)
13218         if [[ $WRITEBACK -eq 0 ]]; then
13219                 error "No page in writeback, writeback=$WRITEBACK"
13220         fi
13221
13222         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13223         set_nodes_failloc "$(osts_nodes)" 0
13224
13225         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13226         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13227                     grep -c writeback)
13228         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13229                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13230         fi
13231
13232         rm -f $DIR/$tfile
13233         echo "Dirty pages gaurenteed flushed via fsync"
13234         return 0
13235 }
13236 run_test 118d "Fsync validation inject a delay of the bulk =========="
13237
13238 test_118f() {
13239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13240
13241         reset_async
13242
13243         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13244         lctl set_param fail_loc=0x8000040a
13245
13246         # Should simulate EINVAL error which is fatal
13247         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13248         RC=$?
13249         if [[ $RC -eq 0 ]]; then
13250                 error "Must return error due to dropped pages, rc=$RC"
13251         fi
13252
13253         lctl set_param fail_loc=0x0
13254
13255         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13256         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13257         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13258                     grep -c writeback)
13259         if [[ $LOCKED -ne 0 ]]; then
13260                 error "Locked pages remain in cache, locked=$LOCKED"
13261         fi
13262
13263         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13264                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13265         fi
13266
13267         rm -f $DIR/$tfile
13268         echo "No pages locked after fsync"
13269
13270         reset_async
13271         return 0
13272 }
13273 run_test 118f "Simulate unrecoverable OSC side error =========="
13274
13275 test_118g() {
13276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13277
13278         reset_async
13279
13280         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13281         lctl set_param fail_loc=0x406
13282
13283         # simulate local -ENOMEM
13284         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13285         RC=$?
13286
13287         lctl set_param fail_loc=0
13288         if [[ $RC -eq 0 ]]; then
13289                 error "Must return error due to dropped pages, rc=$RC"
13290         fi
13291
13292         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13293         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13294         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13295                         grep -c writeback)
13296         if [[ $LOCKED -ne 0 ]]; then
13297                 error "Locked pages remain in cache, locked=$LOCKED"
13298         fi
13299
13300         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13301                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13302         fi
13303
13304         rm -f $DIR/$tfile
13305         echo "No pages locked after fsync"
13306
13307         reset_async
13308         return 0
13309 }
13310 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13311
13312 test_118h() {
13313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13314         remote_ost_nodsh && skip "remote OST with nodsh"
13315
13316         reset_async
13317
13318         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13319         set_nodes_failloc "$(osts_nodes)" 0x20e
13320         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13321         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13322         RC=$?
13323
13324         set_nodes_failloc "$(osts_nodes)" 0
13325         if [[ $RC -eq 0 ]]; then
13326                 error "Must return error due to dropped pages, rc=$RC"
13327         fi
13328
13329         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13330         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13331         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13332                     grep -c writeback)
13333         if [[ $LOCKED -ne 0 ]]; then
13334                 error "Locked pages remain in cache, locked=$LOCKED"
13335         fi
13336
13337         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13338                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13339         fi
13340
13341         rm -f $DIR/$tfile
13342         echo "No pages locked after fsync"
13343
13344         return 0
13345 }
13346 run_test 118h "Verify timeout in handling recoverables errors  =========="
13347
13348 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13349
13350 test_118i() {
13351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13352         remote_ost_nodsh && skip "remote OST with nodsh"
13353
13354         reset_async
13355
13356         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13357         set_nodes_failloc "$(osts_nodes)" 0x20e
13358
13359         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13360         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13361         PID=$!
13362         sleep 5
13363         set_nodes_failloc "$(osts_nodes)" 0
13364
13365         wait $PID
13366         RC=$?
13367         if [[ $RC -ne 0 ]]; then
13368                 error "got error, but should be not, rc=$RC"
13369         fi
13370
13371         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13372         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13373         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13374         if [[ $LOCKED -ne 0 ]]; then
13375                 error "Locked pages remain in cache, locked=$LOCKED"
13376         fi
13377
13378         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13379                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13380         fi
13381
13382         rm -f $DIR/$tfile
13383         echo "No pages locked after fsync"
13384
13385         return 0
13386 }
13387 run_test 118i "Fix error before timeout in recoverable error  =========="
13388
13389 [ "$SLOW" = "no" ] && set_resend_count 4
13390
13391 test_118j() {
13392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13393         remote_ost_nodsh && skip "remote OST with nodsh"
13394
13395         reset_async
13396
13397         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13398         set_nodes_failloc "$(osts_nodes)" 0x220
13399
13400         # return -EIO from OST
13401         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13402         RC=$?
13403         set_nodes_failloc "$(osts_nodes)" 0x0
13404         if [[ $RC -eq 0 ]]; then
13405                 error "Must return error due to dropped pages, rc=$RC"
13406         fi
13407
13408         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13409         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13410         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13411         if [[ $LOCKED -ne 0 ]]; then
13412                 error "Locked pages remain in cache, locked=$LOCKED"
13413         fi
13414
13415         # in recoverable error on OST we want resend and stay until it finished
13416         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13417                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13418         fi
13419
13420         rm -f $DIR/$tfile
13421         echo "No pages locked after fsync"
13422
13423         return 0
13424 }
13425 run_test 118j "Simulate unrecoverable OST side error =========="
13426
13427 test_118k()
13428 {
13429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13430         remote_ost_nodsh && skip "remote OSTs with nodsh"
13431
13432         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13433         set_nodes_failloc "$(osts_nodes)" 0x20e
13434         test_mkdir $DIR/$tdir
13435
13436         for ((i=0;i<10;i++)); do
13437                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13438                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13439                 SLEEPPID=$!
13440                 sleep 0.500s
13441                 kill $SLEEPPID
13442                 wait $SLEEPPID
13443         done
13444
13445         set_nodes_failloc "$(osts_nodes)" 0
13446         rm -rf $DIR/$tdir
13447 }
13448 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13449
13450 test_118l() # LU-646
13451 {
13452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13453
13454         test_mkdir $DIR/$tdir
13455         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13456         rm -rf $DIR/$tdir
13457 }
13458 run_test 118l "fsync dir"
13459
13460 test_118m() # LU-3066
13461 {
13462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13463
13464         test_mkdir $DIR/$tdir
13465         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13466         rm -rf $DIR/$tdir
13467 }
13468 run_test 118m "fdatasync dir ========="
13469
13470 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13471
13472 test_118n()
13473 {
13474         local begin
13475         local end
13476
13477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13478         remote_ost_nodsh && skip "remote OSTs with nodsh"
13479
13480         # Sleep to avoid a cached response.
13481         #define OBD_STATFS_CACHE_SECONDS 1
13482         sleep 2
13483
13484         # Inject a 10 second delay in the OST_STATFS handler.
13485         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13486         set_nodes_failloc "$(osts_nodes)" 0x242
13487
13488         begin=$SECONDS
13489         stat --file-system $MOUNT > /dev/null
13490         end=$SECONDS
13491
13492         set_nodes_failloc "$(osts_nodes)" 0
13493
13494         if ((end - begin > 20)); then
13495             error "statfs took $((end - begin)) seconds, expected 10"
13496         fi
13497 }
13498 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13499
13500 test_119a() # bug 11737
13501 {
13502         BSIZE=$((512 * 1024))
13503         directio write $DIR/$tfile 0 1 $BSIZE
13504         # We ask to read two blocks, which is more than a file size.
13505         # directio will indicate an error when requested and actual
13506         # sizes aren't equeal (a normal situation in this case) and
13507         # print actual read amount.
13508         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13509         if [ "$NOB" != "$BSIZE" ]; then
13510                 error "read $NOB bytes instead of $BSIZE"
13511         fi
13512         rm -f $DIR/$tfile
13513 }
13514 run_test 119a "Short directIO read must return actual read amount"
13515
13516 test_119b() # bug 11737
13517 {
13518         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13519
13520         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13521         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13522         sync
13523         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13524                 error "direct read failed"
13525         rm -f $DIR/$tfile
13526 }
13527 run_test 119b "Sparse directIO read must return actual read amount"
13528
13529 test_119c() # bug 13099
13530 {
13531         BSIZE=1048576
13532         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13533         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13534         rm -f $DIR/$tfile
13535 }
13536 run_test 119c "Testing for direct read hitting hole"
13537
13538 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13539 # Maloo test history
13540
13541 test_119e()
13542 {
13543         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13544                 skip "Need server version at least 2.15.58"
13545         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13546
13547         local stripe_size=$((1024 * 1024)) #1 MiB
13548         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13549         local file_size=$((25 * stripe_size))
13550         local bsizes
13551
13552         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13553         stack_trap "rm -f $DIR/$tfile*"
13554
13555         # Just a bit bigger than the largest size in the test set below
13556         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13557                 error "buffered i/o to create file failed"
13558
13559         # trivial test of unaligned DIO
13560         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13561                 iflag=direct oflag=direct ||
13562                 error "trivial unaligned dio failed"
13563
13564         # Clean up before next part of test
13565         rm -f $DIR/$tfile.2
13566
13567         if zfs_or_rotational; then
13568                 # DIO on ZFS can take up to 2 seconds per IO
13569                 # rotational is better, but still slow.
13570                 # Limit testing on those media to larger sizes
13571                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13572                         $((stripe_size + 1024))"
13573         else
13574                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13575                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13576                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13577                         $((stripe_size - 1)) $stripe_size \
13578                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13579                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13580         fi
13581
13582         for bs in $bsizes; do
13583                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13584                 echo "Read/write with DIO at size $bs"
13585                 # Read and write with DIO from source to dest
13586                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13587                         iflag=direct oflag=direct ||
13588                         error "dio failed"
13589
13590                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13591                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13592                         error "size incorrect, file copy read/write bsize: $bs"
13593                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13594                         error "files differ, bsize $bs"
13595                 rm -f $DIR/$tfile.2
13596         done
13597 }
13598 run_test 119e "Basic tests of dio read and write at various sizes"
13599
13600 test_119f()
13601 {
13602         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13603
13604         local stripe_size=$((1024 * 1024)) #1 MiB
13605         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13606         local file_size=$((25 * stripe_size))
13607         local bsizes
13608
13609         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13610         stack_trap "rm -f $DIR/$tfile*"
13611
13612         # Just a bit bigger than the largest size in the test set below
13613         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13614                 error "buffered i/o to create file failed"
13615
13616         if zfs_or_rotational; then
13617                 # DIO on ZFS can take up to 2 seconds per IO
13618                 # rotational is better, but still slow.
13619                 # Limit testing on those media to larger sizes
13620                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13621                         $((stripe_size + 1024))"
13622         else
13623                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13624                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13625                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13626                         $((stripe_size - 1)) $stripe_size \
13627                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13628                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13629         fi
13630
13631         for bs in $bsizes; do
13632                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13633                 # Read and write with DIO from source to dest in two
13634                 # threads - should give correct copy of file
13635
13636                 echo "bs: $bs"
13637                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13638                         oflag=direct conv=notrunc &
13639                 pid_dio1=$!
13640                 # Note block size is different here for a more interesting race
13641                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13642                         iflag=direct oflag=direct conv=notrunc &
13643                 pid_dio2=$!
13644                 wait $pid_dio1
13645                 rc1=$?
13646                 wait $pid_dio2
13647                 rc2=$?
13648                 if (( rc1 != 0 )); then
13649                         error "dio copy 1 w/bsize $bs failed: $rc1"
13650                 fi
13651                 if (( rc2 != 0 )); then
13652                         error "dio copy 2 w/bsize $bs failed: $rc2"
13653                 fi
13654
13655
13656                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13657                         error "size incorrect, file copy read/write bsize: $bs"
13658                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13659                         error "files differ, bsize $bs"
13660                 rm -f $DIR/$tfile.2
13661         done
13662 }
13663 run_test 119f "dio vs dio race"
13664
13665 test_119g()
13666 {
13667         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13668
13669         local stripe_size=$((1024 * 1024)) #1 MiB
13670         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13671         local file_size=$((25 * stripe_size))
13672         local bsizes
13673
13674         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13675         stack_trap "rm -f $DIR/$tfile*"
13676
13677         # Just a bit bigger than the largest size in the test set below
13678         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13679                 error "buffered i/o to create file failed"
13680
13681         if zfs_or_rotational; then
13682                 # DIO on ZFS can take up to 2 seconds per IO
13683                 # rotational is better, but still slow.
13684                 # Limit testing on those media to larger sizes
13685                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13686                         $((stripe_size + 1024))"
13687         else
13688                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13689                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13690                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13691                         $((stripe_size - 1)) $stripe_size \
13692                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13693                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13694         fi
13695
13696         for bs in $bsizes; do
13697                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13698                 echo "bs: $bs"
13699                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13700                         oflag=direct conv=notrunc &
13701                 pid_dio1=$!
13702                 # Buffered I/O with similar but not the same block size
13703                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13704                 pid_bio2=$!
13705                 wait $pid_dio1
13706                 rc1=$?
13707                 wait $pid_bio2
13708                 rc2=$?
13709                 if (( rc1 != 0 )); then
13710                         error "dio copy 1 w/bsize $bs failed: $rc1"
13711                 fi
13712                 if (( rc2 != 0 )); then
13713                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13714                 fi
13715
13716                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13717                         error "size incorrect"
13718                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13719                         error "files differ, bsize $bs"
13720                 rm -f $DIR/$tfile.2
13721         done
13722 }
13723 run_test 119g "dio vs buffered I/O race"
13724
13725 test_119h()
13726 {
13727         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13728
13729         local stripe_size=$((1024 * 1024)) #1 MiB
13730         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13731         local file_size=$((25 * stripe_size))
13732         local bsizes
13733
13734         stack_trap "rm -f $DIR/$tfile.*"
13735
13736         if zfs_or_rotational; then
13737                 # DIO on ZFS can take up to 2 seconds per IO
13738                 # rotational is better, but still slow.
13739                 # Limit testing on those media to larger sizes
13740                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13741                         $((stripe_size + 1024))"
13742         else
13743                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13744                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13745                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13746                         $((stripe_size - 1)) $stripe_size \
13747                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13748                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13749         fi
13750
13751         for bs in $bsizes; do
13752                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13753                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13754                 echo "unaligned writes of blocksize: $bs"
13755                 # Write a file with unaligned DIO and regular DIO, and compare
13756                 # them
13757                 # with 'u', multiop randomly unaligns the io from the buffer
13758                 $MULTIOP $DIR/$tfile.1 \
13759                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13760                         error "multiop memory unaligned write failed, $bs"
13761                 $MULTIOP $DIR/$tfile.2 \
13762                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13763                         error "multiop memory aligned write failed, $bs"
13764
13765                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13766                         error "files differ, bsize $bs"
13767                 rm -f $DIR/$tfile.*
13768         done
13769
13770         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13771         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13772                 error "dd to create source file for read failed"
13773
13774         # Just a few quick tests to make sure unaligned DIO reads don't crash
13775         for bs in $bsizes; do
13776
13777                 echo "unaligned reads of blocksize: $bs"
13778                 # with 'u', multiop randomly unaligns the io from the buffer
13779                 $MULTIOP $DIR/$tfile.1 \
13780                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13781                         error "multiop memory unaligned read failed, $bs"
13782
13783         done
13784         rm -f $DIR/$tfile*
13785 }
13786 run_test 119h "basic tests of memory unaligned dio"
13787
13788 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13789 test_119i()
13790 {
13791         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13792         which aiocp || skip_env "no aiocp installed"
13793
13794         local stripe_size=$((1024 * 1024)) #1 MiB
13795         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13796         local file_size=$((25 * stripe_size))
13797         local bsizes
13798
13799         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13800         stack_trap "rm -f $DIR/$tfile.*"
13801
13802         # Just a bit bigger than the largest size in the test set below
13803         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13804                 error "buffered i/o to create file failed"
13805
13806         if zfs_or_rotational; then
13807                 # DIO on ZFS can take up to 2 seconds per IO
13808                 # rotational is better, but still slow.
13809                 # Limit testing on those media to larger sizes
13810                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13811                         $((stripe_size + 1024))"
13812         else
13813                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13814                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13815                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13816                         $((stripe_size - 1)) $stripe_size \
13817                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13818                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13819         fi
13820
13821         # Do page aligned and NOT page aligned AIO
13822         for align in 8 512 $((PAGE_SIZE)); do
13823         # Deliberately includes a few aligned sizes
13824         for bs in $bsizes; do
13825                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13826
13827                 echo "bs: $bs, align: $align, file_size $file_size"
13828                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13829                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13830                         error "unaligned aio failed, bs: $bs, align: $align"
13831
13832                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13833                         error "size incorrect"
13834                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13835                         error "files differ"
13836                 rm -f $DIR/$tfile.2
13837         done
13838         done
13839 }
13840 run_test 119i "test unaligned aio at varying sizes"
13841
13842 test_120a() {
13843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13844         remote_mds_nodsh && skip "remote MDS with nodsh"
13845         test_mkdir -i0 -c1 $DIR/$tdir
13846         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13847                 skip_env "no early lock cancel on server"
13848
13849         lru_resize_disable mdc
13850         lru_resize_disable osc
13851         cancel_lru_locks mdc
13852         # asynchronous object destroy at MDT could cause bl ast to client
13853         cancel_lru_locks osc
13854
13855         stat $DIR/$tdir > /dev/null
13856         can1=$(do_facet mds1 \
13857                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13858                awk '/ldlm_cancel/ {print $2}')
13859         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13860                awk '/ldlm_bl_callback/ {print $2}')
13861         test_mkdir -i0 -c1 $DIR/$tdir/d1
13862         can2=$(do_facet mds1 \
13863                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13864                awk '/ldlm_cancel/ {print $2}')
13865         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13866                awk '/ldlm_bl_callback/ {print $2}')
13867         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13868         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13869         lru_resize_enable mdc
13870         lru_resize_enable osc
13871 }
13872 run_test 120a "Early Lock Cancel: mkdir test"
13873
13874 test_120b() {
13875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13876         remote_mds_nodsh && skip "remote MDS with nodsh"
13877         test_mkdir $DIR/$tdir
13878         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13879                 skip_env "no early lock cancel on server"
13880
13881         lru_resize_disable mdc
13882         lru_resize_disable osc
13883         cancel_lru_locks mdc
13884         stat $DIR/$tdir > /dev/null
13885         can1=$(do_facet $SINGLEMDS \
13886                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13887                awk '/ldlm_cancel/ {print $2}')
13888         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13889                awk '/ldlm_bl_callback/ {print $2}')
13890         touch $DIR/$tdir/f1
13891         can2=$(do_facet $SINGLEMDS \
13892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13893                awk '/ldlm_cancel/ {print $2}')
13894         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13895                awk '/ldlm_bl_callback/ {print $2}')
13896         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13897         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13898         lru_resize_enable mdc
13899         lru_resize_enable osc
13900 }
13901 run_test 120b "Early Lock Cancel: create test"
13902
13903 test_120c() {
13904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13905         remote_mds_nodsh && skip "remote MDS with nodsh"
13906         test_mkdir -i0 -c1 $DIR/$tdir
13907         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13908                 skip "no early lock cancel on server"
13909
13910         lru_resize_disable mdc
13911         lru_resize_disable osc
13912         test_mkdir -i0 -c1 $DIR/$tdir/d1
13913         test_mkdir -i0 -c1 $DIR/$tdir/d2
13914         touch $DIR/$tdir/d1/f1
13915         cancel_lru_locks mdc
13916         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13917         can1=$(do_facet mds1 \
13918                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13919                awk '/ldlm_cancel/ {print $2}')
13920         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13921                awk '/ldlm_bl_callback/ {print $2}')
13922         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13923         can2=$(do_facet mds1 \
13924                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13925                awk '/ldlm_cancel/ {print $2}')
13926         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13927                awk '/ldlm_bl_callback/ {print $2}')
13928         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13929         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13930         lru_resize_enable mdc
13931         lru_resize_enable osc
13932 }
13933 run_test 120c "Early Lock Cancel: link test"
13934
13935 test_120d() {
13936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13937         remote_mds_nodsh && skip "remote MDS with nodsh"
13938         test_mkdir -i0 -c1 $DIR/$tdir
13939         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13940                 skip_env "no early lock cancel on server"
13941
13942         lru_resize_disable mdc
13943         lru_resize_disable osc
13944         touch $DIR/$tdir
13945         cancel_lru_locks mdc
13946         stat $DIR/$tdir > /dev/null
13947         can1=$(do_facet mds1 \
13948                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13949                awk '/ldlm_cancel/ {print $2}')
13950         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13951                awk '/ldlm_bl_callback/ {print $2}')
13952         chmod a+x $DIR/$tdir
13953         can2=$(do_facet mds1 \
13954                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13955                awk '/ldlm_cancel/ {print $2}')
13956         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13957                awk '/ldlm_bl_callback/ {print $2}')
13958         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13959         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13960         lru_resize_enable mdc
13961         lru_resize_enable osc
13962 }
13963 run_test 120d "Early Lock Cancel: setattr test"
13964
13965 test_120e() {
13966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13967         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13968                 skip_env "no early lock cancel on server"
13969         remote_mds_nodsh && skip "remote MDS with nodsh"
13970
13971         local dlmtrace_set=false
13972
13973         test_mkdir -i0 -c1 $DIR/$tdir
13974         lru_resize_disable mdc
13975         lru_resize_disable osc
13976         ! $LCTL get_param debug | grep -q dlmtrace &&
13977                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13978         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13979         cancel_lru_locks mdc
13980         cancel_lru_locks osc
13981         dd if=$DIR/$tdir/f1 of=/dev/null
13982         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13983         # XXX client can not do early lock cancel of OST lock
13984         # during unlink (LU-4206), so cancel osc lock now.
13985         sleep 2
13986         cancel_lru_locks osc
13987         can1=$(do_facet mds1 \
13988                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13989                awk '/ldlm_cancel/ {print $2}')
13990         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13991                awk '/ldlm_bl_callback/ {print $2}')
13992         unlink $DIR/$tdir/f1
13993         sleep 5
13994         can2=$(do_facet mds1 \
13995                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13996                awk '/ldlm_cancel/ {print $2}')
13997         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13998                awk '/ldlm_bl_callback/ {print $2}')
13999         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14000                 $LCTL dk $TMP/cancel.debug.txt
14001         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14002                 $LCTL dk $TMP/blocking.debug.txt
14003         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14004         lru_resize_enable mdc
14005         lru_resize_enable osc
14006 }
14007 run_test 120e "Early Lock Cancel: unlink test"
14008
14009 test_120f() {
14010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14011         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14012                 skip_env "no early lock cancel on server"
14013         remote_mds_nodsh && skip "remote MDS with nodsh"
14014
14015         test_mkdir -i0 -c1 $DIR/$tdir
14016         lru_resize_disable mdc
14017         lru_resize_disable osc
14018         test_mkdir -i0 -c1 $DIR/$tdir/d1
14019         test_mkdir -i0 -c1 $DIR/$tdir/d2
14020         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14021         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14022         cancel_lru_locks mdc
14023         cancel_lru_locks osc
14024         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14025         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14026         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14027         # XXX client can not do early lock cancel of OST lock
14028         # during rename (LU-4206), so cancel osc lock now.
14029         sleep 2
14030         cancel_lru_locks osc
14031         can1=$(do_facet mds1 \
14032                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14033                awk '/ldlm_cancel/ {print $2}')
14034         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14035                awk '/ldlm_bl_callback/ {print $2}')
14036         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14037         sleep 5
14038         can2=$(do_facet mds1 \
14039                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14040                awk '/ldlm_cancel/ {print $2}')
14041         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14042                awk '/ldlm_bl_callback/ {print $2}')
14043         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14044         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14045         lru_resize_enable mdc
14046         lru_resize_enable osc
14047 }
14048 run_test 120f "Early Lock Cancel: rename test"
14049
14050 test_120g() {
14051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14052         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14053                 skip_env "no early lock cancel on server"
14054         remote_mds_nodsh && skip "remote MDS with nodsh"
14055
14056         lru_resize_disable mdc
14057         lru_resize_disable osc
14058         count=10000
14059         echo create $count files
14060         test_mkdir $DIR/$tdir
14061         cancel_lru_locks mdc
14062         cancel_lru_locks osc
14063         t0=$(date +%s)
14064
14065         can0=$(do_facet $SINGLEMDS \
14066                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14067                awk '/ldlm_cancel/ {print $2}')
14068         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14069                awk '/ldlm_bl_callback/ {print $2}')
14070         createmany -o $DIR/$tdir/f $count
14071         sync
14072         can1=$(do_facet $SINGLEMDS \
14073                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14074                awk '/ldlm_cancel/ {print $2}')
14075         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14076                awk '/ldlm_bl_callback/ {print $2}')
14077         t1=$(date +%s)
14078         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14079         echo rm $count files
14080         rm -r $DIR/$tdir
14081         sync
14082         can2=$(do_facet $SINGLEMDS \
14083                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14084                awk '/ldlm_cancel/ {print $2}')
14085         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14086                awk '/ldlm_bl_callback/ {print $2}')
14087         t2=$(date +%s)
14088         echo total: $count removes in $((t2-t1))
14089         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14090         sleep 2
14091         # wait for commitment of removal
14092         lru_resize_enable mdc
14093         lru_resize_enable osc
14094 }
14095 run_test 120g "Early Lock Cancel: performance test"
14096
14097 test_121() { #bug #10589
14098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14099
14100         rm -rf $DIR/$tfile
14101         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14102 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14103         lctl set_param fail_loc=0x310
14104         cancel_lru_locks osc > /dev/null
14105         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14106         lctl set_param fail_loc=0
14107         [[ $reads -eq $writes ]] ||
14108                 error "read $reads blocks, must be $writes blocks"
14109 }
14110 run_test 121 "read cancel race ========="
14111
14112 test_123a_base() { # was test 123, statahead(bug 11401)
14113         local lsx="$1"
14114
14115         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14116
14117         SLOWOK=0
14118         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14119                 log "testing UP system. Performance may be lower than expected."
14120                 SLOWOK=1
14121         fi
14122         running_in_vm && SLOWOK=1
14123
14124         $LCTL set_param mdc.*.batch_stats=0
14125
14126         rm -rf $DIR/$tdir
14127         test_mkdir $DIR/$tdir
14128         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14129         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14130         MULT=10
14131         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14132                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14133
14134                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14135                 lctl set_param -n llite.*.statahead_max 0
14136                 lctl get_param llite.*.statahead_max
14137                 cancel_lru_locks mdc
14138                 cancel_lru_locks osc
14139                 stime=$(date +%s)
14140                 time $lsx $DIR/$tdir | wc -l
14141                 etime=$(date +%s)
14142                 delta=$((etime - stime))
14143                 log "$lsx $i files without statahead: $delta sec"
14144                 lctl set_param llite.*.statahead_max=$max
14145
14146                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14147                          awk '/statahead.wrong:/ { print $NF }')
14148                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14149                 cancel_lru_locks mdc
14150                 cancel_lru_locks osc
14151                 stime=$(date +%s)
14152                 time $lsx $DIR/$tdir | wc -l
14153                 etime=$(date +%s)
14154                 delta_sa=$((etime - stime))
14155                 log "$lsx $i files with statahead: $delta_sa sec"
14156                 lctl get_param -n llite.*.statahead_stats
14157                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14158                          awk '/statahead.wrong:/ { print $NF }')
14159
14160                 [[ $swrong -lt $ewrong ]] &&
14161                         log "statahead was stopped, maybe too many locks held!"
14162                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14163
14164                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14165                         max=$(lctl get_param -n llite.*.statahead_max |
14166                                 head -n 1)
14167                         lctl set_param -n llite.*.statahead_max 0
14168                         lctl get_param llite.*.statahead_max
14169                         cancel_lru_locks mdc
14170                         cancel_lru_locks osc
14171                         stime=$(date +%s)
14172                         time $lsx $DIR/$tdir | wc -l
14173                         etime=$(date +%s)
14174                         delta=$((etime - stime))
14175                         log "$lsx $i files again without statahead: $delta sec"
14176                         lctl set_param llite.*.statahead_max=$max
14177                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14178                                 if [ $SLOWOK -eq 0 ]; then
14179                                         error "$lsx $i files is slower with statahead!"
14180                                 else
14181                                         log "$lsx $i files is slower with statahead!"
14182                                 fi
14183                                 break
14184                         fi
14185                 fi
14186
14187                 [ $delta -gt 20 ] && break
14188                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14189                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14190         done
14191         log "$lsx done"
14192
14193         stime=$(date +%s)
14194         rm -r $DIR/$tdir
14195         sync
14196         etime=$(date +%s)
14197         delta=$((etime - stime))
14198         log "rm -r $DIR/$tdir/: $delta seconds"
14199         log "rm done"
14200         lctl get_param -n llite.*.statahead_stats
14201         $LCTL get_param mdc.*.batch_stats
14202 }
14203
14204 test_123aa() {
14205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14206
14207         test_123a_base "ls -l"
14208 }
14209 run_test 123aa "verify statahead work"
14210
14211 test_123ab() {
14212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14213
14214         statx_supported || skip_env "Test must be statx() syscall supported"
14215
14216         test_123a_base "$STATX -l"
14217 }
14218 run_test 123ab "verify statahead work by using statx"
14219
14220 test_123ac() {
14221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14222
14223         statx_supported || skip_env "Test must be statx() syscall supported"
14224
14225         local rpcs_before
14226         local rpcs_after
14227         local agl_before
14228         local agl_after
14229
14230         cancel_lru_locks $OSC
14231         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14232         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14233                      awk '/agl.total:/ { print $NF }')
14234         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14235         test_123a_base "$STATX --cached=always -D"
14236         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14237                     awk '/agl.total:/ { print $NF }')
14238         [ $agl_before -eq $agl_after ] ||
14239                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14240         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14241         [ $rpcs_after -eq $rpcs_before ] ||
14242                 error "$STATX should not send glimpse RPCs to $OSC"
14243 }
14244 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14245
14246 test_batch_statahead() {
14247         local max=$1
14248         local batch_max=$2
14249         local num=10000
14250         local batch_rpcs
14251         local unbatch_rpcs
14252         local hit_total
14253
14254         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14255         $LCTL set_param mdc.*.batch_stats=0
14256         $LCTL set_param llite.*.statahead_max=$max
14257         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14258         # Verify that batched statahead is faster than one without statahead
14259         test_123a_base "ls -l"
14260
14261         stack_trap "rm -rf $DIR/$tdir" EXIT
14262         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14263         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14264
14265         # unbatched statahead
14266         $LCTL set_param llite.*.statahead_batch_max=0
14267         $LCTL set_param llite.*.statahead_stats=clear
14268         $LCTL set_param mdc.*.stats=clear
14269         cancel_lru_locks mdc
14270         cancel_lru_locks osc
14271         time ls -l $DIR/$tdir | wc -l
14272         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14273         sleep 2
14274         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14275                     awk '/hit.total:/ { print $NF }')
14276         # hit ratio should be larger than 75% (7500).
14277         (( $hit_total > 7500 )) ||
14278                 error "unbatched statahead hit count ($hit_total) is too low"
14279
14280         # batched statahead
14281         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14282         $LCTL set_param llite.*.statahead_stats=clear
14283         $LCTL set_param mdc.*.batch_stats=clear
14284         $LCTL set_param mdc.*.stats=clear
14285         cancel_lru_locks mdc
14286         cancel_lru_locks osc
14287         time ls -l $DIR/$tdir | wc -l
14288         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14289         # wait for statahead thread to quit and update statahead stats
14290         sleep 2
14291         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14292                     awk '/hit.total:/ { print $NF }')
14293         # hit ratio should be larger than 75% (7500).
14294         (( $hit_total > 7500 )) ||
14295                 error "batched statahead hit count ($hit_total) is too low"
14296
14297         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14298         (( $unbatch_rpcs > $batch_rpcs )) ||
14299                 error "batched statahead does not reduce RPC count"
14300         $LCTL get_param mdc.*.batch_stats
14301 }
14302
14303 test_123ad() {
14304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14305
14306         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14307                 skip "Need server version at least 2.15.53"
14308
14309         local max
14310         local batch_max
14311
14312         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14313         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14314
14315         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14316         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14317
14318         test_batch_statahead 32 32
14319         test_batch_statahead 2048 256
14320 }
14321 run_test 123ad "Verify batching statahead works correctly"
14322
14323 test_123b () { # statahead(bug 15027)
14324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14325
14326         test_mkdir $DIR/$tdir
14327         createmany -o $DIR/$tdir/$tfile-%d 1000
14328
14329         cancel_lru_locks mdc
14330         cancel_lru_locks osc
14331
14332 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14333         lctl set_param fail_loc=0x80000803
14334         ls -lR $DIR/$tdir > /dev/null
14335         log "ls done"
14336         lctl set_param fail_loc=0x0
14337         lctl get_param -n llite.*.statahead_stats
14338         rm -r $DIR/$tdir
14339         sync
14340
14341 }
14342 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14343
14344 test_123c() {
14345         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14346
14347         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14348         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14349         touch $DIR/$tdir.1/{1..3}
14350         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14351
14352         remount_client $MOUNT
14353
14354         $MULTIOP $DIR/$tdir.0 Q
14355
14356         # let statahead to complete
14357         ls -l $DIR/$tdir.0 > /dev/null
14358
14359         testid=$(echo $TESTNAME | tr '_' ' ')
14360         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14361                 error "statahead warning" || true
14362 }
14363 run_test 123c "Can not initialize inode warning on DNE statahead"
14364
14365 test_123d() {
14366         local num=100
14367         local swrong
14368         local ewrong
14369
14370         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14371         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14372                 error "setdirstripe $DIR/$tdir failed"
14373         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14374         remount_client $MOUNT
14375         $LCTL get_param llite.*.statahead_max
14376         $LCTL set_param llite.*.statahead_stats=0 ||
14377                 error "clear statahead_stats failed"
14378         swrong=$(lctl get_param -n llite.*.statahead_stats |
14379                  awk '/statahead.wrong:/ { print $NF }')
14380         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14381         # wait for statahead thread finished to update hit/miss stats.
14382         sleep 1
14383         $LCTL get_param -n llite.*.statahead_stats
14384         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14385                  awk '/statahead.wrong:/ { print $NF }')
14386         (( $swrong == $ewrong )) ||
14387                 log "statahead was stopped, maybe too many locks held!"
14388 }
14389 run_test 123d "Statahead on striped directories works correctly"
14390
14391 test_123e() {
14392         local max
14393         local batch_max
14394         local dir=$DIR/$tdir
14395
14396         mkdir $dir || error "mkdir $dir failed"
14397         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14398         stack_trap "rm -rf $dir"
14399
14400         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14401
14402         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14403         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14404         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14405         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14406
14407         $LCTL set_param llite.*.statahead_max=2048
14408         $LCTL set_param llite.*.statahead_batch_max=1024
14409
14410         ls -l $dir
14411         $LCTL get_param mdc.*.batch_stats
14412         $LCTL get_param llite.*.statahead_*
14413 }
14414 run_test 123e "statahead with large wide striping"
14415
14416 test_123f() {
14417         local max
14418         local batch_max
14419         local dir=$DIR/$tdir
14420
14421         mkdir $dir || error "mkdir $dir failed"
14422         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14423         stack_trap "rm -rf $dir"
14424
14425         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14426
14427         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14428         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14429
14430         $LCTL set_param llite.*.statahead_max=64
14431         $LCTL set_param llite.*.statahead_batch_max=64
14432
14433         ls -l $dir
14434         lctl get_param mdc.*.batch_stats
14435         lctl get_param llite.*.statahead_*
14436
14437         $LCTL set_param llite.*.statahead_max=$max
14438         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14439 }
14440 run_test 123f "Retry mechanism with large wide striping files"
14441
14442 test_124a() {
14443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14444         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14445                 skip_env "no lru resize on server"
14446
14447         local NR=2000
14448
14449         test_mkdir $DIR/$tdir
14450
14451         log "create $NR files at $DIR/$tdir"
14452         createmany -o $DIR/$tdir/f $NR ||
14453                 error "failed to create $NR files in $DIR/$tdir"
14454
14455         cancel_lru_locks mdc
14456         ls -l $DIR/$tdir > /dev/null
14457
14458         local NSDIR=""
14459         local LRU_SIZE=0
14460         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14461                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14462                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14463                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14464                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14465                         log "NSDIR=$NSDIR"
14466                         log "NS=$(basename $NSDIR)"
14467                         break
14468                 fi
14469         done
14470
14471         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14472                 skip "Not enough cached locks created!"
14473         fi
14474         log "LRU=$LRU_SIZE"
14475
14476         local SLEEP=30
14477
14478         # We know that lru resize allows one client to hold $LIMIT locks
14479         # for 10h. After that locks begin to be killed by client.
14480         local MAX_HRS=10
14481         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14482         log "LIMIT=$LIMIT"
14483         if [ $LIMIT -lt $LRU_SIZE ]; then
14484                 skip "Limit is too small $LIMIT"
14485         fi
14486
14487         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14488         # killing locks. Some time was spent for creating locks. This means
14489         # that up to the moment of sleep finish we must have killed some of
14490         # them (10-100 locks). This depends on how fast ther were created.
14491         # Many of them were touched in almost the same moment and thus will
14492         # be killed in groups.
14493         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14494
14495         # Use $LRU_SIZE_B here to take into account real number of locks
14496         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14497         local LRU_SIZE_B=$LRU_SIZE
14498         log "LVF=$LVF"
14499         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14500         log "OLD_LVF=$OLD_LVF"
14501         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14502
14503         # Let's make sure that we really have some margin. Client checks
14504         # cached locks every 10 sec.
14505         SLEEP=$((SLEEP+20))
14506         log "Sleep ${SLEEP} sec"
14507         local SEC=0
14508         while ((SEC<$SLEEP)); do
14509                 echo -n "..."
14510                 sleep 5
14511                 SEC=$((SEC+5))
14512                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14513                 echo -n "$LRU_SIZE"
14514         done
14515         echo ""
14516         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14517         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14518
14519         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14520                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14521                 unlinkmany $DIR/$tdir/f $NR
14522                 return
14523         }
14524
14525         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14526         log "unlink $NR files at $DIR/$tdir"
14527         unlinkmany $DIR/$tdir/f $NR
14528 }
14529 run_test 124a "lru resize ======================================="
14530
14531 get_max_pool_limit()
14532 {
14533         local limit=$($LCTL get_param \
14534                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14535         local max=0
14536         for l in $limit; do
14537                 if [[ $l -gt $max ]]; then
14538                         max=$l
14539                 fi
14540         done
14541         echo $max
14542 }
14543
14544 test_124b() {
14545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14546         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14547                 skip_env "no lru resize on server"
14548
14549         LIMIT=$(get_max_pool_limit)
14550
14551         NR=$(($(default_lru_size)*20))
14552         if [[ $NR -gt $LIMIT ]]; then
14553                 log "Limit lock number by $LIMIT locks"
14554                 NR=$LIMIT
14555         fi
14556
14557         IFree=$(mdsrate_inodes_available)
14558         if [ $IFree -lt $NR ]; then
14559                 log "Limit lock number by $IFree inodes"
14560                 NR=$IFree
14561         fi
14562
14563         lru_resize_disable mdc
14564         test_mkdir -p $DIR/$tdir/disable_lru_resize
14565
14566         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14567         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14568         cancel_lru_locks mdc
14569         stime=`date +%s`
14570         PID=""
14571         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14572         PID="$PID $!"
14573         sleep 2
14574         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14575         PID="$PID $!"
14576         sleep 2
14577         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14578         PID="$PID $!"
14579         wait $PID
14580         etime=`date +%s`
14581         nolruresize_delta=$((etime-stime))
14582         log "ls -la time: $nolruresize_delta seconds"
14583         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14584         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14585
14586         lru_resize_enable mdc
14587         test_mkdir -p $DIR/$tdir/enable_lru_resize
14588
14589         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14590         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14591         cancel_lru_locks mdc
14592         stime=`date +%s`
14593         PID=""
14594         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14595         PID="$PID $!"
14596         sleep 2
14597         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14598         PID="$PID $!"
14599         sleep 2
14600         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14601         PID="$PID $!"
14602         wait $PID
14603         etime=`date +%s`
14604         lruresize_delta=$((etime-stime))
14605         log "ls -la time: $lruresize_delta seconds"
14606         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14607
14608         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14609                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14610         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14611                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14612         else
14613                 log "lru resize performs the same with no lru resize"
14614         fi
14615         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14616 }
14617 run_test 124b "lru resize (performance test) ======================="
14618
14619 test_124c() {
14620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14621         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14622                 skip_env "no lru resize on server"
14623
14624         # cache ununsed locks on client
14625         local nr=100
14626         cancel_lru_locks mdc
14627         test_mkdir $DIR/$tdir
14628         createmany -o $DIR/$tdir/f $nr ||
14629                 error "failed to create $nr files in $DIR/$tdir"
14630         ls -l $DIR/$tdir > /dev/null
14631
14632         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14633         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14634         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14635         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14636         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14637
14638         # set lru_max_age to 1 sec
14639         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14640         echo "sleep $((recalc_p * 2)) seconds..."
14641         sleep $((recalc_p * 2))
14642
14643         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14644         # restore lru_max_age
14645         $LCTL set_param -n $nsdir.lru_max_age $max_age
14646         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14647         unlinkmany $DIR/$tdir/f $nr
14648 }
14649 run_test 124c "LRUR cancel very aged locks"
14650
14651 test_124d() {
14652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14653         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14654                 skip_env "no lru resize on server"
14655
14656         # cache ununsed locks on client
14657         local nr=100
14658
14659         lru_resize_disable mdc
14660         stack_trap "lru_resize_enable mdc" EXIT
14661
14662         cancel_lru_locks mdc
14663
14664         # asynchronous object destroy at MDT could cause bl ast to client
14665         test_mkdir $DIR/$tdir
14666         createmany -o $DIR/$tdir/f $nr ||
14667                 error "failed to create $nr files in $DIR/$tdir"
14668         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14669
14670         ls -l $DIR/$tdir > /dev/null
14671
14672         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14673         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14674         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14675         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14676
14677         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14678
14679         # set lru_max_age to 1 sec
14680         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14681         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14682
14683         echo "sleep $((recalc_p * 2)) seconds..."
14684         sleep $((recalc_p * 2))
14685
14686         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14687
14688         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14689 }
14690 run_test 124d "cancel very aged locks if lru-resize disabled"
14691
14692 test_125() { # 13358
14693         $LCTL get_param -n llite.*.client_type | grep -q local ||
14694                 skip "must run as local client"
14695         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14696                 skip_env "must have acl enabled"
14697         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14698         id $USER0 || skip_env "missing user $USER0"
14699
14700         test_mkdir $DIR/$tdir
14701         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14702         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14703                 error "setfacl $DIR/$tdir failed"
14704         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14705 }
14706 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14707
14708 test_126() { # bug 12829/13455
14709         $GSS && skip_env "must run as gss disabled"
14710         $LCTL get_param -n llite.*.client_type | grep -q local ||
14711                 skip "must run as local client"
14712         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14713
14714         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14715         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14716         rm -f $DIR/$tfile
14717         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14718 }
14719 run_test 126 "check that the fsgid provided by the client is taken into account"
14720
14721 test_127a() { # bug 15521
14722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14723         local name count samp unit min max sum sumsq
14724         local tmpfile=$TMP/$tfile.tmp
14725
14726         # enable stats header if it is disabled
14727         $LCTL set_param enable_stats_header=1
14728
14729         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14730         echo "stats before reset"
14731         stack_trap "rm -f $tmpfile"
14732         local now=$(date +%s)
14733
14734         $LCTL get_param osc.*.stats | tee $tmpfile
14735
14736         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14737         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14738         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14739         local uptime=$(awk '{ print $1 }' /proc/uptime)
14740
14741         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14742         (( ${snapshot_time%\.*} >= $now - 5 &&
14743            ${snapshot_time%\.*} <= $now + 5 )) ||
14744                 error "snapshot_time=$snapshot_time != now=$now"
14745         # elapsed _should_ be from mount, but at least less than uptime
14746         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14747                 error "elapsed=$elapsed > uptime=$uptime"
14748         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14749            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14750                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14751
14752         $LCTL set_param osc.*.stats=0
14753         local reset=$(date +%s)
14754         local fsize=$((2048 * 1024))
14755
14756         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14757         cancel_lru_locks osc
14758         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14759
14760         now=$(date +%s)
14761         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14762         while read name count samp unit min max sum sumsq; do
14763                 [[ "$samp" == "samples" ]] || continue
14764
14765                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14766                 [ ! $min ] && error "Missing min value for $name proc entry"
14767                 eval $name=$count || error "Wrong proc format"
14768
14769                 case $name in
14770                 read_bytes|write_bytes)
14771                         [[ "$unit" =~ "bytes" ]] ||
14772                                 error "unit is not 'bytes': $unit"
14773                         (( $min >= 4096 )) || error "min is too small: $min"
14774                         (( $min <= $fsize )) || error "min is too big: $min"
14775                         (( $max >= 4096 )) || error "max is too small: $max"
14776                         (( $max <= $fsize )) || error "max is too big: $max"
14777                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14778                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14779                                 error "sumsquare is too small: $sumsq"
14780                         (( $sumsq <= $fsize * $fsize )) ||
14781                                 error "sumsquare is too big: $sumsq"
14782                         ;;
14783                 ost_read|ost_write)
14784                         [[ "$unit" =~ "usec" ]] ||
14785                                 error "unit is not 'usec': $unit"
14786                         ;;
14787                 *)      ;;
14788                 esac
14789         done < $tmpfile
14790
14791         #check that we actually got some stats
14792         [ "$read_bytes" ] || error "Missing read_bytes stats"
14793         [ "$write_bytes" ] || error "Missing write_bytes stats"
14794         [ "$read_bytes" != 0 ] || error "no read done"
14795         [ "$write_bytes" != 0 ] || error "no write done"
14796
14797         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14798         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14799         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14800
14801         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14802         (( ${snapshot_time%\.*} >= $now - 5 &&
14803            ${snapshot_time%\.*} <= $now + 5 )) ||
14804                 error "reset snapshot_time=$snapshot_time != now=$now"
14805         # elapsed should be from time of stats reset
14806         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14807            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14808                 error "reset elapsed=$elapsed > $now - $reset"
14809         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14810            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14811                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14812 }
14813 run_test 127a "verify the client stats are sane"
14814
14815 test_127b() { # bug LU-333
14816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14817         local name count samp unit min max sum sumsq
14818
14819         echo "stats before reset"
14820         $LCTL get_param llite.*.stats
14821         $LCTL set_param llite.*.stats=0
14822
14823         # perform 2 reads and writes so MAX is different from SUM.
14824         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14825         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14826         cancel_lru_locks osc
14827         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14828         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14829
14830         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14831         stack_trap "rm -f $TMP/$tfile.tmp"
14832         while read name count samp unit min max sum sumsq; do
14833                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14834                 eval $name=$count || error "Wrong proc format"
14835
14836                 case $name in
14837                 read_bytes|write_bytes)
14838                         [[ "$unit" =~ "bytes" ]] ||
14839                                 error "unit is not 'bytes': $unit"
14840                         (( $count == 2 )) || error "count is not 2: $count"
14841                         (( $min == $PAGE_SIZE )) ||
14842                                 error "min is not $PAGE_SIZE: $min"
14843                         (( $max == $PAGE_SIZE )) ||
14844                                 error "max is not $PAGE_SIZE: $max"
14845                         (( $sum == $PAGE_SIZE * 2 )) ||
14846                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14847                         ;;
14848                 read|write)
14849                         [[ "$unit" =~ "usec" ]] ||
14850                                 error "unit is not 'usec': $unit"
14851                         ;;
14852                 *)      ;;
14853                 esac
14854         done < $TMP/$tfile.tmp
14855
14856         #check that we actually got some stats
14857         [ "$read_bytes" ] || error "Missing read_bytes stats"
14858         [ "$write_bytes" ] || error "Missing write_bytes stats"
14859         [ "$read_bytes" != 0 ] || error "no read done"
14860         [ "$write_bytes" != 0 ] || error "no write done"
14861 }
14862 run_test 127b "verify the llite client stats are sane"
14863
14864 test_127c() { # LU-12394
14865         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14866         local size
14867         local bsize
14868         local reads
14869         local writes
14870         local count
14871
14872         $LCTL set_param llite.*.extents_stats=1
14873         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14874
14875         # Use two stripes so there is enough space in default config
14876         $LFS setstripe -c 2 $DIR/$tfile
14877
14878         # Extent stats start at 0-4K and go in power of two buckets
14879         # LL_HIST_START = 12 --> 2^12 = 4K
14880         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14881         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14882         # small configs
14883         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14884                 do
14885                 # Write and read, 2x each, second time at a non-zero offset
14886                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14887                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14888                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14889                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14890                 rm -f $DIR/$tfile
14891         done
14892
14893         $LCTL get_param llite.*.extents_stats
14894
14895         count=2
14896         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14897                 do
14898                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14899                                 grep -m 1 $bsize)
14900                 reads=$(echo $bucket | awk '{print $5}')
14901                 writes=$(echo $bucket | awk '{print $9}')
14902                 [ "$reads" -eq $count ] ||
14903                         error "$reads reads in < $bsize bucket, expect $count"
14904                 [ "$writes" -eq $count ] ||
14905                         error "$writes writes in < $bsize bucket, expect $count"
14906         done
14907
14908         # Test mmap write and read
14909         $LCTL set_param llite.*.extents_stats=c
14910         size=512
14911         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14912         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14913         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14914
14915         $LCTL get_param llite.*.extents_stats
14916
14917         count=$(((size*1024) / PAGE_SIZE))
14918
14919         bsize=$((2 * PAGE_SIZE / 1024))K
14920
14921         bucket=$($LCTL get_param -n llite.*.extents_stats |
14922                         grep -m 1 $bsize)
14923         reads=$(echo $bucket | awk '{print $5}')
14924         writes=$(echo $bucket | awk '{print $9}')
14925         # mmap writes fault in the page first, creating an additonal read
14926         [ "$reads" -eq $((2 * count)) ] ||
14927                 error "$reads reads in < $bsize bucket, expect $count"
14928         [ "$writes" -eq $count ] ||
14929                 error "$writes writes in < $bsize bucket, expect $count"
14930 }
14931 run_test 127c "test llite extent stats with regular & mmap i/o"
14932
14933 test_128() { # bug 15212
14934         touch $DIR/$tfile
14935         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14936                 find $DIR/$tfile
14937                 find $DIR/$tfile
14938         EOF
14939
14940         result=$(grep error $TMP/$tfile.log)
14941         rm -f $DIR/$tfile $TMP/$tfile.log
14942         [ -z "$result" ] ||
14943                 error "consecutive find's under interactive lfs failed"
14944 }
14945 run_test 128 "interactive lfs for 2 consecutive find's"
14946
14947 set_dir_limits () {
14948         local mntdev
14949         local canondev
14950         local node
14951
14952         local ldproc=/proc/fs/ldiskfs
14953         local facets=$(get_facets MDS)
14954
14955         for facet in ${facets//,/ }; do
14956                 canondev=$(ldiskfs_canon \
14957                            *.$(convert_facet2label $facet).mntdev $facet)
14958                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14959                         ldproc=/sys/fs/ldiskfs
14960                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14961                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14962         done
14963 }
14964
14965 check_mds_dmesg() {
14966         local facets=$(get_facets MDS)
14967         for facet in ${facets//,/ }; do
14968                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14969         done
14970         return 1
14971 }
14972
14973 test_129() {
14974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14975         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14976                 skip "Need MDS version with at least 2.5.56"
14977         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14978                 skip_env "ldiskfs only test"
14979         fi
14980         remote_mds_nodsh && skip "remote MDS with nodsh"
14981
14982         local ENOSPC=28
14983         local has_warning=false
14984
14985         rm -rf $DIR/$tdir
14986         mkdir -p $DIR/$tdir
14987
14988         # block size of mds1
14989         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14990         set_dir_limits $maxsize $((maxsize * 6 / 8))
14991         stack_trap "set_dir_limits 0 0"
14992         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14993         local dirsize=$(stat -c%s "$DIR/$tdir")
14994         local nfiles=0
14995         while (( $dirsize <= $maxsize )); do
14996                 $MCREATE $DIR/$tdir/file_base_$nfiles
14997                 rc=$?
14998                 # check two errors:
14999                 # ENOSPC for ext4 max_dir_size, which has been used since
15000                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15001                 if (( rc == ENOSPC )); then
15002                         set_dir_limits 0 0
15003                         echo "rc=$rc returned as expected after $nfiles files"
15004
15005                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15006                                 error "create failed w/o dir size limit"
15007
15008                         # messages may be rate limited if test is run repeatedly
15009                         check_mds_dmesg '"is approaching max"' ||
15010                                 echo "warning message should be output"
15011                         check_mds_dmesg '"has reached max"' ||
15012                                 echo "reached message should be output"
15013
15014                         dirsize=$(stat -c%s "$DIR/$tdir")
15015
15016                         [[ $dirsize -ge $maxsize ]] && return 0
15017                         error "dirsize $dirsize < $maxsize after $nfiles files"
15018                 elif (( rc != 0 )); then
15019                         break
15020                 fi
15021                 nfiles=$((nfiles + 1))
15022                 dirsize=$(stat -c%s "$DIR/$tdir")
15023         done
15024
15025         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15026 }
15027 run_test 129 "test directory size limit ========================"
15028
15029 OLDIFS="$IFS"
15030 cleanup_130() {
15031         trap 0
15032         IFS="$OLDIFS"
15033         rm -f $DIR/$tfile
15034 }
15035
15036 test_130a() {
15037         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15038         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15039
15040         trap cleanup_130 EXIT RETURN
15041
15042         local fm_file=$DIR/$tfile
15043         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15044         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15045                 error "dd failed for $fm_file"
15046
15047         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15048         filefrag -ves $fm_file
15049         local rc=$?
15050         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15051                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15052         (( $rc == 0 )) || error "filefrag $fm_file failed"
15053
15054         filefrag_op=$(filefrag -ve -k $fm_file |
15055                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15056         local lun=$($LFS getstripe -i $fm_file)
15057
15058         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15059         IFS=$'\n'
15060         local tot_len=0
15061         for line in $filefrag_op; do
15062                 local frag_lun=$(echo $line | cut -d: -f5)
15063                 local ext_len=$(echo $line | cut -d: -f4)
15064
15065                 if (( $frag_lun != $lun )); then
15066                         error "FIEMAP on 1-stripe file($fm_file) failed"
15067                         return
15068                 fi
15069                 (( tot_len += ext_len ))
15070         done
15071
15072         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15073                 error "FIEMAP on 1-stripe file($fm_file) failed"
15074                 return
15075         fi
15076
15077         echo "FIEMAP on single striped file succeeded"
15078 }
15079 run_test 130a "FIEMAP (1-stripe file)"
15080
15081 test_130b() {
15082         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15083
15084         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15085         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15086         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15087                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15088
15089         trap cleanup_130 EXIT RETURN
15090
15091         local fm_file=$DIR/$tfile
15092         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15093                 error "setstripe on $fm_file"
15094
15095         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15096                 error "dd failed on $fm_file"
15097
15098         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15099         filefrag_op=$(filefrag -ve -k $fm_file |
15100                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15101
15102         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15103                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15104
15105         IFS=$'\n'
15106         local tot_len=0
15107         local num_luns=1
15108
15109         for line in $filefrag_op; do
15110                 local frag_lun=$(echo $line | cut -d: -f5 |
15111                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15112                 local ext_len=$(echo $line | cut -d: -f4)
15113                 if (( $frag_lun != $last_lun )); then
15114                         if (( tot_len != 1024 )); then
15115                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15116                                 return
15117                         else
15118                                 (( num_luns += 1 ))
15119                                 tot_len=0
15120                         fi
15121                 fi
15122                 (( tot_len += ext_len ))
15123                 last_lun=$frag_lun
15124         done
15125         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15126                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15127                 return
15128         fi
15129
15130         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15131 }
15132 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15133
15134 test_130c() {
15135         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15136
15137         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15138         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15139         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15140                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15141
15142         trap cleanup_130 EXIT RETURN
15143
15144         local fm_file=$DIR/$tfile
15145         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15146
15147         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15148                 error "dd failed on $fm_file"
15149
15150         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15151         filefrag_op=$(filefrag -ve -k $fm_file |
15152                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15153
15154         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15155                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15156
15157         IFS=$'\n'
15158         local tot_len=0
15159         local num_luns=1
15160         for line in $filefrag_op; do
15161                 local frag_lun=$(echo $line | cut -d: -f5 |
15162                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15163                 local ext_len=$(echo $line | cut -d: -f4)
15164                 if (( $frag_lun != $last_lun )); then
15165                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15166                         if (( logical != 512 )); then
15167                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15168                                 return
15169                         fi
15170                         if (( tot_len != 512 )); then
15171                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15172                                 return
15173                         else
15174                                 (( num_luns += 1 ))
15175                                 tot_len=0
15176                         fi
15177                 fi
15178                 (( tot_len += ext_len ))
15179                 last_lun=$frag_lun
15180         done
15181         if (( num_luns != 2 || tot_len != 512 )); then
15182                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15183                 return
15184         fi
15185
15186         echo "FIEMAP on 2-stripe file with hole succeeded"
15187 }
15188 run_test 130c "FIEMAP (2-stripe file with hole)"
15189
15190 test_130d() {
15191         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15192
15193         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15194         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15195         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15196                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15197
15198         trap cleanup_130 EXIT RETURN
15199
15200         local fm_file=$DIR/$tfile
15201         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15202                         error "setstripe on $fm_file"
15203
15204         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15205         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15206                 error "dd failed on $fm_file"
15207
15208         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15209         filefrag_op=$(filefrag -ve -k $fm_file |
15210                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15211
15212         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15213                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15214
15215         IFS=$'\n'
15216         local tot_len=0
15217         local num_luns=1
15218         for line in $filefrag_op; do
15219                 local frag_lun=$(echo $line | cut -d: -f5 |
15220                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15221                 local ext_len=$(echo $line | cut -d: -f4)
15222                 if (( $frag_lun != $last_lun )); then
15223                         if (( tot_len != 1024 )); then
15224                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15225                                 return
15226                         else
15227                                 (( num_luns += 1 ))
15228                                 local tot_len=0
15229                         fi
15230                 fi
15231                 (( tot_len += ext_len ))
15232                 last_lun=$frag_lun
15233         done
15234         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15235                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15236                 return
15237         fi
15238
15239         echo "FIEMAP on N-stripe file succeeded"
15240 }
15241 run_test 130d "FIEMAP (N-stripe file)"
15242
15243 test_130e() {
15244         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15245
15246         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15247         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15248         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15249                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15250
15251         trap cleanup_130 EXIT RETURN
15252
15253         local fm_file=$DIR/$tfile
15254         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15255         stack_trap "rm -f $fm_file"
15256
15257         local num_blks=512
15258         local expected_len=$(( (num_blks / 2) * 64 ))
15259         for ((i = 0; i < $num_blks; i++)); do
15260                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15261                         conv=notrunc > /dev/null 2>&1
15262         done
15263
15264         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15265         filefrag_op=$(filefrag -ve -k $fm_file |
15266                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15267
15268         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15269
15270         IFS=$'\n'
15271         local tot_len=0
15272         local num_luns=1
15273         for line in $filefrag_op; do
15274                 local frag_lun=$(echo $line | cut -d: -f5)
15275                 local ext_len=$(echo $line | cut -d: -f4)
15276                 if (( $frag_lun != $last_lun )); then
15277                         if (( tot_len != $expected_len )); then
15278                                 error "OST$last_lun $tot_len != $expected_len"
15279                         else
15280                                 (( num_luns += 1 ))
15281                                 tot_len=0
15282                         fi
15283                 fi
15284                 (( tot_len += ext_len ))
15285                 last_lun=$frag_lun
15286         done
15287         if (( num_luns != 2 || tot_len != $expected_len )); then
15288                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15289         fi
15290
15291         echo "FIEMAP with continuation calls succeeded"
15292 }
15293 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15294
15295 test_130f() {
15296         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15297         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15298         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15299                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15300
15301         local fm_file=$DIR/$tfile
15302         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15303                 error "multiop create with lov_delay_create on $fm_file"
15304
15305         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15306         filefrag_extents=$(filefrag -vek $fm_file |
15307                            awk '/extents? found/ { print $2 }')
15308         if (( $filefrag_extents != 0 )); then
15309                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15310         fi
15311
15312         rm -f $fm_file
15313 }
15314 run_test 130f "FIEMAP (unstriped file)"
15315
15316 test_130g() {
15317         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15318                 skip "Need MDS version with at least 2.12.53 for overstriping"
15319         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15320         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15321         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15322                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15323
15324         local file=$DIR/$tfile
15325         local nr=$((OSTCOUNT * 100))
15326
15327         $LFS setstripe -C $nr -S1M $file ||
15328                 error "failed to setstripe -C $nr $file"
15329
15330         stack_trap "rm -f $file"
15331         dd if=/dev/zero of=$file count=$nr bs=1M
15332         sync
15333         nr=$($LFS getstripe -c $file)
15334
15335         local extents=$(filefrag -v $file |
15336                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15337
15338         echo "filefrag list $extents extents in file with stripecount $nr"
15339         if (( extents < nr )); then
15340                 $LFS getstripe $file
15341                 filefrag -v $file
15342                 error "filefrag printed $extents < $nr extents"
15343         fi
15344 }
15345 run_test 130g "FIEMAP (overstripe file)"
15346
15347 # Test for writev/readv
15348 test_131a() {
15349         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15350                 error "writev test failed"
15351         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15352                 error "readv failed"
15353         rm -f $DIR/$tfile
15354 }
15355 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15356
15357 test_131b() {
15358         local fsize=$((524288 + 1048576 + 1572864))
15359         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15360                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15361                         error "append writev test failed"
15362
15363         ((fsize += 1572864 + 1048576))
15364         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15365                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15366                         error "append writev test failed"
15367         rm -f $DIR/$tfile
15368 }
15369 run_test 131b "test append writev"
15370
15371 test_131c() {
15372         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15373         error "NOT PASS"
15374 }
15375 run_test 131c "test read/write on file w/o objects"
15376
15377 test_131d() {
15378         rwv -f $DIR/$tfile -w -n 1 1572864
15379         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15380         if [ "$NOB" != 1572864 ]; then
15381                 error "Short read filed: read $NOB bytes instead of 1572864"
15382         fi
15383         rm -f $DIR/$tfile
15384 }
15385 run_test 131d "test short read"
15386
15387 test_131e() {
15388         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15389         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15390         error "read hitting hole failed"
15391         rm -f $DIR/$tfile
15392 }
15393 run_test 131e "test read hitting hole"
15394
15395 check_stats() {
15396         local facet=$1
15397         local op=$2
15398         local want=${3:-0}
15399         local res
15400
15401         # open             11 samples [usecs] 468 4793 13658 35791898
15402         case $facet in
15403         mds*) res=($(do_facet $facet \
15404                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15405                  ;;
15406         ost*) res=($(do_facet $facet \
15407                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15408                  ;;
15409         *) error "Wrong facet '$facet'" ;;
15410         esac
15411         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15412         # if $want is zero, it means any stat increment is ok.
15413         if (( $want > 0 )); then
15414                 local count=${res[1]}
15415
15416                 if (( $count != $want )); then
15417                         if [[ $facet =~ "mds" ]]; then
15418                                 do_nodes $(comma_list $(mdts_nodes)) \
15419                                         $LCTL get_param mdt.*.md_stats
15420                         else
15421                                 do_nodes $(comma_list $(osts-nodes)) \
15422                                         $LCTL get_param obdfilter.*.stats
15423                         fi
15424                         error "The $op counter on $facet is $count, not $want"
15425                 fi
15426         fi
15427 }
15428
15429 test_133a() {
15430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15431         remote_ost_nodsh && skip "remote OST with nodsh"
15432         remote_mds_nodsh && skip "remote MDS with nodsh"
15433         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15434                 skip_env "MDS doesn't support rename stats"
15435
15436         local testdir=$DIR/${tdir}/stats_testdir
15437
15438         mkdir -p $DIR/${tdir}
15439
15440         # clear stats.
15441         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15442         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15443
15444         # verify mdt stats first.
15445         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15446         check_stats $SINGLEMDS "mkdir" 1
15447
15448         # clear "open" from "lfs mkdir" above
15449         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15450         touch ${testdir}/${tfile} || error "touch failed"
15451         check_stats $SINGLEMDS "open" 1
15452         check_stats $SINGLEMDS "close" 1
15453         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15454                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15455                 check_stats $SINGLEMDS "mknod" 2
15456         }
15457         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15458         check_stats $SINGLEMDS "unlink" 1
15459         rm -f ${testdir}/${tfile} || error "file remove failed"
15460         check_stats $SINGLEMDS "unlink" 2
15461
15462         # remove working dir and check mdt stats again.
15463         rmdir ${testdir} || error "rmdir failed"
15464         check_stats $SINGLEMDS "rmdir" 1
15465
15466         local testdir1=$DIR/${tdir}/stats_testdir1
15467         mkdir_on_mdt0 -p ${testdir}
15468         mkdir_on_mdt0 -p ${testdir1}
15469         touch ${testdir1}/test1
15470         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15471         check_stats $SINGLEMDS "crossdir_rename" 1
15472
15473         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15474         check_stats $SINGLEMDS "samedir_rename" 1
15475
15476         rm -rf $DIR/${tdir}
15477 }
15478 run_test 133a "Verifying MDT stats ========================================"
15479
15480 test_133b() {
15481         local res
15482
15483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15484         remote_ost_nodsh && skip "remote OST with nodsh"
15485         remote_mds_nodsh && skip "remote MDS with nodsh"
15486
15487         local testdir=$DIR/${tdir}/stats_testdir
15488
15489         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15490         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15491         touch ${testdir}/${tfile} || error "touch failed"
15492         cancel_lru_locks mdc
15493
15494         # clear stats.
15495         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15496         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15497
15498         # extra mdt stats verification.
15499         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15500         check_stats $SINGLEMDS "setattr" 1
15501         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15502         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15503         then            # LU-1740
15504                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15505                 check_stats $SINGLEMDS "getattr" 1
15506         fi
15507         rm -rf $DIR/${tdir}
15508
15509         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15510         # so the check below is not reliable
15511         [ $MDSCOUNT -eq 1 ] || return 0
15512
15513         # Sleep to avoid a cached response.
15514         #define OBD_STATFS_CACHE_SECONDS 1
15515         sleep 2
15516         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15517         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15518         $LFS df || error "lfs failed"
15519         check_stats $SINGLEMDS "statfs" 1
15520
15521         # check aggregated statfs (LU-10018)
15522         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15523                 return 0
15524         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15525                 return 0
15526         sleep 2
15527         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15528         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15529         df $DIR
15530         check_stats $SINGLEMDS "statfs" 1
15531
15532         # We want to check that the client didn't send OST_STATFS to
15533         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15534         # extra care is needed here.
15535         if remote_mds; then
15536                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15537                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15538
15539                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15540                 [ "$res" ] && error "OST got STATFS"
15541         fi
15542
15543         return 0
15544 }
15545 run_test 133b "Verifying extra MDT stats =================================="
15546
15547 test_133c() {
15548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15549         remote_ost_nodsh && skip "remote OST with nodsh"
15550         remote_mds_nodsh && skip "remote MDS with nodsh"
15551
15552         local testdir=$DIR/$tdir/stats_testdir
15553
15554         test_mkdir -p $testdir
15555
15556         # verify obdfilter stats.
15557         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15558         sync
15559         cancel_lru_locks osc
15560         wait_delete_completed
15561
15562         # clear stats.
15563         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15564         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15565
15566         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15567                 error "dd failed"
15568         sync
15569         cancel_lru_locks osc
15570         check_stats ost1 "write" 1
15571
15572         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15573         check_stats ost1 "read" 1
15574
15575         > $testdir/$tfile || error "truncate failed"
15576         check_stats ost1 "punch" 1
15577
15578         rm -f $testdir/$tfile || error "file remove failed"
15579         wait_delete_completed
15580         check_stats ost1 "destroy" 1
15581
15582         rm -rf $DIR/$tdir
15583 }
15584 run_test 133c "Verifying OST stats ========================================"
15585
15586 order_2() {
15587         local value=$1
15588         local orig=$value
15589         local order=1
15590
15591         while [ $value -ge 2 ]; do
15592                 order=$((order*2))
15593                 value=$((value/2))
15594         done
15595
15596         if [ $orig -gt $order ]; then
15597                 order=$((order*2))
15598         fi
15599         echo $order
15600 }
15601
15602 size_in_KMGT() {
15603     local value=$1
15604     local size=('K' 'M' 'G' 'T');
15605     local i=0
15606     local size_string=$value
15607
15608     while [ $value -ge 1024 ]; do
15609         if [ $i -gt 3 ]; then
15610             #T is the biggest unit we get here, if that is bigger,
15611             #just return XXXT
15612             size_string=${value}T
15613             break
15614         fi
15615         value=$((value >> 10))
15616         if [ $value -lt 1024 ]; then
15617             size_string=${value}${size[$i]}
15618             break
15619         fi
15620         i=$((i + 1))
15621     done
15622
15623     echo $size_string
15624 }
15625
15626 get_rename_size() {
15627         local size=$1
15628         local context=${2:-.}
15629         local sample=$(do_facet $SINGLEMDS $LCTL \
15630                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15631                 grep -A1 $context |
15632                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15633         echo $sample
15634 }
15635
15636 test_133d() {
15637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15638         remote_ost_nodsh && skip "remote OST with nodsh"
15639         remote_mds_nodsh && skip "remote MDS with nodsh"
15640         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15641                 skip_env "MDS doesn't support rename stats"
15642
15643         local testdir1=$DIR/${tdir}/stats_testdir1
15644         local testdir2=$DIR/${tdir}/stats_testdir2
15645         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15646
15647         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15648
15649         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15650         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15651
15652         createmany -o $testdir1/test 512 || error "createmany failed"
15653
15654         # check samedir rename size
15655         mv ${testdir1}/test0 ${testdir1}/test_0
15656
15657         local testdir1_size=$(ls -l $DIR/${tdir} |
15658                 awk '/stats_testdir1/ {print $5}')
15659         local testdir2_size=$(ls -l $DIR/${tdir} |
15660                 awk '/stats_testdir2/ {print $5}')
15661
15662         testdir1_size=$(order_2 $testdir1_size)
15663         testdir2_size=$(order_2 $testdir2_size)
15664
15665         testdir1_size=$(size_in_KMGT $testdir1_size)
15666         testdir2_size=$(size_in_KMGT $testdir2_size)
15667
15668         echo "source rename dir size: ${testdir1_size}"
15669         echo "target rename dir size: ${testdir2_size}"
15670
15671         local cmd="do_facet $SINGLEMDS $LCTL "
15672         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15673
15674         eval $cmd || error "$cmd failed"
15675         local samedir=$($cmd | grep 'same_dir')
15676         local same_sample=$(get_rename_size $testdir1_size)
15677         [ -z "$samedir" ] && error "samedir_rename_size count error"
15678         [[ $same_sample -eq 1 ]] ||
15679                 error "samedir_rename_size error $same_sample"
15680         echo "Check same dir rename stats success"
15681
15682         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15683
15684         # check crossdir rename size
15685         mv ${testdir1}/test_0 ${testdir2}/test_0
15686
15687         testdir1_size=$(ls -l $DIR/${tdir} |
15688                 awk '/stats_testdir1/ {print $5}')
15689         testdir2_size=$(ls -l $DIR/${tdir} |
15690                 awk '/stats_testdir2/ {print $5}')
15691
15692         testdir1_size=$(order_2 $testdir1_size)
15693         testdir2_size=$(order_2 $testdir2_size)
15694
15695         testdir1_size=$(size_in_KMGT $testdir1_size)
15696         testdir2_size=$(size_in_KMGT $testdir2_size)
15697
15698         echo "source rename dir size: ${testdir1_size}"
15699         echo "target rename dir size: ${testdir2_size}"
15700
15701         eval $cmd || error "$cmd failed"
15702         local crossdir=$($cmd | grep 'crossdir')
15703         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15704         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15705         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15706         [[ $src_sample -eq 1 ]] ||
15707                 error "crossdir_rename_size error $src_sample"
15708         [[ $tgt_sample -eq 1 ]] ||
15709                 error "crossdir_rename_size error $tgt_sample"
15710         echo "Check cross dir rename stats success"
15711         rm -rf $DIR/${tdir}
15712 }
15713 run_test 133d "Verifying rename_stats ========================================"
15714
15715 test_133e() {
15716         remote_mds_nodsh && skip "remote MDS with nodsh"
15717         remote_ost_nodsh && skip "remote OST with nodsh"
15718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15719
15720         local testdir=$DIR/${tdir}/stats_testdir
15721         local ctr f0 f1 bs=32768 count=42 sum
15722
15723         mkdir -p ${testdir} || error "mkdir failed"
15724
15725         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15726
15727         for ctr in {write,read}_bytes; do
15728                 sync
15729                 cancel_lru_locks osc
15730
15731                 do_facet ost1 $LCTL set_param -n \
15732                         "obdfilter.*.exports.clear=clear"
15733
15734                 if [ $ctr = write_bytes ]; then
15735                         f0=/dev/zero
15736                         f1=${testdir}/${tfile}
15737                 else
15738                         f0=${testdir}/${tfile}
15739                         f1=/dev/null
15740                 fi
15741
15742                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15743                         error "dd failed"
15744                 sync
15745                 cancel_lru_locks osc
15746
15747                 sum=$(do_facet ost1 $LCTL get_param \
15748                         "obdfilter.*.exports.*.stats" |
15749                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15750                                 $1 == ctr { sum += $7 }
15751                                 END { printf("%0.0f", sum) }')
15752
15753                 if ((sum != bs * count)); then
15754                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15755                 fi
15756         done
15757
15758         rm -rf $DIR/${tdir}
15759 }
15760 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15761
15762 test_133f() {
15763         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15764                 skip "too old lustre for get_param -R ($facet_ver)"
15765
15766         # verifying readability.
15767         $LCTL get_param -R '*' &> /dev/null
15768
15769         # Verifing writability with badarea_io.
15770         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15771         local skipped_params='force_lbug|changelog_mask|daemon_file'
15772         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15773                 egrep -v "$skipped_params" |
15774                 xargs -n 1 find $proc_dirs -name |
15775                 xargs -n 1 badarea_io ||
15776                 error "client badarea_io failed"
15777
15778         # remount the FS in case writes/reads /proc break the FS
15779         cleanup || error "failed to unmount"
15780         setup || error "failed to setup"
15781 }
15782 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15783
15784 test_133g() {
15785         remote_mds_nodsh && skip "remote MDS with nodsh"
15786         remote_ost_nodsh && skip "remote OST with nodsh"
15787
15788         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15789         local proc_dirs_str=$(eval echo $proc_dirs)
15790         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15791         local facet
15792         for facet in mds1 ost1; do
15793                 local facet_ver=$(lustre_version_code $facet)
15794                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15795                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15796                 else
15797                         log "$facet: too old lustre for get_param -R"
15798                 fi
15799                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15800                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15801                                 tr -d = | egrep -v $skipped_params |
15802                                 xargs -n 1 find $proc_dirs_str -name |
15803                                 xargs -n 1 badarea_io" ||
15804                                         error "$facet badarea_io failed"
15805                 else
15806                         skip_noexit "$facet: too old lustre for get_param -R"
15807                 fi
15808         done
15809
15810         # remount the FS in case writes/reads /proc break the FS
15811         cleanup || error "failed to unmount"
15812         setup || error "failed to setup"
15813 }
15814 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15815
15816 test_133h() {
15817         remote_mds_nodsh && skip "remote MDS with nodsh"
15818         remote_ost_nodsh && skip "remote OST with nodsh"
15819         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15820                 skip "Need MDS version at least 2.9.54"
15821
15822         local facet
15823         for facet in client mds1 ost1; do
15824                 # Get the list of files that are missing the terminating newline
15825                 local plist=$(do_facet $facet
15826                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15827                 local ent
15828                 for ent in $plist; do
15829                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15830                                 awk -v FS='\v' -v RS='\v\v' \
15831                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15832                                         print FILENAME}'" 2>/dev/null)
15833                         [ -z $missing ] || {
15834                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15835                                 error "file does not end with newline: $facet-$ent"
15836                         }
15837                 done
15838         done
15839 }
15840 run_test 133h "Proc files should end with newlines"
15841
15842 test_134a() {
15843         remote_mds_nodsh && skip "remote MDS with nodsh"
15844         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15845                 skip "Need MDS version at least 2.7.54"
15846
15847         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15848         cancel_lru_locks mdc
15849
15850         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15851         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15852         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15853
15854         local nr=1000
15855         createmany -o $DIR/$tdir/f $nr ||
15856                 error "failed to create $nr files in $DIR/$tdir"
15857         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15858
15859         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15860         do_facet mds1 $LCTL set_param fail_loc=0x327
15861         do_facet mds1 $LCTL set_param fail_val=500
15862         touch $DIR/$tdir/m
15863
15864         echo "sleep 10 seconds ..."
15865         sleep 10
15866         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15867
15868         do_facet mds1 $LCTL set_param fail_loc=0
15869         do_facet mds1 $LCTL set_param fail_val=0
15870         [ $lck_cnt -lt $unused ] ||
15871                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15872
15873         rm $DIR/$tdir/m
15874         unlinkmany $DIR/$tdir/f $nr
15875 }
15876 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15877
15878 test_134b() {
15879         remote_mds_nodsh && skip "remote MDS with nodsh"
15880         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15881                 skip "Need MDS version at least 2.7.54"
15882
15883         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15884         cancel_lru_locks mdc
15885
15886         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15887                         ldlm.lock_reclaim_threshold_mb)
15888         # disable reclaim temporarily
15889         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15890
15891         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15892         do_facet mds1 $LCTL set_param fail_loc=0x328
15893         do_facet mds1 $LCTL set_param fail_val=500
15894
15895         $LCTL set_param debug=+trace
15896
15897         local nr=600
15898         createmany -o $DIR/$tdir/f $nr &
15899         local create_pid=$!
15900
15901         echo "Sleep $TIMEOUT seconds ..."
15902         sleep $TIMEOUT
15903         if ! ps -p $create_pid  > /dev/null 2>&1; then
15904                 do_facet mds1 $LCTL set_param fail_loc=0
15905                 do_facet mds1 $LCTL set_param fail_val=0
15906                 do_facet mds1 $LCTL set_param \
15907                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15908                 error "createmany finished incorrectly!"
15909         fi
15910         do_facet mds1 $LCTL set_param fail_loc=0
15911         do_facet mds1 $LCTL set_param fail_val=0
15912         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15913         wait $create_pid || return 1
15914
15915         unlinkmany $DIR/$tdir/f $nr
15916 }
15917 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15918
15919 test_135() {
15920         remote_mds_nodsh && skip "remote MDS with nodsh"
15921         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15922                 skip "Need MDS version at least 2.13.50"
15923         local fname
15924
15925         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15926
15927 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15928         #set only one record at plain llog
15929         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15930
15931         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15932
15933         #fill already existed plain llog each 64767
15934         #wrapping whole catalog
15935         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15936
15937         createmany -o $DIR/$tdir/$tfile_ 64700
15938         for (( i = 0; i < 64700; i = i + 2 ))
15939         do
15940                 rm $DIR/$tdir/$tfile_$i &
15941                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15942                 local pid=$!
15943                 wait $pid
15944         done
15945
15946         #waiting osp synchronization
15947         wait_delete_completed
15948 }
15949 run_test 135 "Race catalog processing"
15950
15951 test_136() {
15952         remote_mds_nodsh && skip "remote MDS with nodsh"
15953         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15954                 skip "Need MDS version at least 2.13.50"
15955         local fname
15956
15957         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15958         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15959         #set only one record at plain llog
15960 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15961         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15962
15963         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15964
15965         #fill already existed 2 plain llogs each 64767
15966         #wrapping whole catalog
15967         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15968         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15969         wait_delete_completed
15970
15971         createmany -o $DIR/$tdir/$tfile_ 10
15972         sleep 25
15973
15974         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15975         for (( i = 0; i < 10; i = i + 3 ))
15976         do
15977                 rm $DIR/$tdir/$tfile_$i &
15978                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15979                 local pid=$!
15980                 wait $pid
15981                 sleep 7
15982                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15983         done
15984
15985         #waiting osp synchronization
15986         wait_delete_completed
15987 }
15988 run_test 136 "Race catalog processing 2"
15989
15990 test_140() { #bug-17379
15991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15992
15993         test_mkdir $DIR/$tdir
15994         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15995         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15996
15997         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15998         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15999         local i=0
16000         while i=$((i + 1)); do
16001                 test_mkdir $i
16002                 cd $i || error "Changing to $i"
16003                 ln -s ../stat stat || error "Creating stat symlink"
16004                 # Read the symlink until ELOOP present,
16005                 # not LBUGing the system is considered success,
16006                 # we didn't overrun the stack.
16007                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16008                 if [ $ret -ne 0 ]; then
16009                         if [ $ret -eq 40 ]; then
16010                                 break  # -ELOOP
16011                         else
16012                                 error "Open stat symlink"
16013                                         return
16014                         fi
16015                 fi
16016         done
16017         i=$((i - 1))
16018         echo "The symlink depth = $i"
16019         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16020                 error "Invalid symlink depth"
16021
16022         # Test recursive symlink
16023         ln -s symlink_self symlink_self
16024         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16025         echo "open symlink_self returns $ret"
16026         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16027 }
16028 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16029
16030 test_150a() {
16031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16032
16033         local TF="$TMP/$tfile"
16034
16035         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16036         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16037         cp $TF $DIR/$tfile
16038         cancel_lru_locks $OSC
16039         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16040         remount_client $MOUNT
16041         df -P $MOUNT
16042         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16043
16044         $TRUNCATE $TF 6000
16045         $TRUNCATE $DIR/$tfile 6000
16046         cancel_lru_locks $OSC
16047         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16048
16049         echo "12345" >>$TF
16050         echo "12345" >>$DIR/$tfile
16051         cancel_lru_locks $OSC
16052         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16053
16054         echo "12345" >>$TF
16055         echo "12345" >>$DIR/$tfile
16056         cancel_lru_locks $OSC
16057         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16058 }
16059 run_test 150a "truncate/append tests"
16060
16061 test_150b() {
16062         check_set_fallocate_or_skip
16063         local out
16064
16065         touch $DIR/$tfile
16066         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16067         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16068                 skip_eopnotsupp "$out|check_fallocate failed"
16069 }
16070 run_test 150b "Verify fallocate (prealloc) functionality"
16071
16072 test_150bb() {
16073         check_set_fallocate_or_skip
16074
16075         touch $DIR/$tfile
16076         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16077         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16078         > $DIR/$tfile
16079         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16080         # precomputed md5sum for 20MB of zeroes
16081         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16082         local sum=($(md5sum $DIR/$tfile))
16083
16084         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16085
16086         check_set_fallocate 1
16087
16088         > $DIR/$tfile
16089         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16090         sum=($(md5sum $DIR/$tfile))
16091
16092         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16093 }
16094 run_test 150bb "Verify fallocate modes both zero space"
16095
16096 test_150c() {
16097         check_set_fallocate_or_skip
16098         local striping="-c2"
16099
16100         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16101         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16102         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16103         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16104         local want=$((OSTCOUNT * 1048576))
16105
16106         # Must allocate all requested space, not more than 5% extra
16107         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16108                 error "bytes $bytes is not $want"
16109
16110         rm -f $DIR/$tfile
16111
16112         echo "verify fallocate on PFL file"
16113
16114         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16115
16116         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16117                 error "Create $DIR/$tfile failed"
16118         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16119         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16120         want=$((512 * 1048576))
16121
16122         # Must allocate all requested space, not more than 5% extra
16123         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16124                 error "bytes $bytes is not $want"
16125 }
16126 run_test 150c "Verify fallocate Size and Blocks"
16127
16128 test_150d() {
16129         check_set_fallocate_or_skip
16130         local striping="-c2"
16131
16132         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16133
16134         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16135         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16136                 error "setstripe failed"
16137         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16138         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16139         local want=$((OSTCOUNT * 1048576))
16140
16141         # Must allocate all requested space, not more than 5% extra
16142         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16143                 error "bytes $bytes is not $want"
16144 }
16145 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16146
16147 test_150e() {
16148         check_set_fallocate_or_skip
16149
16150         echo "df before:"
16151         $LFS df
16152         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16153         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16154                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16155
16156         # Find OST with Minimum Size
16157         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16158                        sort -un | head -1)
16159
16160         # Get 100MB per OST of the available space to reduce run time
16161         # else 60% of the available space if we are running SLOW tests
16162         if [ $SLOW == "no" ]; then
16163                 local space=$((1024 * 100 * OSTCOUNT))
16164         else
16165                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16166         fi
16167
16168         fallocate -l${space}k $DIR/$tfile ||
16169                 error "fallocate ${space}k $DIR/$tfile failed"
16170         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16171
16172         # get size immediately after fallocate. This should be correctly
16173         # updated
16174         local size=$(stat -c '%s' $DIR/$tfile)
16175         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16176
16177         # Sleep for a while for statfs to get updated. And not pull from cache.
16178         sleep 2
16179
16180         echo "df after fallocate:"
16181         $LFS df
16182
16183         (( size / 1024 == space )) || error "size $size != requested $space"
16184         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16185                 error "used $used < space $space"
16186
16187         rm $DIR/$tfile || error "rm failed"
16188         sync
16189         wait_delete_completed
16190
16191         echo "df after unlink:"
16192         $LFS df
16193 }
16194 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16195
16196 test_150f() {
16197         local size
16198         local blocks
16199         local want_size_before=20480 # in bytes
16200         local want_blocks_before=40 # 512 sized blocks
16201         local want_blocks_after=24  # 512 sized blocks
16202         local length=$(((want_blocks_before - want_blocks_after) * 512))
16203
16204         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16205                 skip "need at least 2.14.0 for fallocate punch"
16206
16207         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16208                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16209         fi
16210
16211         check_set_fallocate_or_skip
16212         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16213
16214         [[ "x$DOM" == "xyes" ]] &&
16215                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16216
16217         echo "Verify fallocate punch: Range within the file range"
16218         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16219                 error "dd failed for bs 4096 and count 5"
16220
16221         # Call fallocate with punch range which is within the file range
16222         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16223                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16224         # client must see changes immediately after fallocate
16225         size=$(stat -c '%s' $DIR/$tfile)
16226         blocks=$(stat -c '%b' $DIR/$tfile)
16227
16228         # Verify punch worked.
16229         (( blocks == want_blocks_after )) ||
16230                 error "punch failed: blocks $blocks != $want_blocks_after"
16231
16232         (( size == want_size_before )) ||
16233                 error "punch failed: size $size != $want_size_before"
16234
16235         # Verify there is hole in file
16236         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16237         # precomputed md5sum
16238         local expect="4a9a834a2db02452929c0a348273b4aa"
16239
16240         cksum=($(md5sum $DIR/$tfile))
16241         [[ "${cksum[0]}" == "$expect" ]] ||
16242                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16243
16244         # Start second sub-case for fallocate punch.
16245         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16246         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16247                 error "dd failed for bs 4096 and count 5"
16248
16249         # Punch range less than block size will have no change in block count
16250         want_blocks_after=40  # 512 sized blocks
16251
16252         # Punch overlaps two blocks and less than blocksize
16253         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16254                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16255         size=$(stat -c '%s' $DIR/$tfile)
16256         blocks=$(stat -c '%b' $DIR/$tfile)
16257
16258         # Verify punch worked.
16259         (( blocks == want_blocks_after )) ||
16260                 error "punch failed: blocks $blocks != $want_blocks_after"
16261
16262         (( size == want_size_before )) ||
16263                 error "punch failed: size $size != $want_size_before"
16264
16265         # Verify if range is really zero'ed out. We expect Zeros.
16266         # precomputed md5sum
16267         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16268         cksum=($(md5sum $DIR/$tfile))
16269         [[ "${cksum[0]}" == "$expect" ]] ||
16270                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16271 }
16272 run_test 150f "Verify fallocate punch functionality"
16273
16274 test_150g() {
16275         local space
16276         local size
16277         local blocks
16278         local blocks_after
16279         local size_after
16280         local BS=4096 # Block size in bytes
16281
16282         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16283                 skip "need at least 2.14.0 for fallocate punch"
16284
16285         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16286                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16287         fi
16288
16289         check_set_fallocate_or_skip
16290         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16291
16292         if [[ "x$DOM" == "xyes" ]]; then
16293                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16294                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16295         else
16296                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16297                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16298         fi
16299
16300         # Get 100MB per OST of the available space to reduce run time
16301         # else 60% of the available space if we are running SLOW tests
16302         if [ $SLOW == "no" ]; then
16303                 space=$((1024 * 100 * OSTCOUNT))
16304         else
16305                 # Find OST with Minimum Size
16306                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16307                         sort -un | head -1)
16308                 echo "min size OST: $space"
16309                 space=$(((space * 60)/100 * OSTCOUNT))
16310         fi
16311         # space in 1k units, round to 4k blocks
16312         local blkcount=$((space * 1024 / $BS))
16313
16314         echo "Verify fallocate punch: Very large Range"
16315         fallocate -l${space}k $DIR/$tfile ||
16316                 error "fallocate ${space}k $DIR/$tfile failed"
16317         # write 1M at the end, start and in the middle
16318         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16319                 error "dd failed: bs $BS count 256"
16320         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16321                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16322         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16323                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16324
16325         # Gather stats.
16326         size=$(stat -c '%s' $DIR/$tfile)
16327
16328         # gather punch length.
16329         local punch_size=$((size - (BS * 2)))
16330
16331         echo "punch_size = $punch_size"
16332         echo "size - punch_size: $((size - punch_size))"
16333         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16334
16335         # Call fallocate to punch all except 2 blocks. We leave the
16336         # first and the last block
16337         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16338         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16339                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16340
16341         size_after=$(stat -c '%s' $DIR/$tfile)
16342         blocks_after=$(stat -c '%b' $DIR/$tfile)
16343
16344         # Verify punch worked.
16345         # Size should be kept
16346         (( size == size_after )) ||
16347                 error "punch failed: size $size != $size_after"
16348
16349         # two 4k data blocks to remain plus possible 1 extra extent block
16350         (( blocks_after <= ((BS / 512) * 3) )) ||
16351                 error "too many blocks remains: $blocks_after"
16352
16353         # Verify that file has hole between the first and the last blocks
16354         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16355         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16356
16357         echo "Hole at [$hole_start, $hole_end)"
16358         (( hole_start == BS )) ||
16359                 error "no hole at offset $BS after punch"
16360
16361         (( hole_end == BS + punch_size )) ||
16362                 error "data at offset $hole_end < $((BS + punch_size))"
16363 }
16364 run_test 150g "Verify fallocate punch on large range"
16365
16366 test_150h() {
16367         local file=$DIR/$tfile
16368         local size
16369
16370         check_set_fallocate_or_skip
16371         statx_supported || skip_env "Test must be statx() syscall supported"
16372
16373         # fallocate() does not update the size information on the MDT
16374         fallocate -l 16K $file || error "failed to fallocate $file"
16375         cancel_lru_locks $OSC
16376         # STATX with cached-always mode will not send glimpse RPCs to OST,
16377         # it uses the caching attrs on the client side as much as possible.
16378         size=$($STATX --cached=always -c %s $file)
16379         [ $size == 16384 ] ||
16380                 error "size after fallocate() is $size, expected 16384"
16381 }
16382 run_test 150h "Verify extend fallocate updates the file size"
16383
16384 #LU-2902 roc_hit was not able to read all values from lproc
16385 function roc_hit_init() {
16386         local list=$(comma_list $(osts_nodes))
16387         local dir=$DIR/$tdir-check
16388         local file=$dir/$tfile
16389         local BEFORE
16390         local AFTER
16391         local idx
16392
16393         test_mkdir $dir
16394         #use setstripe to do a write to every ost
16395         for i in $(seq 0 $((OSTCOUNT-1))); do
16396                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16397                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16398                 idx=$(printf %04x $i)
16399                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16400                         awk '$1 == "cache_access" {sum += $7}
16401                                 END { printf("%0.0f", sum) }')
16402
16403                 cancel_lru_locks osc
16404                 cat $file >/dev/null
16405
16406                 AFTER=$(get_osd_param $list *OST*$idx stats |
16407                         awk '$1 == "cache_access" {sum += $7}
16408                                 END { printf("%0.0f", sum) }')
16409
16410                 echo BEFORE:$BEFORE AFTER:$AFTER
16411                 if ! let "AFTER - BEFORE == 4"; then
16412                         rm -rf $dir
16413                         error "roc_hit is not safe to use"
16414                 fi
16415                 rm $file
16416         done
16417
16418         rm -rf $dir
16419 }
16420
16421 function roc_hit() {
16422         local list=$(comma_list $(osts_nodes))
16423         echo $(get_osd_param $list '' stats |
16424                 awk '$1 == "cache_hit" {sum += $7}
16425                         END { printf("%0.0f", sum) }')
16426 }
16427
16428 function set_cache() {
16429         local on=1
16430
16431         if [ "$2" == "off" ]; then
16432                 on=0;
16433         fi
16434         local list=$(comma_list $(osts_nodes))
16435         set_osd_param $list '' $1_cache_enable $on
16436
16437         cancel_lru_locks osc
16438 }
16439
16440 test_151() {
16441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16442         remote_ost_nodsh && skip "remote OST with nodsh"
16443         (( CLIENT_VERSION == OST1_VERSION )) ||
16444                 skip "LU-13081: no interop testing for OSS cache"
16445
16446         local CPAGES=3
16447         local list=$(comma_list $(osts_nodes))
16448
16449         # check whether obdfilter is cache capable at all
16450         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16451                 skip "not cache-capable obdfilter"
16452         fi
16453
16454         # check cache is enabled on all obdfilters
16455         if get_osd_param $list '' read_cache_enable | grep 0; then
16456                 skip "oss cache is disabled"
16457         fi
16458
16459         set_osd_param $list '' writethrough_cache_enable 1
16460
16461         # check write cache is enabled on all obdfilters
16462         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16463                 skip "oss write cache is NOT enabled"
16464         fi
16465
16466         roc_hit_init
16467
16468         #define OBD_FAIL_OBD_NO_LRU  0x609
16469         do_nodes $list $LCTL set_param fail_loc=0x609
16470
16471         # pages should be in the case right after write
16472         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16473                 error "dd failed"
16474
16475         local BEFORE=$(roc_hit)
16476         cancel_lru_locks osc
16477         cat $DIR/$tfile >/dev/null
16478         local AFTER=$(roc_hit)
16479
16480         do_nodes $list $LCTL set_param fail_loc=0
16481
16482         if ! let "AFTER - BEFORE == CPAGES"; then
16483                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16484         fi
16485
16486         cancel_lru_locks osc
16487         # invalidates OST cache
16488         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16489         set_osd_param $list '' read_cache_enable 0
16490         cat $DIR/$tfile >/dev/null
16491
16492         # now data shouldn't be found in the cache
16493         BEFORE=$(roc_hit)
16494         cancel_lru_locks osc
16495         cat $DIR/$tfile >/dev/null
16496         AFTER=$(roc_hit)
16497         if let "AFTER - BEFORE != 0"; then
16498                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16499         fi
16500
16501         set_osd_param $list '' read_cache_enable 1
16502         rm -f $DIR/$tfile
16503 }
16504 run_test 151 "test cache on oss and controls ==============================="
16505
16506 test_152() {
16507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16508
16509         local TF="$TMP/$tfile"
16510
16511         # simulate ENOMEM during write
16512 #define OBD_FAIL_OST_NOMEM      0x226
16513         lctl set_param fail_loc=0x80000226
16514         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16515         cp $TF $DIR/$tfile
16516         sync || error "sync failed"
16517         lctl set_param fail_loc=0
16518
16519         # discard client's cache
16520         cancel_lru_locks osc
16521
16522         # simulate ENOMEM during read
16523         lctl set_param fail_loc=0x80000226
16524         cmp $TF $DIR/$tfile || error "cmp failed"
16525         lctl set_param fail_loc=0
16526
16527         rm -f $TF
16528 }
16529 run_test 152 "test read/write with enomem ============================"
16530
16531 test_153() {
16532         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16533 }
16534 run_test 153 "test if fdatasync does not crash ======================="
16535
16536 dot_lustre_fid_permission_check() {
16537         local fid=$1
16538         local ffid=$MOUNT/.lustre/fid/$fid
16539         local test_dir=$2
16540
16541         echo "stat fid $fid"
16542         stat $ffid || error "stat $ffid failed."
16543         echo "touch fid $fid"
16544         touch $ffid || error "touch $ffid failed."
16545         echo "write to fid $fid"
16546         cat /etc/hosts > $ffid || error "write $ffid failed."
16547         echo "read fid $fid"
16548         diff /etc/hosts $ffid || error "read $ffid failed."
16549         echo "append write to fid $fid"
16550         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16551         echo "rename fid $fid"
16552         mv $ffid $test_dir/$tfile.1 &&
16553                 error "rename $ffid to $tfile.1 should fail."
16554         touch $test_dir/$tfile.1
16555         mv $test_dir/$tfile.1 $ffid &&
16556                 error "rename $tfile.1 to $ffid should fail."
16557         rm -f $test_dir/$tfile.1
16558         echo "truncate fid $fid"
16559         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16560         echo "link fid $fid"
16561         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16562         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16563                 id $USER0 || skip_env "missing user $USER0"
16564                 echo "setfacl fid $fid"
16565                 setfacl -R -m u:$USER0:rwx $ffid ||
16566                         error "setfacl $ffid failed"
16567                 echo "getfacl fid $fid"
16568                 getfacl $ffid || error "getfacl $ffid failed."
16569         fi
16570         echo "unlink fid $fid"
16571         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16572         echo "mknod fid $fid"
16573         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16574
16575         fid=[0xf00000400:0x1:0x0]
16576         ffid=$MOUNT/.lustre/fid/$fid
16577
16578         echo "stat non-exist fid $fid"
16579         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16580         echo "write to non-exist fid $fid"
16581         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16582         echo "link new fid $fid"
16583         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16584
16585         mkdir -p $test_dir/$tdir
16586         touch $test_dir/$tdir/$tfile
16587         fid=$($LFS path2fid $test_dir/$tdir)
16588         rc=$?
16589         [ $rc -ne 0 ] &&
16590                 error "error: could not get fid for $test_dir/$dir/$tfile."
16591
16592         ffid=$MOUNT/.lustre/fid/$fid
16593
16594         echo "ls $fid"
16595         ls $ffid || error "ls $ffid failed."
16596         echo "touch $fid/$tfile.1"
16597         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16598
16599         echo "touch $MOUNT/.lustre/fid/$tfile"
16600         touch $MOUNT/.lustre/fid/$tfile && \
16601                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16602
16603         echo "setxattr to $MOUNT/.lustre/fid"
16604         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16605
16606         echo "listxattr for $MOUNT/.lustre/fid"
16607         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16608
16609         echo "delxattr from $MOUNT/.lustre/fid"
16610         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16611
16612         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16613         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16614                 error "touch invalid fid should fail."
16615
16616         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16617         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16618                 error "touch non-normal fid should fail."
16619
16620         echo "rename $tdir to $MOUNT/.lustre/fid"
16621         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16622                 error "rename to $MOUNT/.lustre/fid should fail."
16623
16624         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16625         then            # LU-3547
16626                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16627                 local new_obf_mode=777
16628
16629                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16630                 chmod $new_obf_mode $DIR/.lustre/fid ||
16631                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16632
16633                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16634                 [ $obf_mode -eq $new_obf_mode ] ||
16635                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16636
16637                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16638                 chmod $old_obf_mode $DIR/.lustre/fid ||
16639                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16640         fi
16641
16642         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16643         fid=$($LFS path2fid $test_dir/$tfile-2)
16644
16645         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16646         then # LU-5424
16647                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16648                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16649                         error "create lov data thru .lustre failed"
16650         fi
16651         echo "cp /etc/passwd $test_dir/$tfile-2"
16652         cp /etc/passwd $test_dir/$tfile-2 ||
16653                 error "copy to $test_dir/$tfile-2 failed."
16654         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16655         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16656                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16657
16658         rm -rf $test_dir/tfile.lnk
16659         rm -rf $test_dir/$tfile-2
16660 }
16661
16662 test_154A() {
16663         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16664                 skip "Need MDS version at least 2.4.1"
16665
16666         local tf=$DIR/$tfile
16667         touch $tf
16668
16669         local fid=$($LFS path2fid $tf)
16670         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16671
16672         # check that we get the same pathname back
16673         local rootpath
16674         local found
16675         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16676                 echo "$rootpath $fid"
16677                 found=$($LFS fid2path $rootpath "$fid")
16678                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16679                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16680         done
16681
16682         # check wrong root path format
16683         rootpath=$MOUNT"_wrong"
16684         found=$($LFS fid2path $rootpath "$fid")
16685         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16686 }
16687 run_test 154A "lfs path2fid and fid2path basic checks"
16688
16689 test_154B() {
16690         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16691                 skip "Need MDS version at least 2.4.1"
16692
16693         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16694         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16695         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16696         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16697
16698         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16699         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16700
16701         # check that we get the same pathname
16702         echo "PFID: $PFID, name: $name"
16703         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16704         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16705         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16706                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16707
16708         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16709 }
16710 run_test 154B "verify the ll_decode_linkea tool"
16711
16712 test_154a() {
16713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16714         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16715         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16716                 skip "Need MDS version at least 2.2.51"
16717         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16718
16719         cp /etc/hosts $DIR/$tfile
16720
16721         fid=$($LFS path2fid $DIR/$tfile)
16722         rc=$?
16723         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16724
16725         dot_lustre_fid_permission_check "$fid" $DIR ||
16726                 error "dot lustre permission check $fid failed"
16727
16728         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16729
16730         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16731
16732         touch $MOUNT/.lustre/file &&
16733                 error "creation is not allowed under .lustre"
16734
16735         mkdir $MOUNT/.lustre/dir &&
16736                 error "mkdir is not allowed under .lustre"
16737
16738         rm -rf $DIR/$tfile
16739 }
16740 run_test 154a "Open-by-FID"
16741
16742 test_154b() {
16743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16744         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16745         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16746         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16747                 skip "Need MDS version at least 2.2.51"
16748
16749         local remote_dir=$DIR/$tdir/remote_dir
16750         local MDTIDX=1
16751         local rc=0
16752
16753         mkdir -p $DIR/$tdir
16754         $LFS mkdir -i $MDTIDX $remote_dir ||
16755                 error "create remote directory failed"
16756
16757         cp /etc/hosts $remote_dir/$tfile
16758
16759         fid=$($LFS path2fid $remote_dir/$tfile)
16760         rc=$?
16761         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16762
16763         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16764                 error "dot lustre permission check $fid failed"
16765         rm -rf $DIR/$tdir
16766 }
16767 run_test 154b "Open-by-FID for remote directory"
16768
16769 test_154c() {
16770         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16771                 skip "Need MDS version at least 2.4.1"
16772
16773         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16774         local FID1=$($LFS path2fid $DIR/$tfile.1)
16775         local FID2=$($LFS path2fid $DIR/$tfile.2)
16776         local FID3=$($LFS path2fid $DIR/$tfile.3)
16777
16778         local N=1
16779         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16780                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16781                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16782                 local want=FID$N
16783                 [ "$FID" = "${!want}" ] ||
16784                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16785                 N=$((N + 1))
16786         done
16787
16788         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16789         do
16790                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16791                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16792                 N=$((N + 1))
16793         done
16794 }
16795 run_test 154c "lfs path2fid and fid2path multiple arguments"
16796
16797 test_154d() {
16798         remote_mds_nodsh && skip "remote MDS with nodsh"
16799         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16800                 skip "Need MDS version at least 2.5.53"
16801
16802         if remote_mds; then
16803                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16804         else
16805                 nid="0@lo"
16806         fi
16807         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16808         local fd
16809         local cmd
16810
16811         rm -f $DIR/$tfile
16812         touch $DIR/$tfile
16813
16814         local fid=$($LFS path2fid $DIR/$tfile)
16815         # Open the file
16816         fd=$(free_fd)
16817         cmd="exec $fd<$DIR/$tfile"
16818         eval $cmd
16819         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16820         echo "$fid_list" | grep "$fid"
16821         rc=$?
16822
16823         cmd="exec $fd>/dev/null"
16824         eval $cmd
16825         if [ $rc -ne 0 ]; then
16826                 error "FID $fid not found in open files list $fid_list"
16827         fi
16828 }
16829 run_test 154d "Verify open file fid"
16830
16831 test_154e()
16832 {
16833         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16834                 skip "Need MDS version at least 2.6.50"
16835
16836         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16837                 error ".lustre returned by readdir"
16838         fi
16839 }
16840 run_test 154e ".lustre is not returned by readdir"
16841
16842 test_154f() {
16843         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16844
16845         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16846         mkdir_on_mdt0 $DIR/$tdir
16847         # test dirs inherit from its stripe
16848         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16849         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16850         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16851         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16852         touch $DIR/f
16853
16854         # get fid of parents
16855         local FID0=$($LFS path2fid $DIR/$tdir)
16856         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16857         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16858         local FID3=$($LFS path2fid $DIR)
16859
16860         # check that path2fid --parents returns expected <parent_fid>/name
16861         # 1) test for a directory (single parent)
16862         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16863         [ "$parent" == "$FID0/foo1" ] ||
16864                 error "expected parent: $FID0/foo1, got: $parent"
16865
16866         # 2) test for a file with nlink > 1 (multiple parents)
16867         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16868         echo "$parent" | grep -F "$FID1/$tfile" ||
16869                 error "$FID1/$tfile not returned in parent list"
16870         echo "$parent" | grep -F "$FID2/link" ||
16871                 error "$FID2/link not returned in parent list"
16872
16873         # 3) get parent by fid
16874         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16875         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16876         echo "$parent" | grep -F "$FID1/$tfile" ||
16877                 error "$FID1/$tfile not returned in parent list (by fid)"
16878         echo "$parent" | grep -F "$FID2/link" ||
16879                 error "$FID2/link not returned in parent list (by fid)"
16880
16881         # 4) test for entry in root directory
16882         parent=$($LFS path2fid --parents $DIR/f)
16883         echo "$parent" | grep -F "$FID3/f" ||
16884                 error "$FID3/f not returned in parent list"
16885
16886         # 5) test it on root directory
16887         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16888                 error "$MOUNT should not have parents"
16889
16890         # enable xattr caching and check that linkea is correctly updated
16891         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16892         save_lustre_params client "llite.*.xattr_cache" > $save
16893         lctl set_param llite.*.xattr_cache 1
16894
16895         # 6.1) linkea update on rename
16896         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16897
16898         # get parents by fid
16899         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16900         # foo1 should no longer be returned in parent list
16901         echo "$parent" | grep -F "$FID1" &&
16902                 error "$FID1 should no longer be in parent list"
16903         # the new path should appear
16904         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16905                 error "$FID2/$tfile.moved is not in parent list"
16906
16907         # 6.2) linkea update on unlink
16908         rm -f $DIR/$tdir/foo2/link
16909         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16910         # foo2/link should no longer be returned in parent list
16911         echo "$parent" | grep -F "$FID2/link" &&
16912                 error "$FID2/link should no longer be in parent list"
16913         true
16914
16915         rm -f $DIR/f
16916         restore_lustre_params < $save
16917         rm -f $save
16918 }
16919 run_test 154f "get parent fids by reading link ea"
16920
16921 test_154g()
16922 {
16923         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16924            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16925                 skip "Need MDS version at least 2.6.92"
16926
16927         mkdir_on_mdt0 $DIR/$tdir
16928         llapi_fid_test -d $DIR/$tdir
16929 }
16930 run_test 154g "various llapi FID tests"
16931
16932 test_154h()
16933 {
16934         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16935                 skip "Need client at least version 2.15.55.1"
16936
16937         # Create an empty file
16938         touch $DIR/$tfile
16939
16940         # Get FID (interactive mode) and save under $TMP/$tfile.log
16941         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16942                 path2fid $DIR/$tfile
16943         EOF
16944
16945         fid=$(cat $TMP/$tfile.log)
16946         # $fid should not be empty
16947         [[ ! -z $fid ]] || error "FID is empty"
16948         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16949 }
16950 run_test 154h "Verify interactive path2fid"
16951
16952 test_155_small_load() {
16953     local temp=$TMP/$tfile
16954     local file=$DIR/$tfile
16955
16956     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16957         error "dd of=$temp bs=6096 count=1 failed"
16958     cp $temp $file
16959     cancel_lru_locks $OSC
16960     cmp $temp $file || error "$temp $file differ"
16961
16962     $TRUNCATE $temp 6000
16963     $TRUNCATE $file 6000
16964     cmp $temp $file || error "$temp $file differ (truncate1)"
16965
16966     echo "12345" >>$temp
16967     echo "12345" >>$file
16968     cmp $temp $file || error "$temp $file differ (append1)"
16969
16970     echo "12345" >>$temp
16971     echo "12345" >>$file
16972     cmp $temp $file || error "$temp $file differ (append2)"
16973
16974     rm -f $temp $file
16975     true
16976 }
16977
16978 test_155_big_load() {
16979         remote_ost_nodsh && skip "remote OST with nodsh"
16980
16981         local temp=$TMP/$tfile
16982         local file=$DIR/$tfile
16983
16984         free_min_max
16985         local cache_size=$(do_facet ost$((MAXI+1)) \
16986                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16987
16988         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16989         # pre-set value
16990         if [ -z "$cache_size" ]; then
16991                 cache_size=256
16992         fi
16993         local large_file_size=$((cache_size * 2))
16994
16995         echo "OSS cache size: $cache_size KB"
16996         echo "Large file size: $large_file_size KB"
16997
16998         [ $MAXV -le $large_file_size ] &&
16999                 skip_env "max available OST size needs > $large_file_size KB"
17000
17001         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17002
17003         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17004                 error "dd of=$temp bs=$large_file_size count=1k failed"
17005         cp $temp $file
17006         ls -lh $temp $file
17007         cancel_lru_locks osc
17008         cmp $temp $file || error "$temp $file differ"
17009
17010         rm -f $temp $file
17011         true
17012 }
17013
17014 save_writethrough() {
17015         local facets=$(get_facets OST)
17016
17017         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17018 }
17019
17020 test_155a() {
17021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17022
17023         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17024
17025         save_writethrough $p
17026
17027         set_cache read on
17028         set_cache writethrough on
17029         test_155_small_load
17030         restore_lustre_params < $p
17031         rm -f $p
17032 }
17033 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17034
17035 test_155b() {
17036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17037
17038         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17039
17040         save_writethrough $p
17041
17042         set_cache read on
17043         set_cache writethrough off
17044         test_155_small_load
17045         restore_lustre_params < $p
17046         rm -f $p
17047 }
17048 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17049
17050 test_155c() {
17051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17052
17053         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17054
17055         save_writethrough $p
17056
17057         set_cache read off
17058         set_cache writethrough on
17059         test_155_small_load
17060         restore_lustre_params < $p
17061         rm -f $p
17062 }
17063 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17064
17065 test_155d() {
17066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17067
17068         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17069
17070         save_writethrough $p
17071
17072         set_cache read off
17073         set_cache writethrough off
17074         test_155_small_load
17075         restore_lustre_params < $p
17076         rm -f $p
17077 }
17078 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17079
17080 test_155e() {
17081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17082
17083         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17084
17085         save_writethrough $p
17086
17087         set_cache read on
17088         set_cache writethrough on
17089         test_155_big_load
17090         restore_lustre_params < $p
17091         rm -f $p
17092 }
17093 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17094
17095 test_155f() {
17096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17097
17098         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17099
17100         save_writethrough $p
17101
17102         set_cache read on
17103         set_cache writethrough off
17104         test_155_big_load
17105         restore_lustre_params < $p
17106         rm -f $p
17107 }
17108 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17109
17110 test_155g() {
17111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17112
17113         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17114
17115         save_writethrough $p
17116
17117         set_cache read off
17118         set_cache writethrough on
17119         test_155_big_load
17120         restore_lustre_params < $p
17121         rm -f $p
17122 }
17123 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17124
17125 test_155h() {
17126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17127
17128         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17129
17130         save_writethrough $p
17131
17132         set_cache read off
17133         set_cache writethrough off
17134         test_155_big_load
17135         restore_lustre_params < $p
17136         rm -f $p
17137 }
17138 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17139
17140 test_156() {
17141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17142         remote_ost_nodsh && skip "remote OST with nodsh"
17143         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17144                 skip "stats not implemented on old servers"
17145         [ "$ost1_FSTYPE" = "zfs" ] &&
17146                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17147         (( CLIENT_VERSION == OST1_VERSION )) ||
17148                 skip "LU-13081: no interop testing for OSS cache"
17149
17150         local CPAGES=3
17151         local BEFORE
17152         local AFTER
17153         local file="$DIR/$tfile"
17154         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17155
17156         save_writethrough $p
17157         roc_hit_init
17158
17159         log "Turn on read and write cache"
17160         set_cache read on
17161         set_cache writethrough on
17162
17163         log "Write data and read it back."
17164         log "Read should be satisfied from the cache."
17165         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17166         BEFORE=$(roc_hit)
17167         cancel_lru_locks osc
17168         cat $file >/dev/null
17169         AFTER=$(roc_hit)
17170         if ! let "AFTER - BEFORE == CPAGES"; then
17171                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17172         else
17173                 log "cache hits: before: $BEFORE, after: $AFTER"
17174         fi
17175
17176         log "Read again; it should be satisfied from the cache."
17177         BEFORE=$AFTER
17178         cancel_lru_locks osc
17179         cat $file >/dev/null
17180         AFTER=$(roc_hit)
17181         if ! let "AFTER - BEFORE == CPAGES"; then
17182                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17183         else
17184                 log "cache hits:: before: $BEFORE, after: $AFTER"
17185         fi
17186
17187         log "Turn off the read cache and turn on the write cache"
17188         set_cache read off
17189         set_cache writethrough on
17190
17191         log "Read again; it should be satisfied from the cache."
17192         BEFORE=$(roc_hit)
17193         cancel_lru_locks osc
17194         cat $file >/dev/null
17195         AFTER=$(roc_hit)
17196         if ! let "AFTER - BEFORE == CPAGES"; then
17197                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17198         else
17199                 log "cache hits:: before: $BEFORE, after: $AFTER"
17200         fi
17201
17202         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17203                 # > 2.12.56 uses pagecache if cached
17204                 log "Read again; it should not be satisfied from the cache."
17205                 BEFORE=$AFTER
17206                 cancel_lru_locks osc
17207                 cat $file >/dev/null
17208                 AFTER=$(roc_hit)
17209                 if ! let "AFTER - BEFORE == 0"; then
17210                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17211                 else
17212                         log "cache hits:: before: $BEFORE, after: $AFTER"
17213                 fi
17214         fi
17215
17216         log "Write data and read it back."
17217         log "Read should be satisfied from the cache."
17218         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17219         BEFORE=$(roc_hit)
17220         cancel_lru_locks osc
17221         cat $file >/dev/null
17222         AFTER=$(roc_hit)
17223         if ! let "AFTER - BEFORE == CPAGES"; then
17224                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17225         else
17226                 log "cache hits:: before: $BEFORE, after: $AFTER"
17227         fi
17228
17229         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17230                 # > 2.12.56 uses pagecache if cached
17231                 log "Read again; it should not be satisfied from the cache."
17232                 BEFORE=$AFTER
17233                 cancel_lru_locks osc
17234                 cat $file >/dev/null
17235                 AFTER=$(roc_hit)
17236                 if ! let "AFTER - BEFORE == 0"; then
17237                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17238                 else
17239                         log "cache hits:: before: $BEFORE, after: $AFTER"
17240                 fi
17241         fi
17242
17243         log "Turn off read and write cache"
17244         set_cache read off
17245         set_cache writethrough off
17246
17247         log "Write data and read it back"
17248         log "It should not be satisfied from the cache."
17249         rm -f $file
17250         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17251         cancel_lru_locks osc
17252         BEFORE=$(roc_hit)
17253         cat $file >/dev/null
17254         AFTER=$(roc_hit)
17255         if ! let "AFTER - BEFORE == 0"; then
17256                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17257         else
17258                 log "cache hits:: before: $BEFORE, after: $AFTER"
17259         fi
17260
17261         log "Turn on the read cache and turn off the write cache"
17262         set_cache read on
17263         set_cache writethrough off
17264
17265         log "Write data and read it back"
17266         log "It should not be satisfied from the cache."
17267         rm -f $file
17268         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17269         BEFORE=$(roc_hit)
17270         cancel_lru_locks osc
17271         cat $file >/dev/null
17272         AFTER=$(roc_hit)
17273         if ! let "AFTER - BEFORE == 0"; then
17274                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17275         else
17276                 log "cache hits:: before: $BEFORE, after: $AFTER"
17277         fi
17278
17279         log "Read again; it should be satisfied from the cache."
17280         BEFORE=$(roc_hit)
17281         cancel_lru_locks osc
17282         cat $file >/dev/null
17283         AFTER=$(roc_hit)
17284         if ! let "AFTER - BEFORE == CPAGES"; then
17285                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17286         else
17287                 log "cache hits:: before: $BEFORE, after: $AFTER"
17288         fi
17289
17290         restore_lustre_params < $p
17291         rm -f $p $file
17292 }
17293 run_test 156 "Verification of tunables"
17294
17295 test_160a() {
17296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17297         remote_mds_nodsh && skip "remote MDS with nodsh"
17298         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17299                 skip "Need MDS version at least 2.2.0"
17300
17301         changelog_register || error "changelog_register failed"
17302         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17303         changelog_users $SINGLEMDS | grep -q $cl_user ||
17304                 error "User $cl_user not found in changelog_users"
17305
17306         mkdir_on_mdt0 $DIR/$tdir
17307
17308         # change something
17309         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17310         changelog_clear 0 || error "changelog_clear failed"
17311         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17312         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17313         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17314         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17315         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17316         rm $DIR/$tdir/pics/desktop.jpg
17317
17318         echo "verifying changelog mask"
17319         changelog_chmask "-MKDIR"
17320         changelog_chmask "-CLOSE"
17321
17322         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17323         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17324
17325         changelog_chmask "+MKDIR"
17326         changelog_chmask "+CLOSE"
17327
17328         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17329         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17330
17331         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17332         CLOSES=$(changelog_dump | grep -c "CLOSE")
17333         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17334         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17335
17336         # verify contents
17337         echo "verifying target fid"
17338         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17339         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17340         [ "$fidc" == "$fidf" ] ||
17341                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17342         echo "verifying parent fid"
17343         # The FID returned from the Changelog may be the directory shard on
17344         # a different MDT, and not the FID returned by path2fid on the parent.
17345         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17346         # since this is what will matter when recreating this file in the tree.
17347         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17348         local pathp=$($LFS fid2path $MOUNT "$fidp")
17349         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17350                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17351
17352         echo "getting records for $cl_user"
17353         changelog_users $SINGLEMDS
17354         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17355         local nclr=3
17356         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17357                 error "changelog_clear failed"
17358         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17359         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17360         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17361                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17362
17363         local min0_rec=$(changelog_users $SINGLEMDS |
17364                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17365         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17366                           awk '{ print $1; exit; }')
17367
17368         changelog_dump | tail -n 5
17369         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17370         [ $first_rec == $((min0_rec + 1)) ] ||
17371                 error "first index should be $min0_rec + 1 not $first_rec"
17372
17373         # LU-3446 changelog index reset on MDT restart
17374         local cur_rec1=$(changelog_users $SINGLEMDS |
17375                          awk '/^current.index:/ { print $NF }')
17376         changelog_clear 0 ||
17377                 error "clear all changelog records for $cl_user failed"
17378         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17379         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17380                 error "Fail to start $SINGLEMDS"
17381         local cur_rec2=$(changelog_users $SINGLEMDS |
17382                          awk '/^current.index:/ { print $NF }')
17383         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17384         [ $cur_rec1 == $cur_rec2 ] ||
17385                 error "current index should be $cur_rec1 not $cur_rec2"
17386
17387         echo "verifying users from this test are deregistered"
17388         changelog_deregister || error "changelog_deregister failed"
17389         changelog_users $SINGLEMDS | grep -q $cl_user &&
17390                 error "User '$cl_user' still in changelog_users"
17391
17392         # lctl get_param -n mdd.*.changelog_users
17393         # current_index: 144
17394         # ID    index (idle seconds)
17395         # cl3   144   (2) mask=<list>
17396         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17397                 # this is the normal case where all users were deregistered
17398                 # make sure no new records are added when no users are present
17399                 local last_rec1=$(changelog_users $SINGLEMDS |
17400                                   awk '/^current.index:/ { print $NF }')
17401                 touch $DIR/$tdir/chloe
17402                 local last_rec2=$(changelog_users $SINGLEMDS |
17403                                   awk '/^current.index:/ { print $NF }')
17404                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17405                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17406         else
17407                 # any changelog users must be leftovers from a previous test
17408                 changelog_users $SINGLEMDS
17409                 echo "other changelog users; can't verify off"
17410         fi
17411 }
17412 run_test 160a "changelog sanity"
17413
17414 test_160b() { # LU-3587
17415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17416         remote_mds_nodsh && skip "remote MDS with nodsh"
17417         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17418                 skip "Need MDS version at least 2.2.0"
17419
17420         changelog_register || error "changelog_register failed"
17421         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17422         changelog_users $SINGLEMDS | grep -q $cl_user ||
17423                 error "User '$cl_user' not found in changelog_users"
17424
17425         local longname1=$(str_repeat a 255)
17426         local longname2=$(str_repeat b 255)
17427
17428         cd $DIR
17429         echo "creating very long named file"
17430         touch $longname1 || error "create of '$longname1' failed"
17431         echo "renaming very long named file"
17432         mv $longname1 $longname2
17433
17434         changelog_dump | grep RENME | tail -n 5
17435         rm -f $longname2
17436 }
17437 run_test 160b "Verify that very long rename doesn't crash in changelog"
17438
17439 test_160c() {
17440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17441         remote_mds_nodsh && skip "remote MDS with nodsh"
17442
17443         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17444                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17445                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17446                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17447
17448         local rc=0
17449
17450         # Registration step
17451         changelog_register || error "changelog_register failed"
17452
17453         rm -rf $DIR/$tdir
17454         mkdir -p $DIR/$tdir
17455         $MCREATE $DIR/$tdir/foo_160c
17456         changelog_chmask "-TRUNC"
17457         $TRUNCATE $DIR/$tdir/foo_160c 200
17458         changelog_chmask "+TRUNC"
17459         $TRUNCATE $DIR/$tdir/foo_160c 199
17460         changelog_dump | tail -n 5
17461         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17462         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17463 }
17464 run_test 160c "verify that changelog log catch the truncate event"
17465
17466 test_160d() {
17467         remote_mds_nodsh && skip "remote MDS with nodsh"
17468         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17470         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17471                 skip "Need MDS version at least 2.7.60"
17472
17473         # Registration step
17474         changelog_register || error "changelog_register failed"
17475
17476         mkdir -p $DIR/$tdir/migrate_dir
17477         changelog_clear 0 || error "changelog_clear failed"
17478
17479         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17480         changelog_dump | tail -n 5
17481         local migrates=$(changelog_dump | grep -c "MIGRT")
17482         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17483 }
17484 run_test 160d "verify that changelog log catch the migrate event"
17485
17486 test_160e() {
17487         remote_mds_nodsh && skip "remote MDS with nodsh"
17488
17489         # Create a user
17490         changelog_register || error "changelog_register failed"
17491
17492         local MDT0=$(facet_svc $SINGLEMDS)
17493         local rc
17494
17495         # No user (expect fail)
17496         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17497         rc=$?
17498         if [ $rc -eq 0 ]; then
17499                 error "Should fail without user"
17500         elif [ $rc -ne 4 ]; then
17501                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17502         fi
17503
17504         # Delete a future user (expect fail)
17505         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17506         rc=$?
17507         if [ $rc -eq 0 ]; then
17508                 error "Deleted non-existant user cl77"
17509         elif [ $rc -ne 2 ]; then
17510                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17511         fi
17512
17513         # Clear to a bad index (1 billion should be safe)
17514         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17515         rc=$?
17516
17517         if [ $rc -eq 0 ]; then
17518                 error "Successfully cleared to invalid CL index"
17519         elif [ $rc -ne 22 ]; then
17520                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17521         fi
17522 }
17523 run_test 160e "changelog negative testing (should return errors)"
17524
17525 test_160f() {
17526         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17527         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17528                 skip "Need MDS version at least 2.10.56"
17529
17530         local mdts=$(comma_list $(mdts_nodes))
17531
17532         # Create a user
17533         changelog_register || error "first changelog_register failed"
17534         changelog_register || error "second changelog_register failed"
17535         local cl_users
17536         declare -A cl_user1
17537         declare -A cl_user2
17538         local user_rec1
17539         local user_rec2
17540         local i
17541
17542         # generate some changelog records to accumulate on each MDT
17543         # use all_char because created files should be evenly distributed
17544         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17545                 error "test_mkdir $tdir failed"
17546         log "$(date +%s): creating first files"
17547         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17548                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17549                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17550         done
17551
17552         # check changelogs have been generated
17553         local start=$SECONDS
17554         local idle_time=$((MDSCOUNT * 5 + 5))
17555         local nbcl=$(changelog_dump | wc -l)
17556         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17557
17558         for param in "changelog_max_idle_time=$idle_time" \
17559                      "changelog_gc=1" \
17560                      "changelog_min_gc_interval=2" \
17561                      "changelog_min_free_cat_entries=3"; do
17562                 local MDT0=$(facet_svc $SINGLEMDS)
17563                 local var="${param%=*}"
17564                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17565
17566                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17567                 do_nodes $mdts $LCTL set_param mdd.*.$param
17568         done
17569
17570         # force cl_user2 to be idle (1st part), but also cancel the
17571         # cl_user1 records so that it is not evicted later in the test.
17572         local sleep1=$((idle_time / 2))
17573         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17574         sleep $sleep1
17575
17576         # simulate changelog catalog almost full
17577         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17578         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17579
17580         for i in $(seq $MDSCOUNT); do
17581                 cl_users=(${CL_USERS[mds$i]})
17582                 cl_user1[mds$i]="${cl_users[0]}"
17583                 cl_user2[mds$i]="${cl_users[1]}"
17584
17585                 [ -n "${cl_user1[mds$i]}" ] ||
17586                         error "mds$i: no user registered"
17587                 [ -n "${cl_user2[mds$i]}" ] ||
17588                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17589
17590                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17591                 [ -n "$user_rec1" ] ||
17592                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17593                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17594                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17595                 [ -n "$user_rec2" ] ||
17596                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17597                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17598                      "$user_rec1 + 2 == $user_rec2"
17599                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17600                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17601                               "$user_rec1 + 2, but is $user_rec2"
17602                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17603                 [ -n "$user_rec2" ] ||
17604                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17605                 [ $user_rec1 == $user_rec2 ] ||
17606                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17607                               "$user_rec1, but is $user_rec2"
17608         done
17609
17610         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17611         local sleep2=$((idle_time - (SECONDS - start) + 1))
17612         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17613         sleep $sleep2
17614
17615         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17616         # cl_user1 should be OK because it recently processed records.
17617         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17618         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17619                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17620                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17621         done
17622
17623         # ensure gc thread is done
17624         for i in $(mdts_nodes); do
17625                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17626                         error "$i: GC-thread not done"
17627         done
17628
17629         local first_rec
17630         for (( i = 1; i <= MDSCOUNT; i++ )); do
17631                 # check cl_user1 still registered
17632                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17633                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17634                 # check cl_user2 unregistered
17635                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17636                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17637
17638                 # check changelogs are present and starting at $user_rec1 + 1
17639                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17640                 [ -n "$user_rec1" ] ||
17641                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17642                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17643                             awk '{ print $1; exit; }')
17644
17645                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17646                 [ $((user_rec1 + 1)) == $first_rec ] ||
17647                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17648         done
17649 }
17650 run_test 160f "changelog garbage collect (timestamped users)"
17651
17652 test_160g() {
17653         remote_mds_nodsh && skip "remote MDS with nodsh"
17654         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17655                 skip "Need MDS version at least 2.14.55"
17656
17657         local mdts=$(comma_list $(mdts_nodes))
17658
17659         # Create a user
17660         changelog_register || error "first changelog_register failed"
17661         changelog_register || error "second changelog_register failed"
17662         local cl_users
17663         declare -A cl_user1
17664         declare -A cl_user2
17665         local user_rec1
17666         local user_rec2
17667         local i
17668
17669         # generate some changelog records to accumulate on each MDT
17670         # use all_char because created files should be evenly distributed
17671         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17672                 error "test_mkdir $tdir failed"
17673         for ((i = 0; i < MDSCOUNT; i++)); do
17674                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17675                         error "create $DIR/$tdir/d$i.1 failed"
17676         done
17677
17678         # check changelogs have been generated
17679         local nbcl=$(changelog_dump | wc -l)
17680         (( $nbcl > 0 )) || error "no changelogs found"
17681
17682         # reduce the max_idle_indexes value to make sure we exceed it
17683         for param in "changelog_max_idle_indexes=2" \
17684                      "changelog_gc=1" \
17685                      "changelog_min_gc_interval=2"; do
17686                 local MDT0=$(facet_svc $SINGLEMDS)
17687                 local var="${param%=*}"
17688                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17689
17690                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17691                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17692                         error "unable to set mdd.*.$param"
17693         done
17694
17695         local start=$SECONDS
17696         for i in $(seq $MDSCOUNT); do
17697                 cl_users=(${CL_USERS[mds$i]})
17698                 cl_user1[mds$i]="${cl_users[0]}"
17699                 cl_user2[mds$i]="${cl_users[1]}"
17700
17701                 [ -n "${cl_user1[mds$i]}" ] ||
17702                         error "mds$i: user1 is not registered"
17703                 [ -n "${cl_user2[mds$i]}" ] ||
17704                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17705
17706                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17707                 [ -n "$user_rec1" ] ||
17708                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17709                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17710                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17711                 [ -n "$user_rec2" ] ||
17712                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17713                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17714                      "$user_rec1 + 2 == $user_rec2"
17715                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17716                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17717                               "expected $user_rec1 + 2, but is $user_rec2"
17718                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17719                 [ -n "$user_rec2" ] ||
17720                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17721                 [ $user_rec1 == $user_rec2 ] ||
17722                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17723                               "expected $user_rec1, but is $user_rec2"
17724         done
17725
17726         # ensure we are past the previous changelog_min_gc_interval set above
17727         local sleep2=$((start + 2 - SECONDS))
17728         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17729         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17730         # cl_user1 should be OK because it recently processed records.
17731         for ((i = 0; i < MDSCOUNT; i++)); do
17732                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17733                         error "create $DIR/$tdir/d$i.3 failed"
17734         done
17735
17736         # ensure gc thread is done
17737         for i in $(mdts_nodes); do
17738                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17739                         error "$i: GC-thread not done"
17740         done
17741
17742         local first_rec
17743         for (( i = 1; i <= MDSCOUNT; i++ )); do
17744                 # check cl_user1 still registered
17745                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17746                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17747                 # check cl_user2 unregistered
17748                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17749                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17750
17751                 # check changelogs are present and starting at $user_rec1 + 1
17752                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17753                 [ -n "$user_rec1" ] ||
17754                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17755                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17756                             awk '{ print $1; exit; }')
17757
17758                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17759                 [ $((user_rec1 + 1)) == $first_rec ] ||
17760                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17761         done
17762 }
17763 run_test 160g "changelog garbage collect on idle records"
17764
17765 test_160h() {
17766         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17767         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17768                 skip "Need MDS version at least 2.10.56"
17769
17770         local mdts=$(comma_list $(mdts_nodes))
17771
17772         # Create a user
17773         changelog_register || error "first changelog_register failed"
17774         changelog_register || error "second changelog_register failed"
17775         local cl_users
17776         declare -A cl_user1
17777         declare -A cl_user2
17778         local user_rec1
17779         local user_rec2
17780         local i
17781
17782         # generate some changelog records to accumulate on each MDT
17783         # use all_char because created files should be evenly distributed
17784         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17785                 error "test_mkdir $tdir failed"
17786         for ((i = 0; i < MDSCOUNT; i++)); do
17787                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17788                         error "create $DIR/$tdir/d$i.1 failed"
17789         done
17790
17791         # check changelogs have been generated
17792         local nbcl=$(changelog_dump | wc -l)
17793         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17794
17795         for param in "changelog_max_idle_time=10" \
17796                      "changelog_gc=1" \
17797                      "changelog_min_gc_interval=2"; do
17798                 local MDT0=$(facet_svc $SINGLEMDS)
17799                 local var="${param%=*}"
17800                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17801
17802                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17803                 do_nodes $mdts $LCTL set_param mdd.*.$param
17804         done
17805
17806         # force cl_user2 to be idle (1st part)
17807         sleep 9
17808
17809         for i in $(seq $MDSCOUNT); do
17810                 cl_users=(${CL_USERS[mds$i]})
17811                 cl_user1[mds$i]="${cl_users[0]}"
17812                 cl_user2[mds$i]="${cl_users[1]}"
17813
17814                 [ -n "${cl_user1[mds$i]}" ] ||
17815                         error "mds$i: no user registered"
17816                 [ -n "${cl_user2[mds$i]}" ] ||
17817                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17818
17819                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17820                 [ -n "$user_rec1" ] ||
17821                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17822                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17823                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17824                 [ -n "$user_rec2" ] ||
17825                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17826                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17827                      "$user_rec1 + 2 == $user_rec2"
17828                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17829                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17830                               "$user_rec1 + 2, but is $user_rec2"
17831                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17832                 [ -n "$user_rec2" ] ||
17833                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17834                 [ $user_rec1 == $user_rec2 ] ||
17835                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17836                               "$user_rec1, but is $user_rec2"
17837         done
17838
17839         # force cl_user2 to be idle (2nd part) and to reach
17840         # changelog_max_idle_time
17841         sleep 2
17842
17843         # force each GC-thread start and block then
17844         # one per MDT/MDD, set fail_val accordingly
17845         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17846         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17847
17848         # generate more changelogs to trigger fail_loc
17849         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17850                 error "create $DIR/$tdir/${tfile}bis failed"
17851
17852         # stop MDT to stop GC-thread, should be done in back-ground as it will
17853         # block waiting for the thread to be released and exit
17854         declare -A stop_pids
17855         for i in $(seq $MDSCOUNT); do
17856                 stop mds$i &
17857                 stop_pids[mds$i]=$!
17858         done
17859
17860         for i in $(mdts_nodes); do
17861                 local facet
17862                 local nb=0
17863                 local facets=$(facets_up_on_host $i)
17864
17865                 for facet in ${facets//,/ }; do
17866                         if [[ $facet == mds* ]]; then
17867                                 nb=$((nb + 1))
17868                         fi
17869                 done
17870                 # ensure each MDS's gc threads are still present and all in "R"
17871                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17872                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17873                         error "$i: expected $nb GC-thread"
17874                 wait_update $i \
17875                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17876                         "R" 20 ||
17877                         error "$i: GC-thread not found in R-state"
17878                 # check umounts of each MDT on MDS have reached kthread_stop()
17879                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17880                         error "$i: expected $nb umount"
17881                 wait_update $i \
17882                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17883                         error "$i: umount not found in D-state"
17884         done
17885
17886         # release all GC-threads
17887         do_nodes $mdts $LCTL set_param fail_loc=0
17888
17889         # wait for MDT stop to complete
17890         for i in $(seq $MDSCOUNT); do
17891                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17892         done
17893
17894         # XXX
17895         # may try to check if any orphan changelog records are present
17896         # via ldiskfs/zfs and llog_reader...
17897
17898         # re-start/mount MDTs
17899         for i in $(seq $MDSCOUNT); do
17900                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17901                         error "Fail to start mds$i"
17902         done
17903
17904         local first_rec
17905         for i in $(seq $MDSCOUNT); do
17906                 # check cl_user1 still registered
17907                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17908                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17909                 # check cl_user2 unregistered
17910                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17911                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17912
17913                 # check changelogs are present and starting at $user_rec1 + 1
17914                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17915                 [ -n "$user_rec1" ] ||
17916                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17917                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17918                             awk '{ print $1; exit; }')
17919
17920                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17921                 [ $((user_rec1 + 1)) == $first_rec ] ||
17922                         error "mds$i: first index should be $user_rec1 + 1, " \
17923                               "but is $first_rec"
17924         done
17925 }
17926 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17927               "during mount"
17928
17929 test_160i() {
17930
17931         local mdts=$(comma_list $(mdts_nodes))
17932
17933         changelog_register || error "first changelog_register failed"
17934
17935         # generate some changelog records to accumulate on each MDT
17936         # use all_char because created files should be evenly distributed
17937         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17938                 error "test_mkdir $tdir failed"
17939         for ((i = 0; i < MDSCOUNT; i++)); do
17940                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17941                         error "create $DIR/$tdir/d$i.1 failed"
17942         done
17943
17944         # check changelogs have been generated
17945         local nbcl=$(changelog_dump | wc -l)
17946         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17947
17948         # simulate race between register and unregister
17949         # XXX as fail_loc is set per-MDS, with DNE configs the race
17950         # simulation will only occur for one MDT per MDS and for the
17951         # others the normal race scenario will take place
17952         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17953         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17954         do_nodes $mdts $LCTL set_param fail_val=1
17955
17956         # unregister 1st user
17957         changelog_deregister &
17958         local pid1=$!
17959         # wait some time for deregister work to reach race rdv
17960         sleep 2
17961         # register 2nd user
17962         changelog_register || error "2nd user register failed"
17963
17964         wait $pid1 || error "1st user deregister failed"
17965
17966         local i
17967         local last_rec
17968         declare -A LAST_REC
17969         for i in $(seq $MDSCOUNT); do
17970                 if changelog_users mds$i | grep "^cl"; then
17971                         # make sure new records are added with one user present
17972                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17973                                           awk '/^current.index:/ { print $NF }')
17974                 else
17975                         error "mds$i has no user registered"
17976                 fi
17977         done
17978
17979         # generate more changelog records to accumulate on each MDT
17980         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17981                 error "create $DIR/$tdir/${tfile}bis failed"
17982
17983         for i in $(seq $MDSCOUNT); do
17984                 last_rec=$(changelog_users $SINGLEMDS |
17985                            awk '/^current.index:/ { print $NF }')
17986                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17987                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17988                         error "changelogs are off on mds$i"
17989         done
17990 }
17991 run_test 160i "changelog user register/unregister race"
17992
17993 test_160j() {
17994         remote_mds_nodsh && skip "remote MDS with nodsh"
17995         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17996                 skip "Need MDS version at least 2.12.56"
17997
17998         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17999         stack_trap "umount $MOUNT2" EXIT
18000
18001         changelog_register || error "first changelog_register failed"
18002         stack_trap "changelog_deregister" EXIT
18003
18004         # generate some changelog
18005         # use all_char because created files should be evenly distributed
18006         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18007                 error "mkdir $tdir failed"
18008         for ((i = 0; i < MDSCOUNT; i++)); do
18009                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18010                         error "create $DIR/$tdir/d$i.1 failed"
18011         done
18012
18013         # open the changelog device
18014         exec 3>/dev/changelog-$FSNAME-MDT0000
18015         stack_trap "exec 3>&-" EXIT
18016         exec 4</dev/changelog-$FSNAME-MDT0000
18017         stack_trap "exec 4<&-" EXIT
18018
18019         # umount the first lustre mount
18020         umount $MOUNT
18021         stack_trap "mount_client $MOUNT" EXIT
18022
18023         # read changelog, which may or may not fail, but should not crash
18024         cat <&4 >/dev/null
18025
18026         # clear changelog
18027         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18028         changelog_users $SINGLEMDS | grep -q $cl_user ||
18029                 error "User $cl_user not found in changelog_users"
18030
18031         printf 'clear:'$cl_user':0' >&3
18032 }
18033 run_test 160j "client can be umounted while its chanangelog is being used"
18034
18035 test_160k() {
18036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18037         remote_mds_nodsh && skip "remote MDS with nodsh"
18038
18039         mkdir -p $DIR/$tdir/1/1
18040
18041         changelog_register || error "changelog_register failed"
18042         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18043
18044         changelog_users $SINGLEMDS | grep -q $cl_user ||
18045                 error "User '$cl_user' not found in changelog_users"
18046 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18047         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18048         rmdir $DIR/$tdir/1/1 & sleep 1
18049         mkdir $DIR/$tdir/2
18050         touch $DIR/$tdir/2/2
18051         rm -rf $DIR/$tdir/2
18052
18053         wait
18054         sleep 4
18055
18056         changelog_dump | grep rmdir || error "rmdir not recorded"
18057 }
18058 run_test 160k "Verify that changelog records are not lost"
18059
18060 # Verifies that a file passed as a parameter has recently had an operation
18061 # performed on it that has generated an MTIME changelog which contains the
18062 # correct parent FID. As files might reside on a different MDT from the
18063 # parent directory in DNE configurations, the FIDs are translated to paths
18064 # before being compared, which should be identical
18065 compare_mtime_changelog() {
18066         local file="${1}"
18067         local mdtidx
18068         local mtime
18069         local cl_fid
18070         local pdir
18071         local dir
18072
18073         mdtidx=$($LFS getstripe --mdt-index $file)
18074         mdtidx=$(printf "%04x" $mdtidx)
18075
18076         # Obtain the parent FID from the MTIME changelog
18077         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18078         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18079
18080         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18081         [ -z "$cl_fid" ] && error "parent FID not present"
18082
18083         # Verify that the path for the parent FID is the same as the path for
18084         # the test directory
18085         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18086
18087         dir=$(dirname $1)
18088
18089         [[ "${pdir%/}" == "$dir" ]] ||
18090                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18091 }
18092
18093 test_160l() {
18094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18095
18096         remote_mds_nodsh && skip "remote MDS with nodsh"
18097         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18098                 skip "Need MDS version at least 2.13.55"
18099
18100         local cl_user
18101
18102         changelog_register || error "changelog_register failed"
18103         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18104
18105         changelog_users $SINGLEMDS | grep -q $cl_user ||
18106                 error "User '$cl_user' not found in changelog_users"
18107
18108         # Clear some types so that MTIME changelogs are generated
18109         changelog_chmask "-CREAT"
18110         changelog_chmask "-CLOSE"
18111
18112         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18113
18114         # Test CL_MTIME during setattr
18115         touch $DIR/$tdir/$tfile
18116         compare_mtime_changelog $DIR/$tdir/$tfile
18117
18118         # Test CL_MTIME during close
18119         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18120         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18121 }
18122 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18123
18124 test_160m() {
18125         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18126         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18127                 skip "Need MDS version at least 2.14.51"
18128         local cl_users
18129         local cl_user1
18130         local cl_user2
18131         local pid1
18132
18133         # Create a user
18134         changelog_register || error "first changelog_register failed"
18135         changelog_register || error "second changelog_register failed"
18136
18137         cl_users=(${CL_USERS[mds1]})
18138         cl_user1="${cl_users[0]}"
18139         cl_user2="${cl_users[1]}"
18140         # generate some changelog records to accumulate on MDT0
18141         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18142         createmany -m $DIR/$tdir/$tfile 50 ||
18143                 error "create $DIR/$tdir/$tfile failed"
18144         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18145         rm -f $DIR/$tdir
18146
18147         # check changelogs have been generated
18148         local nbcl=$(changelog_dump | wc -l)
18149         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18150
18151 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18152         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18153
18154         __changelog_clear mds1 $cl_user1 +10
18155         __changelog_clear mds1 $cl_user2 0 &
18156         pid1=$!
18157         sleep 2
18158         __changelog_clear mds1 $cl_user1 0 ||
18159                 error "fail to cancel record for $cl_user1"
18160         wait $pid1
18161         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18162 }
18163 run_test 160m "Changelog clear race"
18164
18165 test_160n() {
18166         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18167         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18168                 skip "Need MDS version at least 2.14.51"
18169         local cl_users
18170         local cl_user1
18171         local cl_user2
18172         local pid1
18173         local first_rec
18174         local last_rec=0
18175
18176         # Create a user
18177         changelog_register || error "first changelog_register failed"
18178
18179         cl_users=(${CL_USERS[mds1]})
18180         cl_user1="${cl_users[0]}"
18181
18182         # generate some changelog records to accumulate on MDT0
18183         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18184         first_rec=$(changelog_users $SINGLEMDS |
18185                         awk '/^current.index:/ { print $NF }')
18186         while (( last_rec < (( first_rec + 65000)) )); do
18187                 createmany -m $DIR/$tdir/$tfile 10000 ||
18188                         error "create $DIR/$tdir/$tfile failed"
18189
18190                 for i in $(seq 0 10000); do
18191                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18192                                 > /dev/null
18193                 done
18194
18195                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18196                         error "unlinkmany failed unlink"
18197                 last_rec=$(changelog_users $SINGLEMDS |
18198                         awk '/^current.index:/ { print $NF }')
18199                 echo last record $last_rec
18200                 (( last_rec == 0 )) && error "no changelog found"
18201         done
18202
18203 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18204         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18205
18206         __changelog_clear mds1 $cl_user1 0 &
18207         pid1=$!
18208         sleep 2
18209         __changelog_clear mds1 $cl_user1 0 ||
18210                 error "fail to cancel record for $cl_user1"
18211         wait $pid1
18212         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18213 }
18214 run_test 160n "Changelog destroy race"
18215
18216 test_160o() {
18217         local mdt="$(facet_svc $SINGLEMDS)"
18218
18219         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18220         remote_mds_nodsh && skip "remote MDS with nodsh"
18221         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18222                 skip "Need MDS version at least 2.14.52"
18223
18224         changelog_register --user test_160o -m unlnk+close+open ||
18225                 error "changelog_register failed"
18226
18227         do_facet $SINGLEMDS $LCTL --device $mdt \
18228                                 changelog_register -u "Tt3_-#" &&
18229                 error "bad symbols in name should fail"
18230
18231         do_facet $SINGLEMDS $LCTL --device $mdt \
18232                                 changelog_register -u test_160o &&
18233                 error "the same name registration should fail"
18234
18235         do_facet $SINGLEMDS $LCTL --device $mdt \
18236                         changelog_register -u test_160toolongname &&
18237                 error "too long name registration should fail"
18238
18239         changelog_chmask "MARK+HSM"
18240         lctl get_param mdd.*.changelog*mask
18241         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18242         changelog_users $SINGLEMDS | grep -q $cl_user ||
18243                 error "User $cl_user not found in changelog_users"
18244         #verify username
18245         echo $cl_user | grep -q test_160o ||
18246                 error "User $cl_user has no specific name 'test160o'"
18247
18248         # change something
18249         changelog_clear 0 || error "changelog_clear failed"
18250         # generate some changelog records to accumulate on MDT0
18251         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18252         touch $DIR/$tdir/$tfile                 # open 1
18253
18254         OPENS=$(changelog_dump | grep -c "OPEN")
18255         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18256
18257         # must be no MKDIR it wasn't set as user mask
18258         MKDIR=$(changelog_dump | grep -c "MKDIR")
18259         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18260
18261         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18262                                 mdd.$mdt.changelog_current_mask -n)
18263         # register maskless user
18264         changelog_register || error "changelog_register failed"
18265         # effective mask should be not changed because it is not minimal
18266         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18267                                 mdd.$mdt.changelog_current_mask -n)
18268         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18269         # set server mask to minimal value
18270         changelog_chmask "MARK"
18271         # check effective mask again, should be treated as DEFMASK now
18272         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18273                                 mdd.$mdt.changelog_current_mask -n)
18274         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18275
18276         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18277                 # set server mask back to some value
18278                 changelog_chmask "CLOSE,UNLNK"
18279                 # check effective mask again, should not remain as DEFMASK
18280                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18281                                 mdd.$mdt.changelog_current_mask -n)
18282                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18283         fi
18284
18285         do_facet $SINGLEMDS $LCTL --device $mdt \
18286                                 changelog_deregister -u test_160o ||
18287                 error "cannot deregister by name"
18288 }
18289 run_test 160o "changelog user name and mask"
18290
18291 test_160p() {
18292         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18293         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18294                 skip "Need MDS version at least 2.14.51"
18295         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18296         local cl_users
18297         local cl_user1
18298         local entry_count
18299
18300         # Create a user
18301         changelog_register || error "first changelog_register failed"
18302
18303         cl_users=(${CL_USERS[mds1]})
18304         cl_user1="${cl_users[0]}"
18305
18306         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18307         createmany -m $DIR/$tdir/$tfile 50 ||
18308                 error "create $DIR/$tdir/$tfile failed"
18309         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18310         rm -rf $DIR/$tdir
18311
18312         # check changelogs have been generated
18313         entry_count=$(changelog_dump | wc -l)
18314         ((entry_count != 0)) || error "no changelog entries found"
18315
18316         # remove changelog_users and check that orphan entries are removed
18317         stop mds1
18318         local dev=$(mdsdevname 1)
18319         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18320         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18321         entry_count=$(changelog_dump | wc -l)
18322         ((entry_count == 0)) ||
18323                 error "found $entry_count changelog entries, expected none"
18324 }
18325 run_test 160p "Changelog orphan cleanup with no users"
18326
18327 test_160q() {
18328         local mdt="$(facet_svc $SINGLEMDS)"
18329         local clu
18330
18331         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18332         remote_mds_nodsh && skip "remote MDS with nodsh"
18333         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18334                 skip "Need MDS version at least 2.14.54"
18335
18336         # set server mask to minimal value like server init does
18337         changelog_chmask "MARK"
18338         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18339                 error "changelog_register failed"
18340         # check effective mask again, should be treated as DEFMASK now
18341         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18342                                 mdd.$mdt.changelog_current_mask -n)
18343         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18344                 error "changelog_deregister failed"
18345         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18346 }
18347 run_test 160q "changelog effective mask is DEFMASK if not set"
18348
18349 test_160s() {
18350         remote_mds_nodsh && skip "remote MDS with nodsh"
18351         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18352                 skip "Need MDS version at least 2.14.55"
18353
18354         local mdts=$(comma_list $(mdts_nodes))
18355
18356         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18357         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18358                                        fail_val=$((24 * 3600 * 10))
18359
18360         # Create a user which is 10 days old
18361         changelog_register || error "first changelog_register failed"
18362         local cl_users
18363         declare -A cl_user1
18364         local i
18365
18366         # generate some changelog records to accumulate on each MDT
18367         # use all_char because created files should be evenly distributed
18368         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18369                 error "test_mkdir $tdir failed"
18370         for ((i = 0; i < MDSCOUNT; i++)); do
18371                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18372                         error "create $DIR/$tdir/d$i.1 failed"
18373         done
18374
18375         # check changelogs have been generated
18376         local nbcl=$(changelog_dump | wc -l)
18377         (( nbcl > 0 )) || error "no changelogs found"
18378
18379         # reduce the max_idle_indexes value to make sure we exceed it
18380         for param in "changelog_max_idle_indexes=2097446912" \
18381                      "changelog_max_idle_time=2592000" \
18382                      "changelog_gc=1" \
18383                      "changelog_min_gc_interval=2"; do
18384                 local MDT0=$(facet_svc $SINGLEMDS)
18385                 local var="${param%=*}"
18386                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18387
18388                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18389                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18390                         error "unable to set mdd.*.$param"
18391         done
18392
18393         local start=$SECONDS
18394         for i in $(seq $MDSCOUNT); do
18395                 cl_users=(${CL_USERS[mds$i]})
18396                 cl_user1[mds$i]="${cl_users[0]}"
18397
18398                 [[ -n "${cl_user1[mds$i]}" ]] ||
18399                         error "mds$i: no user registered"
18400         done
18401
18402         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18403         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18404
18405         # ensure we are past the previous changelog_min_gc_interval set above
18406         local sleep2=$((start + 2 - SECONDS))
18407         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18408
18409         # Generate one more changelog to trigger GC
18410         for ((i = 0; i < MDSCOUNT; i++)); do
18411                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18412                         error "create $DIR/$tdir/d$i.3 failed"
18413         done
18414
18415         # ensure gc thread is done
18416         for node in $(mdts_nodes); do
18417                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18418                         error "$node: GC-thread not done"
18419         done
18420
18421         do_nodes $mdts $LCTL set_param fail_loc=0
18422
18423         for (( i = 1; i <= MDSCOUNT; i++ )); do
18424                 # check cl_user1 is purged
18425                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18426                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18427         done
18428         return 0
18429 }
18430 run_test 160s "changelog garbage collect on idle records * time"
18431
18432 test_160t() {
18433         remote_mds_nodsh && skip "remote MDS with nodsh"
18434         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18435                 skip "Need MDS version at least 2.15.50"
18436
18437         local MDT0=$(facet_svc $SINGLEMDS)
18438         local cl_users
18439         local cl_user1
18440         local cl_user2
18441         local start
18442
18443         changelog_register --user user1 -m all ||
18444                 error "user1 failed to register"
18445
18446         mkdir_on_mdt0 $DIR/$tdir
18447         # create default overstripe to maximize changelog size
18448         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18449         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18450         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18451
18452         # user2 consumes less records so less space
18453         changelog_register --user user2 || error "user2 failed to register"
18454         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18455         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18456
18457         # check changelogs have been generated
18458         local nbcl=$(changelog_dump | wc -l)
18459         (( nbcl > 0 )) || error "no changelogs found"
18460
18461         # reduce the changelog_min_gc_interval to force check
18462         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18463                 local var="${param%=*}"
18464                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18465
18466                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18467                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18468                         error "unable to set mdd.*.$param"
18469         done
18470
18471         start=$SECONDS
18472         cl_users=(${CL_USERS[mds1]})
18473         cl_user1="${cl_users[0]}"
18474         cl_user2="${cl_users[1]}"
18475
18476         [[ -n $cl_user1 ]] ||
18477                 error "mds1: user #1 isn't registered"
18478         [[ -n $cl_user2 ]] ||
18479                 error "mds1: user #2 isn't registered"
18480
18481         # ensure we are past the previous changelog_min_gc_interval set above
18482         local sleep2=$((start + 2 - SECONDS))
18483         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18484
18485         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18486         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18487                         fail_val=$(((llog_size1 + llog_size2) / 2))
18488
18489         # Generate more changelog to trigger GC
18490         createmany -o $DIR/$tdir/u3_ 4 ||
18491                 error "create failed for more files"
18492
18493         # ensure gc thread is done
18494         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18495                 error "mds1: GC-thread not done"
18496
18497         do_facet mds1 $LCTL set_param fail_loc=0
18498
18499         # check cl_user1 is purged
18500         changelog_users mds1 | grep -q "$cl_user1" &&
18501                 error "User $cl_user1 is registered"
18502         # check cl_user2 is not purged
18503         changelog_users mds1 | grep -q "$cl_user2" ||
18504                 error "User $cl_user2 is not registered"
18505 }
18506 run_test 160t "changelog garbage collect on lack of space"
18507
18508 test_161a() {
18509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18510
18511         test_mkdir -c1 $DIR/$tdir
18512         cp /etc/hosts $DIR/$tdir/$tfile
18513         test_mkdir -c1 $DIR/$tdir/foo1
18514         test_mkdir -c1 $DIR/$tdir/foo2
18515         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18516         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18517         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18518         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18519         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18520         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18521                 $LFS fid2path $DIR $FID
18522                 error "bad link ea"
18523         fi
18524         # middle
18525         rm $DIR/$tdir/foo2/zachary
18526         # last
18527         rm $DIR/$tdir/foo2/thor
18528         # first
18529         rm $DIR/$tdir/$tfile
18530         # rename
18531         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18532         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18533                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18534         rm $DIR/$tdir/foo2/maggie
18535
18536         # overflow the EA
18537         local longname=$tfile.avg_len_is_thirty_two_
18538         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18539                 error_noexit 'failed to unlink many hardlinks'" EXIT
18540         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18541                 error "failed to hardlink many files"
18542         links=$($LFS fid2path $DIR $FID | wc -l)
18543         echo -n "${links}/1000 links in link EA"
18544         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18545 }
18546 run_test 161a "link ea sanity"
18547
18548 test_161b() {
18549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18550         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18551
18552         local MDTIDX=1
18553         local remote_dir=$DIR/$tdir/remote_dir
18554
18555         mkdir -p $DIR/$tdir
18556         $LFS mkdir -i $MDTIDX $remote_dir ||
18557                 error "create remote directory failed"
18558
18559         cp /etc/hosts $remote_dir/$tfile
18560         mkdir -p $remote_dir/foo1
18561         mkdir -p $remote_dir/foo2
18562         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18563         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18564         ln $remote_dir/$tfile $remote_dir/foo1/luna
18565         ln $remote_dir/$tfile $remote_dir/foo2/thor
18566
18567         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18568                      tr -d ']')
18569         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18570                 $LFS fid2path $DIR $FID
18571                 error "bad link ea"
18572         fi
18573         # middle
18574         rm $remote_dir/foo2/zachary
18575         # last
18576         rm $remote_dir/foo2/thor
18577         # first
18578         rm $remote_dir/$tfile
18579         # rename
18580         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18581         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18582         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18583                 $LFS fid2path $DIR $FID
18584                 error "bad link rename"
18585         fi
18586         rm $remote_dir/foo2/maggie
18587
18588         # overflow the EA
18589         local longname=filename_avg_len_is_thirty_two_
18590         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18591                 error "failed to hardlink many files"
18592         links=$($LFS fid2path $DIR $FID | wc -l)
18593         echo -n "${links}/1000 links in link EA"
18594         [[ ${links} -gt 60 ]] ||
18595                 error "expected at least 60 links in link EA"
18596         unlinkmany $remote_dir/foo2/$longname 1000 ||
18597         error "failed to unlink many hardlinks"
18598 }
18599 run_test 161b "link ea sanity under remote directory"
18600
18601 test_161c() {
18602         remote_mds_nodsh && skip "remote MDS with nodsh"
18603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18604         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18605                 skip "Need MDS version at least 2.1.5"
18606
18607         # define CLF_RENAME_LAST 0x0001
18608         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18609         changelog_register || error "changelog_register failed"
18610
18611         rm -rf $DIR/$tdir
18612         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18613         touch $DIR/$tdir/foo_161c
18614         touch $DIR/$tdir/bar_161c
18615         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18616         changelog_dump | grep RENME | tail -n 5
18617         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18618         changelog_clear 0 || error "changelog_clear failed"
18619         if [ x$flags != "x0x1" ]; then
18620                 error "flag $flags is not 0x1"
18621         fi
18622
18623         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18624         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18625         touch $DIR/$tdir/foo_161c
18626         touch $DIR/$tdir/bar_161c
18627         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18628         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18629         changelog_dump | grep RENME | tail -n 5
18630         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18631         changelog_clear 0 || error "changelog_clear failed"
18632         if [ x$flags != "x0x0" ]; then
18633                 error "flag $flags is not 0x0"
18634         fi
18635         echo "rename overwrite a target having nlink > 1," \
18636                 "changelog record has flags of $flags"
18637
18638         # rename doesn't overwrite a target (changelog flag 0x0)
18639         touch $DIR/$tdir/foo_161c
18640         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18641         changelog_dump | grep RENME | tail -n 5
18642         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18643         changelog_clear 0 || error "changelog_clear failed"
18644         if [ x$flags != "x0x0" ]; then
18645                 error "flag $flags is not 0x0"
18646         fi
18647         echo "rename doesn't overwrite a target," \
18648                 "changelog record has flags of $flags"
18649
18650         # define CLF_UNLINK_LAST 0x0001
18651         # unlink a file having nlink = 1 (changelog flag 0x1)
18652         rm -f $DIR/$tdir/foo2_161c
18653         changelog_dump | grep UNLNK | tail -n 5
18654         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18655         changelog_clear 0 || error "changelog_clear failed"
18656         if [ x$flags != "x0x1" ]; then
18657                 error "flag $flags is not 0x1"
18658         fi
18659         echo "unlink a file having nlink = 1," \
18660                 "changelog record has flags of $flags"
18661
18662         # unlink a file having nlink > 1 (changelog flag 0x0)
18663         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18664         rm -f $DIR/$tdir/foobar_161c
18665         changelog_dump | grep UNLNK | tail -n 5
18666         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18667         changelog_clear 0 || error "changelog_clear failed"
18668         if [ x$flags != "x0x0" ]; then
18669                 error "flag $flags is not 0x0"
18670         fi
18671         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18672 }
18673 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18674
18675 test_161d() {
18676         remote_mds_nodsh && skip "remote MDS with nodsh"
18677         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18678
18679         local pid
18680         local fid
18681
18682         changelog_register || error "changelog_register failed"
18683
18684         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18685         # interfer with $MOUNT/.lustre/fid/ access
18686         mkdir $DIR/$tdir
18687         [[ $? -eq 0 ]] || error "mkdir failed"
18688
18689         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18690         $LCTL set_param fail_loc=0x8000140c
18691         # 5s pause
18692         $LCTL set_param fail_val=5
18693
18694         # create file
18695         echo foofoo > $DIR/$tdir/$tfile &
18696         pid=$!
18697
18698         # wait for create to be delayed
18699         sleep 2
18700
18701         ps -p $pid
18702         [[ $? -eq 0 ]] || error "create should be blocked"
18703
18704         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18705         stack_trap "rm -f $tempfile"
18706         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18707         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18708         # some delay may occur during ChangeLog publishing and file read just
18709         # above, that could allow file write to happen finally
18710         [[ -s $tempfile ]] && echo "file should be empty"
18711
18712         $LCTL set_param fail_loc=0
18713
18714         wait $pid
18715         [[ $? -eq 0 ]] || error "create failed"
18716 }
18717 run_test 161d "create with concurrent .lustre/fid access"
18718
18719 check_path() {
18720         local expected="$1"
18721         shift
18722         local fid="$2"
18723
18724         local path
18725         path=$($LFS fid2path "$@")
18726         local rc=$?
18727
18728         if [ $rc -ne 0 ]; then
18729                 error "path looked up of '$expected' failed: rc=$rc"
18730         elif [ "$path" != "$expected" ]; then
18731                 error "path looked up '$path' instead of '$expected'"
18732         else
18733                 echo "FID '$fid' resolves to path '$path' as expected"
18734         fi
18735 }
18736
18737 test_162a() { # was test_162
18738         test_mkdir -p -c1 $DIR/$tdir/d2
18739         touch $DIR/$tdir/d2/$tfile
18740         touch $DIR/$tdir/d2/x1
18741         touch $DIR/$tdir/d2/x2
18742         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18743         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18744         # regular file
18745         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18746         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18747
18748         # softlink
18749         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18750         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18751         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18752
18753         # softlink to wrong file
18754         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18755         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18756         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18757
18758         # hardlink
18759         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18760         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18761         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18762         # fid2path dir/fsname should both work
18763         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18764         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18765
18766         # hardlink count: check that there are 2 links
18767         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18768         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18769
18770         # hardlink indexing: remove the first link
18771         rm $DIR/$tdir/d2/p/q/r/hlink
18772         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18773 }
18774 run_test 162a "path lookup sanity"
18775
18776 test_162b() {
18777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18779
18780         mkdir $DIR/$tdir
18781         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18782                                 error "create striped dir failed"
18783
18784         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18785                                         tail -n 1 | awk '{print $2}')
18786         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18787
18788         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18789         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18790
18791         # regular file
18792         for ((i=0;i<5;i++)); do
18793                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18794                         error "get fid for f$i failed"
18795                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18796
18797                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18798                         error "get fid for d$i failed"
18799                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18800         done
18801
18802         return 0
18803 }
18804 run_test 162b "striped directory path lookup sanity"
18805
18806 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18807 test_162c() {
18808         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18809                 skip "Need MDS version at least 2.7.51"
18810
18811         local lpath=$tdir.local
18812         local rpath=$tdir.remote
18813
18814         test_mkdir $DIR/$lpath
18815         test_mkdir $DIR/$rpath
18816
18817         for ((i = 0; i <= 101; i++)); do
18818                 lpath="$lpath/$i"
18819                 mkdir $DIR/$lpath
18820                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18821                         error "get fid for local directory $DIR/$lpath failed"
18822                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18823
18824                 rpath="$rpath/$i"
18825                 test_mkdir $DIR/$rpath
18826                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18827                         error "get fid for remote directory $DIR/$rpath failed"
18828                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18829         done
18830
18831         return 0
18832 }
18833 run_test 162c "fid2path works with paths 100 or more directories deep"
18834
18835 oalr_event_count() {
18836         local event="${1}"
18837         local trace="${2}"
18838
18839         awk -v name="${FSNAME}-OST0000" \
18840             -v event="${event}" \
18841             '$1 == "TRACE" && $2 == event && $3 == name' \
18842             "${trace}" |
18843         wc -l
18844 }
18845
18846 oalr_expect_event_count() {
18847         local event="${1}"
18848         local trace="${2}"
18849         local expect="${3}"
18850         local count
18851
18852         count=$(oalr_event_count "${event}" "${trace}")
18853         if ((count == expect)); then
18854                 return 0
18855         fi
18856
18857         error_noexit "${event} event count was '${count}', expected ${expect}"
18858         cat "${trace}" >&2
18859         exit 1
18860 }
18861
18862 cleanup_165() {
18863         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18864         stop ost1
18865         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18866 }
18867
18868 setup_165() {
18869         sync # Flush previous IOs so we can count log entries.
18870         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18871         stack_trap cleanup_165 EXIT
18872 }
18873
18874 test_165a() {
18875         local trace="/tmp/${tfile}.trace"
18876         local rc
18877         local count
18878
18879         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18880                 skip "OFD access log unsupported"
18881
18882         setup_165
18883         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18884         sleep 5
18885
18886         do_facet ost1 ofd_access_log_reader --list
18887         stop ost1
18888
18889         do_facet ost1 killall -TERM ofd_access_log_reader
18890         wait
18891         rc=$?
18892
18893         if ((rc != 0)); then
18894                 error "ofd_access_log_reader exited with rc = '${rc}'"
18895         fi
18896
18897         # Parse trace file for discovery events:
18898         oalr_expect_event_count alr_log_add "${trace}" 1
18899         oalr_expect_event_count alr_log_eof "${trace}" 1
18900         oalr_expect_event_count alr_log_free "${trace}" 1
18901 }
18902 run_test 165a "ofd access log discovery"
18903
18904 test_165b() {
18905         local trace="/tmp/${tfile}.trace"
18906         local file="${DIR}/${tfile}"
18907         local pfid1
18908         local pfid2
18909         local -a entry
18910         local rc
18911         local count
18912         local size
18913         local flags
18914
18915         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18916                 skip "OFD access log unsupported"
18917
18918         setup_165
18919         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18920         sleep 5
18921
18922         do_facet ost1 ofd_access_log_reader --list
18923
18924         lfs setstripe -c 1 -i 0 "${file}"
18925         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18926                 error "cannot create '${file}'"
18927
18928         sleep 5
18929         do_facet ost1 killall -TERM ofd_access_log_reader
18930         wait
18931         rc=$?
18932
18933         if ((rc != 0)); then
18934                 error "ofd_access_log_reader exited with rc = '${rc}'"
18935         fi
18936
18937         oalr_expect_event_count alr_log_entry "${trace}" 1
18938
18939         pfid1=$($LFS path2fid "${file}")
18940
18941         # 1     2             3   4    5     6   7    8    9     10
18942         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18943         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18944
18945         echo "entry = '${entry[*]}'" >&2
18946
18947         pfid2=${entry[4]}
18948         if [[ "${pfid1}" != "${pfid2}" ]]; then
18949                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18950         fi
18951
18952         size=${entry[8]}
18953         if ((size != 1048576)); then
18954                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18955         fi
18956
18957         flags=${entry[10]}
18958         if [[ "${flags}" != "w" ]]; then
18959                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18960         fi
18961
18962         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18963         sleep 5
18964
18965         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18966                 error "cannot read '${file}'"
18967         sleep 5
18968
18969         do_facet ost1 killall -TERM ofd_access_log_reader
18970         wait
18971         rc=$?
18972
18973         if ((rc != 0)); then
18974                 error "ofd_access_log_reader exited with rc = '${rc}'"
18975         fi
18976
18977         oalr_expect_event_count alr_log_entry "${trace}" 1
18978
18979         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18980         echo "entry = '${entry[*]}'" >&2
18981
18982         pfid2=${entry[4]}
18983         if [[ "${pfid1}" != "${pfid2}" ]]; then
18984                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18985         fi
18986
18987         size=${entry[8]}
18988         if ((size != 524288)); then
18989                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18990         fi
18991
18992         flags=${entry[10]}
18993         if [[ "${flags}" != "r" ]]; then
18994                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18995         fi
18996 }
18997 run_test 165b "ofd access log entries are produced and consumed"
18998
18999 test_165c() {
19000         local trace="/tmp/${tfile}.trace"
19001         local file="${DIR}/${tdir}/${tfile}"
19002
19003         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19004                 skip "OFD access log unsupported"
19005
19006         test_mkdir "${DIR}/${tdir}"
19007
19008         setup_165
19009         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19010         sleep 5
19011
19012         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19013
19014         # 4096 / 64 = 64. Create twice as many entries.
19015         for ((i = 0; i < 128; i++)); do
19016                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19017                         error "cannot create file"
19018         done
19019
19020         sync
19021
19022         do_facet ost1 killall -TERM ofd_access_log_reader
19023         wait
19024         rc=$?
19025         if ((rc != 0)); then
19026                 error "ofd_access_log_reader exited with rc = '${rc}'"
19027         fi
19028
19029         unlinkmany  "${file}-%d" 128
19030 }
19031 run_test 165c "full ofd access logs do not block IOs"
19032
19033 oal_get_read_count() {
19034         local stats="$1"
19035
19036         # STATS lustre-OST0001 alr_read_count 1
19037
19038         do_facet ost1 cat "${stats}" |
19039         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19040              END { print count; }'
19041 }
19042
19043 oal_expect_read_count() {
19044         local stats="$1"
19045         local count
19046         local expect="$2"
19047
19048         # Ask ofd_access_log_reader to write stats.
19049         do_facet ost1 killall -USR1 ofd_access_log_reader
19050
19051         # Allow some time for things to happen.
19052         sleep 1
19053
19054         count=$(oal_get_read_count "${stats}")
19055         if ((count == expect)); then
19056                 return 0
19057         fi
19058
19059         error_noexit "bad read count, got ${count}, expected ${expect}"
19060         do_facet ost1 cat "${stats}" >&2
19061         exit 1
19062 }
19063
19064 test_165d() {
19065         local stats="/tmp/${tfile}.stats"
19066         local file="${DIR}/${tdir}/${tfile}"
19067         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19068
19069         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19070                 skip "OFD access log unsupported"
19071
19072         test_mkdir "${DIR}/${tdir}"
19073
19074         setup_165
19075         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19076         sleep 5
19077
19078         lfs setstripe -c 1 -i 0 "${file}"
19079
19080         do_facet ost1 lctl set_param "${param}=rw"
19081         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19082                 error "cannot create '${file}'"
19083         oal_expect_read_count "${stats}" 1
19084
19085         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19086                 error "cannot read '${file}'"
19087         oal_expect_read_count "${stats}" 2
19088
19089         do_facet ost1 lctl set_param "${param}=r"
19090         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19091                 error "cannot create '${file}'"
19092         oal_expect_read_count "${stats}" 2
19093
19094         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19095                 error "cannot read '${file}'"
19096         oal_expect_read_count "${stats}" 3
19097
19098         do_facet ost1 lctl set_param "${param}=w"
19099         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19100                 error "cannot create '${file}'"
19101         oal_expect_read_count "${stats}" 4
19102
19103         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19104                 error "cannot read '${file}'"
19105         oal_expect_read_count "${stats}" 4
19106
19107         do_facet ost1 lctl set_param "${param}=0"
19108         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19109                 error "cannot create '${file}'"
19110         oal_expect_read_count "${stats}" 4
19111
19112         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19113                 error "cannot read '${file}'"
19114         oal_expect_read_count "${stats}" 4
19115
19116         do_facet ost1 killall -TERM ofd_access_log_reader
19117         wait
19118         rc=$?
19119         if ((rc != 0)); then
19120                 error "ofd_access_log_reader exited with rc = '${rc}'"
19121         fi
19122 }
19123 run_test 165d "ofd_access_log mask works"
19124
19125 test_165e() {
19126         local stats="/tmp/${tfile}.stats"
19127         local file0="${DIR}/${tdir}-0/${tfile}"
19128         local file1="${DIR}/${tdir}-1/${tfile}"
19129
19130         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19131                 skip "OFD access log unsupported"
19132
19133         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19134
19135         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19136         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19137
19138         lfs setstripe -c 1 -i 0 "${file0}"
19139         lfs setstripe -c 1 -i 0 "${file1}"
19140
19141         setup_165
19142         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19143         sleep 5
19144
19145         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19146                 error "cannot create '${file0}'"
19147         sync
19148         oal_expect_read_count "${stats}" 0
19149
19150         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19151                 error "cannot create '${file1}'"
19152         sync
19153         oal_expect_read_count "${stats}" 1
19154
19155         do_facet ost1 killall -TERM ofd_access_log_reader
19156         wait
19157         rc=$?
19158         if ((rc != 0)); then
19159                 error "ofd_access_log_reader exited with rc = '${rc}'"
19160         fi
19161 }
19162 run_test 165e "ofd_access_log MDT index filter works"
19163
19164 test_165f() {
19165         local trace="/tmp/${tfile}.trace"
19166         local rc
19167         local count
19168
19169         setup_165
19170         do_facet ost1 timeout 60 ofd_access_log_reader \
19171                 --exit-on-close --debug=- --trace=- > "${trace}" &
19172         sleep 5
19173         stop ost1
19174
19175         wait
19176         rc=$?
19177
19178         if ((rc != 0)); then
19179                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19180                 cat "${trace}"
19181                 exit 1
19182         fi
19183 }
19184 run_test 165f "ofd_access_log_reader --exit-on-close works"
19185
19186 test_169() {
19187         # do directio so as not to populate the page cache
19188         log "creating a 10 Mb file"
19189         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19190                 error "multiop failed while creating a file"
19191         log "starting reads"
19192         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19193         log "truncating the file"
19194         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19195                 error "multiop failed while truncating the file"
19196         log "killing dd"
19197         kill %+ || true # reads might have finished
19198         echo "wait until dd is finished"
19199         wait
19200         log "removing the temporary file"
19201         rm -rf $DIR/$tfile || error "tmp file removal failed"
19202 }
19203 run_test 169 "parallel read and truncate should not deadlock"
19204
19205 test_170() {
19206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19207
19208         $LCTL clear     # bug 18514
19209         $LCTL debug_daemon start $TMP/${tfile}_log_good
19210         touch $DIR/$tfile
19211         $LCTL debug_daemon stop
19212         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19213                 error "sed failed to read log_good"
19214
19215         $LCTL debug_daemon start $TMP/${tfile}_log_good
19216         rm -rf $DIR/$tfile
19217         $LCTL debug_daemon stop
19218
19219         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19220                error "lctl df log_bad failed"
19221
19222         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19223         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19224
19225         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19226         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19227
19228         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19229                 error "bad_line good_line1 good_line2 are empty"
19230
19231         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19232         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19233         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19234
19235         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19236         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19237         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19238
19239         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19240                 error "bad_line_new good_line_new are empty"
19241
19242         local expected_good=$((good_line1 + good_line2*2))
19243
19244         rm -f $TMP/${tfile}*
19245         # LU-231, short malformed line may not be counted into bad lines
19246         if [ $bad_line -ne $bad_line_new ] &&
19247                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19248                 error "expected $bad_line bad lines, but got $bad_line_new"
19249                 return 1
19250         fi
19251
19252         if [ $expected_good -ne $good_line_new ]; then
19253                 error "expected $expected_good good lines, but got $good_line_new"
19254                 return 2
19255         fi
19256         true
19257 }
19258 run_test 170 "test lctl df to handle corrupted log ====================="
19259
19260 test_171() { # bug20592
19261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19262
19263         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19264         $LCTL set_param fail_loc=0x50e
19265         $LCTL set_param fail_val=3000
19266         multiop_bg_pause $DIR/$tfile O_s || true
19267         local MULTIPID=$!
19268         kill -USR1 $MULTIPID
19269         # cause log dump
19270         sleep 3
19271         wait $MULTIPID
19272         if dmesg | grep "recursive fault"; then
19273                 error "caught a recursive fault"
19274         fi
19275         $LCTL set_param fail_loc=0
19276         true
19277 }
19278 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19279
19280 test_172() {
19281
19282         #define OBD_FAIL_OBD_CLEANUP  0x60e
19283         $LCTL set_param fail_loc=0x60e
19284         umount $MOUNT || error "umount $MOUNT failed"
19285         stack_trap "mount_client $MOUNT"
19286
19287         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19288                 error "no client OBDs are remained"
19289
19290         $LCTL dl | while read devno state type name foo; do
19291                 case $type in
19292                 lov|osc|lmv|mdc)
19293                         $LCTL --device $name cleanup
19294                         $LCTL --device $name detach
19295                         ;;
19296                 *)
19297                         # skip server devices
19298                         ;;
19299                 esac
19300         done
19301
19302         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19303                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19304                 error "some client OBDs are still remained"
19305         fi
19306
19307 }
19308 run_test 172 "manual device removal with lctl cleanup/detach ======"
19309
19310 # it would be good to share it with obdfilter-survey/iokit-libecho code
19311 setup_obdecho_osc () {
19312         local rc=0
19313         local ost_nid=$1
19314         local obdfilter_name=$2
19315         echo "Creating new osc for $obdfilter_name on $ost_nid"
19316         # make sure we can find loopback nid
19317         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19318
19319         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19320                            ${obdfilter_name}_osc_UUID || rc=2; }
19321         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19322                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19323         return $rc
19324 }
19325
19326 cleanup_obdecho_osc () {
19327         local obdfilter_name=$1
19328         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19329         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19330         return 0
19331 }
19332
19333 obdecho_test() {
19334         local OBD=$1
19335         local node=$2
19336         local pages=${3:-64}
19337         local rc=0
19338         local id
19339
19340         local count=10
19341         local obd_size=$(get_obd_size $node $OBD)
19342         local page_size=$(get_page_size $node)
19343         if [[ -n "$obd_size" ]]; then
19344                 local new_count=$((obd_size / (pages * page_size / 1024)))
19345                 [[ $new_count -ge $count ]] || count=$new_count
19346         fi
19347
19348         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19349         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19350                            rc=2; }
19351         if [ $rc -eq 0 ]; then
19352             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19353             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19354         fi
19355         echo "New object id is $id"
19356         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19357                            rc=4; }
19358         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19359                            "test_brw $count w v $pages $id" || rc=4; }
19360         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19361                            rc=4; }
19362         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19363                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19364         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19365                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19366         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19367         return $rc
19368 }
19369
19370 test_180a() {
19371         skip "obdecho on osc is no longer supported"
19372 }
19373 run_test 180a "test obdecho on osc"
19374
19375 test_180b() {
19376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19377         remote_ost_nodsh && skip "remote OST with nodsh"
19378
19379         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19380                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19381                 error "failed to load module obdecho"
19382
19383         local target=$(do_facet ost1 $LCTL dl |
19384                        awk '/obdfilter/ { print $4; exit; }')
19385
19386         if [ -n "$target" ]; then
19387                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19388         else
19389                 do_facet ost1 $LCTL dl
19390                 error "there is no obdfilter target on ost1"
19391         fi
19392 }
19393 run_test 180b "test obdecho directly on obdfilter"
19394
19395 test_180c() { # LU-2598
19396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19397         remote_ost_nodsh && skip "remote OST with nodsh"
19398         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19399                 skip "Need MDS version at least 2.4.0"
19400
19401         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19402                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19403                 error "failed to load module obdecho"
19404
19405         local target=$(do_facet ost1 $LCTL dl |
19406                        awk '/obdfilter/ { print $4; exit; }')
19407
19408         if [ -n "$target" ]; then
19409                 local pages=16384 # 64MB bulk I/O RPC size
19410
19411                 obdecho_test "$target" ost1 "$pages" ||
19412                         error "obdecho_test with pages=$pages failed with $?"
19413         else
19414                 do_facet ost1 $LCTL dl
19415                 error "there is no obdfilter target on ost1"
19416         fi
19417 }
19418 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19419
19420 test_181() { # bug 22177
19421         test_mkdir $DIR/$tdir
19422         # create enough files to index the directory
19423         createmany -o $DIR/$tdir/foobar 4000
19424         # print attributes for debug purpose
19425         lsattr -d .
19426         # open dir
19427         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19428         MULTIPID=$!
19429         # remove the files & current working dir
19430         unlinkmany $DIR/$tdir/foobar 4000
19431         rmdir $DIR/$tdir
19432         kill -USR1 $MULTIPID
19433         wait $MULTIPID
19434         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19435         return 0
19436 }
19437 run_test 181 "Test open-unlinked dir ========================"
19438
19439 test_182a() {
19440         local fcount=1000
19441         local tcount=10
19442
19443         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19444
19445         $LCTL set_param mdc.*.rpc_stats=clear
19446
19447         for (( i = 0; i < $tcount; i++ )) ; do
19448                 mkdir $DIR/$tdir/$i
19449         done
19450
19451         for (( i = 0; i < $tcount; i++ )) ; do
19452                 createmany -o $DIR/$tdir/$i/f- $fcount &
19453         done
19454         wait
19455
19456         for (( i = 0; i < $tcount; i++ )) ; do
19457                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19458         done
19459         wait
19460
19461         $LCTL get_param mdc.*.rpc_stats
19462
19463         rm -rf $DIR/$tdir
19464 }
19465 run_test 182a "Test parallel modify metadata operations from mdc"
19466
19467 test_182b() {
19468         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19470         local dcount=1000
19471         local tcount=10
19472         local stime
19473         local etime
19474         local delta
19475
19476         do_facet mds1 $LCTL list_param \
19477                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19478                 skip "MDS lacks parallel RPC handling"
19479
19480         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19481
19482         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19483                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19484
19485         stime=$(date +%s)
19486         createmany -i 0 -d $DIR/$tdir/t- $tcount
19487
19488         for (( i = 0; i < $tcount; i++ )) ; do
19489                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19490         done
19491         wait
19492         etime=$(date +%s)
19493         delta=$((etime - stime))
19494         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19495
19496         stime=$(date +%s)
19497         for (( i = 0; i < $tcount; i++ )) ; do
19498                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19499         done
19500         wait
19501         etime=$(date +%s)
19502         delta=$((etime - stime))
19503         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19504
19505         rm -rf $DIR/$tdir
19506
19507         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19508
19509         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19510
19511         stime=$(date +%s)
19512         createmany -i 0 -d $DIR/$tdir/t- $tcount
19513
19514         for (( i = 0; i < $tcount; i++ )) ; do
19515                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19516         done
19517         wait
19518         etime=$(date +%s)
19519         delta=$((etime - stime))
19520         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19521
19522         stime=$(date +%s)
19523         for (( i = 0; i < $tcount; i++ )) ; do
19524                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19525         done
19526         wait
19527         etime=$(date +%s)
19528         delta=$((etime - stime))
19529         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19530
19531         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19532 }
19533 run_test 182b "Test parallel modify metadata operations from osp"
19534
19535 test_183() { # LU-2275
19536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19537         remote_mds_nodsh && skip "remote MDS with nodsh"
19538         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19539                 skip "Need MDS version at least 2.3.56"
19540
19541         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19542         echo aaa > $DIR/$tdir/$tfile
19543
19544 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19545         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19546
19547         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19548         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19549
19550         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19551
19552         # Flush negative dentry cache
19553         touch $DIR/$tdir/$tfile
19554
19555         # We are not checking for any leaked references here, they'll
19556         # become evident next time we do cleanup with module unload.
19557         rm -rf $DIR/$tdir
19558 }
19559 run_test 183 "No crash or request leak in case of strange dispositions ========"
19560
19561 # test suite 184 is for LU-2016, LU-2017
19562 test_184a() {
19563         check_swap_layouts_support
19564
19565         dir0=$DIR/$tdir/$testnum
19566         test_mkdir -p -c1 $dir0
19567         ref1=/etc/passwd
19568         ref2=/etc/group
19569         file1=$dir0/f1
19570         file2=$dir0/f2
19571         $LFS setstripe -c1 $file1
19572         cp $ref1 $file1
19573         $LFS setstripe -c2 $file2
19574         cp $ref2 $file2
19575         gen1=$($LFS getstripe -g $file1)
19576         gen2=$($LFS getstripe -g $file2)
19577
19578         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19579         gen=$($LFS getstripe -g $file1)
19580         [[ $gen1 != $gen ]] ||
19581                 error "Layout generation on $file1 does not change"
19582         gen=$($LFS getstripe -g $file2)
19583         [[ $gen2 != $gen ]] ||
19584                 error "Layout generation on $file2 does not change"
19585
19586         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19587         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19588
19589         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19590 }
19591 run_test 184a "Basic layout swap"
19592
19593 test_184b() {
19594         check_swap_layouts_support
19595
19596         dir0=$DIR/$tdir/$testnum
19597         mkdir -p $dir0 || error "creating dir $dir0"
19598         file1=$dir0/f1
19599         file2=$dir0/f2
19600         file3=$dir0/f3
19601         dir1=$dir0/d1
19602         dir2=$dir0/d2
19603         mkdir $dir1 $dir2
19604         $LFS setstripe -c1 $file1
19605         $LFS setstripe -c2 $file2
19606         $LFS setstripe -c1 $file3
19607         chown $RUNAS_ID $file3
19608         gen1=$($LFS getstripe -g $file1)
19609         gen2=$($LFS getstripe -g $file2)
19610
19611         $LFS swap_layouts $dir1 $dir2 &&
19612                 error "swap of directories layouts should fail"
19613         $LFS swap_layouts $dir1 $file1 &&
19614                 error "swap of directory and file layouts should fail"
19615         $RUNAS $LFS swap_layouts $file1 $file2 &&
19616                 error "swap of file we cannot write should fail"
19617         $LFS swap_layouts $file1 $file3 &&
19618                 error "swap of file with different owner should fail"
19619         /bin/true # to clear error code
19620 }
19621 run_test 184b "Forbidden layout swap (will generate errors)"
19622
19623 test_184c() {
19624         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19625         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19626         check_swap_layouts_support
19627         check_swap_layout_no_dom $DIR
19628
19629         local dir0=$DIR/$tdir/$testnum
19630         mkdir -p $dir0 || error "creating dir $dir0"
19631
19632         local ref1=$dir0/ref1
19633         local ref2=$dir0/ref2
19634         local file1=$dir0/file1
19635         local file2=$dir0/file2
19636         # create a file large enough for the concurrent test
19637         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19638         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19639         echo "ref file size: ref1($(stat -c %s $ref1))," \
19640              "ref2($(stat -c %s $ref2))"
19641
19642         cp $ref2 $file2
19643         dd if=$ref1 of=$file1 bs=16k &
19644         local DD_PID=$!
19645
19646         # Make sure dd starts to copy file, but wait at most 5 seconds
19647         local loops=0
19648         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19649
19650         $LFS swap_layouts $file1 $file2
19651         local rc=$?
19652         wait $DD_PID
19653         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19654         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19655
19656         # how many bytes copied before swapping layout
19657         local copied=$(stat -c %s $file2)
19658         local remaining=$(stat -c %s $ref1)
19659         remaining=$((remaining - copied))
19660         echo "Copied $copied bytes before swapping layout..."
19661
19662         cmp -n $copied $file1 $ref2 | grep differ &&
19663                 error "Content mismatch [0, $copied) of ref2 and file1"
19664         cmp -n $copied $file2 $ref1 ||
19665                 error "Content mismatch [0, $copied) of ref1 and file2"
19666         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19667                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19668
19669         # clean up
19670         rm -f $ref1 $ref2 $file1 $file2
19671 }
19672 run_test 184c "Concurrent write and layout swap"
19673
19674 test_184d() {
19675         check_swap_layouts_support
19676         check_swap_layout_no_dom $DIR
19677         [ -z "$(which getfattr 2>/dev/null)" ] &&
19678                 skip_env "no getfattr command"
19679
19680         local file1=$DIR/$tdir/$tfile-1
19681         local file2=$DIR/$tdir/$tfile-2
19682         local file3=$DIR/$tdir/$tfile-3
19683         local lovea1
19684         local lovea2
19685
19686         mkdir -p $DIR/$tdir
19687         touch $file1 || error "create $file1 failed"
19688         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19689                 error "create $file2 failed"
19690         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19691                 error "create $file3 failed"
19692         lovea1=$(get_layout_param $file1)
19693
19694         $LFS swap_layouts $file2 $file3 ||
19695                 error "swap $file2 $file3 layouts failed"
19696         $LFS swap_layouts $file1 $file2 ||
19697                 error "swap $file1 $file2 layouts failed"
19698
19699         lovea2=$(get_layout_param $file2)
19700         echo "$lovea1"
19701         echo "$lovea2"
19702         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19703
19704         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19705         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19706 }
19707 run_test 184d "allow stripeless layouts swap"
19708
19709 test_184e() {
19710         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19711                 skip "Need MDS version at least 2.6.94"
19712         check_swap_layouts_support
19713         check_swap_layout_no_dom $DIR
19714         [ -z "$(which getfattr 2>/dev/null)" ] &&
19715                 skip_env "no getfattr command"
19716
19717         local file1=$DIR/$tdir/$tfile-1
19718         local file2=$DIR/$tdir/$tfile-2
19719         local file3=$DIR/$tdir/$tfile-3
19720         local lovea
19721
19722         mkdir -p $DIR/$tdir
19723         touch $file1 || error "create $file1 failed"
19724         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19725                 error "create $file2 failed"
19726         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19727                 error "create $file3 failed"
19728
19729         $LFS swap_layouts $file1 $file2 ||
19730                 error "swap $file1 $file2 layouts failed"
19731
19732         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19733         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19734
19735         echo 123 > $file1 || error "Should be able to write into $file1"
19736
19737         $LFS swap_layouts $file1 $file3 ||
19738                 error "swap $file1 $file3 layouts failed"
19739
19740         echo 123 > $file1 || error "Should be able to write into $file1"
19741
19742         rm -rf $file1 $file2 $file3
19743 }
19744 run_test 184e "Recreate layout after stripeless layout swaps"
19745
19746 test_184f() {
19747         # Create a file with name longer than sizeof(struct stat) ==
19748         # 144 to see if we can get chars from the file name to appear
19749         # in the returned striping. Note that 'f' == 0x66.
19750         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19751
19752         mkdir -p $DIR/$tdir
19753         mcreate $DIR/$tdir/$file
19754         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19755                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19756         fi
19757 }
19758 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19759
19760 test_185() { # LU-2441
19761         # LU-3553 - no volatile file support in old servers
19762         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19763                 skip "Need MDS version at least 2.3.60"
19764
19765         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19766         touch $DIR/$tdir/spoo
19767         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19768         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19769                 error "cannot create/write a volatile file"
19770         [ "$FILESET" == "" ] &&
19771         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19772                 error "FID is still valid after close"
19773
19774         multiop_bg_pause $DIR/$tdir Vw4096_c
19775         local multi_pid=$!
19776
19777         local OLD_IFS=$IFS
19778         IFS=":"
19779         local fidv=($fid)
19780         IFS=$OLD_IFS
19781         # assume that the next FID for this client is sequential, since stdout
19782         # is unfortunately eaten by multiop_bg_pause
19783         local n=$((${fidv[1]} + 1))
19784         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19785         if [ "$FILESET" == "" ]; then
19786                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19787                         error "FID is missing before close"
19788         fi
19789         kill -USR1 $multi_pid
19790         # 1 second delay, so if mtime change we will see it
19791         sleep 1
19792         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19793         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19794 }
19795 run_test 185 "Volatile file support"
19796
19797 function create_check_volatile() {
19798         local idx=$1
19799         local tgt
19800
19801         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19802         local PID=$!
19803         sleep 1
19804         local FID=$(cat /tmp/${tfile}.fid)
19805         [ "$FID" == "" ] && error "can't get FID for volatile"
19806         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19807         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19808         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19809         kill -USR1 $PID
19810         wait
19811         sleep 1
19812         cancel_lru_locks mdc # flush opencache
19813         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19814         return 0
19815 }
19816
19817 test_185a(){
19818         # LU-12516 - volatile creation via .lustre
19819         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19820                 skip "Need MDS version at least 2.3.55"
19821
19822         create_check_volatile 0
19823         [ $MDSCOUNT -lt 2 ] && return 0
19824
19825         # DNE case
19826         create_check_volatile 1
19827
19828         return 0
19829 }
19830 run_test 185a "Volatile file creation in .lustre/fid/"
19831
19832 test_187a() {
19833         remote_mds_nodsh && skip "remote MDS with nodsh"
19834         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19835                 skip "Need MDS version at least 2.3.0"
19836
19837         local dir0=$DIR/$tdir/$testnum
19838         mkdir -p $dir0 || error "creating dir $dir0"
19839
19840         local file=$dir0/file1
19841         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19842         stack_trap "rm -f $file"
19843         local dv1=$($LFS data_version $file)
19844         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19845         local dv2=$($LFS data_version $file)
19846         [[ $dv1 != $dv2 ]] ||
19847                 error "data version did not change on write $dv1 == $dv2"
19848 }
19849 run_test 187a "Test data version change"
19850
19851 test_187b() {
19852         remote_mds_nodsh && skip "remote MDS with nodsh"
19853         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19854                 skip "Need MDS version at least 2.3.0"
19855
19856         local dir0=$DIR/$tdir/$testnum
19857         mkdir -p $dir0 || error "creating dir $dir0"
19858
19859         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19860         [[ ${DV[0]} != ${DV[1]} ]] ||
19861                 error "data version did not change on write"\
19862                       " ${DV[0]} == ${DV[1]}"
19863
19864         # clean up
19865         rm -f $file1
19866 }
19867 run_test 187b "Test data version change on volatile file"
19868
19869 test_200() {
19870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19871         remote_mgs_nodsh && skip "remote MGS with nodsh"
19872         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19873
19874         local POOL=${POOL:-cea1}
19875         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19876         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19877         # Pool OST targets
19878         local first_ost=0
19879         local last_ost=$(($OSTCOUNT - 1))
19880         local ost_step=2
19881         local ost_list=$(seq $first_ost $ost_step $last_ost)
19882         local ost_range="$first_ost $last_ost $ost_step"
19883         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19884         local file_dir=$POOL_ROOT/file_tst
19885         local subdir=$test_path/subdir
19886         local rc=0
19887
19888         while : ; do
19889                 # former test_200a test_200b
19890                 pool_add $POOL                          || { rc=$? ; break; }
19891                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19892                 # former test_200c test_200d
19893                 mkdir -p $test_path
19894                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19895                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19896                 mkdir -p $subdir
19897                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19898                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19899                                                         || { rc=$? ; break; }
19900                 # former test_200e test_200f
19901                 local files=$((OSTCOUNT*3))
19902                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19903                                                         || { rc=$? ; break; }
19904                 pool_create_files $POOL $file_dir $files "$ost_list" \
19905                                                         || { rc=$? ; break; }
19906                 # former test_200g test_200h
19907                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19908                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19909
19910                 # former test_201a test_201b test_201c
19911                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19912
19913                 local f=$test_path/$tfile
19914                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19915                 pool_remove $POOL $f                    || { rc=$? ; break; }
19916                 break
19917         done
19918
19919         destroy_test_pools
19920
19921         return $rc
19922 }
19923 run_test 200 "OST pools"
19924
19925 # usage: default_attr <count | size | offset>
19926 default_attr() {
19927         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19928 }
19929
19930 # usage: check_default_stripe_attr
19931 check_default_stripe_attr() {
19932         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19933         case $1 in
19934         --stripe-count|-c)
19935                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19936         --stripe-size|-S)
19937                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19938         --stripe-index|-i)
19939                 EXPECTED=-1;;
19940         *)
19941                 error "unknown getstripe attr '$1'"
19942         esac
19943
19944         [ $ACTUAL == $EXPECTED ] ||
19945                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19946 }
19947
19948 test_204a() {
19949         test_mkdir $DIR/$tdir
19950         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19951
19952         check_default_stripe_attr --stripe-count
19953         check_default_stripe_attr --stripe-size
19954         check_default_stripe_attr --stripe-index
19955 }
19956 run_test 204a "Print default stripe attributes"
19957
19958 test_204b() {
19959         test_mkdir $DIR/$tdir
19960         $LFS setstripe --stripe-count 1 $DIR/$tdir
19961
19962         check_default_stripe_attr --stripe-size
19963         check_default_stripe_attr --stripe-index
19964 }
19965 run_test 204b "Print default stripe size and offset"
19966
19967 test_204c() {
19968         test_mkdir $DIR/$tdir
19969         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19970
19971         check_default_stripe_attr --stripe-count
19972         check_default_stripe_attr --stripe-index
19973 }
19974 run_test 204c "Print default stripe count and offset"
19975
19976 test_204d() {
19977         test_mkdir $DIR/$tdir
19978         $LFS setstripe --stripe-index 0 $DIR/$tdir
19979
19980         check_default_stripe_attr --stripe-count
19981         check_default_stripe_attr --stripe-size
19982 }
19983 run_test 204d "Print default stripe count and size"
19984
19985 test_204e() {
19986         test_mkdir $DIR/$tdir
19987         $LFS setstripe -d $DIR/$tdir
19988
19989         # LU-16904 check if root is set as PFL layout
19990         local numcomp=$($LFS getstripe --component-count $MOUNT)
19991
19992         if [[ $numcomp -gt 0 ]]; then
19993                 check_default_stripe_attr --stripe-count
19994         else
19995                 check_default_stripe_attr --stripe-count --raw
19996         fi
19997         check_default_stripe_attr --stripe-size --raw
19998         check_default_stripe_attr --stripe-index --raw
19999 }
20000 run_test 204e "Print raw stripe attributes"
20001
20002 test_204f() {
20003         test_mkdir $DIR/$tdir
20004         $LFS setstripe --stripe-count 1 $DIR/$tdir
20005
20006         check_default_stripe_attr --stripe-size --raw
20007         check_default_stripe_attr --stripe-index --raw
20008 }
20009 run_test 204f "Print raw stripe size and offset"
20010
20011 test_204g() {
20012         test_mkdir $DIR/$tdir
20013         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20014
20015         check_default_stripe_attr --stripe-count --raw
20016         check_default_stripe_attr --stripe-index --raw
20017 }
20018 run_test 204g "Print raw stripe count and offset"
20019
20020 test_204h() {
20021         test_mkdir $DIR/$tdir
20022         $LFS setstripe --stripe-index 0 $DIR/$tdir
20023
20024         check_default_stripe_attr --stripe-count --raw
20025         check_default_stripe_attr --stripe-size --raw
20026 }
20027 run_test 204h "Print raw stripe count and size"
20028
20029 # Figure out which job scheduler is being used, if any,
20030 # or use a fake one
20031 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20032         JOBENV=SLURM_JOB_ID
20033 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20034         JOBENV=LSB_JOBID
20035 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20036         JOBENV=PBS_JOBID
20037 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20038         JOBENV=LOADL_STEP_ID
20039 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20040         JOBENV=JOB_ID
20041 else
20042         $LCTL list_param jobid_name > /dev/null 2>&1
20043         if [ $? -eq 0 ]; then
20044                 JOBENV=nodelocal
20045         else
20046                 JOBENV=FAKE_JOBID
20047         fi
20048 fi
20049 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20050
20051 verify_jobstats() {
20052         local cmd=($1)
20053         shift
20054         local facets="$@"
20055
20056 # we don't really need to clear the stats for this test to work, since each
20057 # command has a unique jobid, but it makes debugging easier if needed.
20058 #       for facet in $facets; do
20059 #               local dev=$(convert_facet2label $facet)
20060 #               # clear old jobstats
20061 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20062 #       done
20063
20064         # use a new JobID for each test, or we might see an old one
20065         [ "$JOBENV" = "FAKE_JOBID" ] &&
20066                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20067
20068         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20069
20070         [ "$JOBENV" = "nodelocal" ] && {
20071                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20072                 $LCTL set_param jobid_name=$FAKE_JOBID
20073                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20074         }
20075
20076         log "Test: ${cmd[*]}"
20077         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20078
20079         if [ $JOBENV = "FAKE_JOBID" ]; then
20080                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20081         else
20082                 ${cmd[*]}
20083         fi
20084
20085         # all files are created on OST0000
20086         for facet in $facets; do
20087                 local stats="*.$(convert_facet2label $facet).job_stats"
20088
20089                 # strip out libtool wrappers for in-tree executables
20090                 if (( $(do_facet $facet lctl get_param $stats |
20091                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20092                         do_facet $facet lctl get_param $stats
20093                         error "No jobstats for $JOBVAL found on $facet::$stats"
20094                 fi
20095         done
20096 }
20097
20098 jobstats_set() {
20099         local new_jobenv=$1
20100
20101         set_persistent_param_and_check client "jobid_var" \
20102                 "$FSNAME.sys.jobid_var" $new_jobenv
20103 }
20104
20105 test_205a() { # Job stats
20106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20107         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20108                 skip "Need MDS version with at least 2.7.1"
20109         remote_mgs_nodsh && skip "remote MGS with nodsh"
20110         remote_mds_nodsh && skip "remote MDS with nodsh"
20111         remote_ost_nodsh && skip "remote OST with nodsh"
20112         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20113                 skip "Server doesn't support jobstats"
20114         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20115
20116         local old_jobenv=$($LCTL get_param -n jobid_var)
20117         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20118         stack_trap "jobstats_set $old_jobenv" EXIT
20119
20120         changelog_register
20121
20122         local old_jobid_name=$($LCTL get_param jobid_name)
20123         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20124
20125         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20126                                 mdt.*.job_cleanup_interval | head -n 1)
20127         local new_interval=5
20128         do_facet $SINGLEMDS \
20129                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20130         stack_trap "do_facet $SINGLEMDS \
20131                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20132         local start=$SECONDS
20133
20134         local cmd
20135         # mkdir
20136         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20137         verify_jobstats "$cmd" "$SINGLEMDS"
20138         # rmdir
20139         cmd="rmdir $DIR/$tdir"
20140         verify_jobstats "$cmd" "$SINGLEMDS"
20141         # mkdir on secondary MDT
20142         if [ $MDSCOUNT -gt 1 ]; then
20143                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20144                 verify_jobstats "$cmd" "mds2"
20145         fi
20146         # mknod
20147         cmd="mknod $DIR/$tfile c 1 3"
20148         verify_jobstats "$cmd" "$SINGLEMDS"
20149         # unlink
20150         cmd="rm -f $DIR/$tfile"
20151         verify_jobstats "$cmd" "$SINGLEMDS"
20152         # create all files on OST0000 so verify_jobstats can find OST stats
20153         # open & close
20154         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20155         verify_jobstats "$cmd" "$SINGLEMDS"
20156         # setattr
20157         cmd="touch $DIR/$tfile"
20158         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20159         # write
20160         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20161         verify_jobstats "$cmd" "ost1"
20162         # read
20163         cancel_lru_locks osc
20164         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20165         verify_jobstats "$cmd" "ost1"
20166         # truncate
20167         cmd="$TRUNCATE $DIR/$tfile 0"
20168         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20169         # rename
20170         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20171         verify_jobstats "$cmd" "$SINGLEMDS"
20172         # jobstats expiry - sleep until old stats should be expired
20173         local left=$((new_interval + 5 - (SECONDS - start)))
20174         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20175                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20176                         "0" $left
20177         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20178         verify_jobstats "$cmd" "$SINGLEMDS"
20179         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20180             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20181
20182         # Ensure that jobid are present in changelog (if supported by MDS)
20183         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20184                 changelog_dump | tail -10
20185                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20186                 [ $jobids -eq 9 ] ||
20187                         error "Wrong changelog jobid count $jobids != 9"
20188
20189                 # LU-5862
20190                 JOBENV="disable"
20191                 jobstats_set $JOBENV
20192                 touch $DIR/$tfile
20193                 changelog_dump | grep $tfile
20194                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20195                 [ $jobids -eq 0 ] ||
20196                         error "Unexpected jobids when jobid_var=$JOBENV"
20197         fi
20198
20199         # test '%j' access to environment variable - if supported
20200         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20201                 JOBENV="JOBCOMPLEX"
20202                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20203
20204                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20205         fi
20206
20207         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20208                 JOBENV="JOBCOMPLEX"
20209                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20210
20211                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20212         fi
20213
20214         # test '%j' access to per-session jobid - if supported
20215         if lctl list_param jobid_this_session > /dev/null 2>&1
20216         then
20217                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20218                 lctl set_param jobid_this_session=$USER
20219
20220                 JOBENV="JOBCOMPLEX"
20221                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20222
20223                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20224         fi
20225 }
20226 run_test 205a "Verify job stats"
20227
20228 # LU-13117, LU-13597, LU-16599
20229 test_205b() {
20230         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20231                 skip "Need MDS version at least 2.13.54.91"
20232
20233         local job_stats="mdt.*.job_stats"
20234         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20235
20236         do_facet mds1 $LCTL set_param $job_stats=clear
20237
20238         # Setting jobid_var to USER might not be supported
20239         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20240         $LCTL set_param jobid_var=USER || true
20241         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20242         $LCTL set_param jobid_name="%j.%e.%u"
20243
20244         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20245         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20246                 { do_facet mds1 $LCTL get_param $job_stats;
20247                   error "Unexpected jobid found"; }
20248         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20249                 { do_facet mds1 $LCTL get_param $job_stats;
20250                   error "wrong job_stats format found"; }
20251
20252         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20253                 echo "MDS does not yet escape jobid" && return 0
20254
20255         mkdir_on_mdt0 $DIR/$tdir
20256         $LCTL set_param jobid_var=TEST205b
20257         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20258         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20259                       awk '/has\\x20sp/ {print $3}')
20260         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20261                   error "jobid not escaped"; }
20262
20263         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20264                 # need to run such a command on mds1:
20265                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20266                 #
20267                 # there might be multiple MDTs on single mds server, so need to
20268                 # specifiy MDT0000. Or the command will fail due to other MDTs
20269                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20270                         error "cannot clear escaped jobid in job_stats";
20271         else
20272                 echo "MDS does not support clearing escaped jobid"
20273         fi
20274 }
20275 run_test 205b "Verify job stats jobid and output format"
20276
20277 # LU-13733
20278 test_205c() {
20279         $LCTL set_param llite.*.stats=0
20280         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20281         $LCTL get_param llite.*.stats
20282         $LCTL get_param llite.*.stats | grep \
20283                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20284                         error "wrong client stats format found"
20285 }
20286 run_test 205c "Verify client stats format"
20287
20288 test_205d() {
20289         local file=$DIR/$tdir/$tfile
20290
20291         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20292                 skip "need lustre >= 2.15.53 for lljobstat"
20293         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20294                 skip "need lustre >= 2.15.53 for lljobstat"
20295         verify_yaml_available || skip_env "YAML verification not installed"
20296
20297         test_mkdir -i 0 $DIR/$tdir
20298         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20299         stack_trap "rm -rf $DIR/$tdir"
20300
20301         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20302                 error "failed to write data to $file"
20303         mv $file $file.2
20304
20305         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20306         echo -n 'verify rename_stats...'
20307         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20308                 verify_yaml || error "rename_stats is not valid YAML"
20309         echo " OK"
20310
20311         echo -n 'verify mdt job_stats...'
20312         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20313                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20314         echo " OK"
20315
20316         echo -n 'verify ost job_stats...'
20317         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20318                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20319         echo " OK"
20320 }
20321 run_test 205d "verify the format of some stats files"
20322
20323 test_205e() {
20324         local ops_comma
20325         local file=$DIR/$tdir/$tfile
20326         local -a cli_params
20327
20328         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20329                 skip "need lustre >= 2.15.53 for lljobstat"
20330         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20331                 skip "need lustre >= 2.15.53 for lljobstat"
20332         verify_yaml_available || skip_env "YAML verification not installed"
20333
20334         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20335         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20336         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20337
20338         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20339         stack_trap "rm -rf $DIR/$tdir"
20340
20341         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20342                 error "failed to create $file on ost1"
20343         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20344                 error "failed to write data to $file"
20345
20346         do_facet mds1 "$LCTL get_param *.*.job_stats"
20347         do_facet ost1 "$LCTL get_param *.*.job_stats"
20348
20349         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20350         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20351                 error "The output of lljobstat is not an valid YAML"
20352
20353         # verify that job dd.0 does exist and has some ops on ost1
20354         # typically this line is like:
20355         # - 205e.dd.0:            {ops: 20, ...}
20356         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20357                     awk '$2=="205e.dd.0:" {print $4}')
20358
20359         (( ${ops_comma%,} >= 10 )) ||
20360                 error "cannot find job 205e.dd.0 with ops >= 10"
20361 }
20362 run_test 205e "verify the output of lljobstat"
20363
20364 test_205f() {
20365         verify_yaml_available || skip_env "YAML verification not installed"
20366
20367         # check both qos_ost_weights and qos_mdt_weights
20368         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20369         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20370                 error "qos_ost_weights is not valid YAML"
20371 }
20372 run_test 205f "verify qos_ost_weights YAML format "
20373
20374 __test_205_jobstats_dump() {
20375         local -a pids
20376         local nbr_instance=$1
20377
20378         while true; do
20379                 if (( ${#pids[@]} >= nbr_instance )); then
20380                         wait ${pids[@]}
20381                         pids=()
20382                 fi
20383
20384                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20385                 pids+=( $! )
20386         done
20387 }
20388
20389 __test_205_cleanup() {
20390         kill $@
20391         # Clear all job entries
20392         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20393 }
20394
20395 test_205g() {
20396         local -a mds1_params
20397         local -a cli_params
20398         local pids
20399         local interval=5
20400
20401         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20402         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20403         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20404
20405         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20406         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20407         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20408
20409         # start jobs loop
20410         export TEST205G_ID=205g
20411         stack_trap "unset TEST205G_ID" EXIT
20412         while true; do
20413                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20414         done & pids="$! "
20415
20416         __test_205_jobstats_dump 4 & pids+="$! "
20417         stack_trap "__test_205_cleanup $pids" EXIT INT
20418
20419         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20420 }
20421 run_test 205g "stress test for job_stats procfile"
20422
20423 test_205h() {
20424         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20425                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20426         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20427
20428         local dir=$DIR/$tdir
20429         local f=$dir/$tfile
20430         local f2=$dir/$tfile-2
20431         local f3=$dir/$tfile-3
20432         local subdir=$DIR/dir
20433         local val
20434
20435         local mdts=$(comma_list $(mdts_nodes))
20436         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20437         local client_saved=$($LCTL get_param -n jobid_var)
20438
20439         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20440         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20441
20442         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20443                 error "failed to set job_xattr parameter to user.job"
20444         $LCTL set_param jobid_var=procname.uid ||
20445                 error "failed to set jobid_var parameter"
20446
20447         test_mkdir $dir
20448
20449         touch $f
20450         val=$(getfattr -n user.job $f | grep user.job)
20451         [[ $val = user.job=\"touch.0\" ]] ||
20452                 error "expected user.job=\"touch.0\", got '$val'"
20453
20454         mkdir $subdir
20455         val=$(getfattr -n user.job $subdir | grep user.job)
20456         [[ $val = user.job=\"mkdir.0\" ]] ||
20457                 error "expected user.job=\"mkdir.0\", got '$val'"
20458
20459         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20460                 error "failed to set job_xattr parameter to NONE"
20461
20462         touch $f2
20463         val=$(getfattr -d $f2)
20464         [[ -z $val ]] ||
20465                 error "expected no user xattr, got '$val'"
20466
20467         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20468                 error "failed to set job_xattr parameter to trusted.job"
20469
20470         touch $f3
20471         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20472         [[ $val = trusted.job=\"touch.0\" ]] ||
20473                 error "expected trusted.job=\"touch.0\", got '$val'"
20474 }
20475 run_test 205h "check jobid xattr is stored correctly"
20476
20477 test_205i() {
20478         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20479                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20480
20481         local mdts=$(comma_list $(mdts_nodes))
20482         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20483
20484         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20485
20486         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20487                 error "failed to set mdt.*.job_xattr to user.1234567"
20488
20489         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20490                 error "failed to reject too long job_xattr name"
20491
20492         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20493                 error "failed to reject job_xattr name in bad format"
20494
20495         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20496                 error "failed to reject job_xattr name with invalid character"
20497
20498         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20499                         xargs $LCTL set_param" &&
20500                 error "failed to reject job_xattr name with non-ascii character"
20501
20502         return 0
20503 }
20504 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20505
20506 # LU-1480, LU-1773 and LU-1657
20507 test_206() {
20508         mkdir -p $DIR/$tdir
20509         $LFS setstripe -c -1 $DIR/$tdir
20510 #define OBD_FAIL_LOV_INIT 0x1403
20511         $LCTL set_param fail_loc=0xa0001403
20512         $LCTL set_param fail_val=1
20513         touch $DIR/$tdir/$tfile || true
20514 }
20515 run_test 206 "fail lov_init_raid0() doesn't lbug"
20516
20517 test_207a() {
20518         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20519         local fsz=`stat -c %s $DIR/$tfile`
20520         cancel_lru_locks mdc
20521
20522         # do not return layout in getattr intent
20523 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20524         $LCTL set_param fail_loc=0x170
20525         local sz=`stat -c %s $DIR/$tfile`
20526
20527         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20528
20529         rm -rf $DIR/$tfile
20530 }
20531 run_test 207a "can refresh layout at glimpse"
20532
20533 test_207b() {
20534         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20535         local cksum=`md5sum $DIR/$tfile`
20536         local fsz=`stat -c %s $DIR/$tfile`
20537         cancel_lru_locks mdc
20538         cancel_lru_locks osc
20539
20540         # do not return layout in getattr intent
20541 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20542         $LCTL set_param fail_loc=0x171
20543
20544         # it will refresh layout after the file is opened but before read issues
20545         echo checksum is "$cksum"
20546         echo "$cksum" |md5sum -c --quiet || error "file differs"
20547
20548         rm -rf $DIR/$tfile
20549 }
20550 run_test 207b "can refresh layout at open"
20551
20552 test_208() {
20553         # FIXME: in this test suite, only RD lease is used. This is okay
20554         # for now as only exclusive open is supported. After generic lease
20555         # is done, this test suite should be revised. - Jinshan
20556
20557         remote_mds_nodsh && skip "remote MDS with nodsh"
20558         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20559                 skip "Need MDS version at least 2.4.52"
20560
20561         echo "==== test 1: verify get lease work"
20562         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20563
20564         echo "==== test 2: verify lease can be broken by upcoming open"
20565         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20566         local PID=$!
20567         sleep 2
20568
20569         $MULTIOP $DIR/$tfile oO_RDWR:c
20570         kill -USR1 $PID && wait $PID || error "break lease error"
20571
20572         echo "==== test 3: verify lease can't be granted if an open already exists"
20573         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20574         local PID=$!
20575         sleep 2
20576
20577         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20578         kill -USR1 $PID && wait $PID || error "open file error"
20579
20580         echo "==== test 4: lease can sustain over recovery"
20581         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20582         PID=$!
20583         sleep 2
20584
20585         fail mds1
20586
20587         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20588
20589         echo "==== test 5: lease broken can't be regained by replay"
20590         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20591         PID=$!
20592         sleep 2
20593
20594         # open file to break lease and then recovery
20595         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20596         fail mds1
20597
20598         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20599
20600         rm -f $DIR/$tfile
20601 }
20602 run_test 208 "Exclusive open"
20603
20604 test_209() {
20605         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20606                 skip_env "must have disp_stripe"
20607
20608         touch $DIR/$tfile
20609         sync; sleep 5; sync;
20610
20611         echo 3 > /proc/sys/vm/drop_caches
20612         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20613                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20614         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20615
20616         # open/close 500 times
20617         for i in $(seq 500); do
20618                 cat $DIR/$tfile
20619         done
20620
20621         echo 3 > /proc/sys/vm/drop_caches
20622         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20623                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20624         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20625
20626         echo "before: $req_before, after: $req_after"
20627         [ $((req_after - req_before)) -ge 300 ] &&
20628                 error "open/close requests are not freed"
20629         return 0
20630 }
20631 run_test 209 "read-only open/close requests should be freed promptly"
20632
20633 test_210() {
20634         local pid
20635
20636         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20637         pid=$!
20638         sleep 1
20639
20640         $LFS getstripe $DIR/$tfile
20641         kill -USR1 $pid
20642         wait $pid || error "multiop failed"
20643
20644         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20645         pid=$!
20646         sleep 1
20647
20648         $LFS getstripe $DIR/$tfile
20649         kill -USR1 $pid
20650         wait $pid || error "multiop failed"
20651 }
20652 run_test 210 "lfs getstripe does not break leases"
20653
20654 function test_211() {
20655         local PID
20656         local id
20657         local rc
20658
20659         stack_trap "rm -f $DIR/$tfile" EXIT
20660         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20661                 error "can't create file"
20662         $LFS mirror extend -N $DIR/$tfile ||
20663                 error "can't create a replica"
20664         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20665         $LFS getstripe $DIR/$tfile
20666         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20667         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20668
20669         $MULTIOP $DIR/$tfile OeW_E+eUc &
20670         PID=$!
20671         sleep 0.3
20672
20673         id=$($LFS getstripe $DIR/$tfile |
20674                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20675         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20676                 error "removed last in-sync replica?"
20677
20678         kill -USR1 $PID
20679         wait $PID
20680         (( $? == 0 )) || error "failed split broke the lease"
20681 }
20682 run_test 211 "failed mirror split doesn't break write lease"
20683
20684 test_212() {
20685         size=`date +%s`
20686         size=$((size % 8192 + 1))
20687         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20688         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20689         rm -f $DIR/f212 $DIR/f212.xyz
20690 }
20691 run_test 212 "Sendfile test ============================================"
20692
20693 test_213() {
20694         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20695         cancel_lru_locks osc
20696         lctl set_param fail_loc=0x8000040f
20697         # generate a read lock
20698         cat $DIR/$tfile > /dev/null
20699         # write to the file, it will try to cancel the above read lock.
20700         cat /etc/hosts >> $DIR/$tfile
20701 }
20702 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20703
20704 test_214() { # for bug 20133
20705         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20706         for (( i=0; i < 340; i++ )) ; do
20707                 touch $DIR/$tdir/d214c/a$i
20708         done
20709
20710         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20711         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20712         ls $DIR/d214c || error "ls $DIR/d214c failed"
20713         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20714         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20715 }
20716 run_test 214 "hash-indexed directory test - bug 20133"
20717
20718 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20719 create_lnet_proc_files() {
20720         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20721 }
20722
20723 # counterpart of create_lnet_proc_files
20724 remove_lnet_proc_files() {
20725         rm -f $TMP/lnet_$1.sys
20726 }
20727
20728 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20729 # 3rd arg as regexp for body
20730 check_lnet_proc_stats() {
20731         local l=$(cat "$TMP/lnet_$1" |wc -l)
20732         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20733
20734         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20735 }
20736
20737 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20738 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20739 # optional and can be regexp for 2nd line (lnet.routes case)
20740 check_lnet_proc_entry() {
20741         local blp=2          # blp stands for 'position of 1st line of body'
20742         [ -z "$5" ] || blp=3 # lnet.routes case
20743
20744         local l=$(cat "$TMP/lnet_$1" |wc -l)
20745         # subtracting one from $blp because the body can be empty
20746         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20747
20748         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20749                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20750
20751         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20752                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20753
20754         # bail out if any unexpected line happened
20755         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20756         [ "$?" != 0 ] || error "$2 misformatted"
20757 }
20758
20759 test_215() { # for bugs 18102, 21079, 21517
20760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20761
20762         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20763         local P='[1-9][0-9]*'           # positive numeric
20764         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20765         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20766         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20767         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20768
20769         local L1 # regexp for 1st line
20770         local L2 # regexp for 2nd line (optional)
20771         local BR # regexp for the rest (body)
20772
20773         # lnet.stats should look as 11 space-separated non-negative numerics
20774         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20775         create_lnet_proc_files "stats"
20776         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20777         remove_lnet_proc_files "stats"
20778
20779         # lnet.routes should look like this:
20780         # Routing disabled/enabled
20781         # net hops priority state router
20782         # where net is a string like tcp0, hops > 0, priority >= 0,
20783         # state is up/down,
20784         # router is a string like 192.168.1.1@tcp2
20785         L1="^Routing (disabled|enabled)$"
20786         L2="^net +hops +priority +state +router$"
20787         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20788         create_lnet_proc_files "routes"
20789         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20790         remove_lnet_proc_files "routes"
20791
20792         # lnet.routers should look like this:
20793         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20794         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20795         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20796         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20797         L1="^ref +rtr_ref +alive +router$"
20798         BR="^$P +$P +(up|down) +$NID$"
20799         create_lnet_proc_files "routers"
20800         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20801         remove_lnet_proc_files "routers"
20802
20803         # lnet.peers should look like this:
20804         # nid refs state last max rtr min tx min queue
20805         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20806         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20807         # numeric (0 or >0 or <0), queue >= 0.
20808         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20809         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20810         create_lnet_proc_files "peers"
20811         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20812         remove_lnet_proc_files "peers"
20813
20814         # lnet.buffers  should look like this:
20815         # pages count credits min
20816         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20817         L1="^pages +count +credits +min$"
20818         BR="^ +$N +$N +$I +$I$"
20819         create_lnet_proc_files "buffers"
20820         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20821         remove_lnet_proc_files "buffers"
20822
20823         # lnet.nis should look like this:
20824         # nid status alive refs peer rtr max tx min
20825         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20826         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20827         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20828         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20829         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20830         create_lnet_proc_files "nis"
20831         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20832         remove_lnet_proc_files "nis"
20833
20834         # can we successfully write to lnet.stats?
20835         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20836 }
20837 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20838
20839 test_216() { # bug 20317
20840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20841         remote_ost_nodsh && skip "remote OST with nodsh"
20842
20843         local node
20844         local facets=$(get_facets OST)
20845         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20846
20847         save_lustre_params client "osc.*.contention_seconds" > $p
20848         save_lustre_params $facets \
20849                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20850         save_lustre_params $facets \
20851                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20852         save_lustre_params $facets \
20853                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20854         clear_stats osc.*.osc_stats
20855
20856         # agressive lockless i/o settings
20857         do_nodes $(comma_list $(osts_nodes)) \
20858                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20859                         ldlm.namespaces.filter-*.contended_locks=0 \
20860                         ldlm.namespaces.filter-*.contention_seconds=60"
20861         lctl set_param -n osc.*.contention_seconds=60
20862
20863         $DIRECTIO write $DIR/$tfile 0 10 4096
20864         $CHECKSTAT -s 40960 $DIR/$tfile
20865
20866         # disable lockless i/o
20867         do_nodes $(comma_list $(osts_nodes)) \
20868                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20869                         ldlm.namespaces.filter-*.contended_locks=32 \
20870                         ldlm.namespaces.filter-*.contention_seconds=0"
20871         lctl set_param -n osc.*.contention_seconds=0
20872         clear_stats osc.*.osc_stats
20873
20874         dd if=/dev/zero of=$DIR/$tfile count=0
20875         $CHECKSTAT -s 0 $DIR/$tfile
20876
20877         restore_lustre_params <$p
20878         rm -f $p
20879         rm $DIR/$tfile
20880 }
20881 run_test 216 "check lockless direct write updates file size and kms correctly"
20882
20883 test_217() { # bug 22430
20884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20885
20886         local node
20887
20888         for node in $(nodes_list); do
20889                 local nid=$(host_nids_address $node $NETTYPE)
20890                 local node_ip=$(do_node $node getent ahostsv4 $node |
20891                                 awk '{ print $1; exit; }')
20892
20893                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20894                 # if hostname matches any NID, use hostname for better testing
20895                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20896                         echo "lctl ping node $node@$NETTYPE"
20897                         lctl ping $node@$NETTYPE
20898                 else # otherwise, at least test 'lctl ping' is working
20899                         echo "lctl ping nid $(h2nettype $nid)"
20900                         lctl ping $(h2nettype $nid)
20901                         echo "skipping $node (no hyphen detected)"
20902                 fi
20903         done
20904 }
20905 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20906
20907 test_218() {
20908         # do directio so as not to populate the page cache
20909         log "creating a 10 Mb file"
20910         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20911                 error "multiop failed while creating a file"
20912         log "starting reads"
20913         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20914         log "truncating the file"
20915         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20916                 error "multiop failed while truncating the file"
20917         log "killing dd"
20918         kill %+ || true # reads might have finished
20919         echo "wait until dd is finished"
20920         wait
20921         log "removing the temporary file"
20922         rm -rf $DIR/$tfile || error "tmp file removal failed"
20923 }
20924 run_test 218 "parallel read and truncate should not deadlock"
20925
20926 test_219() {
20927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20928
20929         # write one partial page
20930         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20931         # set no grant so vvp_io_commit_write will do sync write
20932         $LCTL set_param fail_loc=0x411
20933         # write a full page at the end of file
20934         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20935
20936         $LCTL set_param fail_loc=0
20937         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20938         $LCTL set_param fail_loc=0x411
20939         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20940
20941         # LU-4201
20942         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20943         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20944 }
20945 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20946
20947 test_220() { #LU-325
20948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20949         remote_ost_nodsh && skip "remote OST with nodsh"
20950         remote_mds_nodsh && skip "remote MDS with nodsh"
20951         remote_mgs_nodsh && skip "remote MGS with nodsh"
20952
20953         local OSTIDX=0
20954
20955         # create on MDT0000 so the last_id and next_id are correct
20956         mkdir_on_mdt0 $DIR/$tdir
20957         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20958         OST=${OST%_UUID}
20959
20960         # on the mdt's osc
20961         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20962         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20963                         osp.$mdtosc_proc1.prealloc_last_id)
20964         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20965                         osp.$mdtosc_proc1.prealloc_next_id)
20966
20967         $LFS df -i
20968
20969         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20970         #define OBD_FAIL_OST_ENOINO              0x229
20971         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20972         create_pool $FSNAME.$TESTNAME || return 1
20973         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20974
20975         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20976
20977         MDSOBJS=$((last_id - next_id))
20978         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20979
20980         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20981         echo "OST still has $count kbytes free"
20982
20983         echo "create $MDSOBJS files @next_id..."
20984         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20985
20986         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20987                         osp.$mdtosc_proc1.prealloc_last_id)
20988         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20989                         osp.$mdtosc_proc1.prealloc_next_id)
20990
20991         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20992         $LFS df -i
20993
20994         echo "cleanup..."
20995
20996         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20997         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20998
20999         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21000                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21001         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21002                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21003         echo "unlink $MDSOBJS files @$next_id..."
21004         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21005 }
21006 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21007
21008 test_221() {
21009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21010
21011         dd if=`which date` of=$MOUNT/date oflag=sync
21012         chmod +x $MOUNT/date
21013
21014         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21015         $LCTL set_param fail_loc=0x80001401
21016
21017         $MOUNT/date > /dev/null
21018         rm -f $MOUNT/date
21019 }
21020 run_test 221 "make sure fault and truncate race to not cause OOM"
21021
21022 test_222a () {
21023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21024
21025         rm -rf $DIR/$tdir
21026         test_mkdir $DIR/$tdir
21027         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21028         createmany -o $DIR/$tdir/$tfile 10
21029         cancel_lru_locks mdc
21030         cancel_lru_locks osc
21031         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21032         $LCTL set_param fail_loc=0x31a
21033         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21034         $LCTL set_param fail_loc=0
21035         rm -r $DIR/$tdir
21036 }
21037 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21038
21039 test_222b () {
21040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21041
21042         rm -rf $DIR/$tdir
21043         test_mkdir $DIR/$tdir
21044         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21045         createmany -o $DIR/$tdir/$tfile 10
21046         cancel_lru_locks mdc
21047         cancel_lru_locks osc
21048         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21049         $LCTL set_param fail_loc=0x31a
21050         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21051         $LCTL set_param fail_loc=0
21052 }
21053 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21054
21055 test_223 () {
21056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21057
21058         rm -rf $DIR/$tdir
21059         test_mkdir $DIR/$tdir
21060         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21061         createmany -o $DIR/$tdir/$tfile 10
21062         cancel_lru_locks mdc
21063         cancel_lru_locks osc
21064         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21065         $LCTL set_param fail_loc=0x31b
21066         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21067         $LCTL set_param fail_loc=0
21068         rm -r $DIR/$tdir
21069 }
21070 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21071
21072 test_224a() { # LU-1039, MRP-303
21073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21074         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21075         $LCTL set_param fail_loc=0x508
21076         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21077         $LCTL set_param fail_loc=0
21078         df $DIR
21079 }
21080 run_test 224a "Don't panic on bulk IO failure"
21081
21082 test_224bd_sub() { # LU-1039, MRP-303
21083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21084         local timeout=$1
21085
21086         shift
21087         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21088
21089         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21090
21091         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21092         cancel_lru_locks osc
21093         set_checksums 0
21094         stack_trap "set_checksums $ORIG_CSUM" EXIT
21095         local at_max_saved=0
21096
21097         # adaptive timeouts may prevent seeing the issue
21098         if at_is_enabled; then
21099                 at_max_saved=$(at_max_get mds)
21100                 at_max_set 0 mds client
21101                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21102         fi
21103
21104         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21105         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21106         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21107
21108         do_facet ost1 $LCTL set_param fail_loc=0
21109         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21110         df $DIR
21111 }
21112
21113 test_224b() {
21114         test_224bd_sub 3 error "dd failed"
21115 }
21116 run_test 224b "Don't panic on bulk IO failure"
21117
21118 test_224c() { # LU-6441
21119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21120         remote_mds_nodsh && skip "remote MDS with nodsh"
21121
21122         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21123         save_writethrough $p
21124         set_cache writethrough on
21125
21126         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21127         local at_max=$($LCTL get_param -n at_max)
21128         local timeout=$($LCTL get_param -n timeout)
21129         local test_at="at_max"
21130         local param_at="$FSNAME.sys.at_max"
21131         local test_timeout="timeout"
21132         local param_timeout="$FSNAME.sys.timeout"
21133
21134         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21135
21136         set_persistent_param_and_check client "$test_at" "$param_at" 0
21137         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21138
21139         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21140         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21141         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21142         stack_trap "rm -f $DIR/$tfile"
21143         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21144         sync
21145         do_facet ost1 "$LCTL set_param fail_loc=0"
21146
21147         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21148         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21149                 $timeout
21150
21151         $LCTL set_param -n $pages_per_rpc
21152         restore_lustre_params < $p
21153         rm -f $p
21154 }
21155 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21156
21157 test_224d() { # LU-11169
21158         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21159 }
21160 run_test 224d "Don't corrupt data on bulk IO timeout"
21161
21162 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21163 test_225a () {
21164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21165         if [ -z ${MDSSURVEY} ]; then
21166                 skip_env "mds-survey not found"
21167         fi
21168         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21169                 skip "Need MDS version at least 2.2.51"
21170
21171         local mds=$(facet_host $SINGLEMDS)
21172         local target=$(do_nodes $mds 'lctl dl' |
21173                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21174
21175         local cmd1="file_count=1000 thrhi=4"
21176         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21177         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21178         local cmd="$cmd1 $cmd2 $cmd3"
21179
21180         rm -f ${TMP}/mds_survey*
21181         echo + $cmd
21182         eval $cmd || error "mds-survey with zero-stripe failed"
21183         cat ${TMP}/mds_survey*
21184         rm -f ${TMP}/mds_survey*
21185 }
21186 run_test 225a "Metadata survey sanity with zero-stripe"
21187
21188 test_225b () {
21189         if [ -z ${MDSSURVEY} ]; then
21190                 skip_env "mds-survey not found"
21191         fi
21192         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21193                 skip "Need MDS version at least 2.2.51"
21194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21195         remote_mds_nodsh && skip "remote MDS with nodsh"
21196         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21197                 skip_env "Need to mount OST to test"
21198         fi
21199
21200         local mds=$(facet_host $SINGLEMDS)
21201         local target=$(do_nodes $mds 'lctl dl' |
21202                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21203
21204         local cmd1="file_count=1000 thrhi=4"
21205         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21206         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21207         local cmd="$cmd1 $cmd2 $cmd3"
21208
21209         rm -f ${TMP}/mds_survey*
21210         echo + $cmd
21211         eval $cmd || error "mds-survey with stripe_count failed"
21212         cat ${TMP}/mds_survey*
21213         rm -f ${TMP}/mds_survey*
21214 }
21215 run_test 225b "Metadata survey sanity with stripe_count = 1"
21216
21217 mcreate_path2fid () {
21218         local mode=$1
21219         local major=$2
21220         local minor=$3
21221         local name=$4
21222         local desc=$5
21223         local path=$DIR/$tdir/$name
21224         local fid
21225         local rc
21226         local fid_path
21227
21228         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21229                 error "cannot create $desc"
21230
21231         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21232         rc=$?
21233         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21234
21235         fid_path=$($LFS fid2path $MOUNT $fid)
21236         rc=$?
21237         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21238
21239         [ "$path" == "$fid_path" ] ||
21240                 error "fid2path returned $fid_path, expected $path"
21241
21242         echo "pass with $path and $fid"
21243 }
21244
21245 test_226a () {
21246         rm -rf $DIR/$tdir
21247         mkdir -p $DIR/$tdir
21248
21249         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21250         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21251         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21252         mcreate_path2fid 0040666 0 0 dir "directory"
21253         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21254         mcreate_path2fid 0100666 0 0 file "regular file"
21255         mcreate_path2fid 0120666 0 0 link "symbolic link"
21256         mcreate_path2fid 0140666 0 0 sock "socket"
21257 }
21258 run_test 226a "call path2fid and fid2path on files of all type"
21259
21260 test_226b () {
21261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21262
21263         local MDTIDX=1
21264
21265         rm -rf $DIR/$tdir
21266         mkdir -p $DIR/$tdir
21267         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21268                 error "create remote directory failed"
21269         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21270         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21271                                 "character special file (null)"
21272         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21273                                 "character special file (no device)"
21274         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21275         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21276                                 "block special file (loop)"
21277         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21278         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21279         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21280 }
21281 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21282
21283 test_226c () {
21284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21285         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21286                 skip "Need MDS version at least 2.13.55"
21287
21288         local submnt=/mnt/submnt
21289         local srcfile=/etc/passwd
21290         local dstfile=$submnt/passwd
21291         local path
21292         local fid
21293
21294         rm -rf $DIR/$tdir
21295         rm -rf $submnt
21296         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21297                 error "create remote directory failed"
21298         mkdir -p $submnt || error "create $submnt failed"
21299         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21300                 error "mount $submnt failed"
21301         stack_trap "umount $submnt" EXIT
21302
21303         cp $srcfile $dstfile
21304         fid=$($LFS path2fid $dstfile)
21305         path=$($LFS fid2path $submnt "$fid")
21306         [ "$path" = "$dstfile" ] ||
21307                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21308 }
21309 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21310
21311 test_226d () {
21312         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21313                 skip "Need client at least version 2.15.57"
21314
21315         # Define First test dataset
21316         local testdirs_01=$DIR/$tdir
21317         local testdata_01=$testdirs_01/${tdir}_01
21318         local testresult_01=${tdir}_01
21319         # Define Second test dataset
21320         local testdirs_02=$DIR/$tdir/$tdir
21321         local testdata_02=$testdirs_02/${tdir}_02
21322         local testresult_02=${tdir}_02
21323         # Define third test dataset (top level)
21324         local testdata_03=$DIR/${tdir}_03
21325         local testresult_03=${tdir}_03
21326
21327         # Create first test dataset
21328         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21329         touch $testdata_01 || error "cannot create file $testdata_01"
21330
21331         # Create second test dataset
21332         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21333         touch $testdata_02 || error "cannot create file $testdata_02"
21334
21335         # Create third test dataset
21336         touch $testdata_03 || error "cannot create file $testdata_03"
21337
21338         local fid01=$($LFS getstripe -F "$testdata_01") ||
21339                 error "getstripe failed on $testdata_01"
21340         local fid02=$($LFS getstripe -F "$testdata_02") ||
21341                 error "getstripe failed on $testdata_01"
21342         local fid03=$($LFS getstripe -F "$testdata_03") ||
21343                 error "getstripe failed on $testdata_03"
21344
21345         # Verify only -n option
21346         local out1=$($LFS fid2path -n $DIR $fid01) ||
21347                 error "fid2path failed on $fid01"
21348         local out2=$($LFS fid2path -n $DIR $fid02) ||
21349                 error "fid2path failed on $fid02"
21350         local out3=$($LFS fid2path -n $DIR $fid03) ||
21351                 error "fid2path failed on $fid03"
21352
21353         [[ "$out1" == "$testresult_01" ]] ||
21354                 error "fid2path failed: Expected $testresult_01 got $out1"
21355         [[ "$out2" == "$testresult_02" ]] ||
21356                 error "fid2path failed: Expected $testresult_02 got $out2"
21357         [[ "$out3" == "$testresult_03" ]] ||
21358                 error "fid2path failed: Expected $testresult_03 got $out3"
21359
21360         # Verify with option -fn together
21361         out1=$($LFS fid2path -fn $DIR $fid01) ||
21362                 error "fid2path -fn failed on $fid01"
21363         out2=$($LFS fid2path -fn $DIR $fid02) ||
21364                 error "fid2path -fn failed on $fid02"
21365         out3=$($LFS fid2path -fn $DIR $fid03) ||
21366                 error "fid2path -fn failed on $fid03"
21367
21368         local tmpout=$(echo $out1 | cut -d" " -f2)
21369         [[ "$tmpout" == "$testresult_01" ]] ||
21370                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21371
21372         tmpout=$(echo $out2 | cut -d" " -f2)
21373         [[ "$tmpout" == "$testresult_02" ]] ||
21374                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21375
21376         tmpout=$(echo $out3 | cut -d" " -f2)
21377         [[ "$tmpout" == "$testresult_03" ]] ||
21378                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21379 }
21380 run_test 226d "verify fid2path with -n and -fn option"
21381
21382 test_226e () {
21383         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21384                 skip "Need client at least version 2.15.56"
21385
21386         # Define filename with 'newline' and a space
21387         local testfile="Test"$'\n'"file 01"
21388         # Define link name with multiple 'newline' and a space
21389         local linkfile="Link"$'\n'"file "$'\n'"01"
21390         # Remove prior hard link
21391         rm -f $DIR/"$linkfile"
21392
21393         # Create file
21394         touch $DIR/"$testfile"
21395         # Create link
21396         ln $DIR/"$testfile" $DIR/"$linkfile"
21397
21398         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21399                 error "getstripe failed on $DIR/$testfile"
21400
21401         # Call with -0 option
21402         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21403                 echo "FILE:" | grep -c "FILE:")
21404
21405         # With -0 option the output should be exactly 2 lines.
21406         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21407 }
21408 run_test 226e "Verify path2fid -0 option with newline and space"
21409
21410 # LU-1299 Executing or running ldd on a truncated executable does not
21411 # cause an out-of-memory condition.
21412 test_227() {
21413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21414         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21415
21416         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21417         chmod +x $MOUNT/date
21418
21419         $MOUNT/date > /dev/null
21420         ldd $MOUNT/date > /dev/null
21421         rm -f $MOUNT/date
21422 }
21423 run_test 227 "running truncated executable does not cause OOM"
21424
21425 # LU-1512 try to reuse idle OI blocks
21426 test_228a() {
21427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21428         remote_mds_nodsh && skip "remote MDS with nodsh"
21429         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21430
21431         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21432         local myDIR=$DIR/$tdir
21433
21434         mkdir -p $myDIR
21435         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21436         $LCTL set_param fail_loc=0x80001002
21437         createmany -o $myDIR/t- 10000
21438         $LCTL set_param fail_loc=0
21439         # The guard is current the largest FID holder
21440         touch $myDIR/guard
21441         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21442                     tr -d '[')
21443         local IDX=$(($SEQ % 64))
21444
21445         do_facet $SINGLEMDS sync
21446         # Make sure journal flushed.
21447         sleep 6
21448         local blk1=$(do_facet $SINGLEMDS \
21449                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21450                      grep Blockcount | awk '{print $4}')
21451
21452         # Remove old files, some OI blocks will become idle.
21453         unlinkmany $myDIR/t- 10000
21454         # Create new files, idle OI blocks should be reused.
21455         createmany -o $myDIR/t- 2000
21456         do_facet $SINGLEMDS sync
21457         # Make sure journal flushed.
21458         sleep 6
21459         local blk2=$(do_facet $SINGLEMDS \
21460                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21461                      grep Blockcount | awk '{print $4}')
21462
21463         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21464 }
21465 run_test 228a "try to reuse idle OI blocks"
21466
21467 test_228b() {
21468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21469         remote_mds_nodsh && skip "remote MDS with nodsh"
21470         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21471
21472         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21473         local myDIR=$DIR/$tdir
21474
21475         mkdir -p $myDIR
21476         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21477         $LCTL set_param fail_loc=0x80001002
21478         createmany -o $myDIR/t- 10000
21479         $LCTL set_param fail_loc=0
21480         # The guard is current the largest FID holder
21481         touch $myDIR/guard
21482         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21483                     tr -d '[')
21484         local IDX=$(($SEQ % 64))
21485
21486         do_facet $SINGLEMDS sync
21487         # Make sure journal flushed.
21488         sleep 6
21489         local blk1=$(do_facet $SINGLEMDS \
21490                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21491                      grep Blockcount | awk '{print $4}')
21492
21493         # Remove old files, some OI blocks will become idle.
21494         unlinkmany $myDIR/t- 10000
21495
21496         # stop the MDT
21497         stop $SINGLEMDS || error "Fail to stop MDT."
21498         # remount the MDT
21499         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21500                 error "Fail to start MDT."
21501
21502         client_up || error "Fail to df."
21503         # Create new files, idle OI blocks should be reused.
21504         createmany -o $myDIR/t- 2000
21505         do_facet $SINGLEMDS sync
21506         # Make sure journal flushed.
21507         sleep 6
21508         local blk2=$(do_facet $SINGLEMDS \
21509                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21510                      grep Blockcount | awk '{print $4}')
21511
21512         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21513 }
21514 run_test 228b "idle OI blocks can be reused after MDT restart"
21515
21516 #LU-1881
21517 test_228c() {
21518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21519         remote_mds_nodsh && skip "remote MDS with nodsh"
21520         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21521
21522         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21523         local myDIR=$DIR/$tdir
21524
21525         mkdir -p $myDIR
21526         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21527         $LCTL set_param fail_loc=0x80001002
21528         # 20000 files can guarantee there are index nodes in the OI file
21529         createmany -o $myDIR/t- 20000
21530         $LCTL set_param fail_loc=0
21531         # The guard is current the largest FID holder
21532         touch $myDIR/guard
21533         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21534                     tr -d '[')
21535         local IDX=$(($SEQ % 64))
21536
21537         do_facet $SINGLEMDS sync
21538         # Make sure journal flushed.
21539         sleep 6
21540         local blk1=$(do_facet $SINGLEMDS \
21541                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21542                      grep Blockcount | awk '{print $4}')
21543
21544         # Remove old files, some OI blocks will become idle.
21545         unlinkmany $myDIR/t- 20000
21546         rm -f $myDIR/guard
21547         # The OI file should become empty now
21548
21549         # Create new files, idle OI blocks should be reused.
21550         createmany -o $myDIR/t- 2000
21551         do_facet $SINGLEMDS sync
21552         # Make sure journal flushed.
21553         sleep 6
21554         local blk2=$(do_facet $SINGLEMDS \
21555                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21556                      grep Blockcount | awk '{print $4}')
21557
21558         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21559 }
21560 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21561
21562 test_229() { # LU-2482, LU-3448
21563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21564         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21565         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21566                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21567
21568         rm -f $DIR/$tfile
21569
21570         # Create a file with a released layout and stripe count 2.
21571         $MULTIOP $DIR/$tfile H2c ||
21572                 error "failed to create file with released layout"
21573
21574         $LFS getstripe -v $DIR/$tfile
21575
21576         local pattern=$($LFS getstripe -L $DIR/$tfile)
21577         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21578
21579         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21580                 error "getstripe"
21581         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21582         stat $DIR/$tfile || error "failed to stat released file"
21583
21584         chown $RUNAS_ID $DIR/$tfile ||
21585                 error "chown $RUNAS_ID $DIR/$tfile failed"
21586
21587         chgrp $RUNAS_ID $DIR/$tfile ||
21588                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21589
21590         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21591         rm $DIR/$tfile || error "failed to remove released file"
21592 }
21593 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21594
21595 test_230a() {
21596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21597         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21598         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21599                 skip "Need MDS version at least 2.11.52"
21600
21601         local MDTIDX=1
21602
21603         test_mkdir $DIR/$tdir
21604         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21605         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21606         [ $mdt_idx -ne 0 ] &&
21607                 error "create local directory on wrong MDT $mdt_idx"
21608
21609         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21610                         error "create remote directory failed"
21611         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21612         [ $mdt_idx -ne $MDTIDX ] &&
21613                 error "create remote directory on wrong MDT $mdt_idx"
21614
21615         createmany -o $DIR/$tdir/test_230/t- 10 ||
21616                 error "create files on remote directory failed"
21617         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21618         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21619         rm -r $DIR/$tdir || error "unlink remote directory failed"
21620 }
21621 run_test 230a "Create remote directory and files under the remote directory"
21622
21623 test_230b() {
21624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21625         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21626         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21627                 skip "Need MDS version at least 2.11.52"
21628
21629         local MDTIDX=1
21630         local mdt_index
21631         local i
21632         local file
21633         local pid
21634         local stripe_count
21635         local migrate_dir=$DIR/$tdir/migrate_dir
21636         local other_dir=$DIR/$tdir/other_dir
21637
21638         test_mkdir $DIR/$tdir
21639         test_mkdir -i0 -c1 $migrate_dir
21640         test_mkdir -i0 -c1 $other_dir
21641         for ((i=0; i<10; i++)); do
21642                 mkdir -p $migrate_dir/dir_${i}
21643                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21644                         error "create files under remote dir failed $i"
21645         done
21646
21647         cp /etc/passwd $migrate_dir/$tfile
21648         cp /etc/passwd $other_dir/$tfile
21649         chattr +SAD $migrate_dir
21650         chattr +SAD $migrate_dir/$tfile
21651
21652         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21653         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21654         local old_dir_mode=$(stat -c%f $migrate_dir)
21655         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21656
21657         mkdir -p $migrate_dir/dir_default_stripe2
21658         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21659         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21660
21661         mkdir -p $other_dir
21662         ln $migrate_dir/$tfile $other_dir/luna
21663         ln $migrate_dir/$tfile $migrate_dir/sofia
21664         ln $other_dir/$tfile $migrate_dir/david
21665         ln -s $migrate_dir/$tfile $other_dir/zachary
21666         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21667         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21668
21669         local len
21670         local lnktgt
21671
21672         # inline symlink
21673         for len in 58 59 60; do
21674                 lnktgt=$(str_repeat 'l' $len)
21675                 touch $migrate_dir/$lnktgt
21676                 ln -s $lnktgt $migrate_dir/${len}char_ln
21677         done
21678
21679         # PATH_MAX
21680         for len in 4094 4095; do
21681                 lnktgt=$(str_repeat 'l' $len)
21682                 ln -s $lnktgt $migrate_dir/${len}char_ln
21683         done
21684
21685         # NAME_MAX
21686         for len in 254 255; do
21687                 touch $migrate_dir/$(str_repeat 'l' $len)
21688         done
21689
21690         $LFS migrate -m $MDTIDX $migrate_dir ||
21691                 error "fails on migrating remote dir to MDT1"
21692
21693         echo "migratate to MDT1, then checking.."
21694         for ((i = 0; i < 10; i++)); do
21695                 for file in $(find $migrate_dir/dir_${i}); do
21696                         mdt_index=$($LFS getstripe -m $file)
21697                         # broken symlink getstripe will fail
21698                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21699                                 error "$file is not on MDT${MDTIDX}"
21700                 done
21701         done
21702
21703         # the multiple link file should still in MDT0
21704         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21705         [ $mdt_index == 0 ] ||
21706                 error "$file is not on MDT${MDTIDX}"
21707
21708         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21709         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21710                 error " expect $old_dir_flag get $new_dir_flag"
21711
21712         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21713         [ "$old_file_flag" = "$new_file_flag" ] ||
21714                 error " expect $old_file_flag get $new_file_flag"
21715
21716         local new_dir_mode=$(stat -c%f $migrate_dir)
21717         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21718                 error "expect mode $old_dir_mode get $new_dir_mode"
21719
21720         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21721         [ "$old_file_mode" = "$new_file_mode" ] ||
21722                 error "expect mode $old_file_mode get $new_file_mode"
21723
21724         diff /etc/passwd $migrate_dir/$tfile ||
21725                 error "$tfile different after migration"
21726
21727         diff /etc/passwd $other_dir/luna ||
21728                 error "luna different after migration"
21729
21730         diff /etc/passwd $migrate_dir/sofia ||
21731                 error "sofia different after migration"
21732
21733         diff /etc/passwd $migrate_dir/david ||
21734                 error "david different after migration"
21735
21736         diff /etc/passwd $other_dir/zachary ||
21737                 error "zachary different after migration"
21738
21739         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21740                 error "${tfile}_ln different after migration"
21741
21742         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21743                 error "${tfile}_ln_other different after migration"
21744
21745         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21746         [ $stripe_count = 2 ] ||
21747                 error "dir strpe_count $d != 2 after migration."
21748
21749         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21750         [ $stripe_count = 2 ] ||
21751                 error "file strpe_count $d != 2 after migration."
21752
21753         #migrate back to MDT0
21754         MDTIDX=0
21755
21756         $LFS migrate -m $MDTIDX $migrate_dir ||
21757                 error "fails on migrating remote dir to MDT0"
21758
21759         echo "migrate back to MDT0, checking.."
21760         for file in $(find $migrate_dir); do
21761                 mdt_index=$($LFS getstripe -m $file)
21762                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21763                         error "$file is not on MDT${MDTIDX}"
21764         done
21765
21766         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21767         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21768                 error " expect $old_dir_flag get $new_dir_flag"
21769
21770         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21771         [ "$old_file_flag" = "$new_file_flag" ] ||
21772                 error " expect $old_file_flag get $new_file_flag"
21773
21774         local new_dir_mode=$(stat -c%f $migrate_dir)
21775         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21776                 error "expect mode $old_dir_mode get $new_dir_mode"
21777
21778         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21779         [ "$old_file_mode" = "$new_file_mode" ] ||
21780                 error "expect mode $old_file_mode get $new_file_mode"
21781
21782         diff /etc/passwd ${migrate_dir}/$tfile ||
21783                 error "$tfile different after migration"
21784
21785         diff /etc/passwd ${other_dir}/luna ||
21786                 error "luna different after migration"
21787
21788         diff /etc/passwd ${migrate_dir}/sofia ||
21789                 error "sofia different after migration"
21790
21791         diff /etc/passwd ${other_dir}/zachary ||
21792                 error "zachary different after migration"
21793
21794         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21795                 error "${tfile}_ln different after migration"
21796
21797         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21798                 error "${tfile}_ln_other different after migration"
21799
21800         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21801         [ $stripe_count = 2 ] ||
21802                 error "dir strpe_count $d != 2 after migration."
21803
21804         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21805         [ $stripe_count = 2 ] ||
21806                 error "file strpe_count $d != 2 after migration."
21807
21808         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21809 }
21810 run_test 230b "migrate directory"
21811
21812 test_230c() {
21813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21814         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21815         remote_mds_nodsh && skip "remote MDS with nodsh"
21816         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21817                 skip "Need MDS version at least 2.11.52"
21818
21819         local MDTIDX=1
21820         local total=3
21821         local mdt_index
21822         local file
21823         local migrate_dir=$DIR/$tdir/migrate_dir
21824
21825         #If migrating directory fails in the middle, all entries of
21826         #the directory is still accessiable.
21827         test_mkdir $DIR/$tdir
21828         test_mkdir -i0 -c1 $migrate_dir
21829         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21830         stat $migrate_dir
21831         createmany -o $migrate_dir/f $total ||
21832                 error "create files under ${migrate_dir} failed"
21833
21834         # fail after migrating top dir, and this will fail only once, so the
21835         # first sub file migration will fail (currently f3), others succeed.
21836         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21837         do_facet mds1 lctl set_param fail_loc=0x1801
21838         local t=$(ls $migrate_dir | wc -l)
21839         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21840                 error "migrate should fail"
21841         local u=$(ls $migrate_dir | wc -l)
21842         [ "$u" == "$t" ] || error "$u != $t during migration"
21843
21844         # add new dir/file should succeed
21845         mkdir $migrate_dir/dir ||
21846                 error "mkdir failed under migrating directory"
21847         touch $migrate_dir/file ||
21848                 error "create file failed under migrating directory"
21849
21850         # add file with existing name should fail
21851         for file in $migrate_dir/f*; do
21852                 stat $file > /dev/null || error "stat $file failed"
21853                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21854                         error "open(O_CREAT|O_EXCL) $file should fail"
21855                 $MULTIOP $file m && error "create $file should fail"
21856                 touch $DIR/$tdir/remote_dir/$tfile ||
21857                         error "touch $tfile failed"
21858                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21859                         error "link $file should fail"
21860                 mdt_index=$($LFS getstripe -m $file)
21861                 if [ $mdt_index == 0 ]; then
21862                         # file failed to migrate is not allowed to rename to
21863                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21864                                 error "rename to $file should fail"
21865                 else
21866                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21867                                 error "rename to $file failed"
21868                 fi
21869                 echo hello >> $file || error "write $file failed"
21870         done
21871
21872         # resume migration with different options should fail
21873         $LFS migrate -m 0 $migrate_dir &&
21874                 error "migrate -m 0 $migrate_dir should fail"
21875
21876         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21877                 error "migrate -c 2 $migrate_dir should fail"
21878
21879         # resume migration should succeed
21880         $LFS migrate -m $MDTIDX $migrate_dir ||
21881                 error "migrate $migrate_dir failed"
21882
21883         echo "Finish migration, then checking.."
21884         for file in $(find $migrate_dir); do
21885                 mdt_index=$($LFS getstripe -m $file)
21886                 [ $mdt_index == $MDTIDX ] ||
21887                         error "$file is not on MDT${MDTIDX}"
21888         done
21889
21890         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21891 }
21892 run_test 230c "check directory accessiblity if migration failed"
21893
21894 test_230d() {
21895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21896         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21897         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21898                 skip "Need MDS version at least 2.11.52"
21899         # LU-11235
21900         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21901
21902         local migrate_dir=$DIR/$tdir/migrate_dir
21903         local old_index
21904         local new_index
21905         local old_count
21906         local new_count
21907         local new_hash
21908         local mdt_index
21909         local i
21910         local j
21911
21912         old_index=$((RANDOM % MDSCOUNT))
21913         old_count=$((MDSCOUNT - old_index))
21914         new_index=$((RANDOM % MDSCOUNT))
21915         new_count=$((MDSCOUNT - new_index))
21916         new_hash=1 # for all_char
21917
21918         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21919         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21920
21921         test_mkdir $DIR/$tdir
21922         test_mkdir -i $old_index -c $old_count $migrate_dir
21923
21924         for ((i=0; i<100; i++)); do
21925                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21926                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21927                         error "create files under remote dir failed $i"
21928         done
21929
21930         echo -n "Migrate from MDT$old_index "
21931         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21932         echo -n "to MDT$new_index"
21933         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21934         echo
21935
21936         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21937         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21938                 error "migrate remote dir error"
21939
21940         echo "Finish migration, then checking.."
21941         for file in $(find $migrate_dir -maxdepth 1); do
21942                 mdt_index=$($LFS getstripe -m $file)
21943                 if [ $mdt_index -lt $new_index ] ||
21944                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21945                         error "$file is on MDT$mdt_index"
21946                 fi
21947         done
21948
21949         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21950 }
21951 run_test 230d "check migrate big directory"
21952
21953 test_230e() {
21954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21955         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21956         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21957                 skip "Need MDS version at least 2.11.52"
21958
21959         local i
21960         local j
21961         local a_fid
21962         local b_fid
21963
21964         mkdir_on_mdt0 $DIR/$tdir
21965         mkdir $DIR/$tdir/migrate_dir
21966         mkdir $DIR/$tdir/other_dir
21967         touch $DIR/$tdir/migrate_dir/a
21968         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21969         ls $DIR/$tdir/other_dir
21970
21971         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21972                 error "migrate dir fails"
21973
21974         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21975         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21976
21977         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21978         [ $mdt_index == 0 ] || error "a is not on MDT0"
21979
21980         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21981                 error "migrate dir fails"
21982
21983         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21984         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21985
21986         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21987         [ $mdt_index == 1 ] || error "a is not on MDT1"
21988
21989         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21990         [ $mdt_index == 1 ] || error "b is not on MDT1"
21991
21992         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21993         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21994
21995         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21996
21997         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21998 }
21999 run_test 230e "migrate mulitple local link files"
22000
22001 test_230f() {
22002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22004         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22005                 skip "Need MDS version at least 2.11.52"
22006
22007         local a_fid
22008         local ln_fid
22009
22010         mkdir -p $DIR/$tdir
22011         mkdir $DIR/$tdir/migrate_dir
22012         $LFS mkdir -i1 $DIR/$tdir/other_dir
22013         touch $DIR/$tdir/migrate_dir/a
22014         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22015         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22016         ls $DIR/$tdir/other_dir
22017
22018         # a should be migrated to MDT1, since no other links on MDT0
22019         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22020                 error "#1 migrate dir fails"
22021         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22022         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22023         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22024         [ $mdt_index == 1 ] || error "a is not on MDT1"
22025
22026         # a should stay on MDT1, because it is a mulitple link file
22027         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22028                 error "#2 migrate dir fails"
22029         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22030         [ $mdt_index == 1 ] || error "a is not on MDT1"
22031
22032         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22033                 error "#3 migrate dir fails"
22034
22035         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22036         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22037         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22038
22039         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22040         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22041
22042         # a should be migrated to MDT0, since no other links on MDT1
22043         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22044                 error "#4 migrate dir fails"
22045         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22046         [ $mdt_index == 0 ] || error "a is not on MDT0"
22047
22048         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22049 }
22050 run_test 230f "migrate mulitple remote link files"
22051
22052 test_230g() {
22053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22055         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22056                 skip "Need MDS version at least 2.11.52"
22057
22058         mkdir -p $DIR/$tdir/migrate_dir
22059
22060         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22061                 error "migrating dir to non-exist MDT succeeds"
22062         true
22063 }
22064 run_test 230g "migrate dir to non-exist MDT"
22065
22066 test_230h() {
22067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22069         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22070                 skip "Need MDS version at least 2.11.52"
22071
22072         local mdt_index
22073
22074         mkdir -p $DIR/$tdir/migrate_dir
22075
22076         $LFS migrate -m1 $DIR &&
22077                 error "migrating mountpoint1 should fail"
22078
22079         $LFS migrate -m1 $DIR/$tdir/.. &&
22080                 error "migrating mountpoint2 should fail"
22081
22082         # same as mv
22083         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22084                 error "migrating $tdir/migrate_dir/.. should fail"
22085
22086         true
22087 }
22088 run_test 230h "migrate .. and root"
22089
22090 test_230i() {
22091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22093         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22094                 skip "Need MDS version at least 2.11.52"
22095
22096         mkdir -p $DIR/$tdir/migrate_dir
22097
22098         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22099                 error "migration fails with a tailing slash"
22100
22101         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22102                 error "migration fails with two tailing slashes"
22103 }
22104 run_test 230i "lfs migrate -m tolerates trailing slashes"
22105
22106 test_230j() {
22107         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22108         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22109                 skip "Need MDS version at least 2.11.52"
22110
22111         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22112         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22113                 error "create $tfile failed"
22114         cat /etc/passwd > $DIR/$tdir/$tfile
22115
22116         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22117
22118         cmp /etc/passwd $DIR/$tdir/$tfile ||
22119                 error "DoM file mismatch after migration"
22120 }
22121 run_test 230j "DoM file data not changed after dir migration"
22122
22123 test_230k() {
22124         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22125         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22126                 skip "Need MDS version at least 2.11.56"
22127
22128         local total=20
22129         local files_on_starting_mdt=0
22130
22131         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22132         $LFS getdirstripe $DIR/$tdir
22133         for i in $(seq $total); do
22134                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22135                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22136                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22137         done
22138
22139         echo "$files_on_starting_mdt files on MDT0"
22140
22141         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22142         $LFS getdirstripe $DIR/$tdir
22143
22144         files_on_starting_mdt=0
22145         for i in $(seq $total); do
22146                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22147                         error "file $tfile.$i mismatch after migration"
22148                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22149                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22150         done
22151
22152         echo "$files_on_starting_mdt files on MDT1 after migration"
22153         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22154
22155         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22156         $LFS getdirstripe $DIR/$tdir
22157
22158         files_on_starting_mdt=0
22159         for i in $(seq $total); do
22160                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22161                         error "file $tfile.$i mismatch after 2nd migration"
22162                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22163                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22164         done
22165
22166         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22167         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22168
22169         true
22170 }
22171 run_test 230k "file data not changed after dir migration"
22172
22173 test_230l() {
22174         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22175         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22176                 skip "Need MDS version at least 2.11.56"
22177
22178         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22179         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22180                 error "create files under remote dir failed $i"
22181         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22182 }
22183 run_test 230l "readdir between MDTs won't crash"
22184
22185 test_230m() {
22186         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22187         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22188                 skip "Need MDS version at least 2.11.56"
22189
22190         local MDTIDX=1
22191         local mig_dir=$DIR/$tdir/migrate_dir
22192         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22193         local shortstr="b"
22194         local val
22195
22196         echo "Creating files and dirs with xattrs"
22197         test_mkdir $DIR/$tdir
22198         test_mkdir -i0 -c1 $mig_dir
22199         mkdir $mig_dir/dir
22200         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22201                 error "cannot set xattr attr1 on dir"
22202         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22203                 error "cannot set xattr attr2 on dir"
22204         touch $mig_dir/dir/f0
22205         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22206                 error "cannot set xattr attr1 on file"
22207         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22208                 error "cannot set xattr attr2 on file"
22209         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22210         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22211         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22212         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22213         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22214         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22215         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22216         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22217         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22218
22219         echo "Migrating to MDT1"
22220         $LFS migrate -m $MDTIDX $mig_dir ||
22221                 error "fails on migrating dir to MDT1"
22222
22223         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22224         echo "Checking xattrs"
22225         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22226         [ "$val" = $longstr ] ||
22227                 error "expecting xattr1 $longstr on dir, found $val"
22228         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22229         [ "$val" = $shortstr ] ||
22230                 error "expecting xattr2 $shortstr on dir, found $val"
22231         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22232         [ "$val" = $longstr ] ||
22233                 error "expecting xattr1 $longstr on file, found $val"
22234         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22235         [ "$val" = $shortstr ] ||
22236                 error "expecting xattr2 $shortstr on file, found $val"
22237 }
22238 run_test 230m "xattrs not changed after dir migration"
22239
22240 test_230n() {
22241         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22242         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22243                 skip "Need MDS version at least 2.13.53"
22244
22245         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22246         cat /etc/hosts > $DIR/$tdir/$tfile
22247         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22248         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22249
22250         cmp /etc/hosts $DIR/$tdir/$tfile ||
22251                 error "File data mismatch after migration"
22252 }
22253 run_test 230n "Dir migration with mirrored file"
22254
22255 test_230o() {
22256         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22257         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22258                 skip "Need MDS version at least 2.13.52"
22259
22260         local mdts=$(comma_list $(mdts_nodes))
22261         local timeout=100
22262         local restripe_status
22263         local delta
22264         local i
22265
22266         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22267
22268         # in case "crush" hash type is not set
22269         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22270
22271         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22272                            mdt.*MDT0000.enable_dir_restripe)
22273         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22274         stack_trap "do_nodes $mdts $LCTL set_param \
22275                     mdt.*.enable_dir_restripe=$restripe_status"
22276
22277         mkdir $DIR/$tdir
22278         createmany -m $DIR/$tdir/f 100 ||
22279                 error "create files under remote dir failed $i"
22280         createmany -d $DIR/$tdir/d 100 ||
22281                 error "create dirs under remote dir failed $i"
22282
22283         for i in $(seq 2 $MDSCOUNT); do
22284                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22285                 $LFS setdirstripe -c $i $DIR/$tdir ||
22286                         error "split -c $i $tdir failed"
22287                 wait_update $HOSTNAME \
22288                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22289                         error "dir split not finished"
22290                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22291                         awk '/migrate/ {sum += $2} END { print sum }')
22292                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22293                 # delta is around total_files/stripe_count
22294                 (( $delta < 200 / (i - 1) + 4 )) ||
22295                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22296         done
22297 }
22298 run_test 230o "dir split"
22299
22300 test_230p() {
22301         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22302         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22303                 skip "Need MDS version at least 2.13.52"
22304
22305         local mdts=$(comma_list $(mdts_nodes))
22306         local timeout=100
22307         local restripe_status
22308         local delta
22309         local c
22310
22311         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22312
22313         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22314
22315         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22316                            mdt.*MDT0000.enable_dir_restripe)
22317         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22318         stack_trap "do_nodes $mdts $LCTL set_param \
22319                     mdt.*.enable_dir_restripe=$restripe_status"
22320
22321         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22322         createmany -m $DIR/$tdir/f 100 ||
22323                 error "create files under remote dir failed"
22324         createmany -d $DIR/$tdir/d 100 ||
22325                 error "create dirs under remote dir failed"
22326
22327         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22328                 local mdt_hash="crush"
22329
22330                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22331                 $LFS setdirstripe -c $c $DIR/$tdir ||
22332                         error "split -c $c $tdir failed"
22333                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22334                         mdt_hash="$mdt_hash,fixed"
22335                 elif [ $c -eq 1 ]; then
22336                         mdt_hash="none"
22337                 fi
22338                 wait_update $HOSTNAME \
22339                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22340                         error "dir merge not finished"
22341                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22342                         awk '/migrate/ {sum += $2} END { print sum }')
22343                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22344                 # delta is around total_files/stripe_count
22345                 (( delta < 200 / c + 4 )) ||
22346                         error "$delta files migrated >= $((200 / c + 4))"
22347         done
22348 }
22349 run_test 230p "dir merge"
22350
22351 test_230q() {
22352         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22353         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22354                 skip "Need MDS version at least 2.13.52"
22355
22356         local mdts=$(comma_list $(mdts_nodes))
22357         local saved_threshold=$(do_facet mds1 \
22358                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22359         local saved_delta=$(do_facet mds1 \
22360                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22361         local threshold=100
22362         local delta=2
22363         local total=0
22364         local stripe_count=0
22365         local stripe_index
22366         local nr_files
22367         local create
22368
22369         # test with fewer files on ZFS
22370         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22371
22372         stack_trap "do_nodes $mdts $LCTL set_param \
22373                     mdt.*.dir_split_count=$saved_threshold"
22374         stack_trap "do_nodes $mdts $LCTL set_param \
22375                     mdt.*.dir_split_delta=$saved_delta"
22376         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22377         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22378         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22379         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22380         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22381         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22382
22383         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22384         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22385
22386         create=$((threshold * 3 / 2))
22387         while [ $stripe_count -lt $MDSCOUNT ]; do
22388                 createmany -m $DIR/$tdir/f $total $create ||
22389                         error "create sub files failed"
22390                 stat $DIR/$tdir > /dev/null
22391                 total=$((total + create))
22392                 stripe_count=$((stripe_count + delta))
22393                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22394
22395                 wait_update $HOSTNAME \
22396                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22397                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22398
22399                 wait_update $HOSTNAME \
22400                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22401                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22402
22403                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22404                 echo "$nr_files/$total files on MDT$stripe_index after split"
22405                 # allow 10% margin of imbalance with crush hash
22406                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22407                         error "$nr_files files on MDT$stripe_index after split"
22408
22409                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22410                 [ $nr_files -eq $total ] ||
22411                         error "total sub files $nr_files != $total"
22412         done
22413
22414         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22415
22416         echo "fixed layout directory won't auto split"
22417         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22418         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22419                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22420         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22421                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22422 }
22423 run_test 230q "dir auto split"
22424
22425 test_230r() {
22426         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22427         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22428         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22429                 skip "Need MDS version at least 2.13.54"
22430
22431         # maximum amount of local locks:
22432         # parent striped dir - 2 locks
22433         # new stripe in parent to migrate to - 1 lock
22434         # source and target - 2 locks
22435         # Total 5 locks for regular file
22436         mkdir -p $DIR/$tdir
22437         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22438         touch $DIR/$tdir/dir1/eee
22439
22440         # create 4 hardlink for 4 more locks
22441         # Total: 9 locks > RS_MAX_LOCKS (8)
22442         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22443         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22444         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22445         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22446         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22447         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22448         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22449         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22450
22451         cancel_lru_locks mdc
22452
22453         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22454                 error "migrate dir fails"
22455
22456         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22457 }
22458 run_test 230r "migrate with too many local locks"
22459
22460 test_230s() {
22461         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22462                 skip "Need MDS version at least 2.14.52"
22463
22464         local mdts=$(comma_list $(mdts_nodes))
22465         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22466                                 mdt.*MDT0000.enable_dir_restripe)
22467
22468         stack_trap "do_nodes $mdts $LCTL set_param \
22469                     mdt.*.enable_dir_restripe=$restripe_status"
22470
22471         local st
22472         for st in 0 1; do
22473                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22474                 test_mkdir $DIR/$tdir
22475                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22476                         error "$LFS mkdir should return EEXIST if target exists"
22477                 rmdir $DIR/$tdir
22478         done
22479 }
22480 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22481
22482 test_230t()
22483 {
22484         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22485         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22486                 skip "Need MDS version at least 2.14.50"
22487
22488         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22489         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22490         $LFS project -p 1 -s $DIR/$tdir ||
22491                 error "set $tdir project id failed"
22492         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22493                 error "set subdir project id failed"
22494         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22495 }
22496 run_test 230t "migrate directory with project ID set"
22497
22498 test_230u()
22499 {
22500         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22501         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22502                 skip "Need MDS version at least 2.14.53"
22503
22504         local count
22505
22506         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22507         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22508         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22509         for i in $(seq 0 $((MDSCOUNT - 1))); do
22510                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22511                 echo "$count dirs migrated to MDT$i"
22512         done
22513         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22514         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22515 }
22516 run_test 230u "migrate directory by QOS"
22517
22518 test_230v()
22519 {
22520         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22521         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22522                 skip "Need MDS version at least 2.14.53"
22523
22524         local count
22525
22526         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22527         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22528         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22529         for i in $(seq 0 $((MDSCOUNT - 1))); do
22530                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22531                 echo "$count subdirs migrated to MDT$i"
22532                 (( i == 3 )) && (( count > 0 )) &&
22533                         error "subdir shouldn't be migrated to MDT3"
22534         done
22535         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22536         (( count == 3 )) || error "dirs migrated to $count MDTs"
22537 }
22538 run_test 230v "subdir migrated to the MDT where its parent is located"
22539
22540 test_230w() {
22541         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22542         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22543                 skip "Need MDS version at least 2.15.0"
22544
22545         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22546         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22547         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22548
22549         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22550                 error "migrate failed"
22551
22552         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22553                 error "$tdir stripe count mismatch"
22554
22555         for i in $(seq 0 9); do
22556                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22557                         error "d$i is striped"
22558         done
22559 }
22560 run_test 230w "non-recursive mode dir migration"
22561
22562 test_230x() {
22563         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22564         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22565                 skip "Need MDS version at least 2.15.0"
22566
22567         mkdir -p $DIR/$tdir || error "mkdir failed"
22568         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22569
22570         local mdt_name=$(mdtname_from_index 0)
22571         local low=$(do_facet mds2 $LCTL get_param -n \
22572                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22573         local high=$(do_facet mds2 $LCTL get_param -n \
22574                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22575         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22576         local maxage=$(do_facet mds2 $LCTL get_param -n \
22577                 osp.*$mdt_name-osp-MDT0001.maxage)
22578
22579         stack_trap "do_facet mds2 $LCTL set_param -n \
22580                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22581                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22582         stack_trap "do_facet mds2 $LCTL set_param -n \
22583                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22584
22585         do_facet mds2 $LCTL set_param -n \
22586                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22587         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22588         sleep 4
22589         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22590                 error "migrate $tdir should fail"
22591
22592         do_facet mds2 $LCTL set_param -n \
22593                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22594         do_facet mds2 $LCTL set_param -n \
22595                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22596         sleep 4
22597         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22598                 error "migrate failed"
22599         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22600                 error "$tdir stripe count mismatch"
22601 }
22602 run_test 230x "dir migration check space"
22603
22604 test_230y() {
22605         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22606         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22607                 skip "Need MDS version at least 2.15.55.45"
22608
22609         local pid
22610
22611         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22612         $LFS getdirstripe $DIR/$tdir
22613         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22614         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22615         pid=$!
22616         sleep 1
22617
22618         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22619         do_facet mds2 lctl set_param fail_loc=0x1802
22620
22621         wait $pid
22622         do_facet mds2 lctl set_param fail_loc=0
22623         $LFS getdirstripe $DIR/$tdir
22624         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22625         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22626 }
22627 run_test 230y "unlink dir with bad hash type"
22628
22629 test_230z() {
22630         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22631         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22632                 skip "Need MDS version at least 2.15.55.45"
22633
22634         local pid
22635
22636         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22637         $LFS getdirstripe $DIR/$tdir
22638         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22639         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22640         pid=$!
22641         sleep 1
22642
22643         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22644         do_facet mds2 lctl set_param fail_loc=0x1802
22645
22646         wait $pid
22647         do_facet mds2 lctl set_param fail_loc=0
22648         $LFS getdirstripe $DIR/$tdir
22649
22650         # resume migration
22651         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22652                 error "resume migration failed"
22653         $LFS getdirstripe $DIR/$tdir
22654         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22655                 error "migration is not finished"
22656 }
22657 run_test 230z "resume dir migration with bad hash type"
22658
22659 test_231a()
22660 {
22661         # For simplicity this test assumes that max_pages_per_rpc
22662         # is the same across all OSCs
22663         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22664         local bulk_size=$((max_pages * PAGE_SIZE))
22665         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22666                                        head -n 1)
22667
22668         mkdir -p $DIR/$tdir
22669         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22670                 error "failed to set stripe with -S ${brw_size}M option"
22671         stack_trap "rm -rf $DIR/$tdir"
22672
22673         # clear the OSC stats
22674         $LCTL set_param osc.*.stats=0 &>/dev/null
22675         stop_writeback
22676
22677         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22678         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22679                 oflag=direct &>/dev/null || error "dd failed"
22680
22681         sync; sleep 1; sync # just to be safe
22682         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22683         if [ x$nrpcs != "x1" ]; then
22684                 $LCTL get_param osc.*.stats
22685                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22686         fi
22687
22688         start_writeback
22689         # Drop the OSC cache, otherwise we will read from it
22690         cancel_lru_locks osc
22691
22692         # clear the OSC stats
22693         $LCTL set_param osc.*.stats=0 &>/dev/null
22694
22695         # Client reads $bulk_size.
22696         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22697                 iflag=direct &>/dev/null || error "dd failed"
22698
22699         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22700         if [ x$nrpcs != "x1" ]; then
22701                 $LCTL get_param osc.*.stats
22702                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22703         fi
22704 }
22705 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22706
22707 test_231b() {
22708         mkdir -p $DIR/$tdir
22709         stack_trap "rm -rf $DIR/$tdir"
22710         local i
22711         for i in {0..1023}; do
22712                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22713                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22714                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22715         done
22716         sync
22717 }
22718 run_test 231b "must not assert on fully utilized OST request buffer"
22719
22720 test_232a() {
22721         mkdir -p $DIR/$tdir
22722         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22723
22724         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22725         do_facet ost1 $LCTL set_param fail_loc=0x31c
22726
22727         # ignore dd failure
22728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22729         stack_trap "rm -f $DIR/$tdir/$tfile"
22730
22731         do_facet ost1 $LCTL set_param fail_loc=0
22732         umount_client $MOUNT || error "umount failed"
22733         mount_client $MOUNT || error "mount failed"
22734         stop ost1 || error "cannot stop ost1"
22735         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22736 }
22737 run_test 232a "failed lock should not block umount"
22738
22739 test_232b() {
22740         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22741                 skip "Need MDS version at least 2.10.58"
22742
22743         mkdir -p $DIR/$tdir
22744         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22746         stack_trap "rm -f $DIR/$tdir/$tfile"
22747         sync
22748         cancel_lru_locks osc
22749
22750         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22751         do_facet ost1 $LCTL set_param fail_loc=0x31c
22752
22753         # ignore failure
22754         $LFS data_version $DIR/$tdir/$tfile || true
22755
22756         do_facet ost1 $LCTL set_param fail_loc=0
22757         umount_client $MOUNT || error "umount failed"
22758         mount_client $MOUNT || error "mount failed"
22759         stop ost1 || error "cannot stop ost1"
22760         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22761 }
22762 run_test 232b "failed data version lock should not block umount"
22763
22764 test_233a() {
22765         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22766                 skip "Need MDS version at least 2.3.64"
22767         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22768
22769         local fid=$($LFS path2fid $MOUNT)
22770
22771         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22772                 error "cannot access $MOUNT using its FID '$fid'"
22773 }
22774 run_test 233a "checking that OBF of the FS root succeeds"
22775
22776 test_233b() {
22777         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22778                 skip "Need MDS version at least 2.5.90"
22779         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22780
22781         local fid=$($LFS path2fid $MOUNT/.lustre)
22782
22783         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22784                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22785
22786         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22787         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22788                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22789 }
22790 run_test 233b "checking that OBF of the FS .lustre succeeds"
22791
22792 test_234() {
22793         local p="$TMP/sanityN-$TESTNAME.parameters"
22794         save_lustre_params client "llite.*.xattr_cache" > $p
22795         lctl set_param llite.*.xattr_cache 1 ||
22796                 skip_env "xattr cache is not supported"
22797
22798         mkdir -p $DIR/$tdir || error "mkdir failed"
22799         touch $DIR/$tdir/$tfile || error "touch failed"
22800         # OBD_FAIL_LLITE_XATTR_ENOMEM
22801         $LCTL set_param fail_loc=0x1405
22802         getfattr -n user.attr $DIR/$tdir/$tfile &&
22803                 error "getfattr should have failed with ENOMEM"
22804         $LCTL set_param fail_loc=0x0
22805         rm -rf $DIR/$tdir
22806
22807         restore_lustre_params < $p
22808         rm -f $p
22809 }
22810 run_test 234 "xattr cache should not crash on ENOMEM"
22811
22812 test_235() {
22813         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22814                 skip "Need MDS version at least 2.4.52"
22815
22816         flock_deadlock $DIR/$tfile
22817         local RC=$?
22818         case $RC in
22819                 0)
22820                 ;;
22821                 124) error "process hangs on a deadlock"
22822                 ;;
22823                 *) error "error executing flock_deadlock $DIR/$tfile"
22824                 ;;
22825         esac
22826 }
22827 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22828
22829 #LU-2935
22830 test_236() {
22831         check_swap_layouts_support
22832
22833         local ref1=/etc/passwd
22834         local ref2=/etc/group
22835         local file1=$DIR/$tdir/f1
22836         local file2=$DIR/$tdir/f2
22837
22838         test_mkdir -c1 $DIR/$tdir
22839         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22840         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22841         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22842         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22843         local fd=$(free_fd)
22844         local cmd="exec $fd<>$file2"
22845         eval $cmd
22846         rm $file2
22847         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22848                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22849         cmd="exec $fd>&-"
22850         eval $cmd
22851         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22852
22853         #cleanup
22854         rm -rf $DIR/$tdir
22855 }
22856 run_test 236 "Layout swap on open unlinked file"
22857
22858 # LU-4659 linkea consistency
22859 test_238() {
22860         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22861                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22862                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22863                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22864
22865         touch $DIR/$tfile
22866         ln $DIR/$tfile $DIR/$tfile.lnk
22867         touch $DIR/$tfile.new
22868         mv $DIR/$tfile.new $DIR/$tfile
22869         local fid1=$($LFS path2fid $DIR/$tfile)
22870         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22871         local path1=$($LFS fid2path $FSNAME "$fid1")
22872         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22873         local path2=$($LFS fid2path $FSNAME "$fid2")
22874         [ $tfile.lnk == $path2 ] ||
22875                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22876         rm -f $DIR/$tfile*
22877 }
22878 run_test 238 "Verify linkea consistency"
22879
22880 test_239A() { # was test_239
22881         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22882                 skip "Need MDS version at least 2.5.60"
22883
22884         local list=$(comma_list $(mdts_nodes))
22885
22886         mkdir -p $DIR/$tdir
22887         createmany -o $DIR/$tdir/f- 5000
22888         unlinkmany $DIR/$tdir/f- 5000
22889         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22890                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22891         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22892                         osp.*MDT*.sync_in_flight" | calc_sum)
22893         [ "$changes" -eq 0 ] || error "$changes not synced"
22894 }
22895 run_test 239A "osp_sync test"
22896
22897 test_239a() { #LU-5297
22898         remote_mds_nodsh && skip "remote MDS with nodsh"
22899
22900         touch $DIR/$tfile
22901         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22902         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22903         chgrp $RUNAS_GID $DIR/$tfile
22904         wait_delete_completed
22905 }
22906 run_test 239a "process invalid osp sync record correctly"
22907
22908 test_239b() { #LU-5297
22909         remote_mds_nodsh && skip "remote MDS with nodsh"
22910
22911         touch $DIR/$tfile1
22912         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22913         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22914         chgrp $RUNAS_GID $DIR/$tfile1
22915         wait_delete_completed
22916         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22917         touch $DIR/$tfile2
22918         chgrp $RUNAS_GID $DIR/$tfile2
22919         wait_delete_completed
22920 }
22921 run_test 239b "process osp sync record with ENOMEM error correctly"
22922
22923 test_240() {
22924         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22925         remote_mds_nodsh && skip "remote MDS with nodsh"
22926
22927         mkdir -p $DIR/$tdir
22928
22929         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22930                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22931         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22932                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22933
22934         umount_client $MOUNT || error "umount failed"
22935         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22936         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22937         mount_client $MOUNT || error "failed to mount client"
22938
22939         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22940         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22941 }
22942 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22943
22944 test_241_bio() {
22945         local count=$1
22946         local bsize=$2
22947
22948         for LOOP in $(seq $count); do
22949                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22950                 cancel_lru_locks $OSC || true
22951         done
22952 }
22953
22954 test_241_dio() {
22955         local count=$1
22956         local bsize=$2
22957
22958         for LOOP in $(seq $1); do
22959                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22960                         2>/dev/null
22961         done
22962 }
22963
22964 test_241a() { # was test_241
22965         local bsize=$PAGE_SIZE
22966
22967         (( bsize < 40960 )) && bsize=40960
22968         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22969         ls -la $DIR/$tfile
22970         cancel_lru_locks $OSC
22971         test_241_bio 1000 $bsize &
22972         PID=$!
22973         test_241_dio 1000 $bsize
22974         wait $PID
22975 }
22976 run_test 241a "bio vs dio"
22977
22978 test_241b() {
22979         local bsize=$PAGE_SIZE
22980
22981         (( bsize < 40960 )) && bsize=40960
22982         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22983         ls -la $DIR/$tfile
22984         test_241_dio 1000 $bsize &
22985         PID=$!
22986         test_241_dio 1000 $bsize
22987         wait $PID
22988 }
22989 run_test 241b "dio vs dio"
22990
22991 test_242() {
22992         remote_mds_nodsh && skip "remote MDS with nodsh"
22993
22994         mkdir_on_mdt0 $DIR/$tdir
22995         touch $DIR/$tdir/$tfile
22996
22997         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22998         do_facet mds1 lctl set_param fail_loc=0x105
22999         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23000
23001         do_facet mds1 lctl set_param fail_loc=0
23002         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23003 }
23004 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23005
23006 test_243()
23007 {
23008         test_mkdir $DIR/$tdir
23009         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23010 }
23011 run_test 243 "various group lock tests"
23012
23013 test_244a()
23014 {
23015         test_mkdir $DIR/$tdir
23016         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23017         sendfile_grouplock $DIR/$tdir/$tfile || \
23018                 error "sendfile+grouplock failed"
23019         rm -rf $DIR/$tdir
23020 }
23021 run_test 244a "sendfile with group lock tests"
23022
23023 test_244b()
23024 {
23025         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23026
23027         local threads=50
23028         local size=$((1024*1024))
23029
23030         test_mkdir $DIR/$tdir
23031         for i in $(seq 1 $threads); do
23032                 local file=$DIR/$tdir/file_$((i / 10))
23033                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23034                 local pids[$i]=$!
23035         done
23036         for i in $(seq 1 $threads); do
23037                 wait ${pids[$i]}
23038         done
23039 }
23040 run_test 244b "multi-threaded write with group lock"
23041
23042 test_245a() {
23043         local flagname="multi_mod_rpcs"
23044         local connect_data_name="max_mod_rpcs"
23045         local out
23046
23047         # check if multiple modify RPCs flag is set
23048         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23049                 grep "connect_flags:")
23050         echo "$out"
23051
23052         echo "$out" | grep -qw $flagname
23053         if [ $? -ne 0 ]; then
23054                 echo "connect flag $flagname is not set"
23055                 return
23056         fi
23057
23058         # check if multiple modify RPCs data is set
23059         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23060         echo "$out"
23061
23062         echo "$out" | grep -qw $connect_data_name ||
23063                 error "import should have connect data $connect_data_name"
23064 }
23065 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23066
23067 test_245b() {
23068         local flagname="multi_mod_rpcs"
23069         local connect_data_name="max_mod_rpcs"
23070         local out
23071
23072         remote_mds_nodsh && skip "remote MDS with nodsh"
23073         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23074
23075         # check if multiple modify RPCs flag is set
23076         out=$(do_facet mds1 \
23077               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23078               grep "connect_flags:")
23079         echo "$out"
23080
23081         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23082
23083         # check if multiple modify RPCs data is set
23084         out=$(do_facet mds1 \
23085               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23086
23087         [[ "$out" =~ $connect_data_name ]] ||
23088                 {
23089                         echo "$out"
23090                         error "missing connect data $connect_data_name"
23091                 }
23092 }
23093 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23094
23095 cleanup_247() {
23096         local submount=$1
23097
23098         trap 0
23099         umount_client $submount
23100         rmdir $submount
23101 }
23102
23103 test_247a() {
23104         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23105                 grep -q subtree ||
23106                 skip_env "Fileset feature is not supported"
23107
23108         local submount=${MOUNT}_$tdir
23109
23110         mkdir $MOUNT/$tdir
23111         mkdir -p $submount || error "mkdir $submount failed"
23112         FILESET="$FILESET/$tdir" mount_client $submount ||
23113                 error "mount $submount failed"
23114         trap "cleanup_247 $submount" EXIT
23115         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23116         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23117                 error "read $MOUNT/$tdir/$tfile failed"
23118         cleanup_247 $submount
23119 }
23120 run_test 247a "mount subdir as fileset"
23121
23122 test_247b() {
23123         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23124                 skip_env "Fileset feature is not supported"
23125
23126         local submount=${MOUNT}_$tdir
23127
23128         rm -rf $MOUNT/$tdir
23129         mkdir -p $submount || error "mkdir $submount failed"
23130         SKIP_FILESET=1
23131         FILESET="$FILESET/$tdir" mount_client $submount &&
23132                 error "mount $submount should fail"
23133         rmdir $submount
23134 }
23135 run_test 247b "mount subdir that dose not exist"
23136
23137 test_247c() {
23138         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23139                 skip_env "Fileset feature is not supported"
23140
23141         local submount=${MOUNT}_$tdir
23142
23143         mkdir -p $MOUNT/$tdir/dir1
23144         mkdir -p $submount || error "mkdir $submount failed"
23145         trap "cleanup_247 $submount" EXIT
23146         FILESET="$FILESET/$tdir" mount_client $submount ||
23147                 error "mount $submount failed"
23148         local fid=$($LFS path2fid $MOUNT/)
23149         $LFS fid2path $submount $fid && error "fid2path should fail"
23150         cleanup_247 $submount
23151 }
23152 run_test 247c "running fid2path outside subdirectory root"
23153
23154 test_247d() {
23155         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23156                 skip "Fileset feature is not supported"
23157
23158         local submount=${MOUNT}_$tdir
23159
23160         mkdir -p $MOUNT/$tdir/dir1
23161         mkdir -p $submount || error "mkdir $submount failed"
23162         FILESET="$FILESET/$tdir" mount_client $submount ||
23163                 error "mount $submount failed"
23164         trap "cleanup_247 $submount" EXIT
23165
23166         local td=$submount/dir1
23167         local fid=$($LFS path2fid $td)
23168         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23169
23170         # check that we get the same pathname back
23171         local rootpath
23172         local found
23173         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23174                 echo "$rootpath $fid"
23175                 found=$($LFS fid2path $rootpath "$fid")
23176                 [ -n "$found" ] || error "fid2path should succeed"
23177                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23178         done
23179         # check wrong root path format
23180         rootpath=$submount"_wrong"
23181         found=$($LFS fid2path $rootpath "$fid")
23182         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23183
23184         cleanup_247 $submount
23185 }
23186 run_test 247d "running fid2path inside subdirectory root"
23187
23188 # LU-8037
23189 test_247e() {
23190         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23191                 grep -q subtree ||
23192                 skip "Fileset feature is not supported"
23193
23194         local submount=${MOUNT}_$tdir
23195
23196         mkdir $MOUNT/$tdir
23197         mkdir -p $submount || error "mkdir $submount failed"
23198         FILESET="$FILESET/.." mount_client $submount &&
23199                 error "mount $submount should fail"
23200         rmdir $submount
23201 }
23202 run_test 247e "mount .. as fileset"
23203
23204 test_247f() {
23205         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23206         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23207                 skip "Need at least version 2.14.50.162"
23208         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23209                 skip "Fileset feature is not supported"
23210
23211         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23212         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23213                 error "mkdir remote failed"
23214         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23215                 error "mkdir remote/subdir failed"
23216         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23217                 error "mkdir striped failed"
23218         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23219
23220         local submount=${MOUNT}_$tdir
23221
23222         mkdir -p $submount || error "mkdir $submount failed"
23223         stack_trap "rmdir $submount"
23224
23225         local dir
23226         local fileset=$FILESET
23227         local mdts=$(comma_list $(mdts_nodes))
23228
23229         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23230         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23231                 $tdir/striped/subdir $tdir/striped/.; do
23232                 FILESET="$fileset/$dir" mount_client $submount ||
23233                         error "mount $dir failed"
23234                 umount_client $submount
23235         done
23236 }
23237 run_test 247f "mount striped or remote directory as fileset"
23238
23239 test_subdir_mount_lock()
23240 {
23241         local testdir=$1
23242         local submount=${MOUNT}_$(basename $testdir)
23243
23244         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23245
23246         mkdir -p $submount || error "mkdir $submount failed"
23247         stack_trap "rmdir $submount"
23248
23249         FILESET="$fileset/$testdir" mount_client $submount ||
23250                 error "mount $FILESET failed"
23251         stack_trap "umount $submount"
23252
23253         local mdts=$(comma_list $(mdts_nodes))
23254
23255         local nrpcs
23256
23257         stat $submount > /dev/null || error "stat $submount failed"
23258         cancel_lru_locks $MDC
23259         stat $submount > /dev/null || error "stat $submount failed"
23260         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23261         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23262         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23263         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23264                 awk '/getattr/ {sum += $2} END {print sum}')
23265
23266         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23267 }
23268
23269 test_247g() {
23270         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23271
23272         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23273                 error "mkdir $tdir failed"
23274         test_subdir_mount_lock $tdir
23275 }
23276 run_test 247g "striped directory submount revalidate ROOT from cache"
23277
23278 test_247h() {
23279         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23280         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23281                 skip "Need MDS version at least 2.15.51"
23282
23283         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23284         test_subdir_mount_lock $tdir
23285         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23286         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23287                 error "mkdir $tdir.1 failed"
23288         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23289 }
23290 run_test 247h "remote directory submount revalidate ROOT from cache"
23291
23292 test_248a() {
23293         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23294         [ -z "$fast_read_sav" ] && skip "no fast read support"
23295
23296         # create a large file for fast read verification
23297         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23298
23299         # make sure the file is created correctly
23300         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23301                 { rm -f $DIR/$tfile; skip "file creation error"; }
23302
23303         echo "Test 1: verify that fast read is 4 times faster on cache read"
23304
23305         # small read with fast read enabled
23306         $LCTL set_param -n llite.*.fast_read=1
23307         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23308                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23309                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23310         # small read with fast read disabled
23311         $LCTL set_param -n llite.*.fast_read=0
23312         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23313                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23314                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23315
23316         # verify that fast read is 4 times faster for cache read
23317         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23318                 error_not_in_vm "fast read was not 4 times faster: " \
23319                            "$t_fast vs $t_slow"
23320
23321         echo "Test 2: verify the performance between big and small read"
23322         $LCTL set_param -n llite.*.fast_read=1
23323
23324         # 1k non-cache read
23325         cancel_lru_locks osc
23326         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23327                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23328                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23329
23330         # 1M non-cache read
23331         cancel_lru_locks osc
23332         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23333                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23334                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23335
23336         # verify that big IO is not 4 times faster than small IO
23337         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23338                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23339
23340         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23341         rm -f $DIR/$tfile
23342 }
23343 run_test 248a "fast read verification"
23344
23345 test_248b() {
23346         # Default short_io_bytes=16384, try both smaller and larger sizes.
23347         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23348         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23349         echo "bs=53248 count=113 normal buffered write"
23350         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23351                 error "dd of initial data file failed"
23352         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23353
23354         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23355         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23356                 error "dd with sync normal writes failed"
23357         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23358
23359         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23360         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23361                 error "dd with sync small writes failed"
23362         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23363
23364         cancel_lru_locks osc
23365
23366         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23367         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23368         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23369         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23370                 iflag=direct || error "dd with O_DIRECT small read failed"
23371         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23372         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23373                 error "compare $TMP/$tfile.1 failed"
23374
23375         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23376         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23377
23378         # just to see what the maximum tunable value is, and test parsing
23379         echo "test invalid parameter 2MB"
23380         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23381                 error "too-large short_io_bytes allowed"
23382         echo "test maximum parameter 512KB"
23383         # if we can set a larger short_io_bytes, run test regardless of version
23384         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23385                 # older clients may not allow setting it this large, that's OK
23386                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23387                         skip "Need at least client version 2.13.50"
23388                 error "medium short_io_bytes failed"
23389         fi
23390         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23391         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23392
23393         echo "test large parameter 64KB"
23394         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23395         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23396
23397         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23398         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23399                 error "dd with sync large writes failed"
23400         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23401
23402         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23403         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23404         num=$((113 * 4096 / PAGE_SIZE))
23405         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23406         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23407                 error "dd with O_DIRECT large writes failed"
23408         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23409                 error "compare $DIR/$tfile.3 failed"
23410
23411         cancel_lru_locks osc
23412
23413         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23414         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23415                 error "dd with O_DIRECT large read failed"
23416         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23417                 error "compare $TMP/$tfile.2 failed"
23418
23419         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23420         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23421                 error "dd with O_DIRECT large read failed"
23422         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23423                 error "compare $TMP/$tfile.3 failed"
23424 }
23425 run_test 248b "test short_io read and write for both small and large sizes"
23426
23427 test_249() { # LU-7890
23428         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23429                 skip "Need at least version 2.8.54"
23430
23431         rm -f $DIR/$tfile
23432         $LFS setstripe -c 1 $DIR/$tfile
23433         # Offset 2T == 4k * 512M
23434         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23435                 error "dd to 2T offset failed"
23436 }
23437 run_test 249 "Write above 2T file size"
23438
23439 test_250() {
23440         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23441          && skip "no 16TB file size limit on ZFS"
23442
23443         $LFS setstripe -c 1 $DIR/$tfile
23444         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23445         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23446         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23447         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23448                 conv=notrunc,fsync && error "append succeeded"
23449         return 0
23450 }
23451 run_test 250 "Write above 16T limit"
23452
23453 test_251() {
23454         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23455
23456         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23457         #Skip once - writing the first stripe will succeed
23458         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23459         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23460                 error "short write happened"
23461
23462         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23463         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23464                 error "short read happened"
23465
23466         rm -f $DIR/$tfile
23467 }
23468 run_test 251 "Handling short read and write correctly"
23469
23470 test_252() {
23471         remote_mds_nodsh && skip "remote MDS with nodsh"
23472         remote_ost_nodsh && skip "remote OST with nodsh"
23473         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23474                 skip_env "ldiskfs only test"
23475         fi
23476
23477         local tgt
23478         local dev
23479         local out
23480         local uuid
23481         local num
23482         local gen
23483
23484         # check lr_reader on OST0000
23485         tgt=ost1
23486         dev=$(facet_device $tgt)
23487         out=$(do_facet $tgt $LR_READER $dev)
23488         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23489         echo "$out"
23490         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23491         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23492                 error "Invalid uuid returned by $LR_READER on target $tgt"
23493         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23494
23495         # check lr_reader -c on MDT0000
23496         tgt=mds1
23497         dev=$(facet_device $tgt)
23498         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23499                 skip "$LR_READER does not support additional options"
23500         fi
23501         out=$(do_facet $tgt $LR_READER -c $dev)
23502         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23503         echo "$out"
23504         num=$(echo "$out" | grep -c "mdtlov")
23505         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23506                 error "Invalid number of mdtlov clients returned by $LR_READER"
23507         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23508
23509         # check lr_reader -cr on MDT0000
23510         out=$(do_facet $tgt $LR_READER -cr $dev)
23511         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23512         echo "$out"
23513         echo "$out" | grep -q "^reply_data:$" ||
23514                 error "$LR_READER should have returned 'reply_data' section"
23515         num=$(echo "$out" | grep -c "client_generation")
23516         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23517 }
23518 run_test 252 "check lr_reader tool"
23519
23520 test_253() {
23521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23522         remote_mds_nodsh && skip "remote MDS with nodsh"
23523         remote_mgs_nodsh && skip "remote MGS with nodsh"
23524
23525         local ostidx=0
23526         local rc=0
23527         local ost_name=$(ostname_from_index $ostidx)
23528
23529         # on the mdt's osc
23530         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23531         do_facet $SINGLEMDS $LCTL get_param -n \
23532                 osp.$mdtosc_proc1.reserved_mb_high ||
23533                 skip  "remote MDS does not support reserved_mb_high"
23534
23535         rm -rf $DIR/$tdir
23536         wait_mds_ost_sync
23537         wait_delete_completed
23538         mkdir $DIR/$tdir
23539         stack_trap "rm -rf $DIR/$tdir"
23540
23541         pool_add $TESTNAME || error "Pool creation failed"
23542         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23543
23544         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23545                 error "Setstripe failed"
23546
23547         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23548
23549         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23550                     grep "watermarks")
23551         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23552
23553         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23554                         osp.$mdtosc_proc1.prealloc_status)
23555         echo "prealloc_status $oa_status"
23556
23557         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23558                 error "File creation should fail"
23559
23560         #object allocation was stopped, but we still able to append files
23561         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23562                 oflag=append || error "Append failed"
23563
23564         rm -f $DIR/$tdir/$tfile.0
23565
23566         # For this test, we want to delete the files we created to go out of
23567         # space but leave the watermark, so we remain nearly out of space
23568         ost_watermarks_enospc_delete_files $tfile $ostidx
23569
23570         wait_delete_completed
23571
23572         sleep_maxage
23573
23574         for i in $(seq 10 12); do
23575                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23576                         2>/dev/null || error "File creation failed after rm"
23577         done
23578
23579         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23580                         osp.$mdtosc_proc1.prealloc_status)
23581         echo "prealloc_status $oa_status"
23582
23583         if (( oa_status != 0 )); then
23584                 error "Object allocation still disable after rm"
23585         fi
23586 }
23587 run_test 253 "Check object allocation limit"
23588
23589 test_254() {
23590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23591         remote_mds_nodsh && skip "remote MDS with nodsh"
23592
23593         local mdt=$(facet_svc $SINGLEMDS)
23594
23595         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23596                 skip "MDS does not support changelog_size"
23597
23598         local cl_user
23599
23600         changelog_register || error "changelog_register failed"
23601
23602         changelog_clear 0 || error "changelog_clear failed"
23603
23604         local size1=$(do_facet $SINGLEMDS \
23605                       $LCTL get_param -n mdd.$mdt.changelog_size)
23606         echo "Changelog size $size1"
23607
23608         rm -rf $DIR/$tdir
23609         $LFS mkdir -i 0 $DIR/$tdir
23610         # change something
23611         mkdir -p $DIR/$tdir/pics/2008/zachy
23612         touch $DIR/$tdir/pics/2008/zachy/timestamp
23613         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23614         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23615         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23616         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23617         rm $DIR/$tdir/pics/desktop.jpg
23618
23619         local size2=$(do_facet $SINGLEMDS \
23620                       $LCTL get_param -n mdd.$mdt.changelog_size)
23621         echo "Changelog size after work $size2"
23622
23623         (( $size2 > $size1 )) ||
23624                 error "new Changelog size=$size2 less than old size=$size1"
23625 }
23626 run_test 254 "Check changelog size"
23627
23628 ladvise_no_type()
23629 {
23630         local type=$1
23631         local file=$2
23632
23633         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23634                 awk -F: '{print $2}' | grep $type > /dev/null
23635         if [ $? -ne 0 ]; then
23636                 return 0
23637         fi
23638         return 1
23639 }
23640
23641 ladvise_no_ioctl()
23642 {
23643         local file=$1
23644
23645         lfs ladvise -a willread $file > /dev/null 2>&1
23646         if [ $? -eq 0 ]; then
23647                 return 1
23648         fi
23649
23650         lfs ladvise -a willread $file 2>&1 |
23651                 grep "Inappropriate ioctl for device" > /dev/null
23652         if [ $? -eq 0 ]; then
23653                 return 0
23654         fi
23655         return 1
23656 }
23657
23658 percent() {
23659         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23660 }
23661
23662 # run a random read IO workload
23663 # usage: random_read_iops <filename> <filesize> <iosize>
23664 random_read_iops() {
23665         local file=$1
23666         local fsize=$2
23667         local iosize=${3:-4096}
23668
23669         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23670                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23671 }
23672
23673 drop_file_oss_cache() {
23674         local file="$1"
23675         local nodes="$2"
23676
23677         $LFS ladvise -a dontneed $file 2>/dev/null ||
23678                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23679 }
23680
23681 ladvise_willread_performance()
23682 {
23683         local repeat=10
23684         local average_origin=0
23685         local average_cache=0
23686         local average_ladvise=0
23687
23688         for ((i = 1; i <= $repeat; i++)); do
23689                 echo "Iter $i/$repeat: reading without willread hint"
23690                 cancel_lru_locks osc
23691                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23692                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23693                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23694                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23695
23696                 cancel_lru_locks osc
23697                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23698                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23699                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23700
23701                 cancel_lru_locks osc
23702                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23703                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23704                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23705                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23706                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23707         done
23708         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23709         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23710         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23711
23712         speedup_cache=$(percent $average_cache $average_origin)
23713         speedup_ladvise=$(percent $average_ladvise $average_origin)
23714
23715         echo "Average uncached read: $average_origin"
23716         echo "Average speedup with OSS cached read: " \
23717                 "$average_cache = +$speedup_cache%"
23718         echo "Average speedup with ladvise willread: " \
23719                 "$average_ladvise = +$speedup_ladvise%"
23720
23721         local lowest_speedup=20
23722         if (( ${average_cache%.*} < $lowest_speedup )); then
23723                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23724                      " got $average_cache%. Skipping ladvise willread check."
23725                 return 0
23726         fi
23727
23728         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23729         # it is still good to run until then to exercise 'ladvise willread'
23730         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23731                 [ "$ost1_FSTYPE" = "zfs" ] &&
23732                 echo "osd-zfs does not support dontneed or drop_caches" &&
23733                 return 0
23734
23735         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23736         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23737                 error_not_in_vm "Speedup with willread is less than " \
23738                         "$lowest_speedup%, got $average_ladvise%"
23739 }
23740
23741 test_255a() {
23742         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23743                 skip "lustre < 2.8.54 does not support ladvise "
23744         remote_ost_nodsh && skip "remote OST with nodsh"
23745
23746         stack_trap "rm -f $DIR/$tfile"
23747         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23748
23749         ladvise_no_type willread $DIR/$tfile &&
23750                 skip "willread ladvise is not supported"
23751
23752         ladvise_no_ioctl $DIR/$tfile &&
23753                 skip "ladvise ioctl is not supported"
23754
23755         local size_mb=100
23756         local size=$((size_mb * 1048576))
23757         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23758                 error "dd to $DIR/$tfile failed"
23759
23760         lfs ladvise -a willread $DIR/$tfile ||
23761                 error "Ladvise failed with no range argument"
23762
23763         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23764                 error "Ladvise failed with no -l or -e argument"
23765
23766         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23767                 error "Ladvise failed with only -e argument"
23768
23769         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23770                 error "Ladvise failed with only -l argument"
23771
23772         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23773                 error "End offset should not be smaller than start offset"
23774
23775         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23776                 error "End offset should not be equal to start offset"
23777
23778         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23779                 error "Ladvise failed with overflowing -s argument"
23780
23781         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23782                 error "Ladvise failed with overflowing -e argument"
23783
23784         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23785                 error "Ladvise failed with overflowing -l argument"
23786
23787         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23788                 error "Ladvise succeeded with conflicting -l and -e arguments"
23789
23790         echo "Synchronous ladvise should wait"
23791         local delay=8
23792 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23793         do_nodes $(comma_list $(osts_nodes)) \
23794                 $LCTL set_param fail_val=$delay fail_loc=0x237
23795         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23796                 $LCTL set_param fail_loc=0"
23797
23798         local start_ts=$SECONDS
23799         lfs ladvise -a willread $DIR/$tfile ||
23800                 error "Ladvise failed with no range argument"
23801         local end_ts=$SECONDS
23802         local inteval_ts=$((end_ts - start_ts))
23803
23804         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23805                 error "Synchronous advice didn't wait reply"
23806         fi
23807
23808         echo "Asynchronous ladvise shouldn't wait"
23809         local start_ts=$SECONDS
23810         lfs ladvise -a willread -b $DIR/$tfile ||
23811                 error "Ladvise failed with no range argument"
23812         local end_ts=$SECONDS
23813         local inteval_ts=$((end_ts - start_ts))
23814
23815         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23816                 error "Asynchronous advice blocked"
23817         fi
23818
23819         ladvise_willread_performance
23820 }
23821 run_test 255a "check 'lfs ladvise -a willread'"
23822
23823 facet_meminfo() {
23824         local facet=$1
23825         local info=$2
23826
23827         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23828 }
23829
23830 test_255b() {
23831         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23832                 skip "lustre < 2.8.54 does not support ladvise "
23833         remote_ost_nodsh && skip "remote OST with nodsh"
23834
23835         stack_trap "rm -f $DIR/$tfile"
23836         lfs setstripe -c 1 -i 0 $DIR/$tfile
23837
23838         ladvise_no_type dontneed $DIR/$tfile &&
23839                 skip "dontneed ladvise is not supported"
23840
23841         ladvise_no_ioctl $DIR/$tfile &&
23842                 skip "ladvise ioctl is not supported"
23843
23844         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23845                 [ "$ost1_FSTYPE" = "zfs" ] &&
23846                 skip "zfs-osd does not support 'ladvise dontneed'"
23847
23848         local size_mb=100
23849         local size=$((size_mb * 1048576))
23850         # In order to prevent disturbance of other processes, only check 3/4
23851         # of the memory usage
23852         local kibibytes=$((size_mb * 1024 * 3 / 4))
23853
23854         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23855                 error "dd to $DIR/$tfile failed"
23856
23857         #force write to complete before dropping OST cache & checking memory
23858         sync
23859
23860         local total=$(facet_meminfo ost1 MemTotal)
23861         echo "Total memory: $total KiB"
23862
23863         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23864         local before_read=$(facet_meminfo ost1 Cached)
23865         echo "Cache used before read: $before_read KiB"
23866
23867         lfs ladvise -a willread $DIR/$tfile ||
23868                 error "Ladvise willread failed"
23869         local after_read=$(facet_meminfo ost1 Cached)
23870         echo "Cache used after read: $after_read KiB"
23871
23872         lfs ladvise -a dontneed $DIR/$tfile ||
23873                 error "Ladvise dontneed again failed"
23874         local no_read=$(facet_meminfo ost1 Cached)
23875         echo "Cache used after dontneed ladvise: $no_read KiB"
23876
23877         if [ $total -lt $((before_read + kibibytes)) ]; then
23878                 echo "Memory is too small, abort checking"
23879                 return 0
23880         fi
23881
23882         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23883                 error "Ladvise willread should use more memory" \
23884                         "than $kibibytes KiB"
23885         fi
23886
23887         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23888                 error "Ladvise dontneed should release more memory" \
23889                         "than $kibibytes KiB"
23890         fi
23891 }
23892 run_test 255b "check 'lfs ladvise -a dontneed'"
23893
23894 test_255c() {
23895         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23896                 skip "lustre < 2.10.50 does not support lockahead"
23897
23898         local ost1_imp=$(get_osc_import_name client ost1)
23899         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23900                          cut -d'.' -f2)
23901         local count
23902         local new_count
23903         local difference
23904         local i
23905         local rc
23906
23907         test_mkdir -p $DIR/$tdir
23908         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23909
23910         #test 10 returns only success/failure
23911         i=10
23912         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23913         rc=$?
23914         if [ $rc -eq 255 ]; then
23915                 error "Ladvise test${i} failed, ${rc}"
23916         fi
23917
23918         #test 11 counts lock enqueue requests, all others count new locks
23919         i=11
23920         count=$(do_facet ost1 \
23921                 $LCTL get_param -n ost.OSS.ost.stats)
23922         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23923
23924         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23925         rc=$?
23926         if [ $rc -eq 255 ]; then
23927                 error "Ladvise test${i} failed, ${rc}"
23928         fi
23929
23930         new_count=$(do_facet ost1 \
23931                 $LCTL get_param -n ost.OSS.ost.stats)
23932         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23933                    awk '{ print $2 }')
23934
23935         difference="$((new_count - count))"
23936         if [ $difference -ne $rc ]; then
23937                 error "Ladvise test${i}, bad enqueue count, returned " \
23938                       "${rc}, actual ${difference}"
23939         fi
23940
23941         for i in $(seq 12 21); do
23942                 # If we do not do this, we run the risk of having too many
23943                 # locks and starting lock cancellation while we are checking
23944                 # lock counts.
23945                 cancel_lru_locks osc
23946
23947                 count=$($LCTL get_param -n \
23948                        ldlm.namespaces.$imp_name.lock_unused_count)
23949
23950                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23951                 rc=$?
23952                 if [ $rc -eq 255 ]; then
23953                         error "Ladvise test ${i} failed, ${rc}"
23954                 fi
23955
23956                 new_count=$($LCTL get_param -n \
23957                        ldlm.namespaces.$imp_name.lock_unused_count)
23958                 difference="$((new_count - count))"
23959
23960                 # Test 15 output is divided by 100 to map down to valid return
23961                 if [ $i -eq 15 ]; then
23962                         rc="$((rc * 100))"
23963                 fi
23964
23965                 if [ $difference -ne $rc ]; then
23966                         error "Ladvise test ${i}, bad lock count, returned " \
23967                               "${rc}, actual ${difference}"
23968                 fi
23969         done
23970
23971         #test 22 returns only success/failure
23972         i=22
23973         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23974         rc=$?
23975         if [ $rc -eq 255 ]; then
23976                 error "Ladvise test${i} failed, ${rc}"
23977         fi
23978 }
23979 run_test 255c "suite of ladvise lockahead tests"
23980
23981 test_256() {
23982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23983         remote_mds_nodsh && skip "remote MDS with nodsh"
23984         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23985         changelog_users $SINGLEMDS | grep "^cl" &&
23986                 skip "active changelog user"
23987
23988         local cl_user
23989         local cat_sl
23990         local mdt_dev
23991
23992         mdt_dev=$(facet_device $SINGLEMDS)
23993         echo $mdt_dev
23994
23995         changelog_register || error "changelog_register failed"
23996
23997         rm -rf $DIR/$tdir
23998         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23999
24000         changelog_clear 0 || error "changelog_clear failed"
24001
24002         # change something
24003         touch $DIR/$tdir/{1..10}
24004
24005         # stop the MDT
24006         stop $SINGLEMDS || error "Fail to stop MDT"
24007
24008         # remount the MDT
24009         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24010                 error "Fail to start MDT"
24011
24012         #after mount new plainllog is used
24013         touch $DIR/$tdir/{11..19}
24014         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24015         stack_trap "rm -f $tmpfile"
24016         cat_sl=$(do_facet $SINGLEMDS "sync; \
24017                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24018                  llog_reader $tmpfile | grep -c type=1064553b")
24019         do_facet $SINGLEMDS llog_reader $tmpfile
24020
24021         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24022
24023         changelog_clear 0 || error "changelog_clear failed"
24024
24025         cat_sl=$(do_facet $SINGLEMDS "sync; \
24026                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24027                  llog_reader $tmpfile | grep -c type=1064553b")
24028
24029         if (( cat_sl == 2 )); then
24030                 error "Empty plain llog was not deleted from changelog catalog"
24031         elif (( cat_sl != 1 )); then
24032                 error "Active plain llog shouldn't be deleted from catalog"
24033         fi
24034 }
24035 run_test 256 "Check llog delete for empty and not full state"
24036
24037 test_257() {
24038         remote_mds_nodsh && skip "remote MDS with nodsh"
24039         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24040                 skip "Need MDS version at least 2.8.55"
24041
24042         test_mkdir $DIR/$tdir
24043
24044         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24045                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24046         stat $DIR/$tdir
24047
24048 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24049         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24050         local facet=mds$((mdtidx + 1))
24051         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24052         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24053
24054         stop $facet || error "stop MDS failed"
24055         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24056                 error "start MDS fail"
24057         wait_recovery_complete $facet
24058 }
24059 run_test 257 "xattr locks are not lost"
24060
24061 # Verify we take the i_mutex when security requires it
24062 test_258a() {
24063 #define OBD_FAIL_IMUTEX_SEC 0x141c
24064         $LCTL set_param fail_loc=0x141c
24065         touch $DIR/$tfile
24066         chmod u+s $DIR/$tfile
24067         chmod a+rwx $DIR/$tfile
24068         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24069         RC=$?
24070         if [ $RC -ne 0 ]; then
24071                 error "error, failed to take i_mutex, rc=$?"
24072         fi
24073         rm -f $DIR/$tfile
24074 }
24075 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24076
24077 # Verify we do NOT take the i_mutex in the normal case
24078 test_258b() {
24079 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24080         $LCTL set_param fail_loc=0x141d
24081         touch $DIR/$tfile
24082         chmod a+rwx $DIR
24083         chmod a+rw $DIR/$tfile
24084         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24085         RC=$?
24086         if [ $RC -ne 0 ]; then
24087                 error "error, took i_mutex unnecessarily, rc=$?"
24088         fi
24089         rm -f $DIR/$tfile
24090
24091 }
24092 run_test 258b "verify i_mutex security behavior"
24093
24094 test_259() {
24095         local file=$DIR/$tfile
24096         local before
24097         local after
24098
24099         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24100
24101         stack_trap "rm -f $file" EXIT
24102
24103         wait_delete_completed
24104         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24105         echo "before: $before"
24106
24107         $LFS setstripe -i 0 -c 1 $file
24108         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24109         sync_all_data
24110         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24111         echo "after write: $after"
24112
24113 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24114         do_facet ost1 $LCTL set_param fail_loc=0x2301
24115         $TRUNCATE $file 0
24116         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24117         echo "after truncate: $after"
24118
24119         stop ost1
24120         do_facet ost1 $LCTL set_param fail_loc=0
24121         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24122         sleep 2
24123         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24124         echo "after restart: $after"
24125         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24126                 error "missing truncate?"
24127
24128         return 0
24129 }
24130 run_test 259 "crash at delayed truncate"
24131
24132 test_260() {
24133 #define OBD_FAIL_MDC_CLOSE               0x806
24134         $LCTL set_param fail_loc=0x80000806
24135         touch $DIR/$tfile
24136
24137 }
24138 run_test 260 "Check mdc_close fail"
24139
24140 ### Data-on-MDT sanity tests ###
24141 test_270a() {
24142         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24143                 skip "Need MDS version at least 2.10.55 for DoM"
24144
24145         # create DoM file
24146         local dom=$DIR/$tdir/dom_file
24147         local tmp=$DIR/$tdir/tmp_file
24148
24149         mkdir_on_mdt0 $DIR/$tdir
24150
24151         # basic checks for DoM component creation
24152         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24153                 error "Can set MDT layout to non-first entry"
24154
24155         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24156                 error "Can define multiple entries as MDT layout"
24157
24158         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24159
24160         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24161         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24162         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24163
24164         local mdtidx=$($LFS getstripe -m $dom)
24165         local mdtname=MDT$(printf %04x $mdtidx)
24166         local facet=mds$((mdtidx + 1))
24167         local space_check=1
24168
24169         # Skip free space checks with ZFS
24170         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24171
24172         # write
24173         sync
24174         local size_tmp=$((65536 * 3))
24175         local mdtfree1=$(do_facet $facet \
24176                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24177
24178         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24179         # check also direct IO along write
24180         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24181         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24182         sync
24183         cmp $tmp $dom || error "file data is different"
24184         [ $(stat -c%s $dom) == $size_tmp ] ||
24185                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24186         if [ $space_check == 1 ]; then
24187                 local mdtfree2=$(do_facet $facet \
24188                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24189
24190                 # increase in usage from by $size_tmp
24191                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24192                         error "MDT free space wrong after write: " \
24193                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24194         fi
24195
24196         # truncate
24197         local size_dom=10000
24198
24199         $TRUNCATE $dom $size_dom
24200         [ $(stat -c%s $dom) == $size_dom ] ||
24201                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24202         if [ $space_check == 1 ]; then
24203                 mdtfree1=$(do_facet $facet \
24204                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24205                 # decrease in usage from $size_tmp to new $size_dom
24206                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24207                   $(((size_tmp - size_dom) / 1024)) ] ||
24208                         error "MDT free space is wrong after truncate: " \
24209                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24210         fi
24211
24212         # append
24213         cat $tmp >> $dom
24214         sync
24215         size_dom=$((size_dom + size_tmp))
24216         [ $(stat -c%s $dom) == $size_dom ] ||
24217                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24218         if [ $space_check == 1 ]; then
24219                 mdtfree2=$(do_facet $facet \
24220                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24221                 # increase in usage by $size_tmp from previous
24222                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24223                         error "MDT free space is wrong after append: " \
24224                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24225         fi
24226
24227         # delete
24228         rm $dom
24229         if [ $space_check == 1 ]; then
24230                 mdtfree1=$(do_facet $facet \
24231                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24232                 # decrease in usage by $size_dom from previous
24233                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24234                         error "MDT free space is wrong after removal: " \
24235                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24236         fi
24237
24238         # combined striping
24239         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24240                 error "Can't create DoM + OST striping"
24241
24242         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24243         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24244         # check also direct IO along write
24245         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24246         sync
24247         cmp $tmp $dom || error "file data is different"
24248         [ $(stat -c%s $dom) == $size_tmp ] ||
24249                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24250         rm $dom $tmp
24251
24252         return 0
24253 }
24254 run_test 270a "DoM: basic functionality tests"
24255
24256 test_270b() {
24257         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24258                 skip "Need MDS version at least 2.10.55"
24259
24260         local dom=$DIR/$tdir/dom_file
24261         local max_size=1048576
24262
24263         mkdir -p $DIR/$tdir
24264         $LFS setstripe -E $max_size -L mdt $dom
24265
24266         # truncate over the limit
24267         $TRUNCATE $dom $(($max_size + 1)) &&
24268                 error "successful truncate over the maximum size"
24269         # write over the limit
24270         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24271                 error "successful write over the maximum size"
24272         # append over the limit
24273         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24274         echo "12345" >> $dom && error "successful append over the maximum size"
24275         rm $dom
24276
24277         return 0
24278 }
24279 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24280
24281 test_270c() {
24282         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24283                 skip "Need MDS version at least 2.10.55"
24284
24285         mkdir -p $DIR/$tdir
24286         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24287
24288         # check files inherit DoM EA
24289         touch $DIR/$tdir/first
24290         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24291                 error "bad pattern"
24292         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24293                 error "bad stripe count"
24294         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24295                 error "bad stripe size"
24296
24297         # check directory inherits DoM EA and uses it as default
24298         mkdir $DIR/$tdir/subdir
24299         touch $DIR/$tdir/subdir/second
24300         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24301                 error "bad pattern in sub-directory"
24302         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24303                 error "bad stripe count in sub-directory"
24304         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24305                 error "bad stripe size in sub-directory"
24306         return 0
24307 }
24308 run_test 270c "DoM: DoM EA inheritance tests"
24309
24310 test_270d() {
24311         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24312                 skip "Need MDS version at least 2.10.55"
24313
24314         mkdir -p $DIR/$tdir
24315         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24316
24317         # inherit default DoM striping
24318         mkdir $DIR/$tdir/subdir
24319         touch $DIR/$tdir/subdir/f1
24320
24321         # change default directory striping
24322         $LFS setstripe -c 1 $DIR/$tdir/subdir
24323         touch $DIR/$tdir/subdir/f2
24324         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24325                 error "wrong default striping in file 2"
24326         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24327                 error "bad pattern in file 2"
24328         return 0
24329 }
24330 run_test 270d "DoM: change striping from DoM to RAID0"
24331
24332 test_270e() {
24333         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24334                 skip "Need MDS version at least 2.10.55"
24335
24336         mkdir -p $DIR/$tdir/dom
24337         mkdir -p $DIR/$tdir/norm
24338         DOMFILES=20
24339         NORMFILES=10
24340         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24341         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24342
24343         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24344         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24345
24346         # find DoM files by layout
24347         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24348         [ $NUM -eq  $DOMFILES ] ||
24349                 error "lfs find -L: found $NUM, expected $DOMFILES"
24350         echo "Test 1: lfs find 20 DOM files by layout: OK"
24351
24352         # there should be 1 dir with default DOM striping
24353         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24354         [ $NUM -eq  1 ] ||
24355                 error "lfs find -L: found $NUM, expected 1 dir"
24356         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24357
24358         # find DoM files by stripe size
24359         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24360         [ $NUM -eq  $DOMFILES ] ||
24361                 error "lfs find -S: found $NUM, expected $DOMFILES"
24362         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24363
24364         # find files by stripe offset except DoM files
24365         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24366         [ $NUM -eq  $NORMFILES ] ||
24367                 error "lfs find -i: found $NUM, expected $NORMFILES"
24368         echo "Test 5: lfs find no DOM files by stripe index: OK"
24369         return 0
24370 }
24371 run_test 270e "DoM: lfs find with DoM files test"
24372
24373 test_270f() {
24374         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24375                 skip "Need MDS version at least 2.10.55"
24376
24377         local mdtname=${FSNAME}-MDT0000-mdtlov
24378         local dom=$DIR/$tdir/dom_file
24379         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24380                                                 lod.$mdtname.dom_stripesize)
24381         local dom_limit=131072
24382
24383         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24384         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24385                                                 lod.$mdtname.dom_stripesize)
24386         [ ${dom_limit} -eq ${dom_current} ] ||
24387                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24388
24389         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24390         $LFS setstripe -d $DIR/$tdir
24391         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24392                 error "Can't set directory default striping"
24393
24394         # exceed maximum stripe size
24395         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24396                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24397         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24398                 error "Able to create DoM component size more than LOD limit"
24399
24400         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24401         dom_current=$(do_facet mds1 $LCTL get_param -n \
24402                                                 lod.$mdtname.dom_stripesize)
24403         [ 0 -eq ${dom_current} ] ||
24404                 error "Can't set zero DoM stripe limit"
24405         rm $dom
24406
24407         # attempt to create DoM file on server with disabled DoM should
24408         # remove DoM entry from layout and be succeed
24409         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24410                 error "Can't create DoM file (DoM is disabled)"
24411         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24412                 error "File has DoM component while DoM is disabled"
24413         rm $dom
24414
24415         # attempt to create DoM file with only DoM stripe should return error
24416         $LFS setstripe -E $dom_limit -L mdt $dom &&
24417                 error "Able to create DoM-only file while DoM is disabled"
24418
24419         # too low values to be aligned with smallest stripe size 64K
24420         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24421         dom_current=$(do_facet mds1 $LCTL get_param -n \
24422                                                 lod.$mdtname.dom_stripesize)
24423         [ 30000 -eq ${dom_current} ] &&
24424                 error "Can set too small DoM stripe limit"
24425
24426         # 64K is a minimal stripe size in Lustre, expect limit of that size
24427         [ 65536 -eq ${dom_current} ] ||
24428                 error "Limit is not set to 64K but ${dom_current}"
24429
24430         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24431         dom_current=$(do_facet mds1 $LCTL get_param -n \
24432                                                 lod.$mdtname.dom_stripesize)
24433         echo $dom_current
24434         [ 2147483648 -eq ${dom_current} ] &&
24435                 error "Can set too large DoM stripe limit"
24436
24437         do_facet mds1 $LCTL set_param -n \
24438                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24439         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24440                 error "Can't create DoM component size after limit change"
24441         do_facet mds1 $LCTL set_param -n \
24442                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24443         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24444                 error "Can't create DoM file after limit decrease"
24445         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24446                 error "Can create big DoM component after limit decrease"
24447         touch ${dom}_def ||
24448                 error "Can't create file with old default layout"
24449
24450         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24451         return 0
24452 }
24453 run_test 270f "DoM: maximum DoM stripe size checks"
24454
24455 test_270g() {
24456         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24457                 skip "Need MDS version at least 2.13.52"
24458         local dom=$DIR/$tdir/$tfile
24459
24460         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24461         local lodname=${FSNAME}-MDT0000-mdtlov
24462
24463         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24464         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24465         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24466         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24467
24468         local dom_limit=1024
24469         local dom_threshold="50%"
24470
24471         $LFS setstripe -d $DIR/$tdir
24472         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24473                 error "Can't set directory default striping"
24474
24475         do_facet mds1 $LCTL set_param -n \
24476                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24477         # set 0 threshold and create DOM file to change tunable stripesize
24478         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24479         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24480                 error "Failed to create $dom file"
24481         # now tunable dom_cur_stripesize should reach maximum
24482         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24483                                         lod.${lodname}.dom_stripesize_cur_kb)
24484         [[ $dom_current == $dom_limit ]] ||
24485                 error "Current DOM stripesize is not maximum"
24486         rm $dom
24487
24488         # set threshold for further tests
24489         do_facet mds1 $LCTL set_param -n \
24490                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24491         echo "DOM threshold is $dom_threshold free space"
24492         local dom_def
24493         local dom_set
24494         # Spoof bfree to exceed threshold
24495         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24496         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24497         for spfree in 40 20 0 15 30 55; do
24498                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24499                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24500                         error "Failed to create $dom file"
24501                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24502                                         lod.${lodname}.dom_stripesize_cur_kb)
24503                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24504                 [[ $dom_def != $dom_current ]] ||
24505                         error "Default stripe size was not changed"
24506                 if (( spfree > 0 )) ; then
24507                         dom_set=$($LFS getstripe -S $dom)
24508                         (( dom_set == dom_def * 1024 )) ||
24509                                 error "DOM component size is still old"
24510                 else
24511                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24512                                 error "DoM component is set with no free space"
24513                 fi
24514                 rm $dom
24515                 dom_current=$dom_def
24516         done
24517 }
24518 run_test 270g "DoM: default DoM stripe size depends on free space"
24519
24520 test_270h() {
24521         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24522                 skip "Need MDS version at least 2.13.53"
24523
24524         local mdtname=${FSNAME}-MDT0000-mdtlov
24525         local dom=$DIR/$tdir/$tfile
24526         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24527
24528         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24529         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24530
24531         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24532         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24533                 error "can't create OST file"
24534         # mirrored file with DOM entry in the second mirror
24535         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24536                 error "can't create mirror with DoM component"
24537
24538         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24539
24540         # DOM component in the middle and has other enries in the same mirror,
24541         # should succeed but lost DoM component
24542         $LFS setstripe --copy=${dom}_1 $dom ||
24543                 error "Can't create file from OST|DOM mirror layout"
24544         # check new file has no DoM layout after all
24545         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24546                 error "File has DoM component while DoM is disabled"
24547 }
24548 run_test 270h "DoM: DoM stripe removal when disabled on server"
24549
24550 test_270i() {
24551         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24552                 skip "Need MDS version at least 2.14.54"
24553
24554         mkdir $DIR/$tdir
24555         # DoM with plain layout
24556         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24557                 error "default plain layout with DoM must fail"
24558         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24559                 error "setstripe plain file layout with DoM must fail"
24560         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24561                 error "default DoM layout with bad striping must fail"
24562         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24563                 error "setstripe to DoM layout with bad striping must fail"
24564         return 0
24565 }
24566 run_test 270i "DoM: setting invalid DoM striping should fail"
24567
24568 test_270j() {
24569         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24570                 skip "Need MDS version at least 2.15.55.203"
24571
24572         local dom=$DIR/$tdir/$tfile
24573         local odv
24574         local ndv
24575
24576         mkdir -p $DIR/$tdir
24577
24578         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24579
24580         odv=$($LFS data_version $dom)
24581         chmod 666 $dom
24582         mv $dom ${dom}_moved
24583         link ${dom}_moved $dom
24584         setfattr -n user.attrx -v "some_attr" $dom
24585         ndv=$($LFS data_version $dom)
24586         (( $ndv == $odv )) ||
24587                 error "data version was changed by metadata operations"
24588
24589         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24590                 error "failed to write data into $dom"
24591         cancel_lru_locks mdc
24592         ndv=$($LFS data_version $dom)
24593         (( $ndv != $odv )) ||
24594                 error "data version wasn't changed on write"
24595
24596         odv=$ndv
24597         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24598         ndv=$($LFS data_version $dom)
24599         (( $ndv != $odv )) ||
24600                 error "data version wasn't changed on truncate down"
24601
24602         odv=$ndv
24603         $TRUNCATE $dom 25000
24604         ndv=$($LFS data_version $dom)
24605         (( $ndv != $odv )) ||
24606                 error "data version wasn't changed on truncate up"
24607
24608         # check also fallocate for ldiskfs
24609         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24610                 odv=$ndv
24611                 fallocate -l 1048576 $dom
24612                 ndv=$($LFS data_version $dom)
24613                 (( $ndv != $odv )) ||
24614                         error "data version wasn't changed on fallocate"
24615
24616                 odv=$ndv
24617                 fallocate -p --offset 4096 -l 4096 $dom
24618                 ndv=$($LFS data_version $dom)
24619                 (( $ndv != $odv )) ||
24620                         error "data version wasn't changed on fallocate punch"
24621         fi
24622 }
24623 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24624
24625 test_271a() {
24626         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24627                 skip "Need MDS version at least 2.10.55"
24628
24629         local dom=$DIR/$tdir/dom
24630
24631         mkdir -p $DIR/$tdir
24632
24633         $LFS setstripe -E 1024K -L mdt $dom
24634
24635         lctl set_param -n mdc.*.stats=clear
24636         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24637         cat $dom > /dev/null
24638         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24639         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24640         ls $dom
24641         rm -f $dom
24642 }
24643 run_test 271a "DoM: data is cached for read after write"
24644
24645 test_271b() {
24646         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24647                 skip "Need MDS version at least 2.10.55"
24648
24649         local dom=$DIR/$tdir/dom
24650
24651         mkdir -p $DIR/$tdir
24652
24653         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24654
24655         lctl set_param -n mdc.*.stats=clear
24656         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24657         cancel_lru_locks mdc
24658         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24659         # second stat to check size is cached on client
24660         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24661         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24662         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24663         rm -f $dom
24664 }
24665 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24666
24667 test_271ba() {
24668         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24669                 skip "Need MDS version at least 2.10.55"
24670
24671         local dom=$DIR/$tdir/dom
24672
24673         mkdir -p $DIR/$tdir
24674
24675         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24676
24677         lctl set_param -n mdc.*.stats=clear
24678         lctl set_param -n osc.*.stats=clear
24679         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24680         cancel_lru_locks mdc
24681         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24682         # second stat to check size is cached on client
24683         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24684         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24685         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24686         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24687         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24688         rm -f $dom
24689 }
24690 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24691
24692
24693 get_mdc_stats() {
24694         local mdtidx=$1
24695         local param=$2
24696         local mdt=MDT$(printf %04x $mdtidx)
24697
24698         if [ -z $param ]; then
24699                 lctl get_param -n mdc.*$mdt*.stats
24700         else
24701                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24702         fi
24703 }
24704
24705 test_271c() {
24706         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24707                 skip "Need MDS version at least 2.10.55"
24708
24709         local dom=$DIR/$tdir/dom
24710
24711         mkdir -p $DIR/$tdir
24712
24713         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24714
24715         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24716         local facet=mds$((mdtidx + 1))
24717
24718         cancel_lru_locks mdc
24719         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24720         createmany -o $dom 1000
24721         lctl set_param -n mdc.*.stats=clear
24722         smalliomany -w $dom 1000 200
24723         get_mdc_stats $mdtidx
24724         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24725         # Each file has 1 open, 1 IO enqueues, total 2000
24726         # but now we have also +1 getxattr for security.capability, total 3000
24727         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24728         unlinkmany $dom 1000
24729
24730         cancel_lru_locks mdc
24731         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24732         createmany -o $dom 1000
24733         lctl set_param -n mdc.*.stats=clear
24734         smalliomany -w $dom 1000 200
24735         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24736         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24737         # for OPEN and IO lock.
24738         [ $((enq - enq_2)) -ge 1000 ] ||
24739                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24740         unlinkmany $dom 1000
24741         return 0
24742 }
24743 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24744
24745 cleanup_271def_tests() {
24746         trap 0
24747         rm -f $1
24748 }
24749
24750 test_271d() {
24751         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24752                 skip "Need MDS version at least 2.10.57"
24753
24754         local dom=$DIR/$tdir/dom
24755         local tmp=$TMP/$tfile
24756         trap "cleanup_271def_tests $tmp" EXIT
24757
24758         mkdir -p $DIR/$tdir
24759
24760         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24761
24762         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24763
24764         cancel_lru_locks mdc
24765         dd if=/dev/urandom of=$tmp bs=1000 count=1
24766         dd if=$tmp of=$dom bs=1000 count=1
24767         cancel_lru_locks mdc
24768
24769         cat /etc/hosts >> $tmp
24770         lctl set_param -n mdc.*.stats=clear
24771
24772         # append data to the same file it should update local page
24773         echo "Append to the same page"
24774         cat /etc/hosts >> $dom
24775         local num=$(get_mdc_stats $mdtidx ost_read)
24776         local ra=$(get_mdc_stats $mdtidx req_active)
24777         local rw=$(get_mdc_stats $mdtidx req_waittime)
24778
24779         [ -z $num ] || error "$num READ RPC occured"
24780         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24781         echo "... DONE"
24782
24783         # compare content
24784         cmp $tmp $dom || error "file miscompare"
24785
24786         cancel_lru_locks mdc
24787         lctl set_param -n mdc.*.stats=clear
24788
24789         echo "Open and read file"
24790         cat $dom > /dev/null
24791         local num=$(get_mdc_stats $mdtidx ost_read)
24792         local ra=$(get_mdc_stats $mdtidx req_active)
24793         local rw=$(get_mdc_stats $mdtidx req_waittime)
24794
24795         [ -z $num ] || error "$num READ RPC occured"
24796         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24797         echo "... DONE"
24798
24799         # compare content
24800         cmp $tmp $dom || error "file miscompare"
24801
24802         return 0
24803 }
24804 run_test 271d "DoM: read on open (1K file in reply buffer)"
24805
24806 test_271f() {
24807         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24808                 skip "Need MDS version at least 2.10.57"
24809
24810         local dom=$DIR/$tdir/dom
24811         local tmp=$TMP/$tfile
24812         trap "cleanup_271def_tests $tmp" EXIT
24813
24814         mkdir -p $DIR/$tdir
24815
24816         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24817
24818         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24819
24820         cancel_lru_locks mdc
24821         dd if=/dev/urandom of=$tmp bs=265000 count=1
24822         dd if=$tmp of=$dom bs=265000 count=1
24823         cancel_lru_locks mdc
24824         cat /etc/hosts >> $tmp
24825         lctl set_param -n mdc.*.stats=clear
24826
24827         echo "Append to the same page"
24828         cat /etc/hosts >> $dom
24829         local num=$(get_mdc_stats $mdtidx ost_read)
24830         local ra=$(get_mdc_stats $mdtidx req_active)
24831         local rw=$(get_mdc_stats $mdtidx req_waittime)
24832
24833         [ -z $num ] || error "$num READ RPC occured"
24834         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24835         echo "... DONE"
24836
24837         # compare content
24838         cmp $tmp $dom || error "file miscompare"
24839
24840         cancel_lru_locks mdc
24841         lctl set_param -n mdc.*.stats=clear
24842
24843         echo "Open and read file"
24844         cat $dom > /dev/null
24845         local num=$(get_mdc_stats $mdtidx ost_read)
24846         local ra=$(get_mdc_stats $mdtidx req_active)
24847         local rw=$(get_mdc_stats $mdtidx req_waittime)
24848
24849         [ -z $num ] && num=0
24850         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24851         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24852         echo "... DONE"
24853
24854         # compare content
24855         cmp $tmp $dom || error "file miscompare"
24856
24857         return 0
24858 }
24859 run_test 271f "DoM: read on open (200K file and read tail)"
24860
24861 test_271g() {
24862         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24863                 skip "Skipping due to old client or server version"
24864
24865         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24866         # to get layout
24867         $CHECKSTAT -t file $DIR1/$tfile
24868
24869         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24870         MULTIOP_PID=$!
24871         sleep 1
24872         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24873         $LCTL set_param fail_loc=0x80000314
24874         rm $DIR1/$tfile || error "Unlink fails"
24875         RC=$?
24876         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24877         [ $RC -eq 0 ] || error "Failed write to stale object"
24878 }
24879 run_test 271g "Discard DoM data vs client flush race"
24880
24881 test_272a() {
24882         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24883                 skip "Need MDS version at least 2.11.50"
24884
24885         local dom=$DIR/$tdir/dom
24886         mkdir -p $DIR/$tdir
24887
24888         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24889         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24890                 error "failed to write data into $dom"
24891         local old_md5=$(md5sum $dom)
24892
24893         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24894                 error "failed to migrate to the same DoM component"
24895
24896         local new_md5=$(md5sum $dom)
24897
24898         [ "$old_md5" == "$new_md5" ] ||
24899                 error "md5sum differ: $old_md5, $new_md5"
24900
24901         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24902                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24903 }
24904 run_test 272a "DoM migration: new layout with the same DOM component"
24905
24906 test_272b() {
24907         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24908                 skip "Need MDS version at least 2.11.50"
24909
24910         local dom=$DIR/$tdir/dom
24911         mkdir -p $DIR/$tdir
24912         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24913         stack_trap "rm -rf $DIR/$tdir"
24914
24915         local mdtidx=$($LFS getstripe -m $dom)
24916         local mdtname=MDT$(printf %04x $mdtidx)
24917         local facet=mds$((mdtidx + 1))
24918
24919         local mdtfree1=$(do_facet $facet \
24920                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24921         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24922                 error "failed to write data into $dom"
24923         local old_md5=$(md5sum $dom)
24924         cancel_lru_locks mdc
24925         local mdtfree1=$(do_facet $facet \
24926                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24927
24928         $LFS migrate -c2 $dom ||
24929                 error "failed to migrate to the new composite layout"
24930         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24931                 error "MDT stripe was not removed"
24932         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24933                 error "$dir1 shouldn't have DATAVER EA"
24934
24935         cancel_lru_locks mdc
24936         local new_md5=$(md5sum $dom)
24937         [ "$old_md5" == "$new_md5" ] ||
24938                 error "$old_md5 != $new_md5"
24939
24940         # Skip free space checks with ZFS
24941         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24942                 local mdtfree2=$(do_facet $facet \
24943                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24944                 [ $mdtfree2 -gt $mdtfree1 ] ||
24945                         error "MDT space is not freed after migration"
24946         fi
24947         return 0
24948 }
24949 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24950
24951 test_272c() {
24952         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24953                 skip "Need MDS version at least 2.11.50"
24954
24955         local dom=$DIR/$tdir/$tfile
24956         mkdir -p $DIR/$tdir
24957         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24958         stack_trap "rm -rf $DIR/$tdir"
24959
24960         local mdtidx=$($LFS getstripe -m $dom)
24961         local mdtname=MDT$(printf %04x $mdtidx)
24962         local facet=mds$((mdtidx + 1))
24963
24964         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24965                 error "failed to write data into $dom"
24966         local old_md5=$(md5sum $dom)
24967         cancel_lru_locks mdc
24968         local mdtfree1=$(do_facet $facet \
24969                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24970
24971         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24972                 error "failed to migrate to the new composite layout"
24973         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24974                 error "MDT stripe was not removed"
24975
24976         cancel_lru_locks mdc
24977         local new_md5=$(md5sum $dom)
24978         [ "$old_md5" == "$new_md5" ] ||
24979                 error "$old_md5 != $new_md5"
24980
24981         # Skip free space checks with ZFS
24982         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24983                 local mdtfree2=$(do_facet $facet \
24984                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24985                 [ $mdtfree2 -gt $mdtfree1 ] ||
24986                         error "MDS space is not freed after migration"
24987         fi
24988         return 0
24989 }
24990 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24991
24992 test_272d() {
24993         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24994                 skip "Need MDS version at least 2.12.55"
24995
24996         local dom=$DIR/$tdir/$tfile
24997         mkdir -p $DIR/$tdir
24998         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24999
25000         local mdtidx=$($LFS getstripe -m $dom)
25001         local mdtname=MDT$(printf %04x $mdtidx)
25002         local facet=mds$((mdtidx + 1))
25003
25004         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25005                 error "failed to write data into $dom"
25006         local old_md5=$(md5sum $dom)
25007         cancel_lru_locks mdc
25008         local mdtfree1=$(do_facet $facet \
25009                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25010
25011         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25012                 error "failed mirroring to the new composite layout"
25013         $LFS mirror resync $dom ||
25014                 error "failed mirror resync"
25015         $LFS mirror split --mirror-id 1 -d $dom ||
25016                 error "failed mirror split"
25017
25018         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25019                 error "MDT stripe was not removed"
25020
25021         cancel_lru_locks mdc
25022         local new_md5=$(md5sum $dom)
25023         [ "$old_md5" == "$new_md5" ] ||
25024                 error "$old_md5 != $new_md5"
25025
25026         # Skip free space checks with ZFS
25027         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25028                 local mdtfree2=$(do_facet $facet \
25029                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25030                 [ $mdtfree2 -gt $mdtfree1 ] ||
25031                         error "MDS space is not freed after DOM mirror deletion"
25032         fi
25033         return 0
25034 }
25035 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25036
25037 test_272e() {
25038         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25039                 skip "Need MDS version at least 2.12.55"
25040
25041         local dom=$DIR/$tdir/$tfile
25042         mkdir -p $DIR/$tdir
25043         $LFS setstripe -c 2 $dom
25044
25045         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25046                 error "failed to write data into $dom"
25047         local old_md5=$(md5sum $dom)
25048         cancel_lru_locks
25049
25050         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25051                 error "failed mirroring to the DOM layout"
25052         $LFS mirror resync $dom ||
25053                 error "failed mirror resync"
25054         $LFS mirror split --mirror-id 1 -d $dom ||
25055                 error "failed mirror split"
25056
25057         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25058                 error "MDT stripe wasn't set"
25059
25060         cancel_lru_locks
25061         local new_md5=$(md5sum $dom)
25062         [ "$old_md5" == "$new_md5" ] ||
25063                 error "$old_md5 != $new_md5"
25064
25065         return 0
25066 }
25067 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25068
25069 test_272f() {
25070         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25071                 skip "Need MDS version at least 2.12.55"
25072
25073         local dom=$DIR/$tdir/$tfile
25074         mkdir -p $DIR/$tdir
25075         $LFS setstripe -c 2 $dom
25076
25077         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25078                 error "failed to write data into $dom"
25079         local old_md5=$(md5sum $dom)
25080         cancel_lru_locks
25081
25082         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25083                 error "failed migrating to the DOM file"
25084
25085         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25086                 error "MDT stripe wasn't set"
25087
25088         cancel_lru_locks
25089         local new_md5=$(md5sum $dom)
25090         [ "$old_md5" != "$new_md5" ] &&
25091                 error "$old_md5 != $new_md5"
25092
25093         return 0
25094 }
25095 run_test 272f "DoM migration: OST-striped file to DOM file"
25096
25097 test_273a() {
25098         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25099                 skip "Need MDS version at least 2.11.50"
25100
25101         # Layout swap cannot be done if either file has DOM component,
25102         # this will never be supported, migration should be used instead
25103
25104         local dom=$DIR/$tdir/$tfile
25105         mkdir -p $DIR/$tdir
25106
25107         $LFS setstripe -c2 ${dom}_plain
25108         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25109         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25110                 error "can swap layout with DoM component"
25111         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25112                 error "can swap layout with DoM component"
25113
25114         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25115         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25116                 error "can swap layout with DoM component"
25117         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25118                 error "can swap layout with DoM component"
25119         return 0
25120 }
25121 run_test 273a "DoM: layout swapping should fail with DOM"
25122
25123 test_273b() {
25124         mkdir -p $DIR/$tdir
25125         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25126
25127 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25128         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25129
25130         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25131 }
25132 run_test 273b "DoM: race writeback and object destroy"
25133
25134 test_273c() {
25135         mkdir -p $DIR/$tdir
25136         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25137
25138         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25139         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25140
25141         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25142 }
25143 run_test 273c "race writeback and object destroy"
25144
25145 test_275() {
25146         remote_ost_nodsh && skip "remote OST with nodsh"
25147         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25148                 skip "Need OST version >= 2.10.57"
25149
25150         local file=$DIR/$tfile
25151         local oss
25152
25153         oss=$(comma_list $(osts_nodes))
25154
25155         dd if=/dev/urandom of=$file bs=1M count=2 ||
25156                 error "failed to create a file"
25157         stack_trap "rm -f $file"
25158         cancel_lru_locks osc
25159
25160         #lock 1
25161         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25162                 error "failed to read a file"
25163
25164 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25165         $LCTL set_param fail_loc=0x8000031f
25166
25167         cancel_lru_locks osc &
25168         sleep 1
25169
25170 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25171         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25172         #IO takes another lock, but matches the PENDING one
25173         #and places it to the IO RPC
25174         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25175                 error "failed to read a file with PENDING lock"
25176 }
25177 run_test 275 "Read on a canceled duplicate lock"
25178
25179 test_276() {
25180         remote_ost_nodsh && skip "remote OST with nodsh"
25181         local pid
25182
25183         do_facet ost1 "(while true; do \
25184                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25185                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25186         pid=$!
25187
25188         for LOOP in $(seq 20); do
25189                 stop ost1
25190                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25191         done
25192         kill -9 $pid
25193         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25194                 rm $TMP/sanity_276_pid"
25195 }
25196 run_test 276 "Race between mount and obd_statfs"
25197
25198 test_277() {
25199         $LCTL set_param ldlm.namespaces.*.lru_size=0
25200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25201         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25202                           awk '/^used_mb/ { print $2 }')
25203         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25204         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25205                 oflag=direct conv=notrunc
25206         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25207                     awk '/^used_mb/ { print $2 }')
25208         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25209 }
25210 run_test 277 "Direct IO shall drop page cache"
25211
25212 test_278() {
25213         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25214         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25215         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25216                 skip "needs the same host for mdt1 mdt2" && return
25217
25218         local pid1
25219         local pid2
25220
25221 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25222         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25223         stop mds2 &
25224         pid2=$!
25225
25226         stop mds1
25227
25228         echo "Starting MDTs"
25229         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25230         wait $pid2
25231 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25232 #will return NULL
25233         do_facet mds2 $LCTL set_param fail_loc=0
25234
25235         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25236         wait_recovery_complete mds2
25237 }
25238 run_test 278 "Race starting MDS between MDTs stop/start"
25239
25240 test_280() {
25241         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25242                 skip "Need MGS version at least 2.13.52"
25243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25244         combined_mgs_mds || skip "needs combined MGS/MDT"
25245
25246         umount_client $MOUNT
25247 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25248         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25249
25250         mount_client $MOUNT &
25251         sleep 1
25252         stop mgs || error "stop mgs failed"
25253         #for a race mgs would crash
25254         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25255         # make sure we unmount client before remounting
25256         wait
25257         umount_client $MOUNT
25258         mount_client $MOUNT || error "mount client failed"
25259 }
25260 run_test 280 "Race between MGS umount and client llog processing"
25261
25262 cleanup_test_300() {
25263         trap 0
25264         umask $SAVE_UMASK
25265 }
25266 test_striped_dir() {
25267         local mdt_index=$1
25268         local stripe_count
25269         local stripe_index
25270
25271         mkdir -p $DIR/$tdir
25272
25273         SAVE_UMASK=$(umask)
25274         trap cleanup_test_300 RETURN EXIT
25275
25276         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25277                                                 $DIR/$tdir/striped_dir ||
25278                 error "set striped dir error"
25279
25280         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25281         [ "$mode" = "755" ] || error "expect 755 got $mode"
25282
25283         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25284                 error "getdirstripe failed"
25285         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25286         if [ "$stripe_count" != "2" ]; then
25287                 error "1:stripe_count is $stripe_count, expect 2"
25288         fi
25289         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25290         if [ "$stripe_count" != "2" ]; then
25291                 error "2:stripe_count is $stripe_count, expect 2"
25292         fi
25293
25294         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25295         if [ "$stripe_index" != "$mdt_index" ]; then
25296                 error "stripe_index is $stripe_index, expect $mdt_index"
25297         fi
25298
25299         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25300                 error "nlink error after create striped dir"
25301
25302         mkdir $DIR/$tdir/striped_dir/a
25303         mkdir $DIR/$tdir/striped_dir/b
25304
25305         stat $DIR/$tdir/striped_dir/a ||
25306                 error "create dir under striped dir failed"
25307         stat $DIR/$tdir/striped_dir/b ||
25308                 error "create dir under striped dir failed"
25309
25310         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25311                 error "nlink error after mkdir"
25312
25313         rmdir $DIR/$tdir/striped_dir/a
25314         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25315                 error "nlink error after rmdir"
25316
25317         rmdir $DIR/$tdir/striped_dir/b
25318         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25319                 error "nlink error after rmdir"
25320
25321         chattr +i $DIR/$tdir/striped_dir
25322         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25323                 error "immutable flags not working under striped dir!"
25324         chattr -i $DIR/$tdir/striped_dir
25325
25326         rmdir $DIR/$tdir/striped_dir ||
25327                 error "rmdir striped dir error"
25328
25329         cleanup_test_300
25330
25331         true
25332 }
25333
25334 test_300a() {
25335         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25336                 skip "skipped for lustre < 2.7.0"
25337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25339
25340         test_striped_dir 0 || error "failed on striped dir on MDT0"
25341         test_striped_dir 1 || error "failed on striped dir on MDT0"
25342 }
25343 run_test 300a "basic striped dir sanity test"
25344
25345 test_300b() {
25346         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25347                 skip "skipped for lustre < 2.7.0"
25348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25349         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25350
25351         local i
25352         local mtime1
25353         local mtime2
25354         local mtime3
25355
25356         test_mkdir $DIR/$tdir || error "mkdir fail"
25357         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25358                 error "set striped dir error"
25359         for i in {0..9}; do
25360                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25361                 sleep 1
25362                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25363                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25364                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25365                 sleep 1
25366                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25367                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25368                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25369         done
25370         true
25371 }
25372 run_test 300b "check ctime/mtime for striped dir"
25373
25374 test_300c() {
25375         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25376                 skip "skipped for lustre < 2.7.0"
25377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25379
25380         local file_count
25381
25382         mkdir_on_mdt0 $DIR/$tdir
25383         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25384                 error "set striped dir error"
25385
25386         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25387                 error "chown striped dir failed"
25388
25389         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25390                 error "create 5k files failed"
25391
25392         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25393
25394         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25395
25396         rm -rf $DIR/$tdir
25397 }
25398 run_test 300c "chown && check ls under striped directory"
25399
25400 test_300d() {
25401         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25402                 skip "skipped for lustre < 2.7.0"
25403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25405
25406         local stripe_count
25407         local file
25408
25409         mkdir -p $DIR/$tdir
25410         $LFS setstripe -c 2 $DIR/$tdir
25411
25412         #local striped directory
25413         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25414                 error "set striped dir error"
25415         #look at the directories for debug purposes
25416         ls -l $DIR/$tdir
25417         $LFS getdirstripe $DIR/$tdir
25418         ls -l $DIR/$tdir/striped_dir
25419         $LFS getdirstripe $DIR/$tdir/striped_dir
25420         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25421                 error "create 10 files failed"
25422
25423         #remote striped directory
25424         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25425                 error "set striped dir error"
25426         #look at the directories for debug purposes
25427         ls -l $DIR/$tdir
25428         $LFS getdirstripe $DIR/$tdir
25429         ls -l $DIR/$tdir/remote_striped_dir
25430         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25431         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25432                 error "create 10 files failed"
25433
25434         for file in $(find $DIR/$tdir); do
25435                 stripe_count=$($LFS getstripe -c $file)
25436                 [ $stripe_count -eq 2 ] ||
25437                         error "wrong stripe $stripe_count for $file"
25438         done
25439
25440         rm -rf $DIR/$tdir
25441 }
25442 run_test 300d "check default stripe under striped directory"
25443
25444 test_300e() {
25445         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25446                 skip "Need MDS version at least 2.7.55"
25447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25449
25450         local stripe_count
25451         local file
25452
25453         mkdir -p $DIR/$tdir
25454
25455         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25456                 error "set striped dir error"
25457
25458         touch $DIR/$tdir/striped_dir/a
25459         touch $DIR/$tdir/striped_dir/b
25460         touch $DIR/$tdir/striped_dir/c
25461
25462         mkdir $DIR/$tdir/striped_dir/dir_a
25463         mkdir $DIR/$tdir/striped_dir/dir_b
25464         mkdir $DIR/$tdir/striped_dir/dir_c
25465
25466         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25467                 error "set striped adir under striped dir error"
25468
25469         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25470                 error "set striped bdir under striped dir error"
25471
25472         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25473                 error "set striped cdir under striped dir error"
25474
25475         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25476                 error "rename dir under striped dir fails"
25477
25478         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25479                 error "rename dir under different stripes fails"
25480
25481         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25482                 error "rename file under striped dir should succeed"
25483
25484         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25485                 error "rename dir under striped dir should succeed"
25486
25487         rm -rf $DIR/$tdir
25488 }
25489 run_test 300e "check rename under striped directory"
25490
25491 test_300f() {
25492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25493         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25494         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25495                 skip "Need MDS version at least 2.7.55"
25496
25497         local stripe_count
25498         local file
25499
25500         rm -rf $DIR/$tdir
25501         mkdir -p $DIR/$tdir
25502
25503         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25504                 error "set striped dir error"
25505
25506         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25507                 error "set striped dir error"
25508
25509         touch $DIR/$tdir/striped_dir/a
25510         mkdir $DIR/$tdir/striped_dir/dir_a
25511         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25512                 error "create striped dir under striped dir fails"
25513
25514         touch $DIR/$tdir/striped_dir1/b
25515         mkdir $DIR/$tdir/striped_dir1/dir_b
25516         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25517                 error "create striped dir under striped dir fails"
25518
25519         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25520                 error "rename dir under different striped dir should fail"
25521
25522         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25523                 error "rename striped dir under diff striped dir should fail"
25524
25525         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25526                 error "rename file under diff striped dirs fails"
25527
25528         rm -rf $DIR/$tdir
25529 }
25530 run_test 300f "check rename cross striped directory"
25531
25532 test_300_check_default_striped_dir()
25533 {
25534         local dirname=$1
25535         local default_count=$2
25536         local default_index=$3
25537         local stripe_count
25538         local stripe_index
25539         local dir_stripe_index
25540         local dir
25541
25542         echo "checking $dirname $default_count $default_index"
25543         $LFS setdirstripe -D -c $default_count -i $default_index \
25544                                 -H all_char $DIR/$tdir/$dirname ||
25545                 error "set default stripe on striped dir error"
25546         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25547         [ $stripe_count -eq $default_count ] ||
25548                 error "expect $default_count get $stripe_count for $dirname"
25549
25550         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25551         [ $stripe_index -eq $default_index ] ||
25552                 error "expect $default_index get $stripe_index for $dirname"
25553
25554         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25555                                                 error "create dirs failed"
25556
25557         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25558         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25559         for dir in $(find $DIR/$tdir/$dirname/*); do
25560                 stripe_count=$($LFS getdirstripe -c $dir)
25561                 (( $stripe_count == $default_count )) ||
25562                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25563                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25564                 error "stripe count $default_count != $stripe_count for $dir"
25565
25566                 stripe_index=$($LFS getdirstripe -i $dir)
25567                 [ $default_index -eq -1 ] ||
25568                         [ $stripe_index -eq $default_index ] ||
25569                         error "$stripe_index != $default_index for $dir"
25570
25571                 #check default stripe
25572                 stripe_count=$($LFS getdirstripe -D -c $dir)
25573                 [ $stripe_count -eq $default_count ] ||
25574                 error "default count $default_count != $stripe_count for $dir"
25575
25576                 stripe_index=$($LFS getdirstripe -D -i $dir)
25577                 [ $stripe_index -eq $default_index ] ||
25578                 error "default index $default_index != $stripe_index for $dir"
25579         done
25580         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25581 }
25582
25583 test_300g() {
25584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25585         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25586                 skip "Need MDS version at least 2.7.55"
25587
25588         local dir
25589         local stripe_count
25590         local stripe_index
25591
25592         mkdir_on_mdt0 $DIR/$tdir
25593         mkdir $DIR/$tdir/normal_dir
25594
25595         #Checking when client cache stripe index
25596         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25597         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25598                 error "create striped_dir failed"
25599
25600         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25601                 error "create dir0 fails"
25602         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25603         [ $stripe_index -eq 0 ] ||
25604                 error "dir0 expect index 0 got $stripe_index"
25605
25606         mkdir $DIR/$tdir/striped_dir/dir1 ||
25607                 error "create dir1 fails"
25608         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25609         [ $stripe_index -eq 1 ] ||
25610                 error "dir1 expect index 1 got $stripe_index"
25611
25612         #check default stripe count/stripe index
25613         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25614         test_300_check_default_striped_dir normal_dir 1 0
25615         test_300_check_default_striped_dir normal_dir -1 1
25616         test_300_check_default_striped_dir normal_dir 2 -1
25617
25618         #delete default stripe information
25619         echo "delete default stripeEA"
25620         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25621                 error "set default stripe on striped dir error"
25622
25623         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25624         for dir in $(find $DIR/$tdir/normal_dir/*); do
25625                 stripe_count=$($LFS getdirstripe -c $dir)
25626                 [ $stripe_count -eq 0 ] ||
25627                         error "expect 1 get $stripe_count for $dir"
25628         done
25629 }
25630 run_test 300g "check default striped directory for normal directory"
25631
25632 test_300h() {
25633         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25634         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25635                 skip "Need MDS version at least 2.7.55"
25636
25637         local dir
25638         local stripe_count
25639
25640         mkdir $DIR/$tdir
25641         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25642                 error "set striped dir error"
25643
25644         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25645         test_300_check_default_striped_dir striped_dir 1 0
25646         test_300_check_default_striped_dir striped_dir -1 1
25647         test_300_check_default_striped_dir striped_dir 2 -1
25648
25649         #delete default stripe information
25650         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25651                 error "set default stripe on striped dir error"
25652
25653         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25654         for dir in $(find $DIR/$tdir/striped_dir/*); do
25655                 stripe_count=$($LFS getdirstripe -c $dir)
25656                 [ $stripe_count -eq 0 ] ||
25657                         error "expect 1 get $stripe_count for $dir"
25658         done
25659 }
25660 run_test 300h "check default striped directory for striped directory"
25661
25662 test_300i() {
25663         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25664         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25665         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25666                 skip "Need MDS version at least 2.7.55"
25667
25668         local stripe_count
25669         local file
25670
25671         mkdir $DIR/$tdir
25672
25673         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25674                 error "set striped dir error"
25675
25676         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25677                 error "create files under striped dir failed"
25678
25679         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25680                 error "set striped hashdir error"
25681
25682         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25683                 error "create dir0 under hash dir failed"
25684         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25685                 error "create dir1 under hash dir failed"
25686         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25687                 error "create dir2 under hash dir failed"
25688
25689         # unfortunately, we need to umount to clear dir layout cache for now
25690         # once we fully implement dir layout, we can drop this
25691         umount_client $MOUNT || error "umount failed"
25692         mount_client $MOUNT || error "mount failed"
25693
25694         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25695         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25696         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25697
25698         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25699                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25700                         error "create crush2 dir $tdir/hashdir/d3 failed"
25701                 $LFS find -H crush2 $DIR/$tdir/hashdir
25702                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25703                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25704
25705                 # mkdir with an invalid hash type (hash=fail_val) from client
25706                 # should be replaced on MDS with a valid (default) hash type
25707                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25708                 $LCTL set_param fail_loc=0x1901 fail_val=99
25709                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25710
25711                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25712                 local expect=$(do_facet mds1 \
25713                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25714                 [[ $hash == $expect ]] ||
25715                         error "d99 hash '$hash' != expected hash '$expect'"
25716         fi
25717
25718         #set the stripe to be unknown hash type on read
25719         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25720         $LCTL set_param fail_loc=0x1901 fail_val=99
25721         for ((i = 0; i < 10; i++)); do
25722                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25723                         error "stat f-$i failed"
25724                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25725         done
25726
25727         touch $DIR/$tdir/striped_dir/f0 &&
25728                 error "create under striped dir with unknown hash should fail"
25729
25730         $LCTL set_param fail_loc=0
25731
25732         umount_client $MOUNT || error "umount failed"
25733         mount_client $MOUNT || error "mount failed"
25734
25735         return 0
25736 }
25737 run_test 300i "client handle unknown hash type striped directory"
25738
25739 test_300j() {
25740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25742         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25743                 skip "Need MDS version at least 2.7.55"
25744
25745         local stripe_count
25746         local file
25747
25748         mkdir $DIR/$tdir
25749
25750         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25751         $LCTL set_param fail_loc=0x1702
25752         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25753                 error "set striped dir error"
25754
25755         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25756                 error "create files under striped dir failed"
25757
25758         $LCTL set_param fail_loc=0
25759
25760         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25761
25762         return 0
25763 }
25764 run_test 300j "test large update record"
25765
25766 test_300k() {
25767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25769         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25770                 skip "Need MDS version at least 2.7.55"
25771
25772         # this test needs a huge transaction
25773         local kb
25774         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25775              osd*.$FSNAME-MDT0000.kbytestotal")
25776         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25777
25778         local stripe_count
25779         local file
25780
25781         mkdir $DIR/$tdir
25782
25783         #define OBD_FAIL_LARGE_STRIPE   0x1703
25784         $LCTL set_param fail_loc=0x1703
25785         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25786                 error "set striped dir error"
25787         $LCTL set_param fail_loc=0
25788
25789         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25790                 error "getstripeddir fails"
25791         rm -rf $DIR/$tdir/striped_dir ||
25792                 error "unlink striped dir fails"
25793
25794         return 0
25795 }
25796 run_test 300k "test large striped directory"
25797
25798 test_300l() {
25799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25800         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25801         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25802                 skip "Need MDS version at least 2.7.55"
25803
25804         local stripe_index
25805
25806         test_mkdir -p $DIR/$tdir/striped_dir
25807         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25808                         error "chown $RUNAS_ID failed"
25809         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25810                 error "set default striped dir failed"
25811
25812         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25813         $LCTL set_param fail_loc=0x80000158
25814         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25815
25816         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25817         [ $stripe_index -eq 1 ] ||
25818                 error "expect 1 get $stripe_index for $dir"
25819 }
25820 run_test 300l "non-root user to create dir under striped dir with stale layout"
25821
25822 test_300m() {
25823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25824         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25825         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25826                 skip "Need MDS version at least 2.7.55"
25827
25828         mkdir -p $DIR/$tdir/striped_dir
25829         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25830                 error "set default stripes dir error"
25831
25832         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25833
25834         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25835         [ $stripe_count -eq 0 ] ||
25836                         error "expect 0 get $stripe_count for a"
25837
25838         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25839                 error "set default stripes dir error"
25840
25841         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25842
25843         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25844         [ $stripe_count -eq 0 ] ||
25845                         error "expect 0 get $stripe_count for b"
25846
25847         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25848                 error "set default stripes dir error"
25849
25850         mkdir $DIR/$tdir/striped_dir/c &&
25851                 error "default stripe_index is invalid, mkdir c should fails"
25852
25853         rm -rf $DIR/$tdir || error "rmdir fails"
25854 }
25855 run_test 300m "setstriped directory on single MDT FS"
25856
25857 cleanup_300n() {
25858         local list=$(comma_list $(mdts_nodes))
25859
25860         trap 0
25861         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25862 }
25863
25864 test_300n() {
25865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25866         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25867         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25868                 skip "Need MDS version at least 2.7.55"
25869         remote_mds_nodsh && skip "remote MDS with nodsh"
25870
25871         local stripe_index
25872         local list=$(comma_list $(mdts_nodes))
25873
25874         trap cleanup_300n RETURN EXIT
25875         mkdir -p $DIR/$tdir
25876         chmod 777 $DIR/$tdir
25877         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25878                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25879                 error "create striped dir succeeds with gid=0"
25880
25881         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25882         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25883                 error "create striped dir fails with gid=-1"
25884
25885         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25886         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25887                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25888                 error "set default striped dir succeeds with gid=0"
25889
25890
25891         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25892         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25893                 error "set default striped dir fails with gid=-1"
25894
25895
25896         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25897         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25898                                         error "create test_dir fails"
25899         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25900                                         error "create test_dir1 fails"
25901         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25902                                         error "create test_dir2 fails"
25903         cleanup_300n
25904 }
25905 run_test 300n "non-root user to create dir under striped dir with default EA"
25906
25907 test_300o() {
25908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25909         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25910         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25911                 skip "Need MDS version at least 2.7.55"
25912
25913         local numfree1
25914         local numfree2
25915
25916         mkdir -p $DIR/$tdir
25917
25918         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25919         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25920         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25921                 skip "not enough free inodes $numfree1 $numfree2"
25922         fi
25923
25924         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25925         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25926         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25927                 skip "not enough free space $numfree1 $numfree2"
25928         fi
25929
25930         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25931                 error "setdirstripe fails"
25932
25933         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25934                 error "create dirs fails"
25935
25936         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25937         ls $DIR/$tdir/striped_dir > /dev/null ||
25938                 error "ls striped dir fails"
25939         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25940                 error "unlink big striped dir fails"
25941 }
25942 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25943
25944 test_300p() {
25945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25947         remote_mds_nodsh && skip "remote MDS with nodsh"
25948
25949         mkdir_on_mdt0 $DIR/$tdir
25950
25951         #define OBD_FAIL_OUT_ENOSPC     0x1704
25952         do_facet mds2 lctl set_param fail_loc=0x80001704
25953         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25954                  && error "create striped directory should fail"
25955
25956         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25957
25958         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25959         true
25960 }
25961 run_test 300p "create striped directory without space"
25962
25963 test_300q() {
25964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25965         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25966
25967         local fd=$(free_fd)
25968         local cmd="exec $fd<$tdir"
25969         cd $DIR
25970         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25971         eval $cmd
25972         cmd="exec $fd<&-"
25973         trap "eval $cmd" EXIT
25974         cd $tdir || error "cd $tdir fails"
25975         rmdir  ../$tdir || error "rmdir $tdir fails"
25976         mkdir local_dir && error "create dir succeeds"
25977         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25978         eval $cmd
25979         return 0
25980 }
25981 run_test 300q "create remote directory under orphan directory"
25982
25983 test_300r() {
25984         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25985                 skip "Need MDS version at least 2.7.55" && return
25986         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25987
25988         mkdir $DIR/$tdir
25989
25990         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25991                 error "set striped dir error"
25992
25993         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25994                 error "getstripeddir fails"
25995
25996         local stripe_count
25997         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25998                       awk '/lmv_stripe_count:/ { print $2 }')
25999
26000         [ $MDSCOUNT -ne $stripe_count ] &&
26001                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26002
26003         rm -rf $DIR/$tdir/striped_dir ||
26004                 error "unlink striped dir fails"
26005 }
26006 run_test 300r "test -1 striped directory"
26007
26008 test_300s_helper() {
26009         local count=$1
26010
26011         local stripe_dir=$DIR/$tdir/striped_dir.$count
26012
26013         $LFS mkdir -c $count $stripe_dir ||
26014                 error "lfs mkdir -c error"
26015
26016         $LFS getdirstripe $stripe_dir ||
26017                 error "lfs getdirstripe fails"
26018
26019         local stripe_count
26020         stripe_count=$($LFS getdirstripe $stripe_dir |
26021                       awk '/lmv_stripe_count:/ { print $2 }')
26022
26023         [ $count -ne $stripe_count ] &&
26024                 error_noexit "bad stripe count $stripe_count expected $count"
26025
26026         local dupe_stripes
26027         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26028                 awk '/0x/ {count[$1] += 1}; END {
26029                         for (idx in count) {
26030                                 if (count[idx]>1) {
26031                                         print "index " idx " count " count[idx]
26032                                 }
26033                         }
26034                 }')
26035
26036         if [[ -n "$dupe_stripes" ]] ; then
26037                 lfs getdirstripe $stripe_dir
26038                 error_noexit "Dupe MDT above: $dupe_stripes "
26039         fi
26040
26041         rm -rf $stripe_dir ||
26042                 error_noexit "unlink $stripe_dir fails"
26043 }
26044
26045 test_300s() {
26046         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26047                 skip "Need MDS version at least 2.7.55" && return
26048         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26049
26050         mkdir $DIR/$tdir
26051         for count in $(seq 2 $MDSCOUNT); do
26052                 test_300s_helper $count
26053         done
26054 }
26055 run_test 300s "test lfs mkdir -c without -i"
26056
26057 test_300t() {
26058         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26059                 skip "need MDS 2.14.55 or later"
26060         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26061
26062         local testdir="$DIR/$tdir/striped_dir"
26063         local dir1=$testdir/dir1
26064         local dir2=$testdir/dir2
26065
26066         mkdir -p $testdir
26067
26068         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26069                 error "failed to set default stripe count for $testdir"
26070
26071         mkdir $dir1
26072         local stripe_count=$($LFS getdirstripe -c $dir1)
26073
26074         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26075
26076         local max_count=$((MDSCOUNT - 1))
26077         local mdts=$(comma_list $(mdts_nodes))
26078
26079         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26080         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26081
26082         mkdir $dir2
26083         stripe_count=$($LFS getdirstripe -c $dir2)
26084
26085         (( $stripe_count == $max_count )) || error "wrong stripe count"
26086 }
26087 run_test 300t "test max_mdt_stripecount"
26088
26089 prepare_remote_file() {
26090         mkdir $DIR/$tdir/src_dir ||
26091                 error "create remote source failed"
26092
26093         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26094                  error "cp to remote source failed"
26095         touch $DIR/$tdir/src_dir/a
26096
26097         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26098                 error "create remote target dir failed"
26099
26100         touch $DIR/$tdir/tgt_dir/b
26101
26102         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26103                 error "rename dir cross MDT failed!"
26104
26105         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26106                 error "src_child still exists after rename"
26107
26108         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26109                 error "missing file(a) after rename"
26110
26111         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26112                 error "diff after rename"
26113 }
26114
26115 test_310a() {
26116         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26118
26119         local remote_file=$DIR/$tdir/tgt_dir/b
26120
26121         mkdir -p $DIR/$tdir
26122
26123         prepare_remote_file || error "prepare remote file failed"
26124
26125         #open-unlink file
26126         $OPENUNLINK $remote_file $remote_file ||
26127                 error "openunlink $remote_file failed"
26128         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26129 }
26130 run_test 310a "open unlink remote file"
26131
26132 test_310b() {
26133         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26135
26136         local remote_file=$DIR/$tdir/tgt_dir/b
26137
26138         mkdir -p $DIR/$tdir
26139
26140         prepare_remote_file || error "prepare remote file failed"
26141
26142         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26143         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26144         $CHECKSTAT -t file $remote_file || error "check file failed"
26145 }
26146 run_test 310b "unlink remote file with multiple links while open"
26147
26148 test_310c() {
26149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26150         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26151
26152         local remote_file=$DIR/$tdir/tgt_dir/b
26153
26154         mkdir -p $DIR/$tdir
26155
26156         prepare_remote_file || error "prepare remote file failed"
26157
26158         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26159         multiop_bg_pause $remote_file O_uc ||
26160                         error "mulitop failed for remote file"
26161         MULTIPID=$!
26162         $MULTIOP $DIR/$tfile Ouc
26163         kill -USR1 $MULTIPID
26164         wait $MULTIPID
26165 }
26166 run_test 310c "open-unlink remote file with multiple links"
26167
26168 #LU-4825
26169 test_311() {
26170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26171         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26172         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26173                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26174         remote_mds_nodsh && skip "remote MDS with nodsh"
26175
26176         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26177         local mdts=$(comma_list $(mdts_nodes))
26178
26179         mkdir -p $DIR/$tdir
26180         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26181         createmany -o $DIR/$tdir/$tfile. 1000
26182
26183         # statfs data is not real time, let's just calculate it
26184         old_iused=$((old_iused + 1000))
26185
26186         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26187                         osp.*OST0000*MDT0000.create_count")
26188         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26189                                 osp.*OST0000*MDT0000.max_create_count")
26190         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26191
26192         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26193         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26194         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26195
26196         unlinkmany $DIR/$tdir/$tfile. 1000
26197
26198         do_nodes $mdts "$LCTL set_param -n \
26199                         osp.*OST0000*.max_create_count=$max_count"
26200         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26201                 do_nodes $mdts "$LCTL set_param -n \
26202                                 osp.*OST0000*.create_count=$count"
26203         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26204                         grep "=0" && error "create_count is zero"
26205
26206         local new_iused
26207         for i in $(seq 120); do
26208                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26209                 # system may be too busy to destroy all objs in time, use
26210                 # a somewhat small value to not fail autotest
26211                 [ $((old_iused - new_iused)) -gt 400 ] && break
26212                 sleep 1
26213         done
26214
26215         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26216         [ $((old_iused - new_iused)) -gt 400 ] ||
26217                 error "objs not destroyed after unlink"
26218 }
26219 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26220
26221 zfs_get_objid()
26222 {
26223         local ost=$1
26224         local tf=$2
26225         local fid=($($LFS getstripe $tf | grep 0x))
26226         local seq=${fid[3]#0x}
26227         local objid=${fid[1]}
26228
26229         local vdevdir=$(dirname $(facet_vdevice $ost))
26230         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26231         local zfs_zapid=$(do_facet $ost $cmd |
26232                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26233                           awk '/Object/{getline; print $1}')
26234         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26235                           awk "/$objid = /"'{printf $3}')
26236
26237         echo $zfs_objid
26238 }
26239
26240 zfs_object_blksz() {
26241         local ost=$1
26242         local objid=$2
26243
26244         local vdevdir=$(dirname $(facet_vdevice $ost))
26245         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26246         local blksz=$(do_facet $ost $cmd $objid |
26247                       awk '/dblk/{getline; printf $4}')
26248
26249         case "${blksz: -1}" in
26250                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26251                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26252                 *) ;;
26253         esac
26254
26255         echo $blksz
26256 }
26257
26258 test_312() { # LU-4856
26259         remote_ost_nodsh && skip "remote OST with nodsh"
26260         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26261
26262         local max_blksz=$(do_facet ost1 \
26263                           $ZFS get -p recordsize $(facet_device ost1) |
26264                           awk '!/VALUE/{print $3}')
26265         local tf=$DIR/$tfile
26266
26267         $LFS setstripe -c1 $tf
26268         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26269
26270         # Get ZFS object id
26271         local zfs_objid=$(zfs_get_objid $facet $tf)
26272         # block size change by sequential overwrite
26273         local bs
26274
26275         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26276                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26277
26278                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26279                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26280         done
26281         rm -f $tf
26282
26283         $LFS setstripe -c1 $tf
26284         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26285
26286         # block size change by sequential append write
26287         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26288         zfs_objid=$(zfs_get_objid $facet $tf)
26289         local count
26290
26291         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26292                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26293                         oflag=sync conv=notrunc
26294
26295                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26296                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26297                         error "blksz error, actual $blksz, " \
26298                                 "expected: 2 * $count * $PAGE_SIZE"
26299         done
26300         rm -f $tf
26301
26302         # random write
26303         $LFS setstripe -c1 $tf
26304         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26305         zfs_objid=$(zfs_get_objid $facet $tf)
26306
26307         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26308         blksz=$(zfs_object_blksz $facet $zfs_objid)
26309         (( blksz == PAGE_SIZE )) ||
26310                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26311
26312         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26313         blksz=$(zfs_object_blksz $facet $zfs_objid)
26314         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26315
26316         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26317         blksz=$(zfs_object_blksz $facet $zfs_objid)
26318         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26319 }
26320 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26321
26322 test_313() {
26323         remote_ost_nodsh && skip "remote OST with nodsh"
26324
26325         local file=$DIR/$tfile
26326
26327         rm -f $file
26328         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26329
26330         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26331         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26332         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26333                 error "write should failed"
26334         do_facet ost1 "$LCTL set_param fail_loc=0"
26335         rm -f $file
26336 }
26337 run_test 313 "io should fail after last_rcvd update fail"
26338
26339 test_314() {
26340         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26341
26342         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26343         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26344         rm -f $DIR/$tfile
26345         wait_delete_completed
26346         do_facet ost1 "$LCTL set_param fail_loc=0"
26347 }
26348 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26349
26350 test_315() { # LU-618
26351         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26352
26353         local file=$DIR/$tfile
26354         rm -f $file
26355
26356         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26357                 error "multiop file write failed"
26358         $MULTIOP $file oO_RDONLY:r4063232_c &
26359         PID=$!
26360
26361         sleep 2
26362
26363         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26364         kill -USR1 $PID
26365
26366         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26367         rm -f $file
26368 }
26369 run_test 315 "read should be accounted"
26370
26371 test_316() {
26372         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26373         large_xattr_enabled || skip "ea_inode feature disabled"
26374
26375         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26376         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26377         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26378         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26379
26380         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26381 }
26382 run_test 316 "lfs migrate of file with large_xattr enabled"
26383
26384 test_317() {
26385         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26386                 skip "Need MDS version at least 2.11.53"
26387         if [ "$ost1_FSTYPE" == "zfs" ]; then
26388                 skip "LU-10370: no implementation for ZFS"
26389         fi
26390
26391         local trunc_sz
26392         local grant_blk_size
26393
26394         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26395                         awk '/grant_block_size:/ { print $2; exit; }')
26396         #
26397         # Create File of size 5M. Truncate it to below size's and verify
26398         # blocks count.
26399         #
26400         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26401                 error "Create file $DIR/$tfile failed"
26402         stack_trap "rm -f $DIR/$tfile" EXIT
26403
26404         for trunc_sz in 2097152 4097 4000 509 0; do
26405                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26406                         error "truncate $tfile to $trunc_sz failed"
26407                 local sz=$(stat --format=%s $DIR/$tfile)
26408                 local blk=$(stat --format=%b $DIR/$tfile)
26409                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26410                                      grant_blk_size) * 8))
26411
26412                 if [[ $blk -ne $trunc_blk ]]; then
26413                         $(which stat) $DIR/$tfile
26414                         error "Expected Block $trunc_blk got $blk for $tfile"
26415                 fi
26416
26417                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26418                         error "Expected Size $trunc_sz got $sz for $tfile"
26419         done
26420
26421         #
26422         # sparse file test
26423         # Create file with a hole and write actual 65536 bytes which aligned
26424         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26425         #
26426         local bs=65536
26427         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26428                 error "Create file : $DIR/$tfile"
26429
26430         #
26431         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26432         # blocks. The block count must drop to 8.
26433         #
26434         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26435                 ((bs - grant_blk_size) + 1)))
26436         $TRUNCATE $DIR/$tfile $trunc_sz ||
26437                 error "truncate $tfile to $trunc_sz failed"
26438
26439         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26440         sz=$(stat --format=%s $DIR/$tfile)
26441         blk=$(stat --format=%b $DIR/$tfile)
26442
26443         if [[ $blk -ne $trunc_bsz ]]; then
26444                 $(which stat) $DIR/$tfile
26445                 error "Expected Block $trunc_bsz got $blk for $tfile"
26446         fi
26447
26448         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26449                 error "Expected Size $trunc_sz got $sz for $tfile"
26450 }
26451 run_test 317 "Verify blocks get correctly update after truncate"
26452
26453 test_318() {
26454         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26455         local old_max_active=$($LCTL get_param -n \
26456                             ${llite_name}.max_read_ahead_async_active \
26457                             2>/dev/null)
26458
26459         $LCTL set_param llite.*.max_read_ahead_async_active=256
26460         local max_active=$($LCTL get_param -n \
26461                            ${llite_name}.max_read_ahead_async_active \
26462                            2>/dev/null)
26463         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26464
26465         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26466                 error "set max_read_ahead_async_active should succeed"
26467
26468         $LCTL set_param llite.*.max_read_ahead_async_active=512
26469         max_active=$($LCTL get_param -n \
26470                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26471         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26472
26473         # restore @max_active
26474         [ $old_max_active -ne 0 ] && $LCTL set_param \
26475                 llite.*.max_read_ahead_async_active=$old_max_active
26476
26477         local old_threshold=$($LCTL get_param -n \
26478                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26479         local max_per_file_mb=$($LCTL get_param -n \
26480                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26481
26482         local invalid=$(($max_per_file_mb + 1))
26483         $LCTL set_param \
26484                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26485                         && error "set $invalid should fail"
26486
26487         local valid=$(($invalid - 1))
26488         $LCTL set_param \
26489                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26490                         error "set $valid should succeed"
26491         local threshold=$($LCTL get_param -n \
26492                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26493         [ $threshold -eq $valid ] || error \
26494                 "expect threshold $valid got $threshold"
26495         $LCTL set_param \
26496                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26497 }
26498 run_test 318 "Verify async readahead tunables"
26499
26500 test_319() {
26501         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26502
26503         local before=$(date +%s)
26504         local evict
26505         local mdir=$DIR/$tdir
26506         local file=$mdir/xxx
26507
26508         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26509         touch $file
26510
26511 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26512         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26513         $LFS migrate -m1 $mdir &
26514
26515         sleep 1
26516         dd if=$file of=/dev/null
26517         wait
26518         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26519           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26520
26521         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26522 }
26523 run_test 319 "lost lease lock on migrate error"
26524
26525 test_398a() { # LU-4198
26526         local ost1_imp=$(get_osc_import_name client ost1)
26527         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26528                          cut -d'.' -f2)
26529
26530         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26531         stack_trap "rm -f $DIR/$tfile"
26532         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26533
26534         # request a new lock on client
26535         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26536
26537         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26538         local lock_count=$($LCTL get_param -n \
26539                            ldlm.namespaces.$imp_name.lru_size)
26540         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26541
26542         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26543
26544         # no lock cached, should use lockless DIO and not enqueue new lock
26545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26546         lock_count=$($LCTL get_param -n \
26547                      ldlm.namespaces.$imp_name.lru_size)
26548         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26549
26550         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26551
26552         # no lock cached, should use locked DIO append
26553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26554                 conv=notrunc || error "DIO append failed"
26555         lock_count=$($LCTL get_param -n \
26556                      ldlm.namespaces.$imp_name.lru_size)
26557         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26558 }
26559 run_test 398a "direct IO should cancel lock otherwise lockless"
26560
26561 test_398b() { # LU-4198
26562         local before=$(date +%s)
26563         local njobs=4
26564         local size=48
26565
26566         which fio || skip_env "no fio installed"
26567         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26568         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26569
26570         # Single page, multiple pages, stripe size, 4*stripe size
26571         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26572                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26573                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26574                         --numjobs=$njobs --fallocate=none \
26575                         --iodepth=16 --allow_file_create=0 \
26576                         --size=$((size/njobs))M \
26577                         --filename=$DIR/$tfile &
26578                 bg_pid=$!
26579
26580                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26581                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26582                         --numjobs=$njobs --fallocate=none \
26583                         --iodepth=16 --allow_file_create=0 \
26584                         --size=$((size/njobs))M \
26585                         --filename=$DIR/$tfile || true
26586                 wait $bg_pid
26587         done
26588
26589         evict=$(do_facet client $LCTL get_param \
26590                 osc.$FSNAME-OST*-osc-*/state |
26591             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26592
26593         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26594                 (do_facet client $LCTL get_param \
26595                         osc.$FSNAME-OST*-osc-*/state;
26596                     error "eviction happened: $evict before:$before")
26597
26598         rm -f $DIR/$tfile
26599 }
26600 run_test 398b "DIO and buffer IO race"
26601
26602 test_398c() { # LU-4198
26603         local ost1_imp=$(get_osc_import_name client ost1)
26604         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26605                          cut -d'.' -f2)
26606
26607         which fio || skip_env "no fio installed"
26608
26609         saved_debug=$($LCTL get_param -n debug)
26610         $LCTL set_param debug=0
26611
26612         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26613         ((size /= 1024)) # by megabytes
26614         ((size /= 2)) # write half of the OST at most
26615         [ $size -gt 40 ] && size=40 #reduce test time anyway
26616
26617         $LFS setstripe -c 1 $DIR/$tfile
26618
26619         # it seems like ldiskfs reserves more space than necessary if the
26620         # writing blocks are not mapped, so it extends the file firstly
26621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26622         cancel_lru_locks osc
26623
26624         # clear and verify rpc_stats later
26625         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26626
26627         local njobs=4
26628         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26629         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26630                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26631                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26632                 --filename=$DIR/$tfile
26633         [ $? -eq 0 ] || error "fio write error"
26634
26635         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26636                 error "Locks were requested while doing AIO"
26637
26638         # get the percentage of 1-page I/O
26639         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26640                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26641                 awk '{print $7}')
26642         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26643
26644         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26645         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26646                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26647                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26648                 --filename=$DIR/$tfile
26649         [ $? -eq 0 ] || error "fio mixed read write error"
26650
26651         echo "AIO with large block size ${size}M"
26652         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26653                 --numjobs=1 --fallocate=none --ioengine=libaio \
26654                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26655                 --filename=$DIR/$tfile
26656         [ $? -eq 0 ] || error "fio large block size failed"
26657
26658         rm -f $DIR/$tfile
26659         $LCTL set_param debug="$saved_debug"
26660 }
26661 run_test 398c "run fio to test AIO"
26662
26663 test_398d() { #  LU-13846
26664         which aiocp || skip_env "no aiocp installed"
26665         local aio_file=$DIR/$tfile.aio
26666
26667         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26668
26669         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26670         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26671         stack_trap "rm -f $DIR/$tfile $aio_file"
26672
26673         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26674
26675         # test memory unaligned aio
26676         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26677                 error "unaligned aio failed"
26678         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26679
26680         rm -f $DIR/$tfile $aio_file
26681 }
26682 run_test 398d "run aiocp to verify block size > stripe size"
26683
26684 test_398e() {
26685         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26686         touch $DIR/$tfile.new
26687         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26688 }
26689 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26690
26691 test_398f() { #  LU-14687
26692         which aiocp || skip_env "no aiocp installed"
26693         local aio_file=$DIR/$tfile.aio
26694
26695         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26696
26697         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26698         stack_trap "rm -f $DIR/$tfile $aio_file"
26699
26700         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26701         $LCTL set_param fail_loc=0x1418
26702         # make sure we don't crash and fail properly
26703         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26704                 error "aio with page allocation failure succeeded"
26705         $LCTL set_param fail_loc=0
26706         diff $DIR/$tfile $aio_file
26707         [[ $? != 0 ]] || error "no diff after failed aiocp"
26708 }
26709 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26710
26711 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26712 # stripe and i/o size must be > stripe size
26713 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26714 # single RPC in flight.  This test shows async DIO submission is working by
26715 # showing multiple RPCs in flight.
26716 test_398g() { #  LU-13798
26717         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26718
26719         # We need to do some i/o first to acquire enough grant to put our RPCs
26720         # in flight; otherwise a new connection may not have enough grant
26721         # available
26722         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26723                 error "parallel dio failed"
26724         stack_trap "rm -f $DIR/$tfile"
26725
26726         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26727         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26728         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26729         stack_trap "$LCTL set_param -n $pages_per_rpc"
26730
26731         # Recreate file so it's empty
26732         rm -f $DIR/$tfile
26733         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26734         #Pause rpc completion to guarantee we see multiple rpcs in flight
26735         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26736         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26737         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26738
26739         # Clear rpc stats
26740         $LCTL set_param osc.*.rpc_stats=c
26741
26742         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26743                 error "parallel dio failed"
26744         stack_trap "rm -f $DIR/$tfile"
26745
26746         $LCTL get_param osc.*-OST0000-*.rpc_stats
26747         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26748                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26749                 grep "8:" | awk '{print $8}')
26750         # We look at the "8 rpcs in flight" field, and verify A) it is present
26751         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26752         # as expected for an 8M DIO to a file with 1M stripes.
26753         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26754
26755         # Verify turning off parallel dio works as expected
26756         # Clear rpc stats
26757         $LCTL set_param osc.*.rpc_stats=c
26758         $LCTL set_param llite.*.parallel_dio=0
26759         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26760
26761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26762                 error "dio with parallel dio disabled failed"
26763
26764         # Ideally, we would see only one RPC in flight here, but there is an
26765         # unavoidable race between i/o completion and RPC in flight counting,
26766         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26767         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26768         # So instead we just verify it's always < 8.
26769         $LCTL get_param osc.*-OST0000-*.rpc_stats
26770         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26771                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26772                 grep '^$' -B1 | grep . | awk '{print $1}')
26773         [ $ret != "8:" ] ||
26774                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26775 }
26776 run_test 398g "verify parallel dio async RPC submission"
26777
26778 test_398h() { #  LU-13798
26779         local dio_file=$DIR/$tfile.dio
26780
26781         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26782
26783         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26784         stack_trap "rm -f $DIR/$tfile $dio_file"
26785
26786         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26787                 error "parallel dio failed"
26788         diff $DIR/$tfile $dio_file
26789         [[ $? == 0 ]] || error "file diff after aiocp"
26790 }
26791 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26792
26793 test_398i() { #  LU-13798
26794         local dio_file=$DIR/$tfile.dio
26795
26796         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26797
26798         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26799         stack_trap "rm -f $DIR/$tfile $dio_file"
26800
26801         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26802         $LCTL set_param fail_loc=0x1418
26803         # make sure we don't crash and fail properly
26804         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26805                 error "parallel dio page allocation failure succeeded"
26806         diff $DIR/$tfile $dio_file
26807         [[ $? != 0 ]] || error "no diff after failed aiocp"
26808 }
26809 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26810
26811 test_398j() { #  LU-13798
26812         # Stripe size > RPC size but less than i/o size tests split across
26813         # stripes and RPCs for individual i/o op
26814         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26815
26816         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26817         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26818         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26819         stack_trap "$LCTL set_param -n $pages_per_rpc"
26820
26821         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26822                 error "parallel dio write failed"
26823         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26824
26825         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26826                 error "parallel dio read failed"
26827         diff $DIR/$tfile $DIR/$tfile.2
26828         [[ $? == 0 ]] || error "file diff after parallel dio read"
26829 }
26830 run_test 398j "test parallel dio where stripe size > rpc_size"
26831
26832 test_398k() { #  LU-13798
26833         wait_delete_completed
26834         wait_mds_ost_sync
26835
26836         # 4 stripe file; we will cause out of space on OST0
26837         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26838
26839         # Fill OST0 (if it's not too large)
26840         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26841                    head -n1)
26842         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26843                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26844         fi
26845         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26846         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26847                 error "dd should fill OST0"
26848         stack_trap "rm -f $DIR/$tfile.1"
26849
26850         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26851         err=$?
26852
26853         ls -la $DIR/$tfile
26854         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26855                 error "file is not 0 bytes in size"
26856
26857         # dd above should not succeed, but don't error until here so we can
26858         # get debug info above
26859         [[ $err != 0 ]] ||
26860                 error "parallel dio write with enospc succeeded"
26861         stack_trap "rm -f $DIR/$tfile"
26862 }
26863 run_test 398k "test enospc on first stripe"
26864
26865 test_398l() { #  LU-13798
26866         wait_delete_completed
26867         wait_mds_ost_sync
26868
26869         # 4 stripe file; we will cause out of space on OST0
26870         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26871         # happens on the second i/o chunk we issue
26872         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26873
26874         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26875         stack_trap "rm -f $DIR/$tfile"
26876
26877         # Fill OST0 (if it's not too large)
26878         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26879                    head -n1)
26880         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26881                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26882         fi
26883         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26884         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26885                 error "dd should fill OST0"
26886         stack_trap "rm -f $DIR/$tfile.1"
26887
26888         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26889         err=$?
26890         stack_trap "rm -f $DIR/$tfile.2"
26891
26892         # Check that short write completed as expected
26893         ls -la $DIR/$tfile.2
26894         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26895                 error "file is not 1M in size"
26896
26897         # dd above should not succeed, but don't error until here so we can
26898         # get debug info above
26899         [[ $err != 0 ]] ||
26900                 error "parallel dio write with enospc succeeded"
26901
26902         # Truncate source file to same length as output file and diff them
26903         $TRUNCATE $DIR/$tfile 1048576
26904         diff $DIR/$tfile $DIR/$tfile.2
26905         [[ $? == 0 ]] || error "data incorrect after short write"
26906 }
26907 run_test 398l "test enospc on intermediate stripe/RPC"
26908
26909 test_398m() { #  LU-13798
26910         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26911
26912         # Set up failure on OST0, the first stripe:
26913         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26914         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26915         # OST0 is on ost1, OST1 is on ost2.
26916         # So this fail_val specifies OST0
26917         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26918         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26919
26920         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26921                 error "parallel dio write with failure on first stripe succeeded"
26922         stack_trap "rm -f $DIR/$tfile"
26923         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26924
26925         # Place data in file for read
26926         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26927                 error "parallel dio write failed"
26928
26929         # Fail read on OST0, first stripe
26930         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26931         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26932         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26933                 error "parallel dio read with error on first stripe succeeded"
26934         rm -f $DIR/$tfile.2
26935         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26936
26937         # Switch to testing on OST1, second stripe
26938         # Clear file contents, maintain striping
26939         echo > $DIR/$tfile
26940         # Set up failure on OST1, second stripe:
26941         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26942         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26943
26944         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26945                 error "parallel dio write with failure on second stripe succeeded"
26946         stack_trap "rm -f $DIR/$tfile"
26947         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26948
26949         # Place data in file for read
26950         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26951                 error "parallel dio write failed"
26952
26953         # Fail read on OST1, second stripe
26954         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26955         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26956         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26957                 error "parallel dio read with error on second stripe succeeded"
26958         rm -f $DIR/$tfile.2
26959         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26960 }
26961 run_test 398m "test RPC failures with parallel dio"
26962
26963 # Parallel submission of DIO should not cause problems for append, but it's
26964 # important to verify.
26965 test_398n() { #  LU-13798
26966         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26967
26968         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26969                 error "dd to create source file failed"
26970         stack_trap "rm -f $DIR/$tfile"
26971
26972         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26973                 error "parallel dio write with failure on second stripe succeeded"
26974         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26975         diff $DIR/$tfile $DIR/$tfile.1
26976         [[ $? == 0 ]] || error "data incorrect after append"
26977
26978 }
26979 run_test 398n "test append with parallel DIO"
26980
26981 test_398o() {
26982         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26983 }
26984 run_test 398o "right kms with DIO"
26985
26986 test_398p()
26987 {
26988         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26989         which aiocp || skip_env "no aiocp installed"
26990
26991         local stripe_size=$((1024 * 1024)) #1 MiB
26992         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26993         local file_size=$((25 * stripe_size))
26994
26995         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26996         stack_trap "rm -f $DIR/$tfile*"
26997         # Just a bit bigger than the largest size in the test set below
26998         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26999                 error "buffered i/o to create file failed"
27000
27001         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27002                 $((stripe_size * 4)); do
27003
27004                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27005
27006                 echo "bs: $bs, file_size $file_size"
27007                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27008                         $DIR/$tfile.1 $DIR/$tfile.2 &
27009                 pid_dio1=$!
27010                 # Buffered I/O with similar but not the same block size
27011                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27012                         conv=notrunc &
27013                 pid_bio2=$!
27014                 wait $pid_dio1
27015                 rc1=$?
27016                 wait $pid_bio2
27017                 rc2=$?
27018                 if (( rc1 != 0 )); then
27019                         error "aio copy 1 w/bsize $bs failed: $rc1"
27020                 fi
27021                 if (( rc2 != 0 )); then
27022                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27023                 fi
27024
27025                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27026                         error "size incorrect"
27027                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27028                         error "files differ, bsize $bs"
27029                 rm -f $DIR/$tfile.2
27030         done
27031 }
27032 run_test 398p "race aio with buffered i/o"
27033
27034 test_398q()
27035 {
27036         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27037
27038         local stripe_size=$((1024 * 1024)) #1 MiB
27039         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27040         local file_size=$((25 * stripe_size))
27041
27042         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27043         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27044
27045         # Just a bit bigger than the largest size in the test set below
27046         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27047                 error "buffered i/o to create file failed"
27048
27049         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27050                 $((stripe_size * 4)); do
27051
27052                 echo "bs: $bs, file_size $file_size"
27053                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
27054                         conv=notrunc oflag=direct iflag=direct &
27055                 pid_dio1=$!
27056                 # Buffered I/O with similar but not the same block size
27057                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27058                         conv=notrunc &
27059                 pid_bio2=$!
27060                 wait $pid_dio1
27061                 rc1=$?
27062                 wait $pid_bio2
27063                 rc2=$?
27064                 if (( rc1 != 0 )); then
27065                         error "dio copy 1 w/bsize $bs failed: $rc1"
27066                 fi
27067                 if (( rc2 != 0 )); then
27068                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27069                 fi
27070
27071                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27072                         error "size incorrect"
27073                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27074                         error "files differ, bsize $bs"
27075         done
27076
27077         rm -f $DIR/$tfile*
27078 }
27079 run_test 398q "race dio with buffered i/o"
27080
27081 test_fake_rw() {
27082         local read_write=$1
27083         if [ "$read_write" = "write" ]; then
27084                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27085         elif [ "$read_write" = "read" ]; then
27086                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27087         else
27088                 error "argument error"
27089         fi
27090
27091         # turn off debug for performance testing
27092         local saved_debug=$($LCTL get_param -n debug)
27093         $LCTL set_param debug=0
27094
27095         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27096
27097         # get ost1 size - $FSNAME-OST0000
27098         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27099         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27100         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27101
27102         if [ "$read_write" = "read" ]; then
27103                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27104         fi
27105
27106         local start_time=$(date +%s.%N)
27107         $dd_cmd bs=1M count=$blocks oflag=sync ||
27108                 error "real dd $read_write error"
27109         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27110
27111         if [ "$read_write" = "write" ]; then
27112                 rm -f $DIR/$tfile
27113         fi
27114
27115         # define OBD_FAIL_OST_FAKE_RW           0x238
27116         do_facet ost1 $LCTL set_param fail_loc=0x238
27117
27118         local start_time=$(date +%s.%N)
27119         $dd_cmd bs=1M count=$blocks oflag=sync ||
27120                 error "fake dd $read_write error"
27121         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27122
27123         if [ "$read_write" = "write" ]; then
27124                 # verify file size
27125                 cancel_lru_locks osc
27126                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27127                         error "$tfile size not $blocks MB"
27128         fi
27129         do_facet ost1 $LCTL set_param fail_loc=0
27130
27131         echo "fake $read_write $duration_fake vs. normal $read_write" \
27132                 "$duration in seconds"
27133         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27134                 error_not_in_vm "fake write is slower"
27135
27136         $LCTL set_param -n debug="$saved_debug"
27137         rm -f $DIR/$tfile
27138 }
27139 test_399a() { # LU-7655 for OST fake write
27140         remote_ost_nodsh && skip "remote OST with nodsh"
27141
27142         test_fake_rw write
27143 }
27144 run_test 399a "fake write should not be slower than normal write"
27145
27146 test_399b() { # LU-8726 for OST fake read
27147         remote_ost_nodsh && skip "remote OST with nodsh"
27148         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27149                 skip_env "ldiskfs only test"
27150         fi
27151
27152         test_fake_rw read
27153 }
27154 run_test 399b "fake read should not be slower than normal read"
27155
27156 test_400a() { # LU-1606, was conf-sanity test_74
27157         if ! which $CC > /dev/null 2>&1; then
27158                 skip_env "$CC is not installed"
27159         fi
27160
27161         local extra_flags=''
27162         local out=$TMP/$tfile
27163         local prefix=/usr/include/lustre
27164         local prog
27165
27166         # Oleg removes .c files in his test rig so test if any c files exist
27167         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27168                 skip_env "Needed .c test files are missing"
27169
27170         if ! [[ -d $prefix ]]; then
27171                 # Assume we're running in tree and fixup the include path.
27172                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27173                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27174                 extra_flags+=" -L$LUSTRE/utils/.libs"
27175         fi
27176
27177         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27178                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27179                         error "client api broken"
27180         done
27181         rm -f $out
27182 }
27183 run_test 400a "Lustre client api program can compile and link"
27184
27185 test_400b() { # LU-1606, LU-5011
27186         local header
27187         local out=$TMP/$tfile
27188         local prefix=/usr/include/linux/lustre
27189
27190         # We use a hard coded prefix so that this test will not fail
27191         # when run in tree. There are headers in lustre/include/lustre/
27192         # that are not packaged (like lustre_idl.h) and have more
27193         # complicated include dependencies (like config.h and lnet/types.h).
27194         # Since this test about correct packaging we just skip them when
27195         # they don't exist (see below) rather than try to fixup cppflags.
27196
27197         if ! which $CC > /dev/null 2>&1; then
27198                 skip_env "$CC is not installed"
27199         fi
27200
27201         for header in $prefix/*.h; do
27202                 if ! [[ -f "$header" ]]; then
27203                         continue
27204                 fi
27205
27206                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27207                         continue # lustre_ioctl.h is internal header
27208                 fi
27209
27210                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27211                         error "cannot compile '$header'"
27212         done
27213         rm -f $out
27214 }
27215 run_test 400b "packaged headers can be compiled"
27216
27217 test_401a() { #LU-7437
27218         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27219         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27220
27221         #count the number of parameters by "list_param -R"
27222         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27223         #count the number of parameters by listing proc files
27224         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27225         echo "proc_dirs='$proc_dirs'"
27226         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27227         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27228                       sort -u | wc -l)
27229
27230         [ $params -eq $procs ] ||
27231                 error "found $params parameters vs. $procs proc files"
27232
27233         # test the list_param -D option only returns directories
27234         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27235         #count the number of parameters by listing proc directories
27236         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27237                 sort -u | wc -l)
27238
27239         [ $params -eq $procs ] ||
27240                 error "found $params parameters vs. $procs proc files"
27241 }
27242 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27243
27244 test_401b() {
27245         # jobid_var may not allow arbitrary values, so use jobid_name
27246         # if available
27247         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27248                 local testname=jobid_name tmp='testing%p'
27249         else
27250                 local testname=jobid_var tmp=testing
27251         fi
27252
27253         local save=$($LCTL get_param -n $testname)
27254
27255         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27256                 error "no error returned when setting bad parameters"
27257
27258         local jobid_new=$($LCTL get_param -n foe $testname baz)
27259         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27260
27261         $LCTL set_param -n fog=bam $testname=$save bat=fog
27262         local jobid_old=$($LCTL get_param -n foe $testname bag)
27263         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27264 }
27265 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27266
27267 test_401c() {
27268         # jobid_var may not allow arbitrary values, so use jobid_name
27269         # if available
27270         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27271                 local testname=jobid_name
27272         else
27273                 local testname=jobid_var
27274         fi
27275
27276         local jobid_var_old=$($LCTL get_param -n $testname)
27277         local jobid_var_new
27278
27279         $LCTL set_param $testname= &&
27280                 error "no error returned for 'set_param a='"
27281
27282         jobid_var_new=$($LCTL get_param -n $testname)
27283         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27284                 error "$testname was changed by setting without value"
27285
27286         $LCTL set_param $testname &&
27287                 error "no error returned for 'set_param a'"
27288
27289         jobid_var_new=$($LCTL get_param -n $testname)
27290         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27291                 error "$testname was changed by setting without value"
27292 }
27293 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27294
27295 test_401d() {
27296         # jobid_var may not allow arbitrary values, so use jobid_name
27297         # if available
27298         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27299                 local testname=jobid_name new_value='foo=bar%p'
27300         else
27301                 local testname=jobid_var new_valuie=foo=bar
27302         fi
27303
27304         local jobid_var_old=$($LCTL get_param -n $testname)
27305         local jobid_var_new
27306
27307         $LCTL set_param $testname=$new_value ||
27308                 error "'set_param a=b' did not accept a value containing '='"
27309
27310         jobid_var_new=$($LCTL get_param -n $testname)
27311         [[ "$jobid_var_new" == "$new_value" ]] ||
27312                 error "'set_param a=b' failed on a value containing '='"
27313
27314         # Reset the $testname to test the other format
27315         $LCTL set_param $testname=$jobid_var_old
27316         jobid_var_new=$($LCTL get_param -n $testname)
27317         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27318                 error "failed to reset $testname"
27319
27320         $LCTL set_param $testname $new_value ||
27321                 error "'set_param a b' did not accept a value containing '='"
27322
27323         jobid_var_new=$($LCTL get_param -n $testname)
27324         [[ "$jobid_var_new" == "$new_value" ]] ||
27325                 error "'set_param a b' failed on a value containing '='"
27326
27327         $LCTL set_param $testname $jobid_var_old
27328         jobid_var_new=$($LCTL get_param -n $testname)
27329         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27330                 error "failed to reset $testname"
27331 }
27332 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27333
27334 test_401e() { # LU-14779
27335         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27336                 error "lctl list_param MGC* failed"
27337         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27338         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27339                 error "lctl get_param lru_size failed"
27340 }
27341 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27342
27343 test_402() {
27344         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27345         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27346                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27347         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27348                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27349                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27350         remote_mds_nodsh && skip "remote MDS with nodsh"
27351
27352         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27353 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27354         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27355         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27356                 echo "Touch failed - OK"
27357 }
27358 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27359
27360 test_403() {
27361         local file1=$DIR/$tfile.1
27362         local file2=$DIR/$tfile.2
27363         local tfile=$TMP/$tfile
27364
27365         rm -f $file1 $file2 $tfile
27366
27367         touch $file1
27368         ln $file1 $file2
27369
27370         # 30 sec OBD_TIMEOUT in ll_getattr()
27371         # right before populating st_nlink
27372         $LCTL set_param fail_loc=0x80001409
27373         stat -c %h $file1 > $tfile &
27374
27375         # create an alias, drop all locks and reclaim the dentry
27376         < $file2
27377         cancel_lru_locks mdc
27378         cancel_lru_locks osc
27379         sysctl -w vm.drop_caches=2
27380
27381         wait
27382
27383         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27384
27385         rm -f $tfile $file1 $file2
27386 }
27387 run_test 403 "i_nlink should not drop to zero due to aliasing"
27388
27389 test_404() { # LU-6601
27390         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27391                 skip "Need server version newer than 2.8.52"
27392         remote_mds_nodsh && skip "remote MDS with nodsh"
27393
27394         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27395                 awk '/osp .*-osc-MDT/ { print $4}')
27396
27397         local osp
27398         for osp in $mosps; do
27399                 echo "Deactivate: " $osp
27400                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27401                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27402                         awk -vp=$osp '$4 == p { print $2 }')
27403                 [ $stat = IN ] || {
27404                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27405                         error "deactivate error"
27406                 }
27407                 echo "Activate: " $osp
27408                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27409                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27410                         awk -vp=$osp '$4 == p { print $2 }')
27411                 [ $stat = UP ] || {
27412                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27413                         error "activate error"
27414                 }
27415         done
27416 }
27417 run_test 404 "validate manual {de}activated works properly for OSPs"
27418
27419 test_405() {
27420         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27421         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27422                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27423                         skip "Layout swap lock is not supported"
27424
27425         check_swap_layouts_support
27426         check_swap_layout_no_dom $DIR
27427
27428         test_mkdir $DIR/$tdir
27429         swap_lock_test -d $DIR/$tdir ||
27430                 error "One layout swap locked test failed"
27431 }
27432 run_test 405 "Various layout swap lock tests"
27433
27434 test_406() {
27435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27436         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27437         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27439         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27440                 skip "Need MDS version at least 2.8.50"
27441
27442         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27443         local test_pool=$TESTNAME
27444
27445         pool_add $test_pool || error "pool_add failed"
27446         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27447                 error "pool_add_targets failed"
27448
27449         save_layout_restore_at_exit $MOUNT
27450
27451         # parent set default stripe count only, child will stripe from both
27452         # parent and fs default
27453         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27454                 error "setstripe $MOUNT failed"
27455         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27456         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27457         for i in $(seq 10); do
27458                 local f=$DIR/$tdir/$tfile.$i
27459                 touch $f || error "touch failed"
27460                 local count=$($LFS getstripe -c $f)
27461                 [ $count -eq $OSTCOUNT ] ||
27462                         error "$f stripe count $count != $OSTCOUNT"
27463                 local offset=$($LFS getstripe -i $f)
27464                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27465                 local size=$($LFS getstripe -S $f)
27466                 [ $size -eq $((def_stripe_size * 2)) ] ||
27467                         error "$f stripe size $size != $((def_stripe_size * 2))"
27468                 local pool=$($LFS getstripe -p $f)
27469                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27470         done
27471
27472         # change fs default striping, delete parent default striping, now child
27473         # will stripe from new fs default striping only
27474         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27475                 error "change $MOUNT default stripe failed"
27476         $LFS setstripe -c 0 $DIR/$tdir ||
27477                 error "delete $tdir default stripe failed"
27478         for i in $(seq 11 20); do
27479                 local f=$DIR/$tdir/$tfile.$i
27480                 touch $f || error "touch $f failed"
27481                 local count=$($LFS getstripe -c $f)
27482                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27483                 local offset=$($LFS getstripe -i $f)
27484                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27485                 local size=$($LFS getstripe -S $f)
27486                 [ $size -eq $def_stripe_size ] ||
27487                         error "$f stripe size $size != $def_stripe_size"
27488                 local pool=$($LFS getstripe -p $f)
27489                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27490         done
27491
27492         unlinkmany $DIR/$tdir/$tfile. 1 20
27493
27494         local f=$DIR/$tdir/$tfile
27495         pool_remove_all_targets $test_pool $f
27496         pool_remove $test_pool $f
27497 }
27498 run_test 406 "DNE support fs default striping"
27499
27500 test_407() {
27501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27502         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27503                 skip "Need MDS version at least 2.8.55"
27504         remote_mds_nodsh && skip "remote MDS with nodsh"
27505
27506         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27507                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27508         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27509                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27510         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27511
27512         #define OBD_FAIL_DT_TXN_STOP    0x2019
27513         for idx in $(seq $MDSCOUNT); do
27514                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27515         done
27516         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27517         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27518                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27519         true
27520 }
27521 run_test 407 "transaction fail should cause operation fail"
27522
27523 test_408() {
27524         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27525
27526         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27527         lctl set_param fail_loc=0x8000040a
27528         # let ll_prepare_partial_page() fail
27529         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27530
27531         rm -f $DIR/$tfile
27532
27533         # create at least 100 unused inodes so that
27534         # shrink_icache_memory(0) should not return 0
27535         touch $DIR/$tfile-{0..100}
27536         rm -f $DIR/$tfile-{0..100}
27537         sync
27538
27539         echo 2 > /proc/sys/vm/drop_caches
27540 }
27541 run_test 408 "drop_caches should not hang due to page leaks"
27542
27543 test_409()
27544 {
27545         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27546
27547         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27548         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27549         touch $DIR/$tdir/guard || error "(2) Fail to create"
27550
27551         local PREFIX=$(str_repeat 'A' 128)
27552         echo "Create 1K hard links start at $(date)"
27553         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27554                 error "(3) Fail to hard link"
27555
27556         echo "Links count should be right although linkEA overflow"
27557         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27558         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27559         [ $linkcount -eq 1001 ] ||
27560                 error "(5) Unexpected hard links count: $linkcount"
27561
27562         echo "List all links start at $(date)"
27563         ls -l $DIR/$tdir/foo > /dev/null ||
27564                 error "(6) Fail to list $DIR/$tdir/foo"
27565
27566         echo "Unlink hard links start at $(date)"
27567         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27568                 error "(7) Fail to unlink"
27569         echo "Unlink hard links finished at $(date)"
27570 }
27571 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27572
27573 test_410()
27574 {
27575         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27576                 skip "Need client version at least 2.9.59"
27577         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27578                 skip "Need MODULES build"
27579
27580         # Create a file, and stat it from the kernel
27581         local testfile=$DIR/$tfile
27582         touch $testfile
27583
27584         local run_id=$RANDOM
27585         local my_ino=$(stat --format "%i" $testfile)
27586
27587         # Try to insert the module. This will always fail as the
27588         # module is designed to not be inserted.
27589         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27590             &> /dev/null
27591
27592         # Anything but success is a test failure
27593         dmesg | grep -q \
27594             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27595             error "no inode match"
27596 }
27597 run_test 410 "Test inode number returned from kernel thread"
27598
27599 cleanup_test411_cgroup() {
27600         trap 0
27601         cat $1/memory.stat
27602         rmdir "$1"
27603 }
27604
27605 test_411a() {
27606         local cg_basedir=/sys/fs/cgroup/memory
27607         # LU-9966
27608         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27609                 skip "no setup for cgroup"
27610
27611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27612                 error "test file creation failed"
27613         cancel_lru_locks osc
27614
27615         # Create a very small memory cgroup to force a slab allocation error
27616         local cgdir=$cg_basedir/osc_slab_alloc
27617         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27618         trap "cleanup_test411_cgroup $cgdir" EXIT
27619         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27620         echo 1M > $cgdir/memory.limit_in_bytes
27621
27622         # Should not LBUG, just be killed by oom-killer
27623         # dd will return 0 even allocation failure in some environment.
27624         # So don't check return value
27625         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27626         cleanup_test411_cgroup $cgdir
27627
27628         return 0
27629 }
27630 run_test 411a "Slab allocation error with cgroup does not LBUG"
27631
27632 test_411b() {
27633         local cg_basedir=/sys/fs/cgroup/memory
27634         # LU-9966
27635         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27636                 skip "no setup for cgroup"
27637         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27638         # testing suggests we can't reliably avoid OOM with a 64M limit, but it
27639         # seems reasonable to ask that we have at least 128M in the cgroup
27640         local memlimit_mb=256
27641
27642         # Create a cgroup and set memory limit
27643         # (tfile is used as an easy way to get a recognizable cgroup name)
27644         local cgdir=$cg_basedir/$tfile
27645         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27646         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27647         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27648
27649         echo "writing first file"
27650         # Write a file 4x the memory limit in size
27651         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27652                 error "(1) failed to write successfully"
27653
27654         sync
27655         cancel_lru_locks osc
27656
27657         rm -f $DIR/$tfile
27658         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27659
27660         # Try writing at a larger block size
27661         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27662         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27663         # need *some* memory to do IO in)
27664         echo "writing at larger block size"
27665         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27666                 error "(3) failed to write successfully"
27667
27668         sync
27669         cancel_lru_locks osc
27670         rm -f $DIR/$tfile
27671         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27672
27673         # Try writing multiple files at once
27674         echo "writing multiple files"
27675         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27676         local pid1=$!
27677         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27678         local pid2=$!
27679         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27680         local pid3=$!
27681         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27682         local pid4=$!
27683
27684         wait $pid1
27685         local rc1=$?
27686         wait $pid2
27687         local rc2=$?
27688         wait $pid3
27689         local rc3=$?
27690         wait $pid4
27691         local rc4=$?
27692         if (( rc1 != 0)); then
27693                 error "error writing to file from $pid1"
27694         fi
27695         if (( rc2 != 0)); then
27696                 error "error writing to file from $pid2"
27697         fi
27698         if (( rc3 != 0)); then
27699                 error "error writing to file from $pid3"
27700         fi
27701         if (( rc4 != 0)); then
27702                 error "error writing to file from $pid4"
27703         fi
27704
27705         sync
27706         cancel_lru_locks osc
27707
27708         # These files can be large-ish (~1 GiB total), so delete them rather
27709         # than leave for later cleanup
27710         rm -f $DIR/$tfile.*
27711         return 0
27712 }
27713 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27714
27715 test_412() {
27716         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27717         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27718                 skip "Need server version at least 2.10.55"
27719
27720         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27721                 error "mkdir failed"
27722         $LFS getdirstripe $DIR/$tdir
27723         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27724         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27725                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27726         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27727         [ $stripe_count -eq 2 ] ||
27728                 error "expect 2 get $stripe_count"
27729
27730         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27731
27732         local index
27733         local index2
27734
27735         # subdirs should be on the same MDT as parent
27736         for i in $(seq 0 $((MDSCOUNT - 1))); do
27737                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27738                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27739                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27740                 (( index == i )) || error "mdt$i/sub on MDT$index"
27741         done
27742
27743         # stripe offset -1, ditto
27744         for i in {1..10}; do
27745                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27746                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27747                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27748                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27749                 (( index == index2 )) ||
27750                         error "qos$i on MDT$index, sub on MDT$index2"
27751         done
27752
27753         local testdir=$DIR/$tdir/inherit
27754
27755         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27756         # inherit 2 levels
27757         for i in 1 2; do
27758                 testdir=$testdir/s$i
27759                 mkdir $testdir || error "mkdir $testdir failed"
27760                 index=$($LFS getstripe -m $testdir)
27761                 (( index == 1 )) ||
27762                         error "$testdir on MDT$index"
27763         done
27764
27765         # not inherit any more
27766         testdir=$testdir/s3
27767         mkdir $testdir || error "mkdir $testdir failed"
27768         getfattr -d -m dmv $testdir | grep dmv &&
27769                 error "default LMV set on $testdir" || true
27770 }
27771 run_test 412 "mkdir on specific MDTs"
27772
27773 TEST413_COUNT=${TEST413_COUNT:-200}
27774
27775 #
27776 # set_maxage() is used by test_413 only.
27777 # This is a helper function to set maxage. Does not return any value.
27778 # Input: maxage to set
27779 #
27780 set_maxage() {
27781         local lmv_qos_maxage
27782         local lod_qos_maxage
27783         local new_maxage=$1
27784
27785         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27786         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27787         stack_trap "$LCTL set_param \
27788                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27789         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27790                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27791         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27792                 lod.*.mdt_qos_maxage=$new_maxage
27793         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27794                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27795 }
27796
27797 generate_uneven_mdts() {
27798         local threshold=$1
27799         local ffree
27800         local bavail
27801         local max
27802         local min
27803         local max_index
27804         local min_index
27805         local tmp
27806         local i
27807
27808         echo
27809         echo "Check for uneven MDTs: "
27810
27811         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27812         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27813         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27814
27815         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27816         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27817         max_index=0
27818         min_index=0
27819         for ((i = 1; i < ${#ffree[@]}; i++)); do
27820                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27821                 if [ $tmp -gt $max ]; then
27822                         max=$tmp
27823                         max_index=$i
27824                 fi
27825                 if [ $tmp -lt $min ]; then
27826                         min=$tmp
27827                         min_index=$i
27828                 fi
27829         done
27830
27831         (( min > 0 )) || skip "low space on MDT$min_index"
27832         (( ${ffree[min_index]} > 0 )) ||
27833                 skip "no free files on MDT$min_index"
27834         (( ${ffree[min_index]} < 10000000 )) ||
27835                 skip "too many free files on MDT$min_index"
27836
27837         # Check if we need to generate uneven MDTs
27838         local diff=$(((max - min) * 100 / min))
27839         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27840         local testdir # individual folder within $testdirp
27841         local start
27842         local cmd
27843
27844         # fallocate is faster to consume space on MDT, if available
27845         if check_fallocate_supported mds$((min_index + 1)); then
27846                 cmd="fallocate -l 128K "
27847         else
27848                 cmd="dd if=/dev/zero bs=128K count=1 of="
27849         fi
27850
27851         echo "using cmd $cmd"
27852         for (( i = 0; diff < threshold; i++ )); do
27853                 testdir=${testdirp}/$i
27854                 [ -d $testdir ] && continue
27855
27856                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27857
27858                 mkdir -p $testdirp
27859                 # generate uneven MDTs, create till $threshold% diff
27860                 echo -n "weight diff=$diff% must be > $threshold% ..."
27861                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27862                 $LFS mkdir -i $min_index $testdir ||
27863                         error "mkdir $testdir failed"
27864                 $LFS setstripe -E 1M -L mdt $testdir ||
27865                         error "setstripe $testdir failed"
27866                 start=$SECONDS
27867                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27868                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27869                 done
27870                 sync; sleep 1; sync
27871
27872                 # wait for QOS to update
27873                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27874
27875                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27876                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27877                 max=$(((${ffree[max_index]} >> 8) *
27878                         (${bavail[max_index]} * bsize >> 16)))
27879                 min=$(((${ffree[min_index]} >> 8) *
27880                         (${bavail[min_index]} * bsize >> 16)))
27881                 (( min > 0 )) || skip "low space on MDT$min_index"
27882                 diff=$(((max - min) * 100 / min))
27883         done
27884
27885         echo "MDT filesfree available: ${ffree[*]}"
27886         echo "MDT blocks available: ${bavail[*]}"
27887         echo "weight diff=$diff%"
27888 }
27889
27890 test_qos_mkdir() {
27891         local mkdir_cmd=$1
27892         local stripe_count=$2
27893         local mdts=$(comma_list $(mdts_nodes))
27894
27895         local testdir
27896         local lmv_qos_prio_free
27897         local lmv_qos_threshold_rr
27898         local lod_qos_prio_free
27899         local lod_qos_threshold_rr
27900         local total
27901         local count
27902         local i
27903
27904         # @total is total directories created if it's testing plain
27905         # directories, otherwise it's total stripe object count for
27906         # striped directories test.
27907         # remote/striped directory unlinking is slow on zfs and may
27908         # timeout, test with fewer directories
27909         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27910
27911         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27912         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27913         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27914                 head -n1)
27915         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27916         stack_trap "$LCTL set_param \
27917                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27918         stack_trap "$LCTL set_param \
27919                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27920
27921         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27922                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27923         lod_qos_prio_free=${lod_qos_prio_free%%%}
27924         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27925                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27926         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27927         stack_trap "do_nodes $mdts $LCTL set_param \
27928                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27929         stack_trap "do_nodes $mdts $LCTL set_param \
27930                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27931
27932         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27933         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27934
27935         testdir=$DIR/$tdir-s$stripe_count/rr
27936
27937         local stripe_index=$($LFS getstripe -m $testdir)
27938         local test_mkdir_rr=true
27939
27940         getfattr -d -m dmv -e hex $testdir | grep dmv
27941         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27942                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27943                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27944                         test_mkdir_rr=false
27945         fi
27946
27947         echo
27948         $test_mkdir_rr &&
27949                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27950                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27951
27952         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27953         for (( i = 0; i < total / stripe_count; i++ )); do
27954                 eval $mkdir_cmd $testdir/subdir$i ||
27955                         error "$mkdir_cmd subdir$i failed"
27956         done
27957
27958         for (( i = 0; i < $MDSCOUNT; i++ )); do
27959                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27960                 echo "$count directories created on MDT$i"
27961                 if $test_mkdir_rr; then
27962                         (( count == total / stripe_count / MDSCOUNT )) ||
27963                                 error "subdirs are not evenly distributed"
27964                 elif (( i == stripe_index )); then
27965                         (( count == total / stripe_count )) ||
27966                                 error "$count subdirs created on MDT$i"
27967                 else
27968                         (( count == 0 )) ||
27969                                 error "$count subdirs created on MDT$i"
27970                 fi
27971
27972                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27973                         count=$($LFS getdirstripe $testdir/* |
27974                                 grep -c -P "^\s+$i\t")
27975                         echo "$count stripes created on MDT$i"
27976                         # deviation should < 5% of average
27977                         delta=$((count - total / MDSCOUNT))
27978                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27979                                 error "stripes are not evenly distributed"
27980                 fi
27981         done
27982
27983         echo
27984         echo "Check for uneven MDTs: "
27985
27986         local ffree
27987         local bavail
27988         local max
27989         local min
27990         local max_index
27991         local min_index
27992         local tmp
27993
27994         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27995         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27996         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27997
27998         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27999         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28000         max_index=0
28001         min_index=0
28002         for ((i = 1; i < ${#ffree[@]}; i++)); do
28003                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28004                 if [ $tmp -gt $max ]; then
28005                         max=$tmp
28006                         max_index=$i
28007                 fi
28008                 if [ $tmp -lt $min ]; then
28009                         min=$tmp
28010                         min_index=$i
28011                 fi
28012         done
28013         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28014
28015         (( min > 0 )) || skip "low space on MDT$min_index"
28016         (( ${ffree[min_index]} < 10000000 )) ||
28017                 skip "too many free files on MDT$min_index"
28018
28019         generate_uneven_mdts 120
28020
28021         echo "MDT filesfree available: ${ffree[*]}"
28022         echo "MDT blocks available: ${bavail[*]}"
28023         echo "weight diff=$(((max - min) * 100 / min))%"
28024         echo
28025         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28026
28027         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28028         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28029         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28030         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28031         # decrease statfs age, so that it can be updated in time
28032         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28033         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28034
28035         sleep 1
28036
28037         testdir=$DIR/$tdir-s$stripe_count/qos
28038
28039         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28040         for (( i = 0; i < total / stripe_count; i++ )); do
28041                 eval $mkdir_cmd $testdir/subdir$i ||
28042                         error "$mkdir_cmd subdir$i failed"
28043         done
28044
28045         max=0
28046         for (( i = 0; i < $MDSCOUNT; i++ )); do
28047                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28048                 (( count > max )) && max=$count
28049                 echo "$count directories created on MDT$i : curmax=$max"
28050         done
28051
28052         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28053
28054         # D-value should > 10% of average
28055         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28056                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28057
28058         # ditto for stripes
28059         if (( stripe_count > 1 )); then
28060                 max=0
28061                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28062                         count=$($LFS getdirstripe $testdir/* |
28063                                 grep -c -P "^\s+$i\t")
28064                         (( count > max )) && max=$count
28065                         echo "$count stripes created on MDT$i"
28066                 done
28067
28068                 min=$($LFS getdirstripe $testdir/* |
28069                         grep -c -P "^\s+$min_index\t")
28070                 (( max - min > total / MDSCOUNT / 10 )) ||
28071                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28072         fi
28073 }
28074
28075 most_full_mdt() {
28076         local ffree
28077         local bavail
28078         local bsize
28079         local min
28080         local min_index
28081         local tmp
28082
28083         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28084         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28085         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28086
28087         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28088         min_index=0
28089         for ((i = 1; i < ${#ffree[@]}; i++)); do
28090                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28091                 (( tmp < min )) && min=$tmp && min_index=$i
28092         done
28093
28094         echo -n $min_index
28095 }
28096
28097 test_413a() {
28098         [ $MDSCOUNT -lt 2 ] &&
28099                 skip "We need at least 2 MDTs for this test"
28100
28101         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28102                 skip "Need server version at least 2.12.52"
28103
28104         local stripe_max=$((MDSCOUNT - 1))
28105         local stripe_count
28106
28107         # let caller set maxage for latest result
28108         set_maxage 1
28109
28110         # fill MDT unevenly
28111         generate_uneven_mdts 120
28112
28113         # test 4-stripe directory at most, otherwise it's too slow
28114         # We are being very defensive. Although Autotest uses 4 MDTs.
28115         # We make sure stripe_max does not go over 4.
28116         (( stripe_max > 4 )) && stripe_max=4
28117         # unlinking striped directory is slow on zfs, and may timeout, only test
28118         # plain directory
28119         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28120         for stripe_count in $(seq 1 $stripe_max); do
28121                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28122                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28123                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28124                         error "mkdir failed"
28125                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28126         done
28127 }
28128 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28129
28130 test_413b() {
28131         [ $MDSCOUNT -lt 2 ] &&
28132                 skip "We need at least 2 MDTs for this test"
28133
28134         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28135                 skip "Need server version at least 2.12.52"
28136
28137         local stripe_max=$((MDSCOUNT - 1))
28138         local testdir
28139         local stripe_count
28140
28141         # let caller set maxage for latest result
28142         set_maxage 1
28143
28144         # fill MDT unevenly
28145         generate_uneven_mdts 120
28146
28147         # test 4-stripe directory at most, otherwise it's too slow
28148         # We are being very defensive. Although Autotest uses 4 MDTs.
28149         # We make sure stripe_max does not go over 4.
28150         (( stripe_max > 4 )) && stripe_max=4
28151         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28152         for stripe_count in $(seq 1 $stripe_max); do
28153                 testdir=$DIR/$tdir-s$stripe_count
28154                 mkdir $testdir || error "mkdir $testdir failed"
28155                 mkdir $testdir/rr || error "mkdir rr failed"
28156                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28157                         error "mkdir qos failed"
28158                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28159                         $testdir/rr || error "setdirstripe rr failed"
28160                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28161                         error "setdirstripe failed"
28162                 test_qos_mkdir "mkdir" $stripe_count
28163         done
28164 }
28165 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28166
28167 test_413c() {
28168         (( $MDSCOUNT >= 2 )) ||
28169                 skip "We need at least 2 MDTs for this test"
28170
28171         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28172                 skip "Need server version at least 2.14.51"
28173
28174         local testdir
28175         local inherit
28176         local inherit_rr
28177         local lmv_qos_maxage
28178         local lod_qos_maxage
28179
28180         # let caller set maxage for latest result
28181         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28182         $LCTL set_param lmv.*.qos_maxage=1
28183         stack_trap "$LCTL set_param \
28184                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28185         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28186                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28187         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28188                 lod.*.mdt_qos_maxage=1
28189         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28190                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28191
28192         # fill MDT unevenly
28193         generate_uneven_mdts 120
28194
28195         testdir=$DIR/${tdir}-s1
28196         mkdir $testdir || error "mkdir $testdir failed"
28197         mkdir $testdir/rr || error "mkdir rr failed"
28198         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28199         # default max_inherit is -1, default max_inherit_rr is 0
28200         $LFS setdirstripe -D -c 1 $testdir/rr ||
28201                 error "setdirstripe rr failed"
28202         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28203                 error "setdirstripe qos failed"
28204         test_qos_mkdir "mkdir" 1
28205
28206         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28207         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28208         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28209         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28210         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28211
28212         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28213         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28214         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28215         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28216         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28217         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28218         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28219                 error "level2 shouldn't have default LMV" || true
28220 }
28221 run_test 413c "mkdir with default LMV max inherit rr"
28222
28223 test_413d() {
28224         (( MDSCOUNT >= 2 )) ||
28225                 skip "We need at least 2 MDTs for this test"
28226
28227         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28228                 skip "Need server version at least 2.14.51"
28229
28230         local lmv_qos_threshold_rr
28231
28232         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28233                 head -n1)
28234         stack_trap "$LCTL set_param \
28235                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28236
28237         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28238         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28239         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28240                 error "$tdir shouldn't have default LMV"
28241         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28242                 error "mkdir sub failed"
28243
28244         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28245
28246         (( count == 100 )) || error "$count subdirs on MDT0"
28247 }
28248 run_test 413d "inherit ROOT default LMV"
28249
28250 test_413e() {
28251         (( MDSCOUNT >= 2 )) ||
28252                 skip "We need at least 2 MDTs for this test"
28253         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28254                 skip "Need server version at least 2.14.55"
28255
28256         local testdir=$DIR/$tdir
28257         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28258         local max_inherit
28259         local sub_max_inherit
28260
28261         mkdir -p $testdir || error "failed to create $testdir"
28262
28263         # set default max-inherit to -1 if stripe count is 0 or 1
28264         $LFS setdirstripe -D -c 1 $testdir ||
28265                 error "failed to set default LMV"
28266         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28267         (( max_inherit == -1 )) ||
28268                 error "wrong max_inherit value $max_inherit"
28269
28270         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28271         $LFS setdirstripe -D -c -1 $testdir ||
28272                 error "failed to set default LMV"
28273         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28274         (( max_inherit > 0 )) ||
28275                 error "wrong max_inherit value $max_inherit"
28276
28277         # and the subdir will decrease the max_inherit by 1
28278         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28279         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28280         (( sub_max_inherit == max_inherit - 1)) ||
28281                 error "wrong max-inherit of subdir $sub_max_inherit"
28282
28283         # check specified --max-inherit and warning message
28284         stack_trap "rm -f $tmpfile"
28285         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28286                 error "failed to set default LMV"
28287         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28288         (( max_inherit == -1 )) ||
28289                 error "wrong max_inherit value $max_inherit"
28290
28291         # check the warning messages
28292         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28293                 error "failed to detect warning string"
28294         fi
28295 }
28296 run_test 413e "check default max-inherit value"
28297
28298 test_fs_dmv_inherit()
28299 {
28300         local testdir=$DIR/$tdir
28301
28302         local count
28303         local inherit
28304         local inherit_rr
28305
28306         for i in 1 2; do
28307                 mkdir $testdir || error "mkdir $testdir failed"
28308                 count=$($LFS getdirstripe -D -c $testdir)
28309                 (( count == 1 )) ||
28310                         error "$testdir default LMV count mismatch $count != 1"
28311                 inherit=$($LFS getdirstripe -D -X $testdir)
28312                 (( inherit == 3 - i )) ||
28313                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28314                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28315                 (( inherit_rr == 3 - i )) ||
28316                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28317                 testdir=$testdir/sub
28318         done
28319
28320         mkdir $testdir || error "mkdir $testdir failed"
28321         count=$($LFS getdirstripe -D -c $testdir)
28322         (( count == 0 )) ||
28323                 error "$testdir default LMV count not zero: $count"
28324 }
28325
28326 test_413f() {
28327         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28328
28329         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28330                 skip "Need server version at least 2.14.55"
28331
28332         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28333                 error "dump $DIR default LMV failed"
28334         stack_trap "setfattr --restore=$TMP/dmv.ea"
28335
28336         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28337                 error "set $DIR default LMV failed"
28338
28339         test_fs_dmv_inherit
28340 }
28341 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28342
28343 test_413g() {
28344         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28345
28346         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28347         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28348                 error "dump $DIR default LMV failed"
28349         stack_trap "setfattr --restore=$TMP/dmv.ea"
28350
28351         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28352                 error "set $DIR default LMV failed"
28353
28354         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28355                 error "mount $MOUNT2 failed"
28356         stack_trap "umount_client $MOUNT2"
28357
28358         local saved_DIR=$DIR
28359
28360         export DIR=$MOUNT2
28361
28362         stack_trap "export DIR=$saved_DIR"
28363
28364         # first check filesystem-wide default LMV inheritance
28365         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28366
28367         # then check subdirs are spread to all MDTs
28368         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28369
28370         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28371
28372         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28373 }
28374 run_test 413g "enforce ROOT default LMV on subdir mount"
28375
28376 test_413h() {
28377         (( MDSCOUNT >= 2 )) ||
28378                 skip "We need at least 2 MDTs for this test"
28379
28380         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28381                 skip "Need server version at least 2.15.50.6"
28382
28383         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28384
28385         stack_trap "$LCTL set_param \
28386                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28387         $LCTL set_param lmv.*.qos_maxage=1
28388
28389         local depth=5
28390         local rr_depth=4
28391         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28392         local count=$((MDSCOUNT * 20))
28393
28394         generate_uneven_mdts 50
28395
28396         mkdir -p $dir || error "mkdir $dir failed"
28397         stack_trap "rm -rf $dir"
28398         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28399                 --max-inherit-rr=$rr_depth $dir
28400
28401         for ((d=0; d < depth + 2; d++)); do
28402                 log "dir=$dir:"
28403                 for ((sub=0; sub < count; sub++)); do
28404                         mkdir $dir/d$sub
28405                 done
28406                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28407                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28408                 # subdirs within $rr_depth should be created round-robin
28409                 if (( d < rr_depth )); then
28410                         (( ${num[0]} != count )) ||
28411                                 error "all objects created on MDT ${num[1]}"
28412                 fi
28413
28414                 dir=$dir/d0
28415         done
28416 }
28417 run_test 413h "don't stick to parent for round-robin dirs"
28418
28419 test_413i() {
28420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28421
28422         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28423                 skip "Need server version at least 2.14.55"
28424
28425         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28426                 error "dump $DIR default LMV failed"
28427         stack_trap "setfattr --restore=$TMP/dmv.ea"
28428
28429         local testdir=$DIR/$tdir
28430         local def_max_rr=1
28431         local def_max=3
28432         local count
28433
28434         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28435                 --max-inherit-rr=$def_max_rr $DIR ||
28436                 error "set $DIR default LMV failed"
28437
28438         for i in $(seq 2 3); do
28439                 def_max=$((def_max - 1))
28440                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28441
28442                 mkdir $testdir
28443                 # RR is decremented and keeps zeroed once exhausted
28444                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28445                 (( count == def_max_rr )) ||
28446                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28447
28448                 # max-inherit is decremented
28449                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28450                 (( count == def_max )) ||
28451                         error_noexit "$testdir: max-inherit $count != $def_max"
28452
28453                 testdir=$testdir/d$i
28454         done
28455
28456         # d3 is the last inherited from ROOT, no inheritance anymore
28457         # i.e. no the default layout anymore
28458         mkdir -p $testdir/d4/d5
28459         count=$($LFS getdirstripe -D --max-inherit $testdir)
28460         (( count == -1 )) ||
28461                 error_noexit "$testdir: max-inherit $count != -1"
28462
28463         local p_count=$($LFS getdirstripe -i $testdir)
28464
28465         for i in $(seq 4 5); do
28466                 testdir=$testdir/d$i
28467
28468                 # the root default layout is not applied once exhausted
28469                 count=$($LFS getdirstripe -i $testdir)
28470                 (( count == p_count )) ||
28471                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28472         done
28473
28474         $LFS setdirstripe -i 0 $DIR/d2
28475         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28476         (( count == -1 )) ||
28477                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28478 }
28479 run_test 413i "check default layout inheritance"
28480
28481 test_413z() {
28482         local pids=""
28483         local subdir
28484         local pid
28485
28486         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28487                 unlinkmany $subdir/f. $TEST413_COUNT &
28488                 pids="$pids $!"
28489         done
28490
28491         for pid in $pids; do
28492                 wait $pid
28493         done
28494
28495         true
28496 }
28497 run_test 413z "413 test cleanup"
28498
28499 test_414() {
28500 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28501         $LCTL set_param fail_loc=0x80000521
28502         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28503         rm -f $DIR/$tfile
28504 }
28505 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28506
28507 test_415() {
28508         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28509         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28510                 skip "Need server version at least 2.11.52"
28511
28512         # LU-11102
28513         local total=500
28514         local max=120
28515
28516         # this test may be slow on ZFS
28517         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28518
28519         # though this test is designed for striped directory, let's test normal
28520         # directory too since lock is always saved as CoS lock.
28521         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28522         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28523         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28524         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28525         wait_delete_completed_mds
28526
28527         # run a loop without concurrent touch to measure rename duration.
28528         # only for test debug/robustness, NOT part of COS functional test.
28529         local start_time=$SECONDS
28530         for ((i = 0; i < total; i++)); do
28531                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28532                         > /dev/null
28533         done
28534         local baseline=$((SECONDS - start_time))
28535         echo "rename $total files without 'touch' took $baseline sec"
28536
28537         (
28538                 while true; do
28539                         touch $DIR/$tdir
28540                 done
28541         ) &
28542         local setattr_pid=$!
28543
28544         # rename files back to original name so unlinkmany works
28545         start_time=$SECONDS
28546         for ((i = 0; i < total; i++)); do
28547                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28548                         > /dev/null
28549         done
28550         local duration=$((SECONDS - start_time))
28551
28552         kill -9 $setattr_pid
28553
28554         echo "rename $total files with 'touch' took $duration sec"
28555         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28556         (( duration <= max )) ||
28557                 error_not_in_vm "rename took $duration > $max sec"
28558 }
28559 run_test 415 "lock revoke is not missing"
28560
28561 test_416() {
28562         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28563                 skip "Need server version at least 2.11.55"
28564
28565         # define OBD_FAIL_OSD_TXN_START    0x19a
28566         do_facet mds1 lctl set_param fail_loc=0x19a
28567
28568         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28569
28570         true
28571 }
28572 run_test 416 "transaction start failure won't cause system hung"
28573
28574 cleanup_417() {
28575         trap 0
28576         do_nodes $(comma_list $(mdts_nodes)) \
28577                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28578         do_nodes $(comma_list $(mdts_nodes)) \
28579                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28580         do_nodes $(comma_list $(mdts_nodes)) \
28581                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28582 }
28583
28584 test_417() {
28585         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28586         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28587                 skip "Need MDS version at least 2.11.56"
28588
28589         trap cleanup_417 RETURN EXIT
28590
28591         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28592         do_nodes $(comma_list $(mdts_nodes)) \
28593                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28594         $LFS migrate -m 0 $DIR/$tdir.1 &&
28595                 error "migrate dir $tdir.1 should fail"
28596
28597         do_nodes $(comma_list $(mdts_nodes)) \
28598                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28599         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28600                 error "create remote dir $tdir.2 should fail"
28601
28602         do_nodes $(comma_list $(mdts_nodes)) \
28603                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28604         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28605                 error "create striped dir $tdir.3 should fail"
28606         true
28607 }
28608 run_test 417 "disable remote dir, striped dir and dir migration"
28609
28610 # Checks that the outputs of df [-i] and lfs df [-i] match
28611 #
28612 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28613 check_lfs_df() {
28614         local dir=$2
28615         local inodes
28616         local df_out
28617         local lfs_df_out
28618         local count
28619         local passed=false
28620
28621         # blocks or inodes
28622         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28623
28624         for count in {1..100}; do
28625                 do_nodes "$CLIENTS" \
28626                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28627                 sync; sleep 0.2
28628
28629                 # read the lines of interest
28630                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28631                         error "df $inodes $dir | tail -n +2 failed"
28632                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28633                         error "lfs df $inodes $dir | grep summary: failed"
28634
28635                 # skip first substrings of each output as they are different
28636                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28637                 # compare the two outputs
28638                 passed=true
28639                 #  skip "available" on MDT until LU-13997 is fixed.
28640                 #for i in {1..5}; do
28641                 for i in 1 2 4 5; do
28642                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28643                 done
28644                 $passed && break
28645         done
28646
28647         if ! $passed; then
28648                 df -P $inodes $dir
28649                 echo
28650                 lfs df $inodes $dir
28651                 error "df and lfs df $1 output mismatch: "      \
28652                       "df ${inodes}: ${df_out[*]}, "            \
28653                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28654         fi
28655 }
28656
28657 test_418() {
28658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28659
28660         local dir=$DIR/$tdir
28661         local numfiles=$((RANDOM % 4096 + 2))
28662         local numblocks=$((RANDOM % 256 + 1))
28663
28664         wait_delete_completed
28665         test_mkdir $dir
28666
28667         # check block output
28668         check_lfs_df blocks $dir
28669         # check inode output
28670         check_lfs_df inodes $dir
28671
28672         # create a single file and retest
28673         echo "Creating a single file and testing"
28674         createmany -o $dir/$tfile- 1 &>/dev/null ||
28675                 error "creating 1 file in $dir failed"
28676         check_lfs_df blocks $dir
28677         check_lfs_df inodes $dir
28678
28679         # create a random number of files
28680         echo "Creating $((numfiles - 1)) files and testing"
28681         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28682                 error "creating $((numfiles - 1)) files in $dir failed"
28683
28684         # write a random number of blocks to the first test file
28685         echo "Writing $numblocks 4K blocks and testing"
28686         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28687                 count=$numblocks &>/dev/null ||
28688                 error "dd to $dir/${tfile}-0 failed"
28689
28690         # retest
28691         check_lfs_df blocks $dir
28692         check_lfs_df inodes $dir
28693
28694         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28695                 error "unlinking $numfiles files in $dir failed"
28696 }
28697 run_test 418 "df and lfs df outputs match"
28698
28699 test_419()
28700 {
28701         local dir=$DIR/$tdir
28702
28703         mkdir -p $dir
28704         touch $dir/file
28705
28706         cancel_lru_locks mdc
28707
28708         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28709         $LCTL set_param fail_loc=0x1410
28710         cat $dir/file
28711         $LCTL set_param fail_loc=0
28712         rm -rf $dir
28713 }
28714 run_test 419 "Verify open file by name doesn't crash kernel"
28715
28716 test_420()
28717 {
28718         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28719                 skip "Need MDS version at least 2.12.53"
28720
28721         local SAVE_UMASK=$(umask)
28722         local dir=$DIR/$tdir
28723         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28724
28725         mkdir -p $dir
28726         umask 0000
28727         mkdir -m03777 $dir/testdir
28728         ls -dn $dir/testdir
28729         # Need to remove trailing '.' when SELinux is enabled
28730         local dirperms=$(ls -dn $dir/testdir |
28731                          awk '{ sub(/\.$/, "", $1); print $1}')
28732         [ $dirperms == "drwxrwsrwt" ] ||
28733                 error "incorrect perms on $dir/testdir"
28734
28735         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28736                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28737         ls -n $dir/testdir/testfile
28738         local fileperms=$(ls -n $dir/testdir/testfile |
28739                           awk '{ sub(/\.$/, "", $1); print $1}')
28740         [ $fileperms == "-rwxr-xr-x" ] ||
28741                 error "incorrect perms on $dir/testdir/testfile"
28742
28743         umask $SAVE_UMASK
28744 }
28745 run_test 420 "clear SGID bit on non-directories for non-members"
28746
28747 test_421a() {
28748         local cnt
28749         local fid1
28750         local fid2
28751
28752         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28753                 skip "Need MDS version at least 2.12.54"
28754
28755         test_mkdir $DIR/$tdir
28756         createmany -o $DIR/$tdir/f 3
28757         cnt=$(ls -1 $DIR/$tdir | wc -l)
28758         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28759
28760         fid1=$(lfs path2fid $DIR/$tdir/f1)
28761         fid2=$(lfs path2fid $DIR/$tdir/f2)
28762         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28763
28764         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28765         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28766
28767         cnt=$(ls -1 $DIR/$tdir | wc -l)
28768         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28769
28770         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28771         createmany -o $DIR/$tdir/f 3
28772         cnt=$(ls -1 $DIR/$tdir | wc -l)
28773         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28774
28775         fid1=$(lfs path2fid $DIR/$tdir/f1)
28776         fid2=$(lfs path2fid $DIR/$tdir/f2)
28777         echo "remove using fsname $FSNAME"
28778         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28779
28780         cnt=$(ls -1 $DIR/$tdir | wc -l)
28781         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28782 }
28783 run_test 421a "simple rm by fid"
28784
28785 test_421b() {
28786         local cnt
28787         local FID1
28788         local FID2
28789
28790         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28791                 skip "Need MDS version at least 2.12.54"
28792
28793         test_mkdir $DIR/$tdir
28794         createmany -o $DIR/$tdir/f 3
28795         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28796         MULTIPID=$!
28797
28798         FID1=$(lfs path2fid $DIR/$tdir/f1)
28799         FID2=$(lfs path2fid $DIR/$tdir/f2)
28800         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28801
28802         kill -USR1 $MULTIPID
28803         wait
28804
28805         cnt=$(ls $DIR/$tdir | wc -l)
28806         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28807 }
28808 run_test 421b "rm by fid on open file"
28809
28810 test_421c() {
28811         local cnt
28812         local FIDS
28813
28814         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28815                 skip "Need MDS version at least 2.12.54"
28816
28817         test_mkdir $DIR/$tdir
28818         createmany -o $DIR/$tdir/f 3
28819         touch $DIR/$tdir/$tfile
28820         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28821         cnt=$(ls -1 $DIR/$tdir | wc -l)
28822         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28823
28824         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28825         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28826
28827         cnt=$(ls $DIR/$tdir | wc -l)
28828         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28829 }
28830 run_test 421c "rm by fid against hardlinked files"
28831
28832 test_421d() {
28833         local cnt
28834         local FIDS
28835
28836         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28837                 skip "Need MDS version at least 2.12.54"
28838
28839         test_mkdir $DIR/$tdir
28840         createmany -o $DIR/$tdir/f 4097
28841         cnt=$(ls -1 $DIR/$tdir | wc -l)
28842         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28843
28844         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28845         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28846
28847         cnt=$(ls $DIR/$tdir | wc -l)
28848         rm -rf $DIR/$tdir
28849         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28850 }
28851 run_test 421d "rmfid en masse"
28852
28853 test_421e() {
28854         local cnt
28855         local FID
28856
28857         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28858         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28859                 skip "Need MDS version at least 2.12.54"
28860
28861         mkdir -p $DIR/$tdir
28862         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28863         createmany -o $DIR/$tdir/striped_dir/f 512
28864         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28865         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28866
28867         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28868                 sed "s/[/][^:]*://g")
28869         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28870
28871         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28872         rm -rf $DIR/$tdir
28873         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28874 }
28875 run_test 421e "rmfid in DNE"
28876
28877 test_421f() {
28878         local cnt
28879         local FID
28880
28881         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28882                 skip "Need MDS version at least 2.12.54"
28883
28884         test_mkdir $DIR/$tdir
28885         touch $DIR/$tdir/f
28886         cnt=$(ls -1 $DIR/$tdir | wc -l)
28887         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28888
28889         FID=$(lfs path2fid $DIR/$tdir/f)
28890         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28891         # rmfid should fail
28892         cnt=$(ls -1 $DIR/$tdir | wc -l)
28893         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28894
28895         chmod a+rw $DIR/$tdir
28896         ls -la $DIR/$tdir
28897         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28898         # rmfid should fail
28899         cnt=$(ls -1 $DIR/$tdir | wc -l)
28900         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28901
28902         rm -f $DIR/$tdir/f
28903         $RUNAS touch $DIR/$tdir/f
28904         FID=$(lfs path2fid $DIR/$tdir/f)
28905         echo "rmfid as root"
28906         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28907         cnt=$(ls -1 $DIR/$tdir | wc -l)
28908         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28909
28910         rm -f $DIR/$tdir/f
28911         $RUNAS touch $DIR/$tdir/f
28912         cnt=$(ls -1 $DIR/$tdir | wc -l)
28913         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28914         FID=$(lfs path2fid $DIR/$tdir/f)
28915         # rmfid w/o user_fid2path mount option should fail
28916         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28917         cnt=$(ls -1 $DIR/$tdir | wc -l)
28918         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28919
28920         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28921         stack_trap "rmdir $tmpdir"
28922         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28923                 error "failed to mount client'"
28924         stack_trap "umount_client $tmpdir"
28925
28926         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28927         # rmfid should succeed
28928         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28929         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28930
28931         # rmfid shouldn't allow to remove files due to dir's permission
28932         chmod a+rwx $tmpdir/$tdir
28933         touch $tmpdir/$tdir/f
28934         ls -la $tmpdir/$tdir
28935         FID=$(lfs path2fid $tmpdir/$tdir/f)
28936         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28937         return 0
28938 }
28939 run_test 421f "rmfid checks permissions"
28940
28941 test_421g() {
28942         local cnt
28943         local FIDS
28944
28945         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28946         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28947                 skip "Need MDS version at least 2.12.54"
28948
28949         mkdir -p $DIR/$tdir
28950         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28951         createmany -o $DIR/$tdir/striped_dir/f 512
28952         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28953         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28954
28955         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28956                 sed "s/[/][^:]*://g")
28957
28958         rm -f $DIR/$tdir/striped_dir/f1*
28959         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28960         removed=$((512 - cnt))
28961
28962         # few files have been just removed, so we expect
28963         # rmfid to fail on their fids
28964         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28965         [ $removed != $errors ] && error "$errors != $removed"
28966
28967         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28968         rm -rf $DIR/$tdir
28969         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28970 }
28971 run_test 421g "rmfid to return errors properly"
28972
28973 test_421h() {
28974         local mount_other
28975         local mount_ret
28976         local rmfid_ret
28977         local old_fid
28978         local fidA
28979         local fidB
28980         local fidC
28981         local fidD
28982
28983         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28984                 skip "Need MDS version at least 2.15.53"
28985
28986         test_mkdir $DIR/$tdir
28987         test_mkdir $DIR/$tdir/subdir
28988         touch $DIR/$tdir/subdir/file0
28989         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28990         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28991         rm -f $DIR/$tdir/subdir/file0
28992         touch $DIR/$tdir/subdir/fileA
28993         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28994         echo File $DIR/$tdir/subdir/fileA FID $fidA
28995         touch $DIR/$tdir/subdir/fileB
28996         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28997         echo File $DIR/$tdir/subdir/fileB FID $fidB
28998         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28999         touch $DIR/$tdir/subdir/fileC
29000         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29001         echo File $DIR/$tdir/subdir/fileC FID $fidC
29002         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29003         touch $DIR/$tdir/fileD
29004         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29005         echo File $DIR/$tdir/fileD FID $fidD
29006
29007         # mount another client mount point with subdirectory mount
29008         export FILESET=/$tdir/subdir
29009         mount_other=${MOUNT}_other
29010         mount_client $mount_other ${MOUNT_OPTS}
29011         mount_ret=$?
29012         export FILESET=""
29013         (( mount_ret == 0 )) || error "mount $mount_other failed"
29014
29015         echo Removing FIDs:
29016         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29017         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29018         rmfid_ret=$?
29019
29020         umount_client $mount_other || error "umount $mount_other failed"
29021
29022         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29023
29024         # fileA should have been deleted
29025         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29026
29027         # fileB should have been deleted
29028         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29029
29030         # fileC should not have been deleted, fid also exists outside of fileset
29031         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29032
29033         # fileD should not have been deleted, it exists outside of fileset
29034         stat $DIR/$tdir/fileD || error "fileD deleted"
29035 }
29036 run_test 421h "rmfid with fileset mount"
29037
29038 test_422() {
29039         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29040         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29041         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29042         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29043         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29044
29045         local amc=$(at_max_get client)
29046         local amo=$(at_max_get mds1)
29047         local timeout=`lctl get_param -n timeout`
29048
29049         at_max_set 0 client
29050         at_max_set 0 mds1
29051
29052 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29053         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29054                         fail_val=$(((2*timeout + 10)*1000))
29055         touch $DIR/$tdir/d3/file &
29056         sleep 2
29057 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29058         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29059                         fail_val=$((2*timeout + 5))
29060         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29061         local pid=$!
29062         sleep 1
29063         kill -9 $pid
29064         sleep $((2 * timeout))
29065         echo kill $pid
29066         kill -9 $pid
29067         lctl mark touch
29068         touch $DIR/$tdir/d2/file3
29069         touch $DIR/$tdir/d2/file4
29070         touch $DIR/$tdir/d2/file5
29071
29072         wait
29073         at_max_set $amc client
29074         at_max_set $amo mds1
29075
29076         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29077         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29078                 error "Watchdog is always throttled"
29079 }
29080 run_test 422 "kill a process with RPC in progress"
29081
29082 stat_test() {
29083     df -h $MOUNT &
29084     df -h $MOUNT &
29085     df -h $MOUNT &
29086     df -h $MOUNT &
29087     df -h $MOUNT &
29088     df -h $MOUNT &
29089 }
29090
29091 test_423() {
29092     local _stats
29093     # ensure statfs cache is expired
29094     sleep 2;
29095
29096     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29097     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29098
29099     return 0
29100 }
29101 run_test 423 "statfs should return a right data"
29102
29103 test_424() {
29104 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29105         $LCTL set_param fail_loc=0x80000522
29106         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29107         rm -f $DIR/$tfile
29108 }
29109 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29110
29111 test_425() {
29112         test_mkdir -c -1 $DIR/$tdir
29113         $LFS setstripe -c -1 $DIR/$tdir
29114
29115         lru_resize_disable "" 100
29116         stack_trap "lru_resize_enable" EXIT
29117
29118         sleep 5
29119
29120         for i in $(seq $((MDSCOUNT * 125))); do
29121                 local t=$DIR/$tdir/$tfile_$i
29122
29123                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29124                         error_noexit "Create file $t"
29125         done
29126         stack_trap "rm -rf $DIR/$tdir" EXIT
29127
29128         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29129                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29130                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29131
29132                 [ $lock_count -le $lru_size ] ||
29133                         error "osc lock count $lock_count > lru size $lru_size"
29134         done
29135
29136         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29137                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29138                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29139
29140                 [ $lock_count -le $lru_size ] ||
29141                         error "mdc lock count $lock_count > lru size $lru_size"
29142         done
29143 }
29144 run_test 425 "lock count should not exceed lru size"
29145
29146 test_426() {
29147         splice-test -r $DIR/$tfile
29148         splice-test -rd $DIR/$tfile
29149         splice-test $DIR/$tfile
29150         splice-test -d $DIR/$tfile
29151 }
29152 run_test 426 "splice test on Lustre"
29153
29154 test_427() {
29155         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29156         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29157                 skip "Need MDS version at least 2.12.4"
29158         local log
29159
29160         mkdir $DIR/$tdir
29161         mkdir $DIR/$tdir/1
29162         mkdir $DIR/$tdir/2
29163         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29164         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29165
29166         $LFS getdirstripe $DIR/$tdir/1/dir
29167
29168         #first setfattr for creating updatelog
29169         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29170
29171 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29172         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29173         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29174         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29175
29176         sleep 2
29177         fail mds2
29178         wait_recovery_complete mds2 $((2*TIMEOUT))
29179
29180         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29181         echo $log | grep "get update log failed" &&
29182                 error "update log corruption is detected" || true
29183 }
29184 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29185
29186 test_428() {
29187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29188         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29189                               awk '/^max_cached_mb/ { print $2 }')
29190         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29191
29192         $LCTL set_param -n llite.*.max_cached_mb=64
29193
29194         mkdir $DIR/$tdir
29195         $LFS setstripe -c 1 $DIR/$tdir
29196         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29197         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29198         #test write
29199         for f in $(seq 4); do
29200                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29201         done
29202         wait
29203
29204         cancel_lru_locks osc
29205         # Test read
29206         for f in $(seq 4); do
29207                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29208         done
29209         wait
29210 }
29211 run_test 428 "large block size IO should not hang"
29212
29213 test_429() { # LU-7915 / LU-10948
29214         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29215         local testfile=$DIR/$tfile
29216         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29217         local new_flag=1
29218         local first_rpc
29219         local second_rpc
29220         local third_rpc
29221
29222         $LCTL get_param $ll_opencache_threshold_count ||
29223                 skip "client does not have opencache parameter"
29224
29225         set_opencache $new_flag
29226         stack_trap "restore_opencache"
29227         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29228                 error "enable opencache failed"
29229         touch $testfile
29230         # drop MDC DLM locks
29231         cancel_lru_locks mdc
29232         # clear MDC RPC stats counters
29233         $LCTL set_param $mdc_rpcstats=clear
29234
29235         # According to the current implementation, we need to run 3 times
29236         # open & close file to verify if opencache is enabled correctly.
29237         # 1st, RPCs are sent for lookup/open and open handle is released on
29238         #      close finally.
29239         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29240         #      so open handle won't be released thereafter.
29241         # 3rd, No RPC is sent out.
29242         $MULTIOP $testfile oc || error "multiop failed"
29243         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29244         echo "1st: $first_rpc RPCs in flight"
29245
29246         $MULTIOP $testfile oc || error "multiop failed"
29247         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29248         echo "2nd: $second_rpc RPCs in flight"
29249
29250         $MULTIOP $testfile oc || error "multiop failed"
29251         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29252         echo "3rd: $third_rpc RPCs in flight"
29253
29254         #verify no MDC RPC is sent
29255         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29256 }
29257 run_test 429 "verify if opencache flag on client side does work"
29258
29259 lseek_test_430() {
29260         local offset
29261         local file=$1
29262
29263         # data at [200K, 400K)
29264         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29265                 error "256K->512K dd fails"
29266         # data at [2M, 3M)
29267         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29268                 error "2M->3M dd fails"
29269         # data at [4M, 5M)
29270         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29271                 error "4M->5M dd fails"
29272         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29273         # start at first component hole #1
29274         printf "Seeking hole from 1000 ... "
29275         offset=$(lseek_test -l 1000 $file)
29276         echo $offset
29277         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29278         printf "Seeking data from 1000 ... "
29279         offset=$(lseek_test -d 1000 $file)
29280         echo $offset
29281         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29282
29283         # start at first component data block
29284         printf "Seeking hole from 300000 ... "
29285         offset=$(lseek_test -l 300000 $file)
29286         echo $offset
29287         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29288         printf "Seeking data from 300000 ... "
29289         offset=$(lseek_test -d 300000 $file)
29290         echo $offset
29291         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29292
29293         # start at the first component but beyond end of object size
29294         printf "Seeking hole from 1000000 ... "
29295         offset=$(lseek_test -l 1000000 $file)
29296         echo $offset
29297         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29298         printf "Seeking data from 1000000 ... "
29299         offset=$(lseek_test -d 1000000 $file)
29300         echo $offset
29301         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29302
29303         # start at second component stripe 2 (empty file)
29304         printf "Seeking hole from 1500000 ... "
29305         offset=$(lseek_test -l 1500000 $file)
29306         echo $offset
29307         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29308         printf "Seeking data from 1500000 ... "
29309         offset=$(lseek_test -d 1500000 $file)
29310         echo $offset
29311         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29312
29313         # start at second component stripe 1 (all data)
29314         printf "Seeking hole from 3000000 ... "
29315         offset=$(lseek_test -l 3000000 $file)
29316         echo $offset
29317         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29318         printf "Seeking data from 3000000 ... "
29319         offset=$(lseek_test -d 3000000 $file)
29320         echo $offset
29321         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29322
29323         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29324                 error "2nd dd fails"
29325         echo "Add data block at 640K...1280K"
29326
29327         # start at before new data block, in hole
29328         printf "Seeking hole from 600000 ... "
29329         offset=$(lseek_test -l 600000 $file)
29330         echo $offset
29331         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29332         printf "Seeking data from 600000 ... "
29333         offset=$(lseek_test -d 600000 $file)
29334         echo $offset
29335         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29336
29337         # start at the first component new data block
29338         printf "Seeking hole from 1000000 ... "
29339         offset=$(lseek_test -l 1000000 $file)
29340         echo $offset
29341         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29342         printf "Seeking data from 1000000 ... "
29343         offset=$(lseek_test -d 1000000 $file)
29344         echo $offset
29345         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29346
29347         # start at second component stripe 2, new data
29348         printf "Seeking hole from 1200000 ... "
29349         offset=$(lseek_test -l 1200000 $file)
29350         echo $offset
29351         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29352         printf "Seeking data from 1200000 ... "
29353         offset=$(lseek_test -d 1200000 $file)
29354         echo $offset
29355         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29356
29357         # start beyond file end
29358         printf "Using offset > filesize ... "
29359         lseek_test -l 4000000 $file && error "lseek should fail"
29360         printf "Using offset > filesize ... "
29361         lseek_test -d 4000000 $file && error "lseek should fail"
29362
29363         printf "Done\n\n"
29364 }
29365
29366 test_430a() {
29367         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29368                 skip "MDT does not support SEEK_HOLE"
29369
29370         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29371                 skip "OST does not support SEEK_HOLE"
29372
29373         local file=$DIR/$tdir/$tfile
29374
29375         mkdir -p $DIR/$tdir
29376
29377         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29378         # OST stripe #1 will have continuous data at [1M, 3M)
29379         # OST stripe #2 is empty
29380         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29381         lseek_test_430 $file
29382         rm $file
29383         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29384         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29385         lseek_test_430 $file
29386         rm $file
29387         $LFS setstripe -c2 -S 512K $file
29388         echo "Two stripes, stripe size 512K"
29389         lseek_test_430 $file
29390         rm $file
29391         # FLR with stale mirror
29392         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29393                        -N -c2 -S 1M $file
29394         echo "Mirrored file:"
29395         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29396         echo "Plain 2 stripes 1M"
29397         lseek_test_430 $file
29398         rm $file
29399 }
29400 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29401
29402 test_430b() {
29403         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29404                 skip "OST does not support SEEK_HOLE"
29405
29406         local offset
29407         local file=$DIR/$tdir/$tfile
29408
29409         mkdir -p $DIR/$tdir
29410         # Empty layout lseek should fail
29411         $MCREATE $file
29412         # seek from 0
29413         printf "Seeking hole from 0 ... "
29414         lseek_test -l 0 $file && error "lseek should fail"
29415         printf "Seeking data from 0 ... "
29416         lseek_test -d 0 $file && error "lseek should fail"
29417         rm $file
29418
29419         # 1M-hole file
29420         $LFS setstripe -E 1M -c2 -E eof $file
29421         $TRUNCATE $file 1048576
29422         printf "Seeking hole from 1000000 ... "
29423         offset=$(lseek_test -l 1000000 $file)
29424         echo $offset
29425         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29426         printf "Seeking data from 1000000 ... "
29427         lseek_test -d 1000000 $file && error "lseek should fail"
29428         rm $file
29429
29430         # full component followed by non-inited one
29431         $LFS setstripe -E 1M -c2 -E eof $file
29432         dd if=/dev/urandom of=$file bs=1M count=1
29433         printf "Seeking hole from 1000000 ... "
29434         offset=$(lseek_test -l 1000000 $file)
29435         echo $offset
29436         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29437         printf "Seeking hole from 1048576 ... "
29438         lseek_test -l 1048576 $file && error "lseek should fail"
29439         # init second component and truncate back
29440         echo "123" >> $file
29441         $TRUNCATE $file 1048576
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         # boundary checks for big values
29449         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29450         offset=$(lseek_test -d 0 $file.10g)
29451         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29452         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29453         offset=$(lseek_test -d 0 $file.100g)
29454         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29455         return 0
29456 }
29457 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29458
29459 test_430c() {
29460         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29461                 skip "OST does not support SEEK_HOLE"
29462
29463         local file=$DIR/$tdir/$tfile
29464         local start
29465
29466         mkdir -p $DIR/$tdir
29467         stack_trap "rm -f $file $file.tmp"
29468         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29469
29470         # cp version 8.33+ prefers lseek over fiemap
29471         local ver=$(cp --version | awk '{ print $4; exit; }')
29472
29473         echo "cp $ver installed"
29474         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29475                 start=$SECONDS
29476                 time cp -v $file $file.tmp || error "cp $file failed"
29477                 (( SECONDS - start < 5 )) || {
29478                         strace cp $file $file.tmp |&
29479                                 grep -E "open|read|seek|FIEMAP" |
29480                                 grep -A 100 $file
29481                         error "cp: too long runtime $((SECONDS - start))"
29482                 }
29483         else
29484                 echo "cp test skipped due to $ver < 8.33"
29485         fi
29486
29487         # tar version 1.29+ supports SEEK_HOLE/DATA
29488         ver=$(tar --version | awk '{ print $4; exit; }')
29489         echo "tar $ver installed"
29490         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29491                 start=$SECONDS
29492                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29493                 (( SECONDS - start < 5 )) || {
29494                         strace tar cf $file.tmp --sparse $file |&
29495                                 grep -E "open|read|seek|FIEMAP" |
29496                                 grep -A 100 $file
29497                         error "tar: too long runtime $((SECONDS - start))"
29498                 }
29499         else
29500                 echo "tar test skipped due to $ver < 1.29"
29501         fi
29502 }
29503 run_test 430c "lseek: external tools check"
29504
29505 test_431() { # LU-14187
29506         local file=$DIR/$tdir/$tfile
29507
29508         mkdir -p $DIR/$tdir
29509         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29510         dd if=/dev/urandom of=$file bs=4k count=1
29511         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29512         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29513         #define OBD_FAIL_OST_RESTART_IO 0x251
29514         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29515         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29516         cp $file $file.0
29517         cancel_lru_locks
29518         sync_all_data
29519         echo 3 > /proc/sys/vm/drop_caches
29520         diff  $file $file.0 || error "data diff"
29521 }
29522 run_test 431 "Restart transaction for IO"
29523
29524 cleanup_test_432() {
29525         do_facet mgs $LCTL nodemap_activate 0
29526         wait_nm_sync active
29527 }
29528
29529 test_432() {
29530         local tmpdir=$TMP/dir432
29531
29532         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29533                 skip "Need MDS version at least 2.14.52"
29534
29535         stack_trap cleanup_test_432 EXIT
29536         mkdir $DIR/$tdir
29537         mkdir $tmpdir
29538
29539         do_facet mgs $LCTL nodemap_activate 1
29540         wait_nm_sync active
29541         do_facet mgs $LCTL nodemap_modify --name default \
29542                 --property admin --value 1
29543         do_facet mgs $LCTL nodemap_modify --name default \
29544                 --property trusted --value 1
29545         cancel_lru_locks mdc
29546         wait_nm_sync default admin_nodemap
29547         wait_nm_sync default trusted_nodemap
29548
29549         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29550                grep -ci "Operation not permitted") -ne 0 ]; then
29551                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29552         fi
29553 }
29554 run_test 432 "mv dir from outside Lustre"
29555
29556 test_433() {
29557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29558
29559         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29560                 skip "inode cache not supported"
29561
29562         $LCTL set_param llite.*.inode_cache=0
29563         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29564
29565         local count=256
29566         local before
29567         local after
29568
29569         cancel_lru_locks mdc
29570         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29571         createmany -m $DIR/$tdir/f $count
29572         createmany -d $DIR/$tdir/d $count
29573         ls -l $DIR/$tdir > /dev/null
29574         stack_trap "rm -rf $DIR/$tdir"
29575
29576         before=$(num_objects)
29577         cancel_lru_locks mdc
29578         after=$(num_objects)
29579
29580         # sometimes even @before is less than 2 * count
29581         while (( before - after < count )); do
29582                 sleep 1
29583                 after=$(num_objects)
29584                 wait=$((wait + 1))
29585                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29586                 if (( wait > 60 )); then
29587                         error "inode slab grew from $before to $after"
29588                 fi
29589         done
29590
29591         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29592 }
29593 run_test 433 "ldlm lock cancel releases dentries and inodes"
29594
29595 test_434() {
29596         local file
29597         local getxattr_count
29598         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29599         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29600
29601         [[ $(getenforce) == "Disabled" ]] ||
29602                 skip "lsm selinux module have to be disabled for this test"
29603
29604         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29605                 error "fail to create $DIR/$tdir/ on MDT0000"
29606
29607         touch $DIR/$tdir/$tfile-{001..100}
29608
29609         # disable the xattr cache
29610         save_lustre_params client "llite.*.xattr_cache" > $p
29611         lctl set_param llite.*.xattr_cache=0
29612         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29613
29614         # clear clients mdc stats
29615         clear_stats $mdc_stat_param ||
29616                 error "fail to clear stats on mdc MDT0000"
29617
29618         for file in $DIR/$tdir/$tfile-{001..100}; do
29619                 getfattr -n security.selinux $file |&
29620                         grep -q "Operation not supported" ||
29621                         error "getxattr on security.selinux should return EOPNOTSUPP"
29622         done
29623
29624         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29625         (( getxattr_count < 100 )) ||
29626                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29627 }
29628 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29629
29630 test_440() {
29631         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29632                 source $LUSTRE/scripts/bash-completion/lustre
29633         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29634                 source /usr/share/bash-completion/completions/lustre
29635         else
29636                 skip "bash completion scripts not found"
29637         fi
29638
29639         local lctl_completions
29640         local lfs_completions
29641
29642         lctl_completions=$(_lustre_cmds lctl)
29643         if [[ ! $lctl_completions =~ "get_param" ]]; then
29644                 error "lctl bash completion failed"
29645         fi
29646
29647         lfs_completions=$(_lustre_cmds lfs)
29648         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29649                 error "lfs bash completion failed"
29650         fi
29651 }
29652 run_test 440 "bash completion for lfs, lctl"
29653
29654 prep_801() {
29655         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29656         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29657                 skip "Need server version at least 2.9.55"
29658
29659         start_full_debug_logging
29660 }
29661
29662 post_801() {
29663         stop_full_debug_logging
29664 }
29665
29666 barrier_stat() {
29667         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29668                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29669                            awk '/The barrier for/ { print $7 }')
29670                 echo $st
29671         else
29672                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29673                 echo \'$st\'
29674         fi
29675 }
29676
29677 barrier_expired() {
29678         local expired
29679
29680         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29681                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29682                           awk '/will be expired/ { print $7 }')
29683         else
29684                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29685         fi
29686
29687         echo $expired
29688 }
29689
29690 test_801a() {
29691         prep_801
29692
29693         echo "Start barrier_freeze at: $(date)"
29694         #define OBD_FAIL_BARRIER_DELAY          0x2202
29695         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29696         # Do not reduce barrier time - See LU-11873
29697         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29698
29699         sleep 2
29700         local b_status=$(barrier_stat)
29701         echo "Got barrier status at: $(date)"
29702         [ "$b_status" = "'freezing_p1'" ] ||
29703                 error "(1) unexpected barrier status $b_status"
29704
29705         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29706         wait
29707         b_status=$(barrier_stat)
29708         [ "$b_status" = "'frozen'" ] ||
29709                 error "(2) unexpected barrier status $b_status"
29710
29711         local expired=$(barrier_expired)
29712         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29713         sleep $((expired + 3))
29714
29715         b_status=$(barrier_stat)
29716         [ "$b_status" = "'expired'" ] ||
29717                 error "(3) unexpected barrier status $b_status"
29718
29719         # Do not reduce barrier time - See LU-11873
29720         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29721                 error "(4) fail to freeze barrier"
29722
29723         b_status=$(barrier_stat)
29724         [ "$b_status" = "'frozen'" ] ||
29725                 error "(5) unexpected barrier status $b_status"
29726
29727         echo "Start barrier_thaw at: $(date)"
29728         #define OBD_FAIL_BARRIER_DELAY          0x2202
29729         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29730         do_facet mgs $LCTL barrier_thaw $FSNAME &
29731
29732         sleep 2
29733         b_status=$(barrier_stat)
29734         echo "Got barrier status at: $(date)"
29735         [ "$b_status" = "'thawing'" ] ||
29736                 error "(6) unexpected barrier status $b_status"
29737
29738         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29739         wait
29740         b_status=$(barrier_stat)
29741         [ "$b_status" = "'thawed'" ] ||
29742                 error "(7) unexpected barrier status $b_status"
29743
29744         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29745         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29746         do_facet mgs $LCTL barrier_freeze $FSNAME
29747
29748         b_status=$(barrier_stat)
29749         [ "$b_status" = "'failed'" ] ||
29750                 error "(8) unexpected barrier status $b_status"
29751
29752         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29753         do_facet mgs $LCTL barrier_thaw $FSNAME
29754
29755         post_801
29756 }
29757 run_test 801a "write barrier user interfaces and stat machine"
29758
29759 test_801b() {
29760         prep_801
29761
29762         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29763         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29764         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29765         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29766         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29767
29768         cancel_lru_locks mdc
29769
29770         # 180 seconds should be long enough
29771         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29772
29773         local b_status=$(barrier_stat)
29774         [ "$b_status" = "'frozen'" ] ||
29775                 error "(6) unexpected barrier status $b_status"
29776
29777         mkdir $DIR/$tdir/d0/d10 &
29778         mkdir_pid=$!
29779
29780         touch $DIR/$tdir/d1/f13 &
29781         touch_pid=$!
29782
29783         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29784         ln_pid=$!
29785
29786         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29787         mv_pid=$!
29788
29789         rm -f $DIR/$tdir/d4/f12 &
29790         rm_pid=$!
29791
29792         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29793
29794         # To guarantee taht the 'stat' is not blocked
29795         b_status=$(barrier_stat)
29796         [ "$b_status" = "'frozen'" ] ||
29797                 error "(8) unexpected barrier status $b_status"
29798
29799         # let above commands to run at background
29800         sleep 5
29801
29802         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29803         ps -p $touch_pid || error "(10) touch should be blocked"
29804         ps -p $ln_pid || error "(11) link should be blocked"
29805         ps -p $mv_pid || error "(12) rename should be blocked"
29806         ps -p $rm_pid || error "(13) unlink should be blocked"
29807
29808         b_status=$(barrier_stat)
29809         [ "$b_status" = "'frozen'" ] ||
29810                 error "(14) unexpected barrier status $b_status"
29811
29812         do_facet mgs $LCTL barrier_thaw $FSNAME
29813         b_status=$(barrier_stat)
29814         [ "$b_status" = "'thawed'" ] ||
29815                 error "(15) unexpected barrier status $b_status"
29816
29817         wait $mkdir_pid || error "(16) mkdir should succeed"
29818         wait $touch_pid || error "(17) touch should succeed"
29819         wait $ln_pid || error "(18) link should succeed"
29820         wait $mv_pid || error "(19) rename should succeed"
29821         wait $rm_pid || error "(20) unlink should succeed"
29822
29823         post_801
29824 }
29825 run_test 801b "modification will be blocked by write barrier"
29826
29827 test_801c() {
29828         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29829
29830         prep_801
29831
29832         stop mds2 || error "(1) Fail to stop mds2"
29833
29834         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29835
29836         local b_status=$(barrier_stat)
29837         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29838                 do_facet mgs $LCTL barrier_thaw $FSNAME
29839                 error "(2) unexpected barrier status $b_status"
29840         }
29841
29842         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29843                 error "(3) Fail to rescan barrier bitmap"
29844
29845         # Do not reduce barrier time - See LU-11873
29846         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29847
29848         b_status=$(barrier_stat)
29849         [ "$b_status" = "'frozen'" ] ||
29850                 error "(4) unexpected barrier status $b_status"
29851
29852         do_facet mgs $LCTL barrier_thaw $FSNAME
29853         b_status=$(barrier_stat)
29854         [ "$b_status" = "'thawed'" ] ||
29855                 error "(5) unexpected barrier status $b_status"
29856
29857         local devname=$(mdsdevname 2)
29858
29859         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29860
29861         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29862                 error "(7) Fail to rescan barrier bitmap"
29863
29864         post_801
29865 }
29866 run_test 801c "rescan barrier bitmap"
29867
29868 test_802b() {
29869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29870         remote_mds_nodsh && skip "remote MDS with nodsh"
29871
29872         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29873                 skip "readonly option not available"
29874
29875         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29876
29877         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29878                 error "(2) Fail to copy"
29879
29880         # write back all cached data before setting MDT to readonly
29881         cancel_lru_locks
29882         sync_all_data
29883
29884         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29885         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29886
29887         echo "Modify should be refused"
29888         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29889
29890         echo "Read should be allowed"
29891         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29892                 error "(7) Read should succeed under ro mode"
29893
29894         # disable readonly
29895         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29896 }
29897 run_test 802b "be able to set MDTs to readonly"
29898
29899 test_803a() {
29900         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29901         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29902                 skip "MDS needs to be newer than 2.10.54"
29903
29904         mkdir_on_mdt0 $DIR/$tdir
29905         # Create some objects on all MDTs to trigger related logs objects
29906         for idx in $(seq $MDSCOUNT); do
29907                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29908                         $DIR/$tdir/dir${idx} ||
29909                         error "Fail to create $DIR/$tdir/dir${idx}"
29910         done
29911
29912         wait_delete_completed # ensure old test cleanups are finished
29913         sleep 3
29914         echo "before create:"
29915         $LFS df -i $MOUNT
29916         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29917
29918         for i in {1..10}; do
29919                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29920                         error "Fail to create $DIR/$tdir/foo$i"
29921         done
29922
29923         # sync ZFS-on-MDS to refresh statfs data
29924         wait_zfs_commit mds1
29925         sleep 3
29926         echo "after create:"
29927         $LFS df -i $MOUNT
29928         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29929
29930         # allow for an llog to be cleaned up during the test
29931         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29932                 error "before ($before_used) + 10 > after ($after_used)"
29933
29934         for i in {1..10}; do
29935                 rm -rf $DIR/$tdir/foo$i ||
29936                         error "Fail to remove $DIR/$tdir/foo$i"
29937         done
29938
29939         # sync ZFS-on-MDS to refresh statfs data
29940         wait_zfs_commit mds1
29941         wait_delete_completed
29942         sleep 3 # avoid MDT return cached statfs
29943         echo "after unlink:"
29944         $LFS df -i $MOUNT
29945         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29946
29947         # allow for an llog to be created during the test
29948         [ $after_used -le $((before_used + 1)) ] ||
29949                 error "after ($after_used) > before ($before_used) + 1"
29950 }
29951 run_test 803a "verify agent object for remote object"
29952
29953 test_803b() {
29954         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29955         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29956                 skip "MDS needs to be newer than 2.13.56"
29957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29958
29959         for i in $(seq 0 $((MDSCOUNT - 1))); do
29960                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29961         done
29962
29963         local before=0
29964         local after=0
29965
29966         local tmp
29967
29968         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29969         for i in $(seq 0 $((MDSCOUNT - 1))); do
29970                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29971                         awk '/getattr/ { print $2 }')
29972                 before=$((before + tmp))
29973         done
29974         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29975         for i in $(seq 0 $((MDSCOUNT - 1))); do
29976                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29977                         awk '/getattr/ { print $2 }')
29978                 after=$((after + tmp))
29979         done
29980
29981         [ $before -eq $after ] || error "getattr count $before != $after"
29982 }
29983 run_test 803b "remote object can getattr from cache"
29984
29985 test_804() {
29986         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29987         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29988                 skip "MDS needs to be newer than 2.10.54"
29989         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29990
29991         mkdir -p $DIR/$tdir
29992         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29993                 error "Fail to create $DIR/$tdir/dir0"
29994
29995         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29996         local dev=$(mdsdevname 2)
29997
29998         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29999                 grep ${fid} || error "NOT found agent entry for dir0"
30000
30001         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30002                 error "Fail to create $DIR/$tdir/dir1"
30003
30004         touch $DIR/$tdir/dir1/foo0 ||
30005                 error "Fail to create $DIR/$tdir/dir1/foo0"
30006         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30007         local rc=0
30008
30009         for idx in $(seq $MDSCOUNT); do
30010                 dev=$(mdsdevname $idx)
30011                 do_facet mds${idx} \
30012                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30013                         grep ${fid} && rc=$idx
30014         done
30015
30016         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30017                 error "Fail to rename foo0 to foo1"
30018         if [ $rc -eq 0 ]; then
30019                 for idx in $(seq $MDSCOUNT); do
30020                         dev=$(mdsdevname $idx)
30021                         do_facet mds${idx} \
30022                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30023                         grep ${fid} && rc=$idx
30024                 done
30025         fi
30026
30027         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30028                 error "Fail to rename foo1 to foo2"
30029         if [ $rc -eq 0 ]; then
30030                 for idx in $(seq $MDSCOUNT); do
30031                         dev=$(mdsdevname $idx)
30032                         do_facet mds${idx} \
30033                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30034                         grep ${fid} && rc=$idx
30035                 done
30036         fi
30037
30038         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30039
30040         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30041                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30042         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30043                 error "Fail to rename foo2 to foo0"
30044         unlink $DIR/$tdir/dir1/foo0 ||
30045                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30046         rm -rf $DIR/$tdir/dir0 ||
30047                 error "Fail to rm $DIR/$tdir/dir0"
30048
30049         for idx in $(seq $MDSCOUNT); do
30050                 rc=0
30051
30052                 stop mds${idx}
30053                 dev=$(mdsdevname $idx)
30054                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30055                         rc=$?
30056                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30057                         error "mount mds$idx failed"
30058                 df $MOUNT > /dev/null 2>&1
30059
30060                 # e2fsck should not return error
30061                 [ $rc -eq 0 ] ||
30062                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30063         done
30064 }
30065 run_test 804 "verify agent entry for remote entry"
30066
30067 cleanup_805() {
30068         do_facet $SINGLEMDS zfs set quota=$old $fsset
30069         unlinkmany $DIR/$tdir/f- 1000000
30070         trap 0
30071 }
30072
30073 test_805() {
30074         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30075         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30076         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30077                 skip "netfree not implemented before 0.7"
30078         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30079                 skip "Need MDS version at least 2.10.57"
30080
30081         local fsset
30082         local freekb
30083         local usedkb
30084         local old
30085         local quota
30086         local pref="osd-zfs.$FSNAME-MDT0000."
30087
30088         # limit available space on MDS dataset to meet nospace issue
30089         # quickly. then ZFS 0.7.2 can use reserved space if asked
30090         # properly (using netfree flag in osd_declare_destroy()
30091         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30092         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30093                 gawk '{print $3}')
30094         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30095         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30096         let "usedkb=usedkb-freekb"
30097         let "freekb=freekb/2"
30098         if let "freekb > 5000"; then
30099                 let "freekb=5000"
30100         fi
30101         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30102         trap cleanup_805 EXIT
30103         mkdir_on_mdt0 $DIR/$tdir
30104         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30105                 error "Can't set PFL layout"
30106         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30107         rm -rf $DIR/$tdir || error "not able to remove"
30108         do_facet $SINGLEMDS zfs set quota=$old $fsset
30109         trap 0
30110 }
30111 run_test 805 "ZFS can remove from full fs"
30112
30113 # Size-on-MDS test
30114 check_lsom_data()
30115 {
30116         local file=$1
30117         local expect=$(stat -c %s $file)
30118
30119         check_lsom_size $1 $expect
30120
30121         local blocks=$($LFS getsom -b $file)
30122         expect=$(stat -c %b $file)
30123         [[ $blocks == $expect ]] ||
30124                 error "$file expected blocks: $expect, got: $blocks"
30125 }
30126
30127 check_lsom_size()
30128 {
30129         local size
30130         local expect=$2
30131
30132         cancel_lru_locks mdc
30133
30134         size=$($LFS getsom -s $1)
30135         [[ $size == $expect ]] ||
30136                 error "$file expected size: $expect, got: $size"
30137 }
30138
30139 test_806() {
30140         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30141                 skip "Need MDS version at least 2.11.52"
30142
30143         local bs=1048576
30144
30145         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30146
30147         disable_opencache
30148         stack_trap "restore_opencache"
30149
30150         # single-threaded write
30151         echo "Test SOM for single-threaded write"
30152         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30153                 error "write $tfile failed"
30154         check_lsom_size $DIR/$tfile $bs
30155
30156         local num=32
30157         local size=$(($num * $bs))
30158         local offset=0
30159         local i
30160
30161         echo "Test SOM for single client multi-threaded($num) write"
30162         $TRUNCATE $DIR/$tfile 0
30163         for ((i = 0; i < $num; i++)); do
30164                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30165                 local pids[$i]=$!
30166                 offset=$((offset + $bs))
30167         done
30168         for (( i=0; i < $num; i++ )); do
30169                 wait ${pids[$i]}
30170         done
30171         check_lsom_size $DIR/$tfile $size
30172
30173         $TRUNCATE $DIR/$tfile 0
30174         for ((i = 0; i < $num; i++)); do
30175                 offset=$((offset - $bs))
30176                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30177                 local pids[$i]=$!
30178         done
30179         for (( i=0; i < $num; i++ )); do
30180                 wait ${pids[$i]}
30181         done
30182         check_lsom_size $DIR/$tfile $size
30183
30184         # multi-client writes
30185         num=$(get_node_count ${CLIENTS//,/ })
30186         size=$(($num * $bs))
30187         offset=0
30188         i=0
30189
30190         echo "Test SOM for multi-client ($num) writes"
30191         $TRUNCATE $DIR/$tfile 0
30192         for client in ${CLIENTS//,/ }; do
30193                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30194                 local pids[$i]=$!
30195                 i=$((i + 1))
30196                 offset=$((offset + $bs))
30197         done
30198         for (( i=0; i < $num; i++ )); do
30199                 wait ${pids[$i]}
30200         done
30201         check_lsom_size $DIR/$tfile $offset
30202
30203         i=0
30204         $TRUNCATE $DIR/$tfile 0
30205         for client in ${CLIENTS//,/ }; do
30206                 offset=$((offset - $bs))
30207                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30208                 local pids[$i]=$!
30209                 i=$((i + 1))
30210         done
30211         for (( i=0; i < $num; i++ )); do
30212                 wait ${pids[$i]}
30213         done
30214         check_lsom_size $DIR/$tfile $size
30215
30216         # verify SOM blocks count
30217         echo "Verify SOM block count"
30218         $TRUNCATE $DIR/$tfile 0
30219         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30220                 error "failed to write file $tfile with fdatasync and fstat"
30221         check_lsom_data $DIR/$tfile
30222
30223         $TRUNCATE $DIR/$tfile 0
30224         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30225                 error "failed to write file $tfile with fdatasync"
30226         check_lsom_data $DIR/$tfile
30227
30228         $TRUNCATE $DIR/$tfile 0
30229         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30230                 error "failed to write file $tfile with sync IO"
30231         check_lsom_data $DIR/$tfile
30232
30233         # verify truncate
30234         echo "Test SOM for truncate"
30235         # use ftruncate to sync blocks on close request
30236         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30237         check_lsom_size $DIR/$tfile 16384
30238         check_lsom_data $DIR/$tfile
30239
30240         $TRUNCATE $DIR/$tfile 1234
30241         check_lsom_size $DIR/$tfile 1234
30242         # sync blocks on the MDT
30243         $MULTIOP $DIR/$tfile oc
30244         check_lsom_data $DIR/$tfile
30245 }
30246 run_test 806 "Verify Lazy Size on MDS"
30247
30248 test_807() {
30249         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30250         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30251                 skip "Need MDS version at least 2.11.52"
30252
30253         # Registration step
30254         changelog_register || error "changelog_register failed"
30255         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30256         changelog_users $SINGLEMDS | grep -q $cl_user ||
30257                 error "User $cl_user not found in changelog_users"
30258
30259         rm -rf $DIR/$tdir || error "rm $tdir failed"
30260         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30261         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30262         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30263         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30264                 error "truncate $tdir/trunc failed"
30265
30266         local bs=1048576
30267         echo "Test SOM for single-threaded write with fsync"
30268         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30269                 error "write $tfile failed"
30270         sync;sync;sync
30271
30272         # multi-client wirtes
30273         local num=$(get_node_count ${CLIENTS//,/ })
30274         local offset=0
30275         local i=0
30276
30277         echo "Test SOM for multi-client ($num) writes"
30278         touch $DIR/$tfile || error "touch $tfile failed"
30279         $TRUNCATE $DIR/$tfile 0
30280         for client in ${CLIENTS//,/ }; do
30281                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30282                 local pids[$i]=$!
30283                 i=$((i + 1))
30284                 offset=$((offset + $bs))
30285         done
30286         for (( i=0; i < $num; i++ )); do
30287                 wait ${pids[$i]}
30288         done
30289
30290         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30291         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30292         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30293         check_lsom_data $DIR/$tdir/trunc
30294         check_lsom_data $DIR/$tdir/single_dd
30295         check_lsom_data $DIR/$tfile
30296
30297         rm -rf $DIR/$tdir
30298         # Deregistration step
30299         changelog_deregister || error "changelog_deregister failed"
30300 }
30301 run_test 807 "verify LSOM syncing tool"
30302
30303 check_som_nologged()
30304 {
30305         local lines=$($LFS changelog $FSNAME-MDT0000 |
30306                 grep 'x=trusted.som' | wc -l)
30307         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30308 }
30309
30310 test_808() {
30311         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30312                 skip "Need MDS version at least 2.11.55"
30313
30314         # Registration step
30315         changelog_register || error "changelog_register failed"
30316
30317         touch $DIR/$tfile || error "touch $tfile failed"
30318         check_som_nologged
30319
30320         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30321                 error "write $tfile failed"
30322         check_som_nologged
30323
30324         $TRUNCATE $DIR/$tfile 1234
30325         check_som_nologged
30326
30327         $TRUNCATE $DIR/$tfile 1048576
30328         check_som_nologged
30329
30330         # Deregistration step
30331         changelog_deregister || error "changelog_deregister failed"
30332 }
30333 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30334
30335 check_som_nodata()
30336 {
30337         $LFS getsom $1
30338         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30339 }
30340
30341 test_809() {
30342         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30343                 skip "Need MDS version at least 2.11.56"
30344
30345         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30346                 error "failed to create DoM-only file $DIR/$tfile"
30347         touch $DIR/$tfile || error "touch $tfile failed"
30348         check_som_nodata $DIR/$tfile
30349
30350         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30351                 error "write $tfile failed"
30352         check_som_nodata $DIR/$tfile
30353
30354         $TRUNCATE $DIR/$tfile 1234
30355         check_som_nodata $DIR/$tfile
30356
30357         $TRUNCATE $DIR/$tfile 4097
30358         check_som_nodata $DIR/$file
30359 }
30360 run_test 809 "Verify no SOM xattr store for DoM-only files"
30361
30362 test_810() {
30363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30364         $GSS && skip_env "could not run with gss"
30365         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30366                 skip "OST < 2.12.58 doesn't align checksum"
30367
30368         set_checksums 1
30369         stack_trap "set_checksums $ORIG_CSUM" EXIT
30370         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30371
30372         local csum
30373         local before
30374         local after
30375         for csum in $CKSUM_TYPES; do
30376                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30377                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30378                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30379                         eval set -- $i
30380                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30381                         before=$(md5sum $DIR/$tfile)
30382                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30383                         after=$(md5sum $DIR/$tfile)
30384                         [ "$before" == "$after" ] ||
30385                                 error "$csum: $before != $after bs=$1 seek=$2"
30386                 done
30387         done
30388 }
30389 run_test 810 "partial page writes on ZFS (LU-11663)"
30390
30391 test_812a() {
30392         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30393                 skip "OST < 2.12.51 doesn't support this fail_loc"
30394
30395         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30396         # ensure ost1 is connected
30397         stat $DIR/$tfile >/dev/null || error "can't stat"
30398         wait_osc_import_state client ost1 FULL
30399         # no locks, no reqs to let the connection idle
30400         cancel_lru_locks osc
30401
30402         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30403 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30404         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30405         wait_osc_import_state client ost1 CONNECTING
30406         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30407
30408         stat $DIR/$tfile >/dev/null || error "can't stat file"
30409 }
30410 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30411
30412 test_812b() { # LU-12378
30413         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30414                 skip "OST < 2.12.51 doesn't support this fail_loc"
30415
30416         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30417         # ensure ost1 is connected
30418         stat $DIR/$tfile >/dev/null || error "can't stat"
30419         wait_osc_import_state client ost1 FULL
30420         # no locks, no reqs to let the connection idle
30421         cancel_lru_locks osc
30422
30423         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30424 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30425         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30426         wait_osc_import_state client ost1 CONNECTING
30427         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30428
30429         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30430         wait_osc_import_state client ost1 IDLE
30431 }
30432 run_test 812b "do not drop no resend request for idle connect"
30433
30434 test_812c() {
30435         local old
30436
30437         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30438
30439         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30440         $LFS getstripe $DIR/$tfile
30441         $LCTL set_param osc.*.idle_timeout=10
30442         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30443         # ensure ost1 is connected
30444         stat $DIR/$tfile >/dev/null || error "can't stat"
30445         wait_osc_import_state client ost1 FULL
30446         # no locks, no reqs to let the connection idle
30447         cancel_lru_locks osc
30448
30449 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30450         $LCTL set_param fail_loc=0x80000533
30451         sleep 15
30452         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30453 }
30454 run_test 812c "idle import vs lock enqueue race"
30455
30456 test_813() {
30457         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30458         [ -z "$file_heat_sav" ] && skip "no file heat support"
30459
30460         local readsample
30461         local writesample
30462         local readbyte
30463         local writebyte
30464         local readsample1
30465         local writesample1
30466         local readbyte1
30467         local writebyte1
30468
30469         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30470         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30471
30472         $LCTL set_param -n llite.*.file_heat=1
30473         echo "Turn on file heat"
30474         echo "Period second: $period_second, Decay percentage: $decay_pct"
30475
30476         echo "QQQQ" > $DIR/$tfile
30477         echo "QQQQ" > $DIR/$tfile
30478         echo "QQQQ" > $DIR/$tfile
30479         cat $DIR/$tfile > /dev/null
30480         cat $DIR/$tfile > /dev/null
30481         cat $DIR/$tfile > /dev/null
30482         cat $DIR/$tfile > /dev/null
30483
30484         local out=$($LFS heat_get $DIR/$tfile)
30485
30486         $LFS heat_get $DIR/$tfile
30487         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30488         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30489         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30490         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30491
30492         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30493         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30494         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30495         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30496
30497         sleep $((period_second + 3))
30498         echo "Sleep $((period_second + 3)) seconds..."
30499         # The recursion formula to calculate the heat of the file f is as
30500         # follow:
30501         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30502         # Where Hi is the heat value in the period between time points i*I and
30503         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30504         # to the weight of Ci.
30505         out=$($LFS heat_get $DIR/$tfile)
30506         $LFS heat_get $DIR/$tfile
30507         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30508         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30509         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30510         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30511
30512         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30513                 error "read sample ($readsample) is wrong"
30514         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30515                 error "write sample ($writesample) is wrong"
30516         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30517                 error "read bytes ($readbyte) is wrong"
30518         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30519                 error "write bytes ($writebyte) is wrong"
30520
30521         echo "QQQQ" > $DIR/$tfile
30522         echo "QQQQ" > $DIR/$tfile
30523         echo "QQQQ" > $DIR/$tfile
30524         cat $DIR/$tfile > /dev/null
30525         cat $DIR/$tfile > /dev/null
30526         cat $DIR/$tfile > /dev/null
30527         cat $DIR/$tfile > /dev/null
30528
30529         sleep $((period_second + 3))
30530         echo "Sleep $((period_second + 3)) seconds..."
30531
30532         out=$($LFS heat_get $DIR/$tfile)
30533         $LFS heat_get $DIR/$tfile
30534         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30535         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30536         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30537         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30538
30539         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30540                 4 * $decay_pct) / 100") -eq 1 ] ||
30541                 error "read sample ($readsample1) is wrong"
30542         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30543                 3 * $decay_pct) / 100") -eq 1 ] ||
30544                 error "write sample ($writesample1) is wrong"
30545         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30546                 20 * $decay_pct) / 100") -eq 1 ] ||
30547                 error "read bytes ($readbyte1) is wrong"
30548         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30549                 15 * $decay_pct) / 100") -eq 1 ] ||
30550                 error "write bytes ($writebyte1) is wrong"
30551
30552         echo "Turn off file heat for the file $DIR/$tfile"
30553         $LFS heat_set -o $DIR/$tfile
30554
30555         echo "QQQQ" > $DIR/$tfile
30556         echo "QQQQ" > $DIR/$tfile
30557         echo "QQQQ" > $DIR/$tfile
30558         cat $DIR/$tfile > /dev/null
30559         cat $DIR/$tfile > /dev/null
30560         cat $DIR/$tfile > /dev/null
30561         cat $DIR/$tfile > /dev/null
30562
30563         out=$($LFS heat_get $DIR/$tfile)
30564         $LFS heat_get $DIR/$tfile
30565         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30566         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30567         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30568         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30569
30570         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30571         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30572         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30573         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30574
30575         echo "Trun on file heat for the file $DIR/$tfile"
30576         $LFS heat_set -O $DIR/$tfile
30577
30578         echo "QQQQ" > $DIR/$tfile
30579         echo "QQQQ" > $DIR/$tfile
30580         echo "QQQQ" > $DIR/$tfile
30581         cat $DIR/$tfile > /dev/null
30582         cat $DIR/$tfile > /dev/null
30583         cat $DIR/$tfile > /dev/null
30584         cat $DIR/$tfile > /dev/null
30585
30586         out=$($LFS heat_get $DIR/$tfile)
30587         $LFS heat_get $DIR/$tfile
30588         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30589         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30590         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30591         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30592
30593         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30594         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30595         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30596         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30597
30598         $LFS heat_set -c $DIR/$tfile
30599         $LCTL set_param -n llite.*.file_heat=0
30600         echo "Turn off file heat support for the Lustre filesystem"
30601
30602         echo "QQQQ" > $DIR/$tfile
30603         echo "QQQQ" > $DIR/$tfile
30604         echo "QQQQ" > $DIR/$tfile
30605         cat $DIR/$tfile > /dev/null
30606         cat $DIR/$tfile > /dev/null
30607         cat $DIR/$tfile > /dev/null
30608         cat $DIR/$tfile > /dev/null
30609
30610         out=$($LFS heat_get $DIR/$tfile)
30611         $LFS heat_get $DIR/$tfile
30612         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30613         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30614         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30615         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30616
30617         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30618         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30619         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30620         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30621
30622         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30623         rm -f $DIR/$tfile
30624 }
30625 run_test 813 "File heat verfication"
30626
30627 test_814()
30628 {
30629         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30630         echo -n y >> $DIR/$tfile
30631         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30632         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30633 }
30634 run_test 814 "sparse cp works as expected (LU-12361)"
30635
30636 test_815()
30637 {
30638         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30639         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30640 }
30641 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30642
30643 test_816() {
30644         local ost1_imp=$(get_osc_import_name client ost1)
30645         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30646                          cut -d'.' -f2)
30647
30648         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30649         # ensure ost1 is connected
30650
30651         stat $DIR/$tfile >/dev/null || error "can't stat"
30652         wait_osc_import_state client ost1 FULL
30653         # no locks, no reqs to let the connection idle
30654         cancel_lru_locks osc
30655         lru_resize_disable osc
30656         local before
30657         local now
30658         before=$($LCTL get_param -n \
30659                  ldlm.namespaces.$imp_name.lru_size)
30660
30661         wait_osc_import_state client ost1 IDLE
30662         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30663         now=$($LCTL get_param -n \
30664               ldlm.namespaces.$imp_name.lru_size)
30665         [ $before == $now ] || error "lru_size changed $before != $now"
30666 }
30667 run_test 816 "do not reset lru_resize on idle reconnect"
30668
30669 cleanup_817() {
30670         umount $tmpdir
30671         exportfs -u localhost:$DIR/nfsexp
30672         rm -rf $DIR/nfsexp
30673 }
30674
30675 test_817() {
30676         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30677
30678         mkdir -p $DIR/nfsexp
30679         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30680                 error "failed to export nfs"
30681
30682         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30683         stack_trap cleanup_817 EXIT
30684
30685         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30686                 error "failed to mount nfs to $tmpdir"
30687
30688         cp /bin/true $tmpdir
30689         $DIR/nfsexp/true || error "failed to execute 'true' command"
30690 }
30691 run_test 817 "nfsd won't cache write lock for exec file"
30692
30693 test_818() {
30694         test_mkdir -i0 -c1 $DIR/$tdir
30695         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30696         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30697         stop $SINGLEMDS
30698
30699         # restore osp-syn threads
30700         stack_trap "fail $SINGLEMDS"
30701
30702         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30703         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30704         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30705                 error "start $SINGLEMDS failed"
30706         rm -rf $DIR/$tdir
30707
30708         local testid=$(echo $TESTNAME | tr '_' ' ')
30709
30710         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30711                 grep "run LFSCK" || error "run LFSCK is not suggested"
30712 }
30713 run_test 818 "unlink with failed llog"
30714
30715 test_819a() {
30716         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30717         cancel_lru_locks osc
30718         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30719         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30720         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30721         rm -f $TDIR/$tfile
30722 }
30723 run_test 819a "too big niobuf in read"
30724
30725 test_819b() {
30726         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30727         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30728         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30729         cancel_lru_locks osc
30730         sleep 1
30731         rm -f $TDIR/$tfile
30732 }
30733 run_test 819b "too big niobuf in write"
30734
30735
30736 function test_820_start_ost() {
30737         sleep 5
30738
30739         for num in $(seq $OSTCOUNT); do
30740                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30741         done
30742 }
30743
30744 test_820() {
30745         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30746
30747         mkdir $DIR/$tdir
30748         umount_client $MOUNT || error "umount failed"
30749         for num in $(seq $OSTCOUNT); do
30750                 stop ost$num
30751         done
30752
30753         # mount client with no active OSTs
30754         # so that the client can't initialize max LOV EA size
30755         # from OSC notifications
30756         mount_client $MOUNT || error "mount failed"
30757         # delay OST starting to keep this 0 max EA size for a while
30758         test_820_start_ost &
30759
30760         # create a directory on MDS2
30761         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30762                 error "Failed to create directory"
30763         # open intent should update default EA size
30764         # see mdc_update_max_ea_from_body()
30765         # notice this is the very first RPC to MDS2
30766         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30767         ret=$?
30768         echo $out
30769         # With SSK, this situation can lead to -EPERM being returned.
30770         # In that case, simply retry.
30771         if [ $ret -ne 0 ] && $SHARED_KEY; then
30772                 if echo "$out" | grep -q "not permitted"; then
30773                         cp /etc/services $DIR/$tdir/mds2
30774                         ret=$?
30775                 fi
30776         fi
30777         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30778 }
30779 run_test 820 "update max EA from open intent"
30780
30781 test_823() {
30782         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30783         local OST_MAX_PRECREATE=20000
30784
30785         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30786                 skip "Need MDS version at least 2.14.56"
30787
30788         save_lustre_params mds1 \
30789                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30790         do_facet $SINGLEMDS "$LCTL set_param -n \
30791                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30792         do_facet $SINGLEMDS "$LCTL set_param -n \
30793                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30794
30795         stack_trap "restore_lustre_params < $p; rm $p"
30796
30797         do_facet $SINGLEMDS "$LCTL set_param -n \
30798                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30799
30800         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30801                       osp.$FSNAME-OST0000*MDT0000.create_count")
30802         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30803                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30804         local expect_count=$(((($max/2)/256) * 256))
30805
30806         log "setting create_count to 100200:"
30807         log " -result- count: $count with max: $max, expecting: $expect_count"
30808
30809         [[ $count -eq expect_count ]] ||
30810                 error "Create count not set to max precreate."
30811 }
30812 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30813
30814 test_831() {
30815         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30816                 skip "Need MDS version 2.14.56"
30817
30818         local sync_changes=$(do_facet $SINGLEMDS \
30819                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30820
30821         [ "$sync_changes" -gt 100 ] &&
30822                 skip "Sync changes $sync_changes > 100 already"
30823
30824         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30825
30826         $LFS mkdir -i 0 $DIR/$tdir
30827         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30828
30829         save_lustre_params mds1 \
30830                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30831         save_lustre_params mds1 \
30832                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30833
30834         do_facet mds1 "$LCTL set_param -n \
30835                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30836                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30837         stack_trap "restore_lustre_params < $p" EXIT
30838
30839         createmany -o $DIR/$tdir/f- 1000
30840         unlinkmany $DIR/$tdir/f- 1000 &
30841         local UNLINK_PID=$!
30842
30843         while sleep 1; do
30844                 sync_changes=$(do_facet mds1 \
30845                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30846                 # the check in the code is racy, fail the test
30847                 # if the value above the limit by 10.
30848                 [ $sync_changes -gt 110 ] && {
30849                         kill -2 $UNLINK_PID
30850                         wait
30851                         error "osp changes throttling failed, $sync_changes>110"
30852                 }
30853                 kill -0 $UNLINK_PID 2> /dev/null || break
30854         done
30855         wait
30856 }
30857 run_test 831 "throttling unlink/setattr queuing on OSP"
30858
30859 test_832() {
30860         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30861         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30862                 skip "Need MDS version 2.15.52+"
30863         is_rmentry_supported || skip "rm_entry not supported"
30864
30865         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30866         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30867         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30868                 error "mkdir remote_dir failed"
30869         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30870                 error "mkdir striped_dir failed"
30871         touch $DIR/$tdir/file || error "touch file failed"
30872         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30873         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30874 }
30875 run_test 832 "lfs rm_entry"
30876
30877 test_833() {
30878         local file=$DIR/$tfile
30879
30880         stack_trap "rm -f $file" EXIT
30881         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30882
30883         local wpid
30884         local rpid
30885         local rpid2
30886
30887         # Buffered I/O write
30888         (
30889                 while [ ! -e $DIR/sanity.833.lck ]; do
30890                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30891                                 error "failed to write $file"
30892                         sleep 0.$((RANDOM % 4 + 1))
30893                 done
30894         )&
30895         wpid=$!
30896
30897         # Buffered I/O read
30898         (
30899                 while [ ! -e $DIR/sanity.833.lck ]; do
30900                         dd if=$file of=/dev/null bs=1M count=50 ||
30901                                 error "failed to read $file"
30902                         sleep 0.$((RANDOM % 4 + 1))
30903                 done
30904         )&
30905         rpid=$!
30906
30907         # Direct I/O read
30908         (
30909                 while [ ! -e $DIR/sanity.833.lck ]; do
30910                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30911                                 error "failed to read $file in direct I/O mode"
30912                         sleep 0.$((RANDOM % 4 + 1))
30913                 done
30914         )&
30915         rpid2=$!
30916
30917         sleep 30
30918         touch $DIR/sanity.833.lck
30919         wait $wpid || error "$?: buffered write failed"
30920         wait $rpid || error "$?: buffered read failed"
30921         wait $rpid2 || error "$?: direct read failed"
30922 }
30923 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30924
30925 #
30926 # tests that do cleanup/setup should be run at the end
30927 #
30928
30929 test_900() {
30930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30931         local ls
30932
30933         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30934         $LCTL set_param fail_loc=0x903
30935
30936         cancel_lru_locks MGC
30937
30938         FAIL_ON_ERROR=true cleanup
30939         FAIL_ON_ERROR=true setup
30940 }
30941 run_test 900 "umount should not race with any mgc requeue thread"
30942
30943 # LUS-6253/LU-11185
30944 test_901() {
30945         local old
30946         local count
30947         local oldc
30948         local newc
30949         local olds
30950         local news
30951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30952
30953         # some get_param have a bug to handle dot in param name
30954         cancel_lru_locks MGC
30955         old=$(mount -t lustre | wc -l)
30956         # 1 config+sptlrpc
30957         # 2 params
30958         # 3 nodemap
30959         # 4 IR
30960         old=$((old * 4))
30961         oldc=0
30962         count=0
30963         while [ $old -ne $oldc ]; do
30964                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30965                 sleep 1
30966                 ((count++))
30967                 if [ $count -ge $TIMEOUT ]; then
30968                         error "too large timeout"
30969                 fi
30970         done
30971         umount_client $MOUNT || error "umount failed"
30972         mount_client $MOUNT || error "mount failed"
30973         cancel_lru_locks MGC
30974         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30975
30976         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30977
30978         return 0
30979 }
30980 run_test 901 "don't leak a mgc lock on client umount"
30981
30982 # LU-13377
30983 test_902() {
30984         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30985                 skip "client does not have LU-13377 fix"
30986         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30987         $LCTL set_param fail_loc=0x1415
30988         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30989         cancel_lru_locks osc
30990         rm -f $DIR/$tfile
30991 }
30992 run_test 902 "test short write doesn't hang lustre"
30993
30994 # LU-14711
30995 test_903() {
30996         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30997         echo "blah" > $DIR/${tfile}-2
30998         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30999         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31000         $LCTL set_param fail_loc=0x417 fail_val=20
31001
31002         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31003         sleep 1 # To start the destroy
31004         wait_destroy_complete 150 || error "Destroy taking too long"
31005         cat $DIR/$tfile > /dev/null || error "Evicted"
31006 }
31007 run_test 903 "Test long page discard does not cause evictions"
31008
31009 test_904() {
31010         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31011         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31012                 grep -q project || skip "skip project quota not supported"
31013
31014         local testfile="$DIR/$tdir/$tfile"
31015         local xattr="trusted.projid"
31016         local projid
31017         local mdts=$(comma_list $(mdts_nodes))
31018         local saved=$(do_facet mds1 $LCTL get_param -n \
31019                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31020
31021         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31022         stack_trap "do_nodes $mdts $LCTL set_param \
31023                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31024
31025         mkdir -p $DIR/$tdir
31026         touch $testfile
31027         #hide projid xattr on server
31028         $LFS project -p 1 $testfile ||
31029                 error "set $testfile project id failed"
31030         getfattr -m - $testfile | grep $xattr &&
31031                 error "do not show trusted.projid when disabled on server"
31032         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31033         #should be hidden when projid is 0
31034         $LFS project -p 0 $testfile ||
31035                 error "set $testfile project id failed"
31036         getfattr -m - $testfile | grep $xattr &&
31037                 error "do not show trusted.projid with project ID 0"
31038
31039         #still can getxattr explicitly
31040         projid=$(getfattr -n $xattr $testfile |
31041                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31042         [ $projid == "0" ] ||
31043                 error "projid expected 0 not $projid"
31044
31045         #set the projid via setxattr
31046         setfattr -n $xattr -v "1000" $testfile ||
31047                 error "setattr failed with $?"
31048         projid=($($LFS project $testfile))
31049         [ ${projid[0]} == "1000" ] ||
31050                 error "projid expected 1000 not $projid"
31051
31052         #check the new projid via getxattr
31053         $LFS project -p 1001 $testfile ||
31054                 error "set $testfile project id failed"
31055         getfattr -m - $testfile | grep $xattr ||
31056                 error "should show trusted.projid when project ID != 0"
31057         projid=$(getfattr -n $xattr $testfile |
31058                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31059         [ $projid == "1001" ] ||
31060                 error "projid expected 1001 not $projid"
31061
31062         #try to set invalid projid
31063         setfattr -n $xattr -v "4294967295" $testfile &&
31064                 error "set invalid projid should fail"
31065
31066         #remove the xattr means setting projid to 0
31067         setfattr -x $xattr $testfile ||
31068                 error "setfattr failed with $?"
31069         projid=($($LFS project $testfile))
31070         [ ${projid[0]} == "0" ] ||
31071                 error "projid expected 0 not $projid"
31072
31073         #should be hidden when parent has inherit flag and same projid
31074         $LFS project -srp 1002 $DIR/$tdir ||
31075                 error "set $tdir project id failed"
31076         getfattr -m - $testfile | grep $xattr &&
31077                 error "do not show trusted.projid with inherit flag"
31078
31079         #still can getxattr explicitly
31080         projid=$(getfattr -n $xattr $testfile |
31081                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31082         [ $projid == "1002" ] ||
31083                 error "projid expected 1002 not $projid"
31084 }
31085 run_test 904 "virtual project ID xattr"
31086
31087 # LU-8582
31088 test_905() {
31089         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31090                 skip "need OST version >= 2.15.50.220 for fail_loc"
31091
31092         remote_ost_nodsh && skip "remote OST with nodsh"
31093         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31094
31095         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31096
31097         #define OBD_FAIL_OST_OPCODE 0x253
31098         # OST_LADVISE = 21
31099         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31100         $LFS ladvise -a willread $DIR/$tfile &&
31101                 error "unexpected success of ladvise with fault injection"
31102         $LFS ladvise -a willread $DIR/$tfile |&
31103                 grep -q "Operation not supported"
31104         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31105 }
31106 run_test 905 "bad or new opcode should not stuck client"
31107
31108 test_906() {
31109         grep -q io_uring_setup /proc/kallsyms ||
31110                 skip "Client OS does not support io_uring I/O engine"
31111         io_uring_probe || skip "kernel does not support io_uring fully"
31112         which fio || skip_env "no fio installed"
31113         fio --enghelp | grep -q io_uring ||
31114                 skip_env "fio does not support io_uring I/O engine"
31115
31116         local file=$DIR/$tfile
31117         local ioengine="io_uring"
31118         local numjobs=2
31119         local size=50M
31120
31121         fio --name=seqwrite --ioengine=$ioengine        \
31122                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31123                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31124                 error "fio seqwrite $file failed"
31125
31126         fio --name=seqread --ioengine=$ioengine \
31127                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31128                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31129                 error "fio seqread $file failed"
31130
31131         rm -f $file || error "rm -f $file failed"
31132 }
31133 run_test 906 "Simple test for io_uring I/O engine via fio"
31134
31135 test_907() {
31136         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31137
31138         # set stripe size to max rpc size
31139         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31140         $LFS getstripe $DIR/$tfile
31141 #define OBD_FAIL_OST_EROFS               0x216
31142         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31143
31144         local bs=$((max_pages * PAGE_SIZE / 16))
31145
31146         # write full one stripe and one block
31147         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31148
31149         rm $DIR/$tfile || error "rm failed"
31150 }
31151 run_test 907 "write rpc error during unlink"
31152
31153 complete_test $SECONDS
31154 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31155 check_and_cleanup_lustre
31156 if [ "$I_MOUNTED" != "yes" ]; then
31157         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31158 fi
31159 exit_status